# Baseline Tracking
Source: https://learn.nextedy.com/checklist/concepts/baselines
A checklist that only ever shows its *current* state has a fundamental limitation for audit and compliance work: it cannot prove what the checklist looked like at a specific moment in the past.
The best mental model is a photograph album next to a whiteboard. The whiteboard (the live checklist field) is always current — anyone can erase and rewrite it. A baseline is a photograph of that whiteboard taken at a specific moment. You can take as many photographs as you like over time, and none of them change when the whiteboard is later erased and rewritten. What baseline tracking gives you is the album of those photographs, in order, each one linked back to the moment it was taken.
## Why baselines exist
In regulated processes, it's often not enough to show that a Definition of Done checklist is complete *today* — you need to show it was complete *at the time a specific release, revision, or review was approved*, and that the checklist's content at that point matched what governance required. A live-only checklist can't answer "what did this look like when version 3 was approved," because by the time someone asks, the checklist may have moved on. Baseline tracking exists specifically to answer that question.
## What a baseline actually is
A baseline is represented as a lightweight record — not a duplicate copy of the checklist's data, but a reference to a **work item that represents the baseline/revision**, carrying:
* an **ID** (typically the revision or baseline value, e.g. a version tag) — used to build baseline links and match a checklist to a specific revision
* a **label** (human-readable, typically combining the ID and the associated work item's title, falling back to just the ID if no distinct title exists)
* a **date** (the baseline work item's creation date, pre-rendered from the work item's `created` field)
* a **URL** linking to the document at that specific baseline revision
* a **status** (the underlying baseline work item's workflow status, e.g. Open, Approved — rendered with its normal status icon)
* the underlying work item's identifier
In other words, "creating a baseline" in this system means creating (or having Polarion create) a work item that stands in for a document revision, and Nextedy CHECKLIST's baseline machinery finds that work item and uses it as an anchor point to reconstruct the checklist as it existed at that revision.
## The two configuration properties behind baseline lookup
Baseline lookup is driven by document-scoped configuration, resolved via two properties:
* `nextedy.checklist.baselines.itemType` — specifies which work item type represents a baseline record for checklist history. **Default: `btask`.**
* `nextedy.checklist.baselines.baselineField` — specifies which custom field on that baseline item type stores the baseline/revision identifier. **Default: `baseline`.**
These two properties are what let the system build Lucene queries to find either a single baseline item matching a specific revision, or the full set of baseline items associated with a document. If your project uses a different work item type or field to represent revisions, these are the properties to adjust — but note that, unlike the four-level type/field/status hierarchy described in [Configuration Property Hierarchy](/checklist/concepts/configuration-property-hierarchy), these two are read per-document rather than resolved through that broader precedence chain.
**Verify in application**
These two properties and their defaults are documented, but no narrower per-type or per-field scoping is documented for them, unlike most other Checklist configuration properties. Treat them as document-scoped settings rather than assuming they participate in the same four-level hierarchy used elsewhere, and verify this in your Polarion instance before relying on it.
## Two ways a document's baseline history renders
The baseline view for a document behaves differently depending on whether you're looking at a *specific* revision or browsing the *history* as a whole:
1. **General listing mode** — queries all baseline work items associated with the document (via the configured item type and baseline field), sorts them by the baseline field, and renders each as a row showing its label, date, status, and a link to that revision. This is the "photo album" view.
2. **Revision-scoped rendering mode** — when a specific revision context is active, the view looks up the matching baseline work item for that revision and renders the checklist *as it existed at that baseline* rather than the live checklist. This is opening a single photograph instead of browsing the album.
The view also automatically adapts when a document is being exported or rendered as a PDF, switching its render mode based on that context.
**Verify in application**
A flag exists to mark the baselines view as hidden when a document is exported to PDF, but its effect on the exported output is unconfirmed. Confirm in your Polarion instance whether setting this flag actually suppresses the baselines list in PDF output before relying on it for a compliance document that must not show baseline history in its exported form.
## Baselines are read-only history, not editable state
A critical distinction: baseline tracking is a *reporting and traceability* feature, not an editable one. You don't check or uncheck items against a historical baseline — you view what was recorded. The live, editable checklist lives on the current document; baselines only ever look backward at frozen work-item-anchored snapshots.
This is why baseline tracking pairs so naturally with [Workflow Gates](/checklist/concepts/workflow-gates): a gate enforces that a checklist is complete *before* a transition (for example, before a document is approved or a revision is finalized), and a baseline captured at that same point in time gives you durable, queryable evidence that the gate's requirement was actually satisfied when the transition happened — not just that it happens to be satisfied whenever someone looks at it later.
## Common misconceptions
**A baseline is not a copy of the checklist's data**
It's tempting to assume a baseline stores its own independent copy of every checklist item and result. A baseline is better understood as a *pointer* — a work item representing a revision, located via a Lucene query against a configured item type and field — from which the checklist as it existed at that document revision is reconstructed. The baseline mechanism depends on the underlying document revision actually being preserved (a standard Polarion document versioning capability); the baseline work item itself does not duplicate the checklist content independently of that revision.
**Changing the baseline item type or field affects lookup, not history**
Reconfiguring `nextedy.checklist.baselines.itemType` or `nextedy.checklist.baselines.baselineField` changes which work items the system searches for when building the baseline list — it does not migrate or relabel work items that already exist under the old type/field. If you change these properties after baselines are already in use, previously created baseline work items under the old type/field will no longer be found unless they're also updated to match.
## Object scope
Baseline tracking is documented specifically in terms of **documents** — the baseline view is built and queried per-document, and the baseline work item's URL links to the document at that specific baseline revision. Work item, test run, and plan checklists are covered elsewhere by templates and workflow gates, but the baseline/history mechanism is a document-level capability.
**Verify in application**
If your process requires historical snapshots of work item, test run, or plan checklists (rather than document checklists), confirm in your Polarion instance whether an equivalent baseline mechanism exists for those object types. Only document-level baseline tracking is documented.
## Related guides
* [Your First Checklist](/checklist/getting-started/your-first-checklist)
* [Set Up a Plan Checklist (Tutorial)](/checklist/getting-started/setup-plan-checklist)
* [Set Up a Test Run Checklist (Tutorial)](/checklist/getting-started/setup-test-run-checklist)
# Checklist Items, Result States, and Text Syntax
Source: https://learn.nextedy.com/checklist/concepts/checklist-items-and-result-states
Every checklist in Nextedy CHECKLIST is built from the same fundamental unit: the checklist item.
## The checklist item: one row, several independent facts
A checklist item is not just a label and a checkbox. It's a small record that carries several independent pieces of information at once:
* **Label** — the visible text of the item, such as "Peer review completed."
* **Result state** — the current outcome recorded for this item: **Empty** (default), **OK**, **NOK**, or **Pending** (plus a separate, non-selectable **Information** row type).
* **Mandatory flag** — whether this item must be checked for the checklist to be considered complete.
* **Description** — static guidance text, typically written once by whoever authored the template, explaining what the reviewer should actually check.
* **Note** — free text a reviewer adds while working the item, distinct from the description.
* **Template origin** — whether the item was populated from a checklist template or added directly on this instance.
A useful analogy: the label and description are like the printed instructions on a paper form ("check that the fire extinguisher is present — see inspection guide §3"), while the note is what the inspector scribbles in the margin ("replaced 2024-03-01, next due 2025-03-01"). Both live on the same row, but they come from different authors and serve different purposes — the description doesn't change reviewer to reviewer, the note does.
**An item with no result set is still meaningful**
An item that has never been touched defaults to the `Empty` / none state rather than to some arbitrary value. This matters when you're reasoning about "why does this checklist show as incomplete" — an item nobody has looked at yet is indistinguishable, at the data level, from one explicitly reset.
## The result states
A plain checkbox collapses reality into two states: checked or not. A compliance-grade checklist needs more resolution than that, because "reviewed and accepted", "reviewed and explicitly rejected", and "nobody has looked at this yet" are materially different facts — and an audit needs to be able to tell them apart.
| Result state | Stored char | Meaning | Counts as "checked" for gating? |
| ----------------------- | ----------- | -------------------------------------- | ------------------------------------------------ |
| `Empty` (None) | `_` | No decision recorded yet — the default | No |
| `OK` (Checked) | `X` | Reviewed and accepted | Yes |
| `NOK` (Rejected) | `O` | Reviewed and explicitly rejected | No |
| `Pending` (Conditional) | `+` | Accepted conditionally, or still open | Yes — treated as checked for completion purposes |
**Common misconception: Pending is not the same as unchecked**
Because `Pending` sounds provisional, it's tempting to assume it doesn't count toward completion. In fact, an item accepted conditionally is treated the same as a fully checked item when a workflow gate evaluates whether mandatory items are satisfied. If your process needs conditional acceptances to be visibly flagged for later follow-up even though they pass the gate, that follow-up has to happen through the note field or a separate review step — the gate itself won't distinguish `OK` from `Pending`.
**Pending depends on a feature toggle**
`Pending` corresponds to the underlying "Conditional" result state, which is only offered to users when the `nextedy.checklist.conditional_enabled` configuration property is set to `true` — it defaults to `false`, so a fresh installation does not show `Pending` as an option until an administrator enables it. See [Configuration Property Hierarchy](/checklist/concepts/configuration-property-hierarchy) for where this toggle fits among other checklist-wide properties, and [Icon, Feature-Toggle, and Baseline Properties](/checklist/reference/configuration/appearance-and-feature-properties) for the full reference entry, including the companion `conditional_sign` icon property.
There is also a separate, non-actionable row type used for annotations rather than review steps: an **Information** entry (stored char `i`) that carries guidance text but is excluded from every count and completion calculation. Think of it as a section header or a comment embedded in the checklist rather than a thing to check — it never blocks a mandatory-item gate and never appears in progress statistics, because it isn't a decision anyone needs to make.
For example, a checklist with two Information rows ("Section: Code Quality" and "Section: Documentation") plus three actionable rows (one `OK`, one `Empty`, one `Pending`) counts only those three actionable rows toward completion — the two Information rows are excluded entirely.
## Mandatory vs. "all checked": two different gates
Two related but distinct questions get asked of a checklist, and conflating them is a frequent source of confusion when setting up workflow gates:
* **Is every *mandatory* item checked?** — satisfied when all items flagged mandatory hold a checked-equivalent result (`OK` or `Pending`).
* **Is *every* item checked, mandatory or not?** — a stricter requirement that only passes when nothing is left in `NOK` or `Empty`, regardless of the mandatory flag.
An administrator-level configuration property can force the stricter "all items" behavior even for a checklist that has no items individually flagged mandatory — effectively saying "treat this entire checklist as if every row were mandatory." Which of the two gates is in effect determines what a reviewer is actually required to resolve before a transition becomes available. See [Workflow Gates: Definition of Done and Definition of Ready](/checklist/concepts/workflow-gates) for how these two evaluations map onto specific workflow functions and conditions.
## The text syntax: why raw field content matters
Because a checklist is ultimately stored as text in a custom field, that text has a syntax — and understanding it explains why hand-editing a checklist field directly, or letting some other integration write to it, can silently corrupt the checklist:
* Each item is one line that starts with its result state in **square brackets** — `[_]` Empty, `[X]` OK, `[O]` NOK, `[+]` Pending, `[i]` Information — followed by a tab and then the label.
* A `!` placed **immediately after the closing bracket** (before the tab) marks the item mandatory, e.g. `[X]!⇥Label`.
* A leading `/` marks a description line, attached to the item above it.
* A leading `>` marks a note line, attached to the item above it.
```text theme={null}
RAW FIELD TEXT PARSED MEANING
----------------------------------- ---------------------------------
[X]! Review code changes OK · mandatory · "Review code changes"
/See the style guide description of the item above
[_] Update documentation Empty · not mandatory
>Draft ready, awaiting review note on the item above
[+] Run regression suite Pending (conditional accept)
```
(The separator between the bracketed state and the label is a literal **tab**; it is shown as spaces above for readability.)
**This is why field type matters**
Checklist fields are set up as plain multi-line text, not rich text, precisely so this syntax round-trips reliably. When a checklist field's type gets changed to rich text underneath it — which has been observed as a side effect of using certain built-in Polarion work item templates — the syntax can be mangled and items can appear duplicated. If you see duplicated checklist items right after a work item is created from a template, this text-syntax dependency is the place to start investigating; see [Templates](/checklist/concepts/templates) for the documented workaround.
## Where items come from: manual entry vs. templates
An item's `fromTemplate` flag records whether it arrived via a checklist template or was typed directly into this specific instance. This isn't just metadata — it's the hook that makes template-driven updates possible. When a checklist is re-parsed against its template, matching items are updated in place by identifier rather than duplicated, which is what allows a template author to add or reword a review step centrally and have it reflected everywhere the template is referenced, without wiping out notes or results reviewers have already recorded on other, unrelated items.
**Template edits reach existing items**
On a template-driven merge, an item's label, mandatory flag, and description are refreshed from the template while only the recorded **result** is preserved. So editing a template to change which items are mandatory (or to reword an item) **does** propagate to already-existing checklists the next time each one is parsed — you can rely on template edits to retroactively change mandatory flags and labels.
## Building the mental model
The pattern to hold onto: a checklist item is a small bundle of independent facts (label, result, mandatory, description, note, origin), the result states exist because binary checked/unchecked can't represent "reviewed and rejected" or "accepted conditionally" versus "not yet reviewed," and the whole structure is serialized to a specific text syntax that both the rendering UI and any workflow logic depend on being well-formed. Once that clicks, the behavior of workflow gates, template merges, and baseline comparisons (covered in [Workflow Gates: Definition of Done and Definition of Ready](/checklist/concepts/workflow-gates), [Templates](/checklist/concepts/templates), and [Baseline Tracking](/checklist/concepts/baselines)) follows naturally from this underlying data model rather than needing to be memorized as separate rules.
For a broader orientation to how these pieces fit into the product as a whole, see [What Is Nextedy Checklist](/checklist/concepts/what-is-checklist). For hands-on setup instead of concepts, start with [Getting Started](/checklist/getting-started/index).
# Configuration Property Hierarchy
Source: https://learn.nextedy.com/checklist/concepts/configuration-property-hierarchy
Nextedy CHECKLIST is configured almost entirely through **configuration properties** — dot-notation keys set in **Administration > Configuration Properties**.
## The problem the hierarchy solves
Imagine you administer a project with a dozen work item types, each with its own Definition of Done (DoD) and Definition of Ready (DoR) checklist. Some rules genuinely apply everywhere (nobody outside the QA role should ever be able to restructure a checklist). Other rules are far more specific (only while a `userstory` is in status `draft` can the DoR checklist be edited at all). If every property had to be written out in full for every type, every field, and every status combination, your configuration would be enormous and contradiction-prone.
The configuration property hierarchy solves this by letting a single property key omit the segments it doesn't need to be specific about. A property with fewer segments is a broader default; a property with more segments is a narrower override. The system searches from most specific to least specific and applies the first match it finds.
## The general shape of a property key
Properties follow the pattern:
```text theme={null}
nextedy.checklist._TYPEID_._FIELDID_.propertyName
```
Both `_TYPEID_` (the work item type) and `_FIELDID_` (the checklist's custom field ID) are optional. This is confirmed directly for the `allMandatory` property, which controls whether every item in a checklist is treated as mandatory:
```text theme={null}
nextedy.checklist.userstory.dod.allMandatory=true # applies only to 'dod' on 'userstory'
nextedy.checklist.dod.allMandatory=true # applies only to 'dod', for any work item type
nextedy.checklist.userstory.allMandatory=true # applies to any checklist, for 'userstory' only
nextedy.checklist.allMandatory=true # applies to every checklist, on every type
```
**The system searches for the properties in the order listed above** — meaning the most specific form (type + field) is checked first, and the search falls back toward the fully generic form only if nothing more specific is set.
**Mental model: think 'CSS specificity,' not 'first property wins'**
The most useful analogy is CSS specificity: a highly specific selector (an ID selector) beats a general one (a type selector), regardless of the order the rules are written in the stylesheet. Configuration properties behave the same way — it doesn't matter what order you *typed* the properties into Configuration Properties; what matters is how many segments each key specifies. The narrowest applicable key always wins.
## A four-segment example: `adminPermission`
The clearest illustration of the full hierarchy is `adminPermission`, which controls who is allowed to change a checklist's *structure* (add or remove items) as opposed to merely checking items off. Its full key shape adds a workflow status segment:
```text theme={null}
nextedy.checklist._TYPEID_._FIELDID_._STATUS_.adminPermission
```
The documented evaluation order — checked from most specific to least specific — is:
1. `nextedy.checklist.userstory.dod.accepted.adminPermission`
2. `nextedy.checklist.dod.accepted.adminPermission`
3. `nextedy.checklist.userstory.dod.adminPermission`
4. `nextedy.checklist.dod.adminPermission`
5. `nextedy.checklist.userstory.accepted.adminPermission`
6. `nextedy.checklist.accepted.adminPermission`
7. `nextedy.checklist.userstory.adminPermission`
8. `nextedy.checklist.adminPermission`
Notice the pattern: type+field+status beats type+status, which beats field+status, which beats type+field, and so on, down to the fully generic key with no segments at all. The accepted values for `adminPermission` are `@none` (nobody, including admins, may restructure the checklist), `@all` (any user may), or a comma-separated list of user roles (including project-specific roles).
```text theme={null}
# 'dod' checklist can be restructured by global admins and the project_developer role
nextedy.checklist.dod.adminPermission=admin,project_developer
# but once a 'userstory' reaches 'verified', its 'dod' checklist structure is frozen for everyone
nextedy.checklist.dod.verified.adminPermission=@none
# 'dor' checklist can never be restructured on 'userstory' items...
nextedy.checklist.userstory.dor.adminPermission=@none
# ...except while the item is still in 'draft', when anyone can restructure it
nextedy.checklist.userstory.dor.draft.adminPermission=@all
```
This is exactly the kind of "freeze the definition once review starts, but let it evolve early" process rule that regulated teams need, expressed as ordinary property configuration rather than custom workflow logic.
**adminPermission governs structure, not checking items**
This distinction matters enough to repeat: `adminPermission` controls who may add, remove, or redefine checklist items. It says nothing about who may mark existing items as checked or unchecked — that's controlled by ordinary Polarion field permissions (Readonly Fields or field-based Permissions Management), which is a completely separate mechanism layered on top of the checklist-specific hierarchy.
## Other properties that follow the same pattern
The hierarchy isn't unique to `allMandatory` and `adminPermission` — it's the general resolution mechanism for checklist-scoped settings. `workItemTemplateId` and `documentTemplateId` (covered in [Templates](/checklist/concepts/templates)) resolve exactly the same way: a property scoped to `_TYPEID_._FIELDID_` is more specific than one scoped to `_FIELDID_` alone, which in turn is more specific than an unscoped global default.
Some properties, however, are **not** part of this type/field hierarchy at all — they're plugin-wide settings with a single fixed key, not a family of increasingly specific overrides. These are `nextedy.checklist.debug` (troubleshooting logging, default `false`), `nextedy.checklist.conditional_enabled` (master toggle for the Conditional result state — surfaced in the UI as `Pending`, see [Checklist Items, Result States, and Text Syntax](/checklist/concepts/checklist-items-and-result-states) — default `false`, disabled until an administrator sets it; full reference at [Icon, Feature-Toggle, and Baseline Properties](/checklist/reference/configuration/appearance-and-feature-properties)), `nextedy.checklist.searchAttempts` (default `30`), and the icon overrides `nextedy.checklist.checked_sign`, `nextedy.checklist.unchecked_sign`, `nextedy.checklist.no_sign`, and `nextedy.checklist.conditional_sign`. Don't assume every `nextedy.checklist.*` key participates in type/field narrowing — check the specific property's documentation.
**Verify in application**
The baseline-related properties `nextedy.checklist.baselines.itemType` (default `btask`) and `nextedy.checklist.baselines.baselineField` (default `baseline`) are read per-document rather than following the full type/field/status hierarchy described above. Confirm in your Polarion instance whether these support any narrower scoping before assuming they behave identically to `allMandatory` or `adminPermission`.
## Common misconceptions
**A missing narrow property does not mean 'no rule applies'**
A frequent point of confusion is assuming that if you haven't explicitly set a type-specific or field-specific property, the checklist has *no* governing rule. In fact, the system always falls through to the global default (`nextedy.checklist.propertyName`) if one exists, or to the property's built-in default value if no property at all is set anywhere in the hierarchy. "Unconfigured" at the narrow level is not the same as "unconfigured" overall.
**Document-level checklists may not share every property's exact syntax**
Do not assume that the freeze/permission behavior available for work item checklists (like `adminPermission`) is also available, with the same syntax, for document-level checklists. A document-scoped equivalent does exist for `controlField` (`nextedy.checklist.document._TYPEID_._FIELDID_.controlField`), but the full hierarchy and exact key shape for document-level `adminPermission` is unconfirmed. Verify this in your Polarion instance before relying on it.
## Why this design matters for compliance
In a regulated setting, the ability to say "this rule is the organization-wide default, but this specific type in this specific status has a documented, deliberate exception" is not a convenience feature — it's what lets a single configuration file serve as an auditable record of process policy. Because every property key encodes its own scope directly in the key name, an auditor (or a future administrator) can read the full list of configuration properties and reconstruct the entire rule set without needing separate documentation of "which override wins in which case" — the specificity of the key itself answers that question.
## Related guides
* [Your First Checklist](/checklist/getting-started/your-first-checklist)
* [Templates](/checklist/concepts/templates)
* [Workflow Gates: Definition of Done and Definition of Ready](/checklist/concepts/workflow-gates)
# Concepts
Source: https://learn.nextedy.com/checklist/concepts/index
These pages explain how Nextedy CHECKLIST works under the hood — the mental models behind result states, templates, configuration properties, workflow gates, and baselines.
What Checklist is, the objects it attaches to, and how it fits into a Polarion workflow.
The result states an item can hold and the text syntax used to represent them.
How predefined checklist templates keep checklists centrally managed and consistent.
The 4-level precedence system used to resolve `nextedy.checklist.*` properties.
How workflow functions and conditions turn a checklist into an enforceable gate.
How frozen checklist snapshots support audit and compliance review.
**Looking for step-by-step instructions instead?**
These pages explain concepts, not procedures. For hands-on setup, start with [Getting Started](/checklist/getting-started/index) or browse [Guides](/checklist/guides/index).
# Templates
Source: https://learn.nextedy.com/checklist/concepts/templates
A checklist template is the single source of truth for what a checklist *should* contain.
Think of a template the way you'd think of a form used in a paper-based audit process: the form itself (the questions, the order, which boxes are mandatory) is designed once by a process owner. Copies are then handed out to individual reviewers, who fill in their own answers, but nobody is allowed to change the questions on the form itself. Nextedy CHECKLIST templates work the same way — the template defines the *shape* of the checklist, and individual work items, documents, test runs, and plans hold their own *progress* against that shape.
## Why templates exist
Without a template, a checklist is just free text typed directly into a custom field. That works for a one-off list, but it breaks down the moment you need the same review criteria applied consistently across dozens or hundreds of objects — which is exactly the situation in regulated environments where Definition of Done (DoD) and Definition of Ready (DoR) gates must be identical across a whole project or product line.
Templates solve two distinct problems at once:
* **Consistency** — every work item of a given type gets the same checklist items, in the same order, with the same mandatory items flagged.
* **Central maintenance** — when the process changes (a new mandatory review step is added, for example), you edit the template once, and, depending on how the template is applied, that change can propagate outward instead of requiring you to hunt down and edit every individual work item.
## Two ways templates are defined
There are two distinct mechanisms for supplying a template, and they behave differently enough that mixing them up is a common source of confusion.
### 1. Configuration-property templates
The first — and generally preferred — approach points a checklist at a **template work item** (or template document) purely through a configuration property:
```text theme={null}
nextedy.checklist._TYPEID_._FIELDID_.workItemTemplateId=WI-124
```
Here, `_TYPEID_` is the work item type (for example `requirement`) and `_FIELDID_` is the checklist ID — the ID of the custom field that holds the checklist (for example `chkApproved`). Both parts of the key are optional, which is what makes this mechanism hierarchical: you can scope a template narrowly to one type and one checklist, or broadly to any checklist of any type. This precedence behavior is covered in depth in [Configuration Property Hierarchy](/checklist/concepts/configuration-property-hierarchy) — templates are simply one property that follows that same resolution pattern.
For documents (LiveDocs), the equivalent property points at a document path instead of a work item ID:
```text theme={null}
nextedy.checklist.documentSpecification.documentReadyChecklist.documentTemplateId=Specification/Product Spec Template
```
The important consequence is that **all changes to a checklist template are instantly promoted** — because the checklist items themselves are not copied into the work item at creation time; they're read from the template location, live, at parse time. This is a fundamentally different mental model from a "starter" or "seed" list: it is a live pointer, not a snapshot.
**Global templates across projects**
A template doesn't have to live in the same project as the objects using it. Prefixing the template ID with a project ID (`myOtherProject:WI-124`) lets you centralize a template in one project and reuse it from any number of downstream projects — useful when a compliance team owns the agreed DoD/DoR definitions and product teams simply consume them.
### 2. Polarion built-in work item templates
The second approach uses Polarion's own built-in work item templating (create a work item titled something like "TEMPLATE", mark it resolved so it disappears from default views, and reference it from the `workitem-type-enum`). This piggybacks on a platform feature that predates the checklist product.
**Known interaction with Polarion's template copy behavior**
When Polarion's built-in template mechanism copies data from the template into a newly created work item, it can change the checklist field's format from Text to Richtext — which corrupts the checklist's expected text syntax. The workaround is to add a `ChecklistResetToTemplate` workflow function to the type's "init" workflow action, with a `checklist` parameter naming the affected custom field, so the checklist is re-parsed (and its format corrected) immediately after creation. This is a Polarion-side issue rather than a defect in Checklist itself.
## The merge model: how a template's items reach a work item
Understanding *how* a template's items combine with an object's own checklist field explains a lot of behavior that otherwise looks surprising.
When a checklist is parsed, template items are merged into the object's existing items using an ID-based match:
* If an item ID from the template does **not** already exist on the object, it's added as a new item (marked as originating from the template).
* If an item ID **does** already exist, only its **result** is carried over from the stored content — its label, mandatory flag, and description are refreshed from the template. In other words, the template keeps control of the *shape* of each item (its wording and whether it's mandatory), while the reviewer's recorded **result** (checked / rejected / conditional / empty) is preserved.
This merge-by-ID behavior is also what powers **template re-sync**: if the process owner adds a new mandatory item to the template, every work item that reads that template picks up the new item the next time its checklist is parsed — without disturbing results already recorded against the items that already existed.
**Changing an item's mandatory flag reaches existing objects**
Because label, mandatory flag, and description are always taken from the template on merge, changing whether an existing template item is mandatory (or editing its wording) **does** reach in-flight objects — the change is picked up the next time each object's checklist is parsed. Only the recorded result stays with the object. This applies to already-existing items, not just newly-added ones.
## Item-level template metadata: `fromTemplate`
Each checklist item internally tracks whether it originated from a template (as opposed to being added manually to that specific object). This distinction matters conceptually even where the UI doesn't surface it directly to end users: a template-sourced item represents a process requirement handed down from a governing definition, while a manually-added item represents something a specific reviewer decided to track locally. Documentation and process design should treat these as different categories of checklist content — one is centrally governed, the other is ad hoc.
## Object types that can carry a template
Template resolution is supported for all four object types that Checklist can attach to:
| Object type | Template resolution source |
| ------------------ | ------------------------------------------------------------ |
| work item | linked template work item, resolved via `workItemTemplateId` |
| document (LiveDoc) | linked template document, resolved via `documentTemplateId` |
| test run | the test run's own template test run |
| plan | the plan's own template plan |
Test runs and plans resolve their template from the object's native "template" relationship rather than from a configuration property pointing at an arbitrary object — a subtle but important distinction from the work item and document cases.
## Multiple templates for the same checklist
By default, the system picks a template based on the work item or document type alone. But the resolution can be made conditional on the value of another field — a **control field** — so that, for example, a `requirementReady` checklist loads a different template depending on whether a `requirementType` custom field is set to `system` or `software`:
```text theme={null}
nextedy.checklist.workitem.requirementReady.controlField=requirementType
nextedy.checklist.system.requirementReady.workItemTemplateId=EL-120
nextedy.checklist.software.requirementReady.workItemTemplateId=EL-121
```
This is the same dot-notation property hierarchy used everywhere else in Checklist configuration, just with the control field's value substituted in place of the work item type segment. The equivalent mechanism exists for documents via `nextedy.checklist.document._CHECKLISTID_.controlField`.
## Common misconceptions
**A template is not a one-time starter list**
New users sometimes assume that applying a template simply seeds a work item with an initial set of items that can then be freely edited without consequence, the way a code snippet inserts boilerplate text. In practice, template items remain linked by ID to the template's own items, and re-parsing (or an explicit reset/apply-template workflow action) re-syncs against the template. Treat template items as *governed* content, not a one-time copy.
**Editing the template does not retroactively fix already-corrupted fields**
If a checklist field's format was already corrupted by Polarion's built-in template-copy bug (Text becoming Richtext), simply pointing to a correct configuration-property template afterward does not undo that corruption on existing objects. The `ChecklistResetToTemplate` workflow function is the documented remedy, and it must actually run against the affected object.
## Where templates fit in the bigger picture
Templates are one of three pillars that make checklist enforcement possible in a regulated process: the **template** defines what must be checked, [workflow gates](/checklist/concepts/workflow-gates) enforce that it *is* checked before a transition is allowed, and [baselines](/checklist/concepts/baselines) preserve historical proof of what was checked at a point in time. Templates answer the "what should this checklist contain" question; they say nothing on their own about whether completing it is required to proceed — that's the workflow gate's job.
## Related guides
* [Your First Checklist](/checklist/getting-started/your-first-checklist)
* [Set Up a Plan Checklist (Tutorial)](/checklist/getting-started/setup-plan-checklist)
* [Set Up a Test Run Checklist (Tutorial)](/checklist/getting-started/setup-test-run-checklist)
# What Is Nextedy Checklist
Source: https://learn.nextedy.com/checklist/concepts/what-is-checklist
Nextedy CHECKLIST is an actionable checklist app for Siemens Polarion ALM.
## The problem: checklists that nobody enforces
Most engineering organizations already have checklists — a Definition of Done, a peer-review checklist, a release-readiness list. The usual home for these is a wiki page, a document template, or a rich-text field that someone pastes into a work item. The problem is that none of these are *actionable*: nothing stops a reviewer from approving a work item with half the items unaddressed, nothing distinguishes "not applicable" from "forgot to check," and nothing captures what the checklist looked like at the moment a milestone was reached.
Checklist exists to close that gap for regulated and process-driven environments — teams working under ISO 26262, Automotive SPICE, or IEC 62304, where a Definition of Done or Definition of Ready has to be demonstrably enforced, not just written down. Instead of a block of text, a Checklist-backed field becomes a small structured object: a list of checklist items, each with its own result state, that Polarion's workflow engine can inspect and act on.
## The core idea: a checklist is data, not decoration
The most important mental shift is this: a Checklist is not a UI widget bolted onto a field — it's structured data stored *as* that field's content. Checklist reads a plain-text (or rich-text) custom field, parses it into a checklist item, and renders that as an interactive checklist form extension. When a user checks an item, the change is posted back and re-serialized into the same field.
This is why Checklist can attach to so many different kinds of Polarion objects — work items, documents (LiveDocs), test runs, and plans — without needing a bespoke integration for each: as long as the object has a text-based custom field, the same parsing and rendering logic applies.
**Checklist is not limited to work items**
A recurring point of confusion in support requests is whether Checklist works on documents as well as work items. It does — Checklist supports work items, documents (LiveDocs), test runs, and plans as attachment points, each with its own configuration path.
## Anatomy of a checklist item
Each row in a checklist carries a small set of properties, and understanding them clarifies what a checklist *can* express versus what it can't:
* **Label** — the visible text of the item (for example, "Review code changes").
* **Result state** — the current outcome: **Empty** (default), **OK**, **NOK**, or **Pending**. This is the field the workflow engine actually inspects. (A separate, non-selectable **Information** row type also exists, for headings or annotations that carry no result.)
* **Mandatory flag** — whether this specific item must be checked before the checklist counts as complete.
* **Description** — static, template-authored guidance text for the item (rendered distinctly from a note).
* **Note** — a free-text annotation a reviewer adds while working through the checklist, separate from the description.
* **Template origin** — whether the item came from a template or was added locally.
Think of description and note as two different audiences writing to two different fields on the same row: the template author explains *what to check* (description), while the reviewer records *what they found* (note).
## Result states: more than a checkbox
A plain checkbox only has two states. A Checklist item supports **four** result states, because "reviewed and accepted", "reviewed and rejected", "accepted conditionally", and "not yet looked at" are different facts, and conflating them is exactly how compliance checklists lose their evidentiary value.
| Result state | Stored char | What it represents | Counts as complete? |
| --------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------- | ------------------- |
| Empty (None) | `_` | No decision recorded yet — the default | No |
| OK (Checked) | `X` | Reviewed and accepted | Yes |
| NOK (Rejected) | `O` | Reviewed and explicitly rejected | No |
| Pending (Conditional) | `+` | Accepted conditionally / still open. Disabled by default; an administrator enables it via `nextedy.checklist.conditional_enabled`. | Yes |
**Rendered as icons**
In the running product the states show as icons only (no text label): an empty square (Empty), a checked square (OK), a minus square (NOK), and a plus square (Pending). The icon classes are configurable — see [Icon, Feature-Toggle, and Baseline Properties](/checklist/reference/configuration/appearance-and-feature-properties).
The distinction that trips people up most often is between an item that is **Empty** (nobody has looked at it) and one marked **NOK** (somebody reviewed it and explicitly rejected it). Both leave the item "not checked", but only NOK represents a completed review decision. See [Checklist Items, Result States, and Text Syntax](/checklist/concepts/checklist-items-and-result-states) for the full breakdown, including how these states interact with mandatory-item logic.
## Templates: one definition, many instances
Rather than typing the same checklist items into every work item, document, test run, or plan, you define a template once and reference it from a configuration property. When Checklist parses a checklist field, it can merge in items from the linked template — meaning the same review steps are visible on hundreds of items in different sheet, and updates to the template's items propagate the *item content*, not just the result state, to anywhere the template is referenced.
For example, the same checklist template can be referenced from a work item's `dod` field, a document's `dodField`, and a test run's `testDone` field at once, and each one merges in the template's items.
This is the mechanism behind Definition of Done and Definition of Ready: define the required steps once, in one place, and every object of that type inherits them. See [Templates](/checklist/concepts/templates) for how template resolution actually works, including the type-specific and field-specific property forms.
## Configuration properties: precedence, not just settings
Checklist behavior — which items are mandatory by default, which template applies, how summaries are calculated — is controlled through `nextedy.checklist.*` configuration properties set in **Administration > Configuration Properties**. The mental model to hold here is precedence, not just key-value lookup: a property can be scoped globally, to a work item type, to a specific checklist field, or to both a type and a field at once, and Checklist searches from most specific to least specific.
For example, `nextedy.checklist.userstory.dod.allMandatory=true` applies only to the `dod` checklist on `userstory` items, while `nextedy.checklist.allMandatory=true` is a blanket default for every checklist in the project. This lets an administrator set a sane default once and override it narrowly wherever a specific work item type or checklist needs different behavior. The full precedence order and worked examples are in [Configuration Property Hierarchy](/checklist/concepts/configuration-property-hierarchy).
## Workflow gates: from checklist to enforcement
A checklist that nobody is required to complete is just documentation. Checklist becomes *enforcement* when it's wired into Polarion's workflow engine via workflow functions and workflow conditions attached to transitions.
The distinction between the two matters conceptually:
* A **workflow function** is an action that runs during a transition. Some functions (like the fail-if-unchecked family) actively block the transition by throwing a user-visible error if mandatory items aren't checked. Others (reset-to-template, uncheck-all) mutate the checklist state itself as a side effect of the transition.
* A **workflow condition** is a guard evaluated *before* a transition is even offered. If the condition fails, the transition button is simply unavailable or disabled, with a human-readable message explaining which checklist is incomplete.
This is the concrete mechanism behind Definition of Done and Definition of Ready gates: a work item, document, or test run cannot leave a given state until its associated checklist satisfies whatever rule the administrator configured. See [Workflow Gates: Definition of Done and Definition of Ready](/checklist/concepts/workflow-gates) for the available functions and conditions and how to wire them into `workflow.xml`.
## Baselines: freezing a checklist in time
Enforcement answers "was this checked before we proceeded?" Baseline tracking answers a different, equally important question for regulated environments: "what did the checklist look like *then*, and can we prove it?" A baseline is a frozen snapshot of a checklist's state at a point in time, which supports the kind of historical comparison an auditor or safety reviewer expects — not just "is it complete now" but "what changed between this milestone and the last one." See [Baseline Tracking](/checklist/concepts/baselines) for how baseline records are structured and queried.
## Putting it together
The pieces compose into a single lifecycle: a template defines the review steps once; a configuration property links that template (and any mandatory-item rules) to a specific field on a specific object type; the checklist form extension renders that field as an interactive checklist for reviewers to work through; a workflow function or condition inspects the resulting result states to gate a transition; and, where audit trails matter, a baseline preserves what the checklist looked like at that moment.
Once this lifecycle clicks, the rest of the documentation is mostly filling in specifics: which object types support which configuration paths, exactly which workflow functions exist, and how the property precedence resolves in edge cases. Start with [Checklist Items, Result States, and Text Syntax](/checklist/concepts/checklist-items-and-result-states) if you want to go deeper on the data model, or jump straight to [Getting Started](/checklist/getting-started/index) if you'd rather learn by setting one up.
# Workflow Gates: Definition of Done and Definition of Ready
Source: https://learn.nextedy.com/checklist/concepts/workflow-gates
A checklist that nobody is required to complete is just a list.
Think of the checklist itself as the *questionnaire*, and the workflow gate as the *bouncer at the door*. The questionnaire can exist and be filled out with nobody ever checking it — but the bouncer is what actually stops someone from walking through the door of a status transition until the questionnaire says they're allowed to.
## Two philosophies: conditions vs. functions
Checklist gates come in two structurally different forms, and the distinction between them is the single most important thing to understand before configuring a gate.
**Workflow conditions** *gate the availability* of a transition. A condition is evaluated continuously; if it doesn't pass, the transition button is simply not available (or is shown with an explanation of why it's disabled). Nothing is thrown, no error dialog interrupts the user — the door just isn't there to walk through.
**Workflow functions** *actively block execution* if invoked as part of a transition that a user has already initiated. A function throws a user-friendly exception when its condition isn't met, aborting the transition attempt after the user has already tried to click through it.
**Why both exist**
A condition gives a cleaner user experience (you can't click what isn't there), but functions provide a hard backstop — useful when a transition can be triggered by automation, or when you deliberately want the click to be possible but rejected with an explanatory message rather than silently hidden. Many configurations use conditions for the primary UI experience and rely on the equivalent function as defense in depth.
## The gate-relevant functions and conditions
| Name | Kind | Effect |
| ----------------------------------- | --------- | ----------------------------------------------------------------------------------------------------- |
| `ChecklistAllChecked` | Condition | Enables the transition only if every item in the specified checklist is checked — mandatory or not. |
| `ChecklistMandatoryChecked` | Condition | Enables the transition only if every **mandatory** item in the specified checklist is checked. |
| `ChecklistFailIfAnyUnchecked` | Function | Throws a user-friendly exception, blocking the transition, if any item in the checklist is unchecked. |
| `ChecklistFailIfMandatoryUnchecked` | Function | Throws a user-friendly exception, blocking the transition, if any mandatory item is unchecked. |
| `ChecklistApplyTemplate` | Function | Applies the configured template to the checklist field(s) as a transition action. |
| `ChecklistResetToTemplate` | Function | Resets the checklist field(s) back to template state, discarding all local progress. |
| `ChecklistUncheckAll` | Function | Clears every item's result, without touching the template linkage. |
All seven accept a **mandatory `checklist` argument** — the ID of the custom field holding the checklist to act on. Multiple checklists can be evaluated together in a single function or condition call by supplying a comma-separated list of custom field IDs in that argument.
## The all-vs-mandatory distinction, and how `allMandatory` bridges them
`ChecklistAllChecked` / `ChecklistFailIfAnyUnchecked` require every item checked. `ChecklistMandatoryChecked` / `ChecklistFailIfMandatoryUnchecked` require only the items flagged **mandatory**. These are genuinely different gates, and choosing the wrong one is a common source of "why did this transition succeed when I have unchecked items" confusion — an unchecked *optional* item never blocks a mandatory-only gate.
The two are connected by the `allMandatory` configuration property (see [Configuration Property Hierarchy](/checklist/concepts/configuration-property-hierarchy)). When `allMandatory` is enabled for a checklist, the mandatory-checked gates additionally require that *every* item — not only those individually flagged mandatory — is checked. In other words, `allMandatory` effectively upgrades a "mandatory items only" gate into an "everything" gate without switching which workflow function or condition you're using.
## Applying and resetting templates as transition actions
`ChecklistApplyTemplate` and `ChecklistResetToTemplate` are not gates in the "block or allow" sense — they're **actions** that run as part of a transition, changing the checklist's state rather than validating it. `ChecklistApplyTemplate` populates the specified checklist field(s) with the template's predefined items; calling it on a field that already has data re-applies the template on top. `ChecklistResetToTemplate` goes further, discarding local additions entirely and returning the checklist to exactly its template state — this is a **destructive** action, since it discards recorded progress.
`ChecklistResetToTemplate` also supports an optional `skipForUsers` argument: a comma-separated list of user IDs for whom the reset is skipped entirely. This exists so that specific accounts — for example, automation or service accounts that trigger the same transition programmatically — don't have their checklist state wiped every time the transition fires. Whitespace around each user ID is trimmed and empty entries are ignored.
**skipForUsers fails open**
Any error encountered while checking the `skipForUsers` list — a malformed argument, for example — is silently swallowed, and the reset proceeds as if the current user were not on the skip list. Don't rely on a malformed `skipForUsers` value to *prevent* a reset — treat it as fail-open, not fail-safe.
`ChecklistUncheckAll` is the simplest of the three actions: it clears every item's recorded result, leaving the checklist's structure (and template linkage) untouched. Use it when the intent is "start the review over" rather than "reset to the officially defined items," which is what `ChecklistResetToTemplate` does instead.
## A representative workflow XML pattern
The following illustrates the general shape of wiring a mandatory-checked condition and a fail-safe function together on a transition, using the `checklist` argument documented for these functions and conditions:
```xml theme={null}
dor
dod
```
**Verify in application**
The argument name `checklist` and its comma-separated multi-field syntax hold for every function and condition on this page. The surrounding `condition`/`action` structure above (`conditionId`/`functionId` attributes, `` nesting) matches the example in [Workflow Functions and Conditions](/checklist/reference/workflow), but the exact schema can still vary by Polarion version — validate against your project's actual workflow file before relying on it as a copy-paste template.
## Object types supported
Gate functions and conditions apply across work items, documents (modules), and test runs. [Workflow Functions and Conditions](/checklist/reference/workflow) lists this target-type coverage for all seven functions and conditions on this page — `ChecklistFailIfMandatoryUnchecked`, `ChecklistFailIfAnyUnchecked`, `ChecklistUncheckAll`, `ChecklistResetToTemplate`, `ChecklistApplyTemplate`, `ChecklistAllChecked`, and `ChecklistMandatoryChecked`. Plans are not among the supported target types, so none of these functions or conditions execute against plans.
## Common misconceptions
**A gate doesn't retroactively check anything for you**
Workflow gates only read the *current* recorded state of a checklist; they never automatically mark items as checked. It is natural to ask whether the reverse holds — whether completing a checklist changes the work item's status by itself. As far as the gate mechanism goes, it does not: a gate can *prevent* a transition when items are unchecked, but nothing about checklist completion pushes a status change forward on its own. The transition still has to be explicitly triggered.
**Information-type items never satisfy or block a gate**
Checklist items with an Information result are excluded from all completion counting used by the underlying checklist logic — they cannot cause `ChecklistAllChecked` to fail, and they can never be "the mandatory item" a `ChecklistMandatoryChecked` gate is waiting on. If a gate isn't blocking when you expect it to, confirm the item you're relying on isn't an information-only row.
## How gates relate to templates and baselines
Workflow gates are the enforcement layer sitting on top of [Templates](/checklist/concepts/templates) (which define what must be checked) and feeding into [Baseline Tracking](/checklist/concepts/baselines) (which preserves a record of what was checked when a gate was passed). A gate without a template behind it still works, but produces an unaudited, ad hoc list; a gate without a baseline captured at the transition point leaves no durable evidence that the gate was satisfied at that moment in time, only that it is satisfied *now*.
## Related guides
* [Your First Checklist](/checklist/getting-started/your-first-checklist)
* [Set Up a Plan Checklist (Tutorial)](/checklist/getting-started/setup-plan-checklist)
* [Set Up a Test Run Checklist (Tutorial)](/checklist/getting-started/setup-test-run-checklist)
# FAQ
Source: https://learn.nextedy.com/checklist/faq/index
Answers to common questions about Nextedy CHECKLIST, from general usage questions to what the product does and does not currently support.
**Verify in application**
Confirm exact UI labels, menu paths, and behavior in your Polarion instance before relying on them operationally.
## What is Nextedy CHECKLIST?
Nextedy CHECKLIST is an app for Siemens Polarion ALM that lets teams define, track, and enforce structured checklists on work items, documents, test runs, and plans. It combines a template system for consistent checklist definitions with workflow integration so checklists can gate transitions, such as Definition of Done (DoD) or Definition of Ready (DoR) reviews. See [Concepts](/checklist/concepts/index) for the underlying model.
## Who is Checklist meant for?
Checklist targets project engineers, quality engineers, process engineers, and Polarion administrators who need structured checklist enforcement for process compliance. End users typically check items and review baselines, while administrators handle template setup, workflow configuration, and configuration property management. See [Getting Started](/checklist/getting-started/index) for role-appropriate starting points.
## Which Polarion object types can have a checklist?
Checklist supports four object types: work items, documents (LiveDocs), test runs, and plans. Each object type has its own setup path — for example, see [Set Up a Plan Checklist](/checklist/getting-started/setup-plan-checklist) and [Set Up a Test Run Checklist](/checklist/getting-started/setup-test-run-checklist).
## What result states can a checklist item have?
Each checklist item can be set to one of four result states: **Empty** (default — nothing recorded yet), **OK** (checked/passed), **NOK** (rejected/failed), and **Pending** (conditional, available only when the conditional state is enabled — off by default). There is also a non-selectable **Information** row type for headings/notes that carry no result. These states are the basis for workflow gate logic and baseline comparisons — see [Concepts](/checklist/concepts/index) for how result states drive gate enforcement.
## How do templates work?
A template is a predefined checklist definition that can be associated with a specific work item type, document type, test run, or plan, so that checklists start from a consistent, repeatable set of items rather than being built by hand each time. Work items and documents resolve their template via a configuration property; test runs and plans resolve theirs from the object's own native template relationship instead. Templates are the standard mechanism for keeping checklist content consistent across similar objects. For a hands-on walkthrough, see [Your First Checklist](/checklist/getting-started/your-first-checklist).
## Can a checklist block a workflow transition?
Yes — Checklist provides workflow functions and workflow conditions that integrate with Polarion's workflow engine, allowing checklist completion (for example, all items checked, or all mandatory items checked) to gate a status transition. This is the primary mechanism for enforcing Definition of Done and Definition of Ready gates. See [Reference](/checklist/reference/index) for the full list of workflow functions and conditions.
## What is a baseline, and why would I create one?
A **baseline** is a frozen snapshot of a checklist at a point in time, used together with baseline comparison views to support audit and compliance reviews — for example, proving that a Definition of Done checklist was fully satisfied at the moment a document revision was approved. Baseline tracking is confirmed for document (LiveDoc) checklists specifically; whether an equivalent mechanism exists for work item, test run, or plan checklists is not confirmed and should be verified in your instance. See [Concepts](/checklist/concepts/baselines) for more on how baselines fit into the broader checklist lifecycle.
## How are checklist settings configured?
Checklist uses a hierarchical **configuration property** system (`nextedy.checklist.*`) with four levels of precedence: a global default, a type-specific override, a field-specific override, and a combined type-and-field-specific override. This lets administrators set an organization-wide default while still tuning behavior for specific work item types or specific fields. See [Reference](/checklist/reference/index) for property syntax and precedence examples.
## Where can I see which items are mandatory?
A **mandatory item** is a checklist item that must be completed (resolved to OK or Pending, both of which count as checked) before a gated transition is allowed. In the rendered checklist, mandatory items are shown with a red `!` icon next to the item and a red left border on the row, so you can see at a glance which items must be completed. The flag is a per-item property, normally set by whoever authors the checklist template — it's recorded in the item's underlying text with a `!` placed immediately after the result token (e.g. `[X]!`), not trailing at the end of the line. Administrators can also force every item in a checklist to be treated as mandatory, regardless of individual flags, using the `allMandatory` configuration property. See [Reference](/checklist/reference/index) for configuration details and [Concepts](/checklist/concepts/checklist-items-and-result-states) for the item text syntax.
## Is there more than one FAQ page?
Yes — this page covers general product questions. For questions specifically about what Checklist can and cannot do, see the [Capabilities and Limitations FAQ](/checklist/faq/capabilities-and-limitations).
## How the pieces fit together
**Start here if you are new**
If you are setting up Checklist for the first time, start with [Your First Checklist](/checklist/getting-started/your-first-checklist), then move to the object-specific tutorials for plans and test runs.
**Verify in application**
Where a capability is not explicitly confirmed below, it is marked as unconfirmed rather than described as working — verify it against your Polarion instance before relying on it.
## Which Polarion object types does Checklist support?
Checklist supports four object types: work items, documents (LiveDocs), test runs, and plans. If you need a checklist on an object type outside this list, it is not part of the confirmed feature set. See [Concepts](/checklist/concepts/index) for how checklists attach to each supported object type.
## Can I enforce a checklist before a status change?
Yes — this is a core capability. Checklist provides workflow functions and workflow conditions that plug into Polarion's workflow engine, so a status transition can be blocked until checklist conditions are met (for example, all items checked, or all mandatory items checked). See [Reference](/checklist/reference/index) for the full list of workflow functions and conditions and their parameters.
## How many workflow functions and conditions are available?
The product brief confirms seven workflow functions and conditions, including behaviors named around all-checked, mandatory-checked, fail-if-unchecked, apply-template, reset-to-template, and uncheck-all. Exact function names, signatures, and parameters should be confirmed on the [Reference](/checklist/reference/index) page rather than assumed from this summary.
## Does Checklist support more than pass/fail per item?
Yes — each checklist item can be set to one of four result states: **Empty** (the default, nothing recorded yet), **OK** (checked/passed), **NOK** (rejected/failed), and **Pending** (conditional). This is richer than a simple checked/unchecked model, letting a reviewer record a failing (NOK) or a conditional (Pending) outcome distinctly from an item nobody has decided yet (Empty). Pending (the conditional state) is only offered when the `conditional_enabled` property is turned on (it is off by default). There is also a non-selectable **Information** row type for headings/notes that carry no result and are excluded from completion counts. See [Concepts](/checklist/concepts/index) for how result states are used in gate logic.
## Can I keep an auditable record of checklist completion over time?
Yes, for document (LiveDoc) checklists — Checklist supports **baseline** tracking, which freezes a checklist snapshot and provides comparison views against that snapshot. This is intended for audit and compliance use cases such as proving a Definition of Done checklist was satisfied at a specific point in time. Baseline tracking is confirmed at the document level; an equivalent mechanism for work item, test run, or plan checklists is not confirmed and should be verified in your instance. See [Concepts](/checklist/concepts/baselines) for details.
## Can different work item types or fields have different checklist behavior?
Yes — configuration properties (`nextedy.checklist.*`) resolve through a four-level hierarchy: a global default, a type-specific override, a field-specific override, and a combined type-and-field-specific override. This lets administrators set organization-wide defaults while tuning behavior narrowly where needed. See [Reference](/checklist/reference/index) for property syntax and precedence examples.
## Can I lock a checklist so it can no longer be edited?
Yes, but "edited" covers two distinct things that lock differently. Locking who can add, remove, or redefine checklist **items** (the checklist's structure) is a confirmed capability via the `adminPermission` configuration property, which can be scoped to a work item type, checklist field, and workflow status — for example, freezing a Definition of Done checklist's structure once a work item reaches `verified`. Locking who can **check or uncheck existing items**, by contrast, is controlled by standard Polarion field permissions (Readonly Fields or Permissions Management), not by a `nextedy.checklist.*` property. See [Reference](/checklist/reference/configuration/permission-and-freeze-properties) for both mechanisms.
**Verify in application**
Whether a dedicated `nextedy.checklist.*.readonly` property also exists to drive read-only state directly (as opposed to it being derived purely from standard Polarion field permissions and workflow status) is not confirmed — verify in your instance.
## Can checklist data be used in reports or dashboards?
Checklist supports **summary field** aggregation, which rolls up checklist status into a field intended for reporting and dashboard integration. This is distinct from the per-item result states and represents an aggregate view of a whole checklist. See [Concepts](/checklist/concepts/index) for more.
## Can checklists be moved between projects or systems?
Only a narrower, confirmed mechanism exists — this is not a general checklist import/export or migration feature. You can paste existing checklist text directly into a template work item to seed its content, and a template can be referenced from another project using the `PROJECTID:WORKITEMID` syntax so multiple projects share one centrally-maintained template. Neither of these moves a checklist's *recorded results* between projects or systems, and there is no confirmed mechanism for exporting/importing a completed checklist (with its result states) as a portable file for backup or migration purposes.
**Verify in application**
If you need to move checklist *results* (not just template content) between projects or systems, this is not a documented capability — verify directly in your instance before relying on it for migration or backup workflows.
## Is there anything Checklist explicitly does not do?
Checklist does not expose or require configuration of its internal implementation — Java class internals, OSGi bundle structure, Velocity template engine internals, and save-hook interceptor architecture are implementation details, not user-facing capabilities, and are intentionally out of scope for this documentation. If you are looking for how to *use* or *configure* Checklist, see [Guides](/checklist/guides/index) and [Reference](/checklist/reference/index) rather than looking for these internals.
## Capability summary
| Area | Supported | Notes |
| ----------------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| Object types | Work items, documents (LiveDocs), test runs, plans | See [Concepts](/checklist/concepts/index) |
| Result states | Empty, OK, NOK, Pending | Four selectable states (Pending only when the conditional state is enabled); plus a non-selectable Information row |
| Gate enforcement | Workflow functions and conditions | Seven total; see [Reference](/checklist/reference/index) |
| Baselines | Frozen snapshot + comparison views | Document (LiveDoc) checklists; not confirmed for other object types |
| Configuration | 4-level property precedence | Global → type → field → type+field |
| Structure lock | `adminPermission` (type/field/status-scoped) | Item-level check/uncheck lock uses standard Polarion field permissions instead |
| Template content import | Paste text into a template work item | Not a cross-project/system checklist migration feature |
| Reporting | Summary field aggregation | For dashboards/reports |
**Where to look next**
For exact workflow function signatures and configuration property syntax, go to [Reference](/checklist/reference/index). For task-based walkthroughs, go to [Guides](/checklist/guides/index).
If your question involves scripting against checklist data (Velocity or a custom workflow function), see the [Reference](/checklist/reference/index) section for the service API and the stored text syntax.
# Getting Started
Source: https://learn.nextedy.com/checklist/getting-started/index
These tutorials walk you through setting up your first Nextedy CHECKLIST on the three most common Polarion object types.
Set up a checklist on a work item, the most common starting point for Checklist.
Add a checklist to a Polarion plan and show it on the plan report.
Add a checklist to a test run and show it on the test run report.
**Pick the tutorial that matches your object type**
All three tutorials follow the same pattern — create a custom field, expose it in the UI, and optionally attach a template — but the exact configuration steps differ by object type. Start with [Your First Checklist](/checklist/getting-started/your-first-checklist) if you are new to Checklist.
# Set Up a Plan Checklist (Tutorial)
Source: https://learn.nextedy.com/checklist/getting-started/setup-plan-checklist
This tutorial walks you through setting up a Nextedy CHECKLIST to control Polarion plans.
## What you will achieve
You will create a custom field to hold plan checklist data, place a script block on the plan report to render the checklist, and configure a plan template so new plans start with the same predefined checklist items.
## Prerequisites
* Administrator access to **Project Administration** in Polarion
* Permission to create custom fields
* Permission to customize plan report pages
* An existing plan (or plan template) to attach the checklist to
In **Project Administration**, create a new custom field of type **Text (multi-line plain text)**. This field stores the checklist's item text and result states for the plan.
You can set up multiple checklist custom fields if you need more than one checklist on a plan (for example, separate DoD and DoR checklists).
**What you should see:** the new custom field listed among your plan custom fields, with type **Text (multi-line plain text)**.
Next, make the checklist visible by adding it to the plan's report page.
1. Open your plan, click the gear/actions menu, and choose **Customize Plan Report**.
2. If possible, select **Customize Shared Report** so the same report layout is used across your plan and plan template — this avoids repeating the setup for every individual plan.
3. Place a **Script Block Widget** wherever you want the checklist to appear on the page, and enter:
```text theme={null}
$checklistService.getChecklistView().plan($plan).checklist("planDone").render()
```
Here, `planDone` refers to the ID of the checklist custom field you created in Step 1 — replace it with your own field ID if you named it differently.
4. Save the report.
**What you should see:** the checklist section now appears on the plan report page, initially empty since no items have been defined yet.
Attaching the checklist to a plan template lets every new plan created from that template start with the same predefined items.
1. Open your plan template by clicking the template link in the plan's properties.
2. If the checklist isn't visible on this plan template yet, repeat Step 2 for the template.
3. Set your checklist items on the template.
**What you should see:** the checklist you defined on the template now also appears — pre-populated — on any plan created from that template.
**Templates propagate automatically**
Once the template plan has a checklist configured, new plans created from it inherit the same checklist items automatically. You don't need to repeat the report configuration for each new plan.
**Repeat the report setup per plan if not shared**
If you did not use **Customize Shared Report** in Step 2, you'll need to repeat that step for every individual plan and its template separately.
## Next steps
* Explore the [Getting Started](/checklist/getting-started/index) section for the equivalent tutorial on [test run checklists](/checklist/getting-started/setup-test-run-checklist) or [work item checklists](/checklist/getting-started/your-first-checklist)
* Visit the [Guides](/checklist/guides/index) section to define a reusable checklist template in more detail and configure permissions
* Check the [Concepts](/checklist/concepts/index) section to understand checklist items, result states, and templates
* See the [Reference](/checklist/reference/index) section for configuration property details
# Set Up a Test Run Checklist (Tutorial)
Source: https://learn.nextedy.com/checklist/getting-started/setup-test-run-checklist
Nextedy CHECKLIST can enforce a structured checklist on Polarion test runs, not just work items.
## What you will achieve
By the end of this tutorial you will have:
* A custom field on the test run object that stores checklist data
* The checklist rendered and editable on the test run's report page
* A test run template that pushes the checklist automatically to every test run created from it
On the test run's report page, a Script Block Widget calls `$checklistService.getChecklistView().testRun($testRun).checklist("testDone").render()`, which renders the `testDone` checklist inline.
**Work items work the same way**
If you are looking to add a checklist to a work item instead, see [Your First Checklist](/checklist/getting-started/your-first-checklist). If you need a checklist on a plan, see [Set Up a Plan Checklist (Tutorial)](/checklist/getting-started/setup-plan-checklist).
## Prerequisites
* Administrator access to the Polarion project (**Project Administration**)
* Checklist installed and licensed on your Polarion instance
* At least one existing test run or test run template to work with
The checklist itself is stored as plain text in a custom field on the test run object.
1. Go to **Project Administration > Custom Fields**.
2. Create a new custom field of type **Text (multi-line plain text)**.
3. Give it a short, memorable ID — for example `testDone`.
**What you should see:** the new field listed among your test run custom fields, with type `Text (multi-line plain text)`.
**Multiple checklists are fine**
You can create more than one checklist custom field on the test run object — for example one for `testDone` and another for a separate review gate. Each is configured and rendered independently.
Next, expose the checklist field on the report page that testers actually see.
1. Open your test run, click the gear/actions menu, and choose **Customize Test Run Page**.
2. Choose **Customize Shared Report** if it's available, so the same layout applies to both the test run and its template. Otherwise you will need to repeat this step for every individual test run.
3. Drag a **Script Block Widget** onto the report page, wherever you want the checklist to appear.
4. Enter the following line into the Script Block Widget:
```text theme={null}
$checklistService.getChecklistView().testRun($testRun).checklist("testDone").render()
```
Replace `testDone` with the ID of the custom field you created in Step 1.
5. Save the report.
**What you should see:** the checklist form extension rendered directly on the test run's report page, with its items ready to be checked off.
**Match the field ID exactly**
The string passed to `.checklist(...)` must exactly match the custom field ID from Step 1. A mismatched ID is a common cause of a checklist that fails to render or appears empty.
Rather than typing checklist items by hand on every test run, define them once on a test run template so every new test run starts pre-populated.
1. Open your test run template by clicking the template link in its properties.
2. If the checklist widget is not visible on the template's report page, repeat Step 2 for the template itself.
3. Enter your checklist items directly into the checklist form extension on the template.
**What you should see:** the checklist items you defined now also appear automatically on test runs created from this template — you no longer need to re-enter them for each run.
When a new test run is created from the template, its `testDone` field is populated with a copy of the same checklist items defined on the template (for example Smoke tests pass, Regression pass, Sign-off recorded).
**Verify in application**
Whether template item edits made *after* a test run is already created automatically re-sync into that existing test run's checklist should be confirmed in your environment before relying on it for audit purposes.
## Next steps
* [Your First Checklist](/checklist/getting-started/your-first-checklist) — the equivalent walkthrough for work items
* [Set Up a Plan Checklist (Tutorial)](/checklist/getting-started/setup-plan-checklist) — apply the same pattern to Polarion plans
* [Concepts](/checklist/concepts/index) — understand result states, templates, and workflow gates before configuring gate enforcement on your test runs
# Your First Checklist
Source: https://learn.nextedy.com/checklist/getting-started/your-first-checklist
This tutorial walks you through setting up your first Nextedy CHECKLIST on a work item — the most common starting point for the product.
## What you will achieve
You will create a custom field to hold checklist data, expose it on the work item form, and attach the **checklist form extension** so the checklist renders and can be interacted with. You will also optionally set up a **summary field** that reports checklist completion.
## Prerequisites
* Administrator access to **Project Administration** in Polarion
* Permission to create custom fields and edit work item form layouts
* A work item type to attach the checklist to (for example, a user story or requirement type)
**Document checklists are different**
This tutorial covers **work item** checklists. To set up a checklist on a document (LiveDoc) instead, see the [Guides](/checklist/guides/index) section.
In **Project Administration**, create a new custom field of type **Text (multi-line plain text)**. This field will hold the raw checklist item text and the result state of each item.
Give the field a short, memorable ID — for example `dod` (for Definition of Done) or `dor` (for Definition of Ready). You'll reference this ID in the next step.
**What you should see:** the new custom field listed among your work item custom fields, with type **Text (multi-line plain text)**.
The checklist form extension replaces the raw text field with an interactive checklist widget, but the underlying custom field must still be present in the form configuration.
**Mandatory step**
The custom field **must** be exposed on the work item form, either inside a `` or inside a ``. It is **not** supported to place the checklist `` outside of a `` or ``. The form extension hides the raw field once it's configured, but Polarion still needs it declared in the layout.
Add the field to your form layout XML as you would any other custom field, inside a panel or section.
In the same form layout, add the **checklist form extension** at the location where you want the checklist to appear:
```xml theme={null}
```
* `checklistId` refers to the ID of the custom field you created in Step 1 (here, `dod`)
* `label` is free text — it becomes the title of the checklist section in the UI
* `id` must always be `ChecklistFormExtension`
**What you should see:** when you open a work item of the configured type, a checklist section appears on the form, titled with whatever you set as `label`. Since the checklist is empty at this point, it will show no checklist items yet.
A **summary field** reports whether a checklist is complete — useful for dashboards and reports.
1. Create a new custom field of type **String (single line plain text)**. Its ID must follow the pattern `YOUR_CHECKLIST_ID_summary` — for example, if your checklist field from Step 1 is `dod`, create `dod_summary`.
2. Make this field **read-only** using the read-only fields configuration page — not by permissions.
3. In **Project Administration > Config Properties**, tell Checklist which checklist field(s) feed the summary, using the type-specific configuration property:
```text theme={null}
nextedy.checklist.userstory.checklistsIdsForSummary=dod
```
This example uses the work item type ID `userstory` and lists the `dod` checklist field ID created in Step 1. To summarize more than one checklist field on the same type, list each distinct checklist field ID separated by commas.
**What you should see:** the summary field populates automatically based on the checklist's completion state once items are checked.
Open a work item of the configured type and check an item in the checklist section. Saving the work item persists the checklist state.
**How saves work**
Checklist state is submitted to the server and written to the corresponding work item within a transaction. If a save fails, the server returns an error — check server logs if a checklist doesn't seem to persist.
Start typing a new entry and then add it by clicking on the + icon on the right. Once you have a few items added, mark some of them as mandatory, and some others as completed. Once an item is saved, you'll see the completion information also on the summary fields.
## Next steps
* Explore the [Concepts](/checklist/concepts/index) section to learn about checklist items, result states, and text syntax
* Visit the [Guides](/checklist/guides/index) section to define a reusable checklist template, configure gate enforcement (DoD / DoR), and cover other work item checklist scenarios
* Check the [Reference](/checklist/reference/index) section for configuration property details
# Track and Compare Checklist Baselines
Source: https://learn.nextedy.com/checklist/guides/baselines
Configure baseline tracking so a document's checklist history is captured at each revision and reviewable for audit and compliance evidence.
## What a baseline captures
A **baseline** is a frozen checklist snapshot tied to a document revision. Nextedy CHECKLIST identifies baselines by querying for work items of a configurable type and reading a configurable field that stores the revision identifier. Each baseline entry displayed to users carries:
* an ID (the revision/baseline value)
* a label (typically the ID combined with the baseline work item's title)
* the creation date of the baseline work item
* the workflow status of the baseline work item
* a URL linking to the document at that specific revision
**Verify in application**
This guide does not cover the exact steps to create a baseline work item (e.g. via a Polarion document baseline/revision action). Confirm the baseline-creation workflow in your project before relying on this guide for that step.
Baseline tracking is configured per document and looks for baseline records using two configuration properties:
```properties theme={null}
# Work item type that represents a "baseline" record for checklist history
nextedy.checklist.baselines.itemType=btask
# Custom field on the baseline item type that stores the baseline/revision identifier
nextedy.checklist.baselines.baselineField=baseline
```
Both properties have defaults:
| Configuration property | Default | Purpose |
| ------------------------------------------- | ---------- | ------------------------------------------------------------- |
| `nextedy.checklist.baselines.itemType` | `btask` | The work item type queried as a baseline record |
| `nextedy.checklist.baselines.baselineField` | `baseline` | The custom field on that type holding the revision identifier |
If your project already uses `btask` for something unrelated to baselines, override `nextedy.checklist.baselines.itemType` in **Administration > Configuration Properties** to point at a dedicated work item type instead.
**Baseline work items must actually exist and be linked to the document**
The baselines list is built entirely from work items matching the configured type and field — it does not automatically snapshot a document's checklist state on its own. If no work item of the configured type (with the baseline field populated) exists for a given revision, that revision will not appear in the baselines list, even if the document itself was revised.
The baselines feature renders in one of two ways, depending on whether a specific revision is in context:
* **General listing** — queries all work items matching the configured baseline item type and sorts them by the baseline field, producing the list of baseline entries (ID, label, date, status, URL).
* **Revision-scoped rendering** — when a specific revision is active in the viewing context, the widget instead looks up the one baseline work item matching that revision and renders the checklist as it existed at that baseline.
The baselines list is rendered as part of a document's (LiveDoc) checklist tooling, alongside the checklist itself. Because a document can have multiple checklists, the baselines view needs to know which checklist it should reflect.
At minimum, confirm the following are set for your document:
* the target **document** the baselines view is bound to
* the **checklist** ID within that document, required when the document defines more than one checklist
* an optional **title** to display above the baselines list
**Verify in application**
This documentation set does not give the exact Velocity/report-page syntax for embedding the baselines widget on a document page — only the equivalent test run checklist embedding syntax. Check your document's report/page configuration in the application, or consult **Set Up a Document (LiveDoc) Checklist**, for the precise embedding steps.
The baselines view supports a flag to hide it when the document is exported or rendered as PDF.
**hideInPdf may not currently suppress rendering**
A flag to hide the baselines view in PDF output exists, but its effect on the exported output is unconfirmed. Verify actual PDF output in your environment before relying on it to keep baselines out of exported documents.
Each entry in the baselines list shows:
* the baseline **label** (falls back to just the ID if the baseline work item has no distinct title)
* the **date** the baseline work item was created
* the **status** of the baseline work item (its workflow status, shown as an icon/label)
* a **URL** linking directly to the document at that revision
Clicking a baseline's URL navigates to the document as of that revision, where the checklist form extension renders the checklist items with the result states (`Empty`, `OK`, `NOK`, `Pending`) as they were recorded at that point in time.
**Use baselines with restricted checklist permissions for audit trails**
Nextedy CHECKLIST does not currently track *which user* checked or commented on an individual checklist item, or *when* they did so, as a built-in, per-item audit feature. If your audit or compliance process needs that level of attribution, combine baseline tracking with the `adminPermission` configuration property (see **Control Who Can Change the Checklist**) to split a single checklist into team-specific checklists, each restricted to the users responsible for that portion — the baseline snapshot then shows what was completed at each freeze point, while permissions constrain who could have completed it.
## Comparing baselines for compliance review
A typical audit or compliance comparison scenario:
1. Open the document's baselines list to see every recorded revision, its date, and its workflow status.
2. Select an earlier baseline to view the checklist exactly as it stood at that revision (result states for every checklist item, including any mandatory items).
3. Select a later baseline (or the current document state) and compare which items changed result state between the two points.
4. Cross-reference the workflow status shown on each baseline entry to confirm the checklist was in the expected state (e.g. all mandatory items checked) before the document transitioned to that status.
This lets reviewers reconstruct, revision by revision, how a Definition of Done or Definition of Ready checklist evolved over the life of the document — useful evidence for ISO 26262, Automotive SPICE, or IEC 62304 process compliance reviews.
## You should now see
A baselines list on the document showing each recorded revision with its ID/label, creation date, workflow status, and a working link to that revision. Opening a baseline's link should render the document's checklist with the result states exactly as they were at that revision, distinct from the checklist's current live state.
## See also
* [Control Who Can Change the Checklist](/checklist/guides/permissions)
* [Set Up a Document (LiveDoc) Checklist](/checklist/guides/setup/documents)
* [Configure Gate Enforcement (DoD / DoR) and Freeze on Status](/checklist/guides/workflow-gates-and-freeze)
* [Export Checklists and Surface Progress in Reports](/checklist/guides/reporting-and-export)
# Guides
Source: https://learn.nextedy.com/checklist/guides/index
These guides show you how to set up and manage Nextedy CHECKLIST across work items, documents, test runs, and plans — from initial installation through templates, workflow gates, permissions, and baselines.
## Topics
Install Checklist on your Polarion server and confirm licensing.
Add a checklist custom field to a work item type and expose it on the form.
Embed a checklist panel inside a LiveDoc using a wiki block.
Attach a checklist to a test run for execution-time verification.
Attach a checklist to a plan for release or milestone gating.
Define a centrally managed template so changes propagate to every item.
Use workflow functions and conditions to gate transitions on checklist completion.
Freeze checklist snapshots and compare them across revisions for audits.
## Guide Groups
### Setup
* [**Installation and Licensing**](/checklist/guides/installation) — Install Checklist and verify licensing before configuring any checklist.
* [**Set Up a Work Item Checklist**](/checklist/guides/setup/work-items) — Custom field, form extension, and optional summary field for work items.
* [**Set Up a Document (LiveDoc) Checklist**](/checklist/guides/setup/documents) — Custom field plus a wiki block for LiveDocs.
* [**Set Up a Test Run Checklist**](/checklist/guides/setup/test-runs) — Attach a checklist to a test run.
* [**Set Up a Plan Checklist**](/checklist/guides/setup/plans) — Attach a checklist to a plan.
### Templates
* [**Create a Checklist Template**](/checklist/guides/templates/create-a-template) — Centrally manage checklist content with `workItemTemplateId` / `documentTemplateId`.
* [**Multiple Templates per Type and Reset on Type Change**](/checklist/guides/templates/multiple-templates-per-type) — Handle several checklist templates on one work item type.
* [**Shared and Cross-Project Templates**](/checklist/guides/templates/shared-and-document-templates) — Reference a template stored in another project.
* [**Import Checklist Content**](/checklist/guides/templates/import-a-checklist) — Bring existing checklist content into a template.
### Workflow and Access
* [**Configure Gate Enforcement (DoD / DoR) and Freeze on Status**](/checklist/guides/workflow-gates-and-freeze) — Block or gate transitions on mandatory items.
* [**Control Who Can Change the Checklist**](/checklist/guides/permissions) — Restrict who can edit checklist structure versus who can check items.
* [**Add Notes and Customize Item Icons**](/checklist/guides/item-notes) — Attach reviewer notes and adjust item icons.
### Baselines and Reporting
* [**Track and Compare Checklist Baselines**](/checklist/guides/baselines) — Freeze and compare checklist snapshots.
* [**Export Checklists and Surface Progress in Reports**](/checklist/guides/reporting-and-export) — Export checklist content and surface summary fields in reports.
### Troubleshooting
* [**Checklist Is Marked Read-Only**](/checklist/guides/troubleshooting/checklist-readonly) — Diagnose why a checklist can't be edited.
* [**Save Errors and Version Compatibility**](/checklist/guides/troubleshooting/save-errors-and-compatibility) — Resolve save failures and version mismatches.
* [**Duplicate, Type-Change, and Formatting Issues**](/checklist/guides/troubleshooting/duplicate-and-type-change-issues) — Fix common data issues after templates or type changes.
**Where to start**
New to Checklist? Start with [Installation and Licensing](/checklist/guides/installation), then follow the setup guide for the object type you need — work item, document, test run, or plan.
# Installation and Licensing
Source: https://learn.nextedy.com/checklist/guides/installation
Install Nextedy CHECKLIST on your Polarion server and confirm it's licensed before setting up any checklists.
## Install Checklist
1. Download the latest distribution from the [Checklist download page](https://checklist.nextedy.com/download).
2. Stop the Polarion service.
3. Unzip the downloaded `checklist.zip`.
4. Copy the `com.nextedy.polarion.checklist` folder into `[POLARION_INSTALL]/polarion/extension`.
5. If you already have a production license, copy the `checklist_lic.json` file into `[POLARION_INSTALL]/polarion/license` , or add it later manually through the Polarion UI once Checklist is already installed.
6. Delete `[POLARION_INSTALL]/data/workspace/.config`.
7. Start the Polarion service.
**Don't skip step 6**
Deleting `[POLARION_INSTALL]/data/workspace/.config` is required for Checklist to register correctly. Skipping this step is a common cause of Checklist not appearing after installation.
## Check the license status
Nextedy CHECKLIST ships with an admin/license page reachable from Polarion administration under **Administration > Nextedy CHECKLIST**. This page shows:
* The Checklist version, resolved from the installed bundle
* Current license status
* Links to documentation (support), pricing (get a quote), the latest-version check, the download page, the changelog, and the setup guide
If the license is not in **OK** status, a colored banner appears wherever a checklist is rendered (work item form, LiveDoc panel, test run, or plan), with links to Help & Documentation, Contact us, and Get a quote.
**Verify in application**
The exact banner colors and thresholds (invalid vs. info-status) are determined by the license state reported by the admin page; confirm current wording and color coding directly on your instance.
## Set up your first checklist
Installation only makes Checklist available — you still need to create a custom field and wire it into a form, LiveDoc, test run, or plan before a checklist appears anywhere:
* Work items: see [Set Up a Work Item Checklist](/checklist/guides/setup/work-items)
* Documents (LiveDocs): see [Set Up a Document (LiveDoc) Checklist](/checklist/guides/setup/documents)
**Project template available**
Nextedy CHECKLIST ships a ready-made Polarion project template (`checklist_template`) that administrators can apply when creating new projects, giving you a working example configuration to start from.
## Security considerations
For security guidance that applies to all Nextedy Polarion add-ons — including the platform vs. add-on responsibility model, administrator permissions, input handling, and recommended configuration — see the common security guidance article on the Nextedy support portal. Refer to the Checklist-specific section within that document for product-specific details.
**Common pitfall: incomplete setup after install**
Installing Checklist and restarting Polarion is not enough on its own. Checklist must still be paired with a custom field and a form extension (work items) or a wiki block (documents) before it does anything visible. Follow the appropriate setup guide immediately after installing.
## Verification
You should now see **Administration > Nextedy CHECKLIST** in your Polarion administration menu, showing the installed version and a license status that is not an error banner. If the license is not **OK**, resolve that before proceeding to checklist setup — the same banner will otherwise appear on every checklist you configure.
## See also
* [Set Up a Work Item Checklist](/checklist/guides/setup/work-items)
* [Set Up a Document (LiveDoc) Checklist](/checklist/guides/setup/documents)
* [Create a Checklist Template](/checklist/guides/templates/create-a-template)
* [Control Who Can Change the Checklist](/checklist/guides/permissions)
# Add Notes and Customize Item Icons
Source: https://learn.nextedy.com/checklist/guides/item-notes
Attach free-text notes to individual checklist items to capture reviewer context, distinct from the static description text defined by the template author.
## Before you start
This guide assumes you already have a checklist set up on a work item, document, test run, or plan. If you haven't created one yet, see [Set Up a Work Item Checklist](/checklist/guides/setup/work-items) or the relevant setup guide for your object type.
## Understanding notes vs. descriptions
A checklist item can carry two different kinds of supporting text, and Checklist distinguishes them visually:
| Text type | Who sets it | Rendering marker | Typical use |
| --------------- | --------------------------------------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------ |
| **Description** | Template author (static, part of the template definition) | Leading `/` | Guidance/help text explaining what the checklist item is asking for |
| **Note** | Reviewer, at check time | Leading `>` | Free-text remark added while working through the checklist (e.g. justification, evidence reference, exception rationale) |
**Verify in application**
Beyond the `/` and `>` markers used in the underlying stored text, the exact visual styling of description vs. note text in the rendered checklist form extension is not confirmed — confirm the on-screen appearance in your Polarion instance.
```text theme={null}
Checklist item storage format (per line):
\t! result + label, trailing "!" marks mandatory
/ description line (template-authored)
> note line (reviewer-added)
Example:
OK\tReview completed by QA lead!
/Confirm the QA lead has signed off on this deliverable
>Signed off 2026-06-30, see attachment in linked document
```
## Add a note to a checklist item
1. Open the object that carries the checklist (work item, document, test run, or plan) in edit mode.
2. Locate the checklist item you want to annotate in the checklist form extension.
3. Use the item's note field to enter your free-text remark.
4. Save the object. The note is persisted as part of the checklist text stored in the underlying custom field, alongside the item's result state.
**Notes survive template re-sync, other fields don't fully**
When a checklist is merged back against its template (for example on template update), only the item's **result** is guaranteed to carry over from the existing item — not necessarily every other field. If you rely on notes for audit evidence, verify after a template re-sync that your notes are still present before treating the checklist as up to date.
## Notes and mandatory items
A note does not change whether an item counts as checked. An item's completion is driven solely by its result state (`Empty`, `OK`, `NOK`, `Pending`) — adding a note to a mandatory item does not itself satisfy the mandatory-item gate. Set the item's result explicitly in addition to any note you add.
**A note is not a substitute for an audit trail of who/when**
Checklist does not currently display, per item, which user set a given result or note, or when they did it. If you need audit evidence of *who* checked or annotated an item and *when*, notes alone will not provide that — see [Control Who Can Change the Checklist](/checklist/guides/permissions) for a documented workaround using team-specific checklists combined with permission configuration.
## Using Information-type items for static context
If you want to show explanatory context in the checklist without it affecting completion statistics, use an **Information**-type item. Items with an `Information` result are excluded from all active-item counts (checked count, mandatory-checked evaluation, all-checked evaluation) — they render in the list but never factor into progress or gating.
**Use Information items for section headers or static guidance**
Because Information items are excluded from `isAllChecked` and `isMandatoryChecked` evaluation, they're a useful way to insert a heading or explanatory line into a long checklist without breaking completion math.
## Custom icons
**Verify in application**
A dedicated, user-configurable "custom icon per item" feature — beyond the standard result-state icons (`Empty`, `OK`, `NOK`, `Pending`) shown by the checklist form extension — is not confirmed. If your use case requires distinct iconography per item beyond result state, verify current support for this directly in the application before relying on it, and treat any icon customization here as unconfirmed pending that check.
By default, the checklist form extension renders result-state icons as square checkboxes:
These can be changed to a different icon style, such as circular checkmark and cross icons:
Icon choices are picked from the [Font Awesome icon library](https://fontawesome.com/v5.15/icons). Open the icon you want, and note the CSS class name shown on its detail page:
**Verify in application**
The class name is then expected to be pasted into a Polarion Administration Configuration Properties entry, but the exact property key and full configuration steps are not confirmed — verify the precise configuration property in your Polarion instance before relying on this.
## Common pitfalls
**Description text is not editable from the checklist form the way notes are**
Descriptions are authored at the template level and are meant to stay static guidance text. If you need to change the wording an end user sees for a checklist item, edit the source template rather than expecting to overwrite the description from an individual object's checklist.
**Don't assume a note proves due diligence during an audit**
Since Checklist does not track a per-item user/timestamp for notes or result changes, a note by itself won't demonstrate *who* recorded it or *when* for compliance purposes. Combine notes with the permission-based workaround in [Control Who Can Change the Checklist](/checklist/guides/permissions) if audit attribution matters for your process.
## Verification
You should now see your entered text rendered as a note line under the relevant checklist item (marked internally with a leading `>`), separate from any template-authored description text (marked with a leading `/`), and the note should persist after saving and reopening the object.
## See also
* [Set Up a Work Item Checklist](/checklist/guides/setup/work-items)
* [Create a Checklist Template](/checklist/guides/templates/create-a-template)
* [Control Who Can Change the Checklist](/checklist/guides/permissions)
* [Configure Gate Enforcement (DoD / DoR) and Freeze on Status](/checklist/guides/workflow-gates-and-freeze)
* [Track and Compare Checklist Baselines](/checklist/guides/baselines)
# Control Who Can Change the Checklist
Source: https://learn.nextedy.com/checklist/guides/permissions
Control separately who can check checklist items and who can add, remove, or edit the checklist's structure.
There are two distinct permission questions to answer:
1. Who can mark items as checked (or set any other result state)?
2. Who can define the checklist structure — add, remove, or edit items?
## Control who can check items
Marking items as checked is just modifying the underlying custom field, so it is controlled by standard Polarion permissions rather than a Checklist-specific property:
* **Administration > Work Items > Readonly Fields** — mark the checklist custom field as read-only for everyone (or for specific conditions supported by that screen).
* **Administration > User Management > Permissions Management** — use field-based permissions to control who can write to the checklist custom field.
Use this level when you need a hard, all-or-nothing lock on the field — nobody who doesn't have write access to the field can check items either.
## Control who can define the checklist structure
Adding, removing, or editing items is a separate concern from checking them, and is typically tied to a workflow status — for example, allowing structure edits only while a work item is in `draft`, then locking the definition once it moves further along.
Configure this with the `adminPermission` configuration property:
```text theme={null}
nextedy.checklist._TYPEID_._FIELDID_._STATUS_.adminPermission
```
Accepted values:
| Value | Meaning |
| ------------------------- | ----------------------------------------------------------------------------- |
| `@none` | Nobody can change the checklist structure |
| `@all` | Anyone can change the checklist structure |
| comma-separated role list | Only the listed user roles (including project roles) can change the structure |
### Example: DoR / DoD checklists with different rules
```text theme={null}
# 'dod' checklist can be controlled by global admin and project_developer roles
nextedy.checklist.dod.adminPermission=admin,project_developer
# but when 'userstory' is in status 'verified' the checklist definition cannot be changed at all
nextedy.checklist.dod.verified.adminPermission=@none
# 'dor' checklist cannot be adjusted at all, unless overridden below
nextedy.checklist.userstory.dor.adminPermission=@none
# 'dor' checklist can be changed by anyone only when the work item is in status 'draft'
nextedy.checklist.userstory.dor.draft.adminPermission=@all
```
With the example above, once a `userstory` leaves status `draft`, there is no UI control to add, delete, or edit items in the `dor` checklist — but users can still mark existing items as checked (that's governed separately, see above).
**Version 25.7.0 also locks the Clear action**
Starting with version 25.7.0, regular users without admin permission on the applicable condition can no longer clear the checklist structure either — the **Clear** button is no longer available under the gear menu icon for them.
## How the system picks which property applies
`adminPermission` supports type, field, and status specificity at once. When resolving the effective value for a given type, checklist ID, and status, the system evaluates keys from most specific to least specific and uses the first one that is set:
Full evaluation order, for example when resolving type `userstory`, checklist `dod`, status `accepted`:
1. `nextedy.checklist.userstory.dod.accepted.adminPermission`
2. `nextedy.checklist.dod.accepted.adminPermission`
3. `nextedy.checklist.userstory.dod.adminPermission`
4. `nextedy.checklist.dod.adminPermission`
5. `nextedy.checklist.userstory.accepted.adminPermission`
6. `nextedy.checklist.accepted.adminPermission`
7. `nextedy.checklist.userstory.adminPermission`
8. `nextedy.checklist.adminPermission`
**Set the property at the right level or it silently falls through**
Because the system walks this precedence list and stops at the first match, a narrowly-scoped property you expect to apply can be silently skipped if a broader property higher in this list is also set and happens to be evaluated first for your combination of type/checklist/status. Always check which properties already exist under **Administration > Configuration Properties** before adding a new one, to avoid two rules unexpectedly conflicting.
## Freeze structure changes as part of a workflow gate
Combining `adminPermission` with a specific `_STATUS` segment is the standard way to freeze a checklist's definition once a work item passes a review gate — for example, [Configure Gate Enforcement (DoD / DoR) and Freeze on Status](/checklist/guides/workflow-gates-and-freeze) shows how to pair this with `mergeTemplate`/`mergeTemplateResolved` so the checklist both stops re-syncing to its template and stops accepting manual structure edits at the same time.
## Known limitation: no per-item audit trail
**No built-in per-item user/timestamp attribution**
The checklist does not currently show, next to each item, which user set its result or added a note, along with a date/time — there is no built-in per-item audit trail.
A documented workaround for audit/compliance scenarios: split a single checklist into team-specific checklists (separate custom fields), and use the `adminPermission` property above to restrict who can change the structure of each one. This at least attributes structural changes to a team/role via the permission configuration, even without built-in per-item timestamps.
## Verification
You should now see:
* Users without the configured role (or when `adminPermission=@none` applies) unable to add, remove, or reorder checklist items, while still able to check existing items (unless the field itself is also read-only).
* The **Clear** action absent from the gear menu for non-admin users on version 25.7.0 and later.
## See also
* [Configure Gate Enforcement (DoD / DoR) and Freeze on Status](/checklist/guides/workflow-gates-and-freeze)
* [Create a Checklist Template](/checklist/guides/templates/create-a-template)
* [Checklist Is Marked Read-Only](/checklist/guides/troubleshooting/checklist-readonly)
* [Track and Compare Checklist Baselines](/checklist/guides/baselines)
# Export Checklists and Surface Progress in Reports
Source: https://learn.nextedy.com/checklist/guides/reporting-and-export
Render a checklist and its progress summary on a LiveReport page, and understand what is and isn't currently possible when exporting checklist results to PDF/Word or tabular reports.
## Render a checklist on a report page
Checklist form extensions live on the object's own page (work item, document, test run, plan), but you can also render a read-only view of a checklist inside a LiveReport — for example a shared test run report or a plan report — using a script block.
1. Open the report you want to customize and click **Customize Report Page**.
2. If the report is shared between an object and its template (for example a test run and its test run template), select **Customize Shared Report** so you only configure it once. Otherwise repeat this procedure for each object individually.
3. Drag a **Script Block Widget** onto the report where you want the checklist to appear.
4. Add the rendering call for the object type you're reporting on:
For a test run:
```text theme={null}
$checklistService.getChecklistView().testRun($testRun).checklist("testDone").render()
```
For a plan:
```text theme={null}
$checklistService.getChecklistView().plan($plan).checklist("planDone").render()
```
The string passed to `.checklist(...)` (`testDone`, `planDone`, etc.) is the ID of the custom field holding that checklist — substitute your own field ID.
5. Save the report.
You should now see the checklist rendered on the report page, reflecting the live result state of each checklist item.
**Reuse the same field ID across templates**
Because the script block references the checklist by custom field ID, once you've wired a shared report template to a field ID, every test run or plan created from that template automatically shows the same checklist on its report — no per-object reconfiguration needed.
## What the checklist tracks internally
Each checklist item carries a result state (`Empty`, `OK`, `NOK`, `Pending`), and the checklist as a whole exposes aggregate counts that a summary field can surface — for example the number of checked items and the number of rejected items. Items using the **Information** type (see [Using Information-type items for static context](/checklist/guides/item-notes)) are excluded from these counts, so an informational row in your checklist will not affect the progress totals shown in the summary. This is distinct from the `Empty` result state, which is a normal, countable state for an active item that simply hasn't been set yet.
## Exporting to PDF or Word
A confirmed configuration property, `nextedy.checklist._TYPEID_._FIELDID_.hideInPdf` (`boolean`, default `false`), suppresses a specific checklist custom field on a specific work item/document type when the containing document or work item is exported to PDF — see [Property Hierarchy and Precedence Reference](/checklist/reference/configuration/property-hierarchy-reference) for the full property definition. Set it to `true` for the checklist field(s) you want hidden from PDF output.
Separately, the baseline-listing view (see [Track and Compare Checklist Baselines](/checklist/guides/baselines)) has its own, distinct `hideInPdf` flag. Its effect on the exported output is unconfirmed, so check your own PDF output before relying on it to keep the baselines list out of an export.
**Baselines-widget hideInPdf is unconfirmed; the checklist-field property is not**
The `hideInPdf()`-style flag on the baseline-listing widget is not documented as a configuration property, and its effect is unconfirmed — expect to establish its behaviour by trial and error. The general `nextedy.checklist._TYPEID_._FIELDID_.hideInPdf` configuration property for the checklist field itself is documented in the [Property Hierarchy and Precedence Reference](/checklist/reference/configuration/property-hierarchy-reference) and is not subject to that same caveat.
**Verify in application**
Beyond the confirmed `hideInPdf` configuration property, this documentation set does not have a full list of Velocity/scripting methods for controlling checklist appearance in exported documents. Confirm any additional export-formatting needs directly in your project.
## Surfacing checklist status outside the object
A common requirement is to see checklist completion status — counts of `OK`/`NOK`/`Pending` items, or an all-checked/mandatory-checked flag — in a tabular or dashboard view, without opening each work item individually.
What **is** confirmed:
* A checklist's aggregate state (checked count, rejected count, and whether all items or all mandatory items are checked) is computed by the checklist itself and can be reflected in a **summary field** on the object's own form. Once configured, the summary field is a normal custom field, so it can be added as a column in a work item query/table and shown across many objects at once — see [Summary Field Reference](/checklist/reference/summary-field) for the full setup.
* That per-object rendering can also be placed on a LiveReport page via the script block shown above, for one object at a time (or one shared template report reused across a set of objects created from that template).
What is **not confirmed**:
* A native LiveReport table-field integration for **live, per-item** checked-state (as opposed to the static `_summary` field text) — for example, rendering a dynamic `1/7 completed` progress format directly as a table column without scripting. The confirmed approach for this is Velocity scripting against `$checklistService.parse()`, not a plain table column. See [IChecklistService and Velocity Rendering API](/checklist/reference/api-service).
* Whether the summary counter shown at the top of the checklist form extension itself (distinct from the `_summary` custom field) can be surfaced via reporting, columns, or export — this is not confirmed to be supported. Verify it in your Polarion instance before relying on it.
**Summary field enables cross-object reporting; live per-item scripting has no table-column shortcut**
To get checklist item counts and status into a report or table across many objects at once, without opening each one, use the **summary field** — it is the confirmed mechanism for this, and a normal custom field usable as a column like any other. For **live per-item** progress in a LiveReport table without scripting, no confirmed built-in mechanism exists for that narrower case.
## Common pitfalls
**Wrong field ID in the script block**
The `.checklist("testDone")` / `.checklist("planDone")` argument must exactly match the custom field ID that holds your checklist. A mismatched ID will not render the intended checklist — double-check the field ID in **Administration** before troubleshooting further.
**Report not shared, changes don't propagate**
If you configure the script block on an individual test run or plan report instead of the shared report template, new test runs/plans created later from the same template will not automatically show the checklist. Prefer **Customize Shared Report** whenever the report can be shared with its template.
## Verification
You should now see the rendered checklist appear on your report page with the current result state of each item, and — where you've built a summary field for the object — a progress summary (checked and rejected counts) reflecting the same underlying data.
## See also
* [Track and Compare Checklist Baselines](/checklist/guides/baselines)
* [Set Up a Test Run Checklist](/checklist/guides/setup/test-runs)
* [Set Up a Plan Checklist](/checklist/guides/setup/plans)
* [Import Checklist Content](/checklist/guides/templates/import-a-checklist)
* [Configure Gate Enforcement (DoD / DoR) and Freeze on Status](/checklist/guides/workflow-gates-and-freeze)
# Set Up a Document (LiveDoc) Checklist
Source: https://learn.nextedy.com/checklist/guides/setup/documents
Add a checklist to a LiveDoc by creating a custom field and embedding a checklist panel with a wiki block.
To set up a checklist on a work item instead, see [Set Up a Work Item Checklist](/checklist/guides/setup/work-items).
## 1. Create the custom field
Create a new document custom field of type **Text (multi-line plain text)**. This field holds the checklist content; you'll reference its ID (for example `dod`) in the wiki block below.
## 2. Add a panel to your LiveDoc
1. Open your live document.
2. Navigate to the place in the document where you want the checklist to appear.
3. Insert a **Wiki Block**.
4. Put the following content into it:
```text theme={null}
$checklistService.getDocumentChecklistView().document($document).checklist("dod").title("Checklist").view($context).render()
```
* `"dod"` is the ID of your document checklist custom field from step 1.
* `.title("Checklist")` is optional — omit it if you don't want a title added above the checklist.
* You can also chain `.hideInPdf()` before `.render()` if you don't want the checklist to appear in PDF exports.
5. Save the document. You should see the checklist panel rendered in place of the wiki block.
**Hide the checklist in PDF exports**
If the interactive checklist widget doesn't make sense in a static PDF, append `.hideInPdf()` before `.render()`. The document checklist view automatically switches to a static HTML rendering of the checklist content when the document is being exported to PDF, unless it's hidden entirely.
## 3. (Optional) Define a checklist template
To centrally manage the checklist content on a document type — so edits to the template propagate to every LiveDoc using it — configure a document template ID:
```properties theme={null}
nextedy.checklist.documentSpecification.documentReadyChecklist.documentTemplateId=Specification/Product Spec Template
```
Here `documentSpecification` is the LiveDoc type and `documentReadyChecklist` is the checklist ID. See [Create a Checklist Template](/checklist/guides/templates/create-a-template) for the full property reference, including how to point at a template stored in another project.
**LivePages are also supported**
The checklist rendering methods described here (`getDocumentChecklistView()`) work on both Documents (LiveDocs) and **LivePages** (Info Pages). Embedding a checklist in a LivePage via a Script Block — e.g. `$checklistService.getDocumentChecklistView().workitem($wi).checklist("dor").view($context).render()` — renders an interactive checklist, and check/uncheck works and persists there just as it does on a LiveDoc.
## How data is saved
When a user checks or unchecks an item in the rendered panel, the browser posts the checklist ID, the target document, and the checklist data back to the server, which writes the change to the document's custom field inside a transaction. If the save fails, the server returns an error and logs the request parameters — useful information if you need to contact support about a document checklist that won't save.
**Follow-up from support: Test Run / LiveReport integration is not a documented setup path**
A separate request to embed Checklists inside Test Run or Test Run Template LiveReport pages was resolved via a live support call rather than written documentation, and is not covered by this guide. If you need a checklist inside a test run context, use the dedicated [Set Up a Test Run Checklist](/checklist/guides/setup/test-runs) guide rather than trying to adapt the document wiki-block snippet above.
## Verification
You should now see the checklist panel rendered inside your LiveDoc wherever you placed the wiki block, with items you can check and uncheck. If you added `.title("Checklist")`, confirm the title appears above the panel. Save the document and reopen it to confirm your checked items persist.
## See also
* [Set Up a Work Item Checklist](/checklist/guides/setup/work-items)
* [Create a Checklist Template](/checklist/guides/templates/create-a-template)
* [Shared and Cross-Project Templates](/checklist/guides/templates/shared-and-document-templates)
* [Control Who Can Change the Checklist](/checklist/guides/permissions)
* [Track and Compare Checklist Baselines](/checklist/guides/baselines)
# Set Up a Plan Checklist
Source: https://learn.nextedy.com/checklist/guides/setup/plans
Attach a checklist to a plan so teams can track plan-level checklist items (such as release-readiness or plan-closure criteria), using the same save, template, and workflow-gate mechanics as work items.
## Before you start
Nextedy CHECKLIST's save mechanism recognizes four target types: documents, test runs, plans, and work items. This guide covers the **plan** target. The examples below use `dod` as the checklist ID — replace it with your own.
**Verify in application**
The steps below follow the supported `IChecklistService` calls and the configuration property patterns documented for the other object types, rather than a click-by-click walkthrough of a plan such as the ones published for work items and documents. Confirm the exact UI steps for exposing a checklist on a plan page in your Polarion instance before rolling this out broadly.
## Steps
### 1. Identify the checklist field on your plan
A checklist on a plan is parsed and stored via a field, the same way as on work items, documents, and test runs. `IChecklistService` exposes dedicated overloads for `IPlan` — `parse(IPlan plan, String field)` and the corresponding `store` and `reset` calls — so plan-level checklists are a first-class, supported path.
Confirm (or create) the custom field that will hold the checklist data for your plan configuration.
### 2. Render the checklist on the plan
Plan checklists are rendered via `$checklistService.getChecklistView().plan($plan).checklist('planDone').render()` in a Velocity script block on the plan report page (see the screenshot below) — the same `getChecklistView` rendering entry point documented in [IChecklistService and Velocity Rendering API](/checklist/reference/api-service), fluently scoped to the target plan. The resulting configuration includes the `allMandatory` flag and a template URL that points at the **template plan** (in the `/plan?id=...` format), which implies:
* Plans support the same `allMandatory` semantics as work items, documents, and test runs (when enabled, all items — not only mandatory ones — must be checked for the checklist to be considered complete).
* A plan can have its own dedicated **template plan**, referenced by a `/plan?id=...` URL, distinct from the `workItemTemplateId` / `documentTemplateId` configuration-property resolution used for work items and documents.
**getChecklistConf has a dedicated IPlan overload**
[IChecklistService and Velocity Rendering API](/checklist/reference/api-service) confirms `getChecklistConf` has a dedicated `IPlan` overload (`getChecklistConf(IPlan plan, String field)`), computing `readonly`/`adminPermission` from the plan's own permission check (`plan.can().modify()`) rather than the work item path's license-authorization check. This is a first-class, supported path, not a workaround.
### 3. \[Optional] Point the plan at a template plan
Checklist templates for plans are resolved from **the plan's own template plan** (`IPlan.getTemplate()`) — a different resolution path than the `workItemTemplateId` / `documentTemplateId` configuration properties used for work items and documents. Set up your template plan and confirm it's configured as the template for the plans you want to gate.
**Only POST is supported**
The checklist save endpoint only supports `doPost`. `doGet` and `doPut` requests to the same servlet always throw a `RuntimeException`. If you're probing the endpoint directly while diagnosing an integration issue, use POST.
### 4. Configure gate enforcement (optional)
If the checklist should block a plan's workflow transition until items are checked, note that the built-in gate functions and conditions cover plans less than they cover work items, documents, and test runs:
* **`ChecklistFailIfMandatoryUnchecked`**, **`ChecklistMandatoryChecked`**, **`ChecklistApplyTemplate`**, and **`ChecklistResetToTemplate`** all support **work items, modules (documents), and test runs** as target types.
**The built-in gates do not run on plan transitions**
As documented in [IChecklistService and Velocity Rendering API](/checklist/reference/api-service) and [Workflow Functions and Conditions](/checklist/reference/workflow), each of these workflow functions and conditions resolves its target as a work item, a document (module), or a test run only — a plan is never a valid target. They do **not** execute against plan transitions. This is distinct from `getChecklistConf(IPlan, String)` and `parse(IPlan, String)`, which make plans a supported checklist *storage* target — plan checklists can be read, stored, and rendered, but cannot currently be gated with these built-in workflow functions/conditions. A custom scripted function or condition against `IChecklistService` is the only path to plan-level gate enforcement today.
Example workflow snippet — shown for reference only; it fires on work item, document, and test run transitions, not on plan transitions:
```xml theme={null}
dod
```
The `checklist` argument is required and accepts a comma-separated list of checklist field IDs. Omitting it throws a `RuntimeException` with the message `checklist attribute missing for wf function: ChecklistFailIfMandatoryUnchecked`.
**Missing checklist argument fails loudly**
The same applies to `ChecklistMandatoryChecked`, which throws `checklist attribute missing for wf condition: ChecklistMandatoryChecked` if the argument is omitted.
## Common pitfalls
**Save failures surface as a generic HTTP 500**
If a checklist fails to save on a plan, the servlet returns a generic HTTP 500 and logs a full parameter dump (project, plan, checklist ID, data) to the server log for diagnostics. Check server logs first when troubleshooting failed saves.
**Reuse the template concept, but the resolution path differs per object type**
Work items and documents resolve templates via configuration properties (`nextedy.checklist._TYPEID_._FIELDID_.workItemTemplateId` / `documentTemplateId`). Plans instead resolve their template from the plan's own configured template plan (`IPlan.getTemplate()`). Don't assume the `workItemTemplateId` property pattern documented for work items applies to plans — confirm the plan-specific template linkage in your application.
## You should now see
After wiring the checklist field to your plan and (optionally) linking it to a template plan, you should now see the checklist form extension rendered on the plan, with items checked/unchecked and saved back via POST, and the `allMandatory` behavior applied consistently with other checklist targets.
## See also
* [Set Up a Work Item Checklist](/checklist/guides/setup/work-items)
* [Set Up a Document (LiveDoc) Checklist](/checklist/guides/setup/documents)
* [Set Up a Test Run Checklist](/checklist/guides/setup/test-runs)
* [Create a Checklist Template](/checklist/guides/templates/create-a-template)
* [Configure Gate Enforcement (DoD / DoR) and Freeze on Status](/checklist/guides/workflow-gates-and-freeze)
* [Save Errors and Version Compatibility](/checklist/guides/troubleshooting/save-errors-and-compatibility)
# Set Up a Test Run Checklist
Source: https://learn.nextedy.com/checklist/guides/setup/test-runs
Attach a checklist to a test run so testers can track a set of checklist items (such as review or exit criteria) directly against the test run, with the same save and template mechanics used on work items.
## Before you start
Nextedy CHECKLIST persists checklist data through a save mechanism that recognizes four target types: documents, test runs, plans, and work items. This guide covers the **test run** target. The examples below use `dod` as the checklist ID — replace it with your own.
**Verify in application**
The steps below follow the supported `IChecklistService` calls and the configuration property patterns documented for the other object types, rather than a click-by-click walkthrough of a test run such as the ones published for work items and documents. Confirm the exact UI steps for exposing a checklist on a test run form/page in your Polarion instance before rolling this out broadly.
## Steps
### 1. Identify the checklist field on your test run type
A checklist on a test run is parsed and stored via a field, the same way as on work items, documents, and plans. `IChecklistService` exposes dedicated overloads for `ITestRun` — `parse(ITestRun testRun, String field)` and the corresponding `store` and `reset` calls — so the underlying save/read mechanism for test runs is a first-class, supported path, not a workaround.
Confirm (or create) the custom field that will hold the checklist data for your test run configuration.
### 2. Render the checklist on the test run
Test run checklists are rendered via `$checklistService.getChecklistView().testRun($testRun).checklist("testDone").render()` in a Velocity script block (see the screenshot below) — the same `getChecklistView` rendering entry point documented in [IChecklistService and Velocity Rendering API](/checklist/reference/api-service), fluently scoped to the target test run. The resulting configuration includes the `allMandatory` flag and a template URL that points at the **template test run** (in the `/testrun?id=...` format), which implies:
* Test runs support the same `allMandatory` semantics as work items and documents (when enabled, all items — not only mandatory ones — must be checked for the checklist to be considered complete).
* A test run can have its own dedicated **template test run**, referenced by a `/testrun?id=...` URL, distinct from how work item and document templates are resolved.
**getChecklistConf has a dedicated ITestRun overload**
[IChecklistService and Velocity Rendering API](/checklist/reference/api-service) confirms `getChecklistConf` has a dedicated `ITestRun` overload (`getChecklistConf(ITestRun testRun, String field)`), computing `readonly`/`adminPermission` from the test run's own permission check (`testRun.can().modify()`) rather than the work item path's license-authorization check. This is a first-class, supported path, not a workaround.
### 3. \[Optional] Point the test run at a template test run
Checklist templates for test runs are resolved from **the test run's own template test run** (`ITestRun.getTemplate()`), which is a different resolution path than the `workItemTemplateId` / `documentTemplateId` configuration properties used for work items and documents. Set up your template test run in Polarion's test run template configuration, and confirm it is configured as the template for the test runs you want to gate.
**Only POST is supported**
The checklist save endpoint only supports `doPost`. `doGet` and `doPut` requests to the same servlet always throw a `RuntimeException`. If you're probing the endpoint directly while diagnosing an integration issue, use POST — a GET or PUT will error even if your parameters are otherwise correct.
### 4. Configure gate enforcement (optional)
If the checklist should block a test run's workflow transition until items are checked, attach one of the workflow functions or conditions to your test run workflow. All three of the following explicitly support test runs as a target type, alongside work items and documents:
* **`ChecklistFailIfMandatoryUnchecked`** — a workflow function/action that aborts the transition with an error if mandatory items aren't checked.
* **`ChecklistMandatoryChecked`** — a workflow condition that gates whether the transition is even available, without throwing.
* **`ChecklistApplyTemplate`** / **`ChecklistResetToTemplate`** — workflow actions that (re)apply or reset the checklist to its template state on a transition.
Example workflow snippet applying the fail-if-unchecked function on a transition:
```xml theme={null}
dod
```
The `checklist` argument is required and accepts a comma-separated list of checklist field IDs — you can validate several checklists in one function call:
```xml theme={null}
dod,dor
```
**Missing checklist argument fails loudly**
If the `checklist` argument is omitted, the workflow function throws a `RuntimeException` with the message `checklist attribute missing for wf function: ChecklistFailIfMandatoryUnchecked` (or the equivalent message naming `ChecklistMandatoryChecked` for the condition). Double-check the argument name and spelling when wiring this into your workflow XML.
### 5. Reset behavior on transitions
`ChecklistResetToTemplate` resets the checklist back to its **template** state (discarding any checked/unchecked progress), which is different from `ChecklistUncheckAll`, which only clears checkmarks while keeping the existing item list. Both support test runs as a target type. `ChecklistResetToTemplate` also accepts an optional `skipForUsers` argument — a comma-separated list of user IDs for which the reset is skipped (useful for service/automation accounts that shouldn't have their checklist wiped on transition).
```xml theme={null}
dod
automation-bot
```
**Use apply-template on init, not on every transition**
For work item templates, the documented workaround for a Polarion template-copy bug is to add `ChecklistResetToTemplate` to the workflow's **init** action so the checklist field type is fixed right after item creation. The same idea applies conceptually to test runs that are created from a template test run — verify whether your test run creation flow needs an equivalent reset step if you see duplicated or malformed checklist entries after creation.
## Common pitfalls
**Save failures surface as a generic HTTP 500**
If a checklist fails to save on a test run, the servlet returns a generic HTTP 500 and logs a full parameter dump (project, testrun, checklist ID, data) to the server log for diagnostics. There's no user-facing detail beyond the 500 — check server logs first when troubleshooting failed saves.
**Live Report Page embedding needs hands-on verification**
Integrating a checklist into a Polarion Test Run or Test Run Template Live Report Page is more involved than the work item or document case, and does not reduce to a written copy-paste recipe. Expect to verify test run + Live Report Page embedding hands-on in your environment rather than reusing a work item or document snippet as-is.
## You should now see
After wiring the checklist field to your test run type and (optionally) attaching workflow functions, you should now see the checklist form extension rendered on the test run, with items checked/unchecked and saved back via POST. If you attached `ChecklistFailIfMandatoryUnchecked` or `ChecklistMandatoryChecked` to a transition, that transition should be blocked (or disabled) until all mandatory items carry a checked result state.
## See also
* [Set Up a Work Item Checklist](/checklist/guides/setup/work-items)
* [Set Up a Document (LiveDoc) Checklist](/checklist/guides/setup/documents)
* [Set Up a Plan Checklist](/checklist/guides/setup/plans)
* [Create a Checklist Template](/checklist/guides/templates/create-a-template)
* [Configure Gate Enforcement (DoD / DoR) and Freeze on Status](/checklist/guides/workflow-gates-and-freeze)
* [Save Errors and Version Compatibility](/checklist/guides/troubleshooting/save-errors-and-compatibility)
# Set Up a Work Item Checklist
Source: https://learn.nextedy.com/checklist/guides/setup/work-items
Add a checklist to a work item type by creating a custom field and exposing it through the checklist form extension.
To set up a checklist on a document (LiveDoc) instead, see [Set Up a Document (LiveDoc) Checklist](/checklist/guides/setup/documents).
## 1. Create the custom field
Create a new custom field of type **Text (multi-line plain text)**. This field will hold the checklist item, whose ID you'll reference in the next step (for example `dod`).
## 2. Expose the field on the work item form
**First**, make sure the custom field is exposed on the work item form, either as part of a **panel** or a **section**. This step is mandatory. The form extension hides the raw field from view, but the field still needs to be present in the form configuration — it is **not** supported to place the checklist field outside of a `` or ``.
**Second**, add the `ChecklistFormExtension` work item extension at the place on the form where you want the checklist to appear:
```xml theme={null}
```
* `checklistId` refers to the ID of the custom field you created in step 1
* `label` is the title shown above the checklist section in the UI — set it to whatever you like
* `id` must be exactly `ChecklistFormExtension`
**Field must live inside a panel or section**
Placing the `` for your checklist custom field directly on the form, outside of a `` or ``, is not supported. Keep the field declaration inside a panel or section even though the extension hides its default rendering.
## 3. (Optional) Set up a summary field
A summary field holds aggregated information about checklist completion, useful for lists, dashboards, and reports.
1. Create a new custom field of type **String (single line plain text)** with the ID `YOUR_CHECKLIST_ID_summary`. For example, if your checklist custom field from step 1 is `dod`, create a custom field called `dod_summary`.
2. Make this field read-only using the read-only fields configuration page (not by permissions).
3. **Required:** tell Checklist to calculate the summary field using **Project Administration > Config Properties**:
```properties theme={null}
nextedy.checklist.userstory.checklistsIdsForSummary=dor,dod
```
This is a comma-separated list of checklist IDs relevant to the `userstory` work item type.
**Summary fields power reporting**
Once a summary field is configured, it reflects checklist completion state without opening the work item, which makes it usable in queries, LiveReports, and dashboards. See [Export Checklists and Surface Progress in Reports](/checklist/guides/reporting-and-export) for more on this.
## 4. (Optional) Define a checklist template
To keep the checklist content centrally managed — so changes propagate to every work item using it — define a template using the `workItemTemplateId` configuration property:
```properties theme={null}
nextedy.checklist.requirement.chkApproved.workItemTemplateId=WI-124
```
Here `requirement` is the work item type and `chkApproved` is the checklist ID. You can also omit the type to apply the template to any type:
```properties theme={null}
nextedy.checklist.chkDone.workItemTemplateId=WI-125
```
Full details, including the built-in Polarion template workaround, are covered in [Create a Checklist Template](/checklist/guides/templates/create-a-template).
**Duplicated checklist items with Polarion's built-in work item templates**
If you use Polarion's own built-in work item templates (as opposed to `workItemTemplateId`) to seed a checklist, be aware of a Polarion bug (not a Nextedy Checklist bug): when Polarion copies data from a template to a new item, it changes the field's format from Text to Richtext. The workaround is to add a `ChecklistResetToTemplate` workflow function to the type's "init" action with a `checklist` parameter set to your checklist custom field's name — this resets the checklist after item creation and fixes the field type. See [Create a Checklist Template](/checklist/guides/templates/create-a-template) for the full workaround.
## How permissions interact with this setup
Two permission layers apply once your checklist is live:
* Who can **check/uncheck items** — controlled by standard Polarion field permissions (read-only fields or field-based permissions).
* Who can **change the checklist structure** (add/remove items) — controlled by the `nextedy.checklist._TYPEID_._FIELDID_._STATUS_.adminPermission` configuration property, often tied to workflow status so the structure can be frozen after a certain point.
See [Control Who Can Change the Checklist](/checklist/guides/permissions) for the full property hierarchy and evaluation order.
## Verification
You should now see a **Definition of Ready** (or whatever label you chose) section on the work item form, rendered by the checklist form extension, with checkable items instead of a raw text field. If you configured a summary field, it should update automatically to reflect the checklist's completion state once you check items and save.
## See also
* [Set Up a Document (LiveDoc) Checklist](/checklist/guides/setup/documents)
* [Create a Checklist Template](/checklist/guides/templates/create-a-template)
* [Control Who Can Change the Checklist](/checklist/guides/permissions)
* [Configure Gate Enforcement (DoD / DoR) and Freeze on Status](/checklist/guides/workflow-gates-and-freeze)
* [Export Checklists and Surface Progress in Reports](/checklist/guides/reporting-and-export)
# Create a Checklist Template
Source: https://learn.nextedy.com/checklist/guides/templates/create-a-template
Define a checklist template so a checklist's content is centrally managed — changes to the template are promoted to every work item, document, test run, or plan that references it.
## Option 1: Use a checklist-only template (recommended)
This is the standard, dedicated template mechanism, driven entirely by configuration properties.
### 1. Open Configuration Properties
Go to **Project Administration > Configuration Properties**.
### 2. Add a template property for your checklist
Pick the property form that matches your scope:
**Type-specific — a checklist ID on a specific work item type:**
```text theme={null}
nextedy.checklist.requirement.chkApproved.workItemTemplateId=WI-124
```
Here `requirement` is the work item type and `chkApproved` is the checklist ID.
**Type-agnostic — a checklist ID that applies to any work item type:**
```text theme={null}
nextedy.checklist.chkDone.workItemTemplateId=WI-125
```
The work item type is omitted, so this template applies regardless of the work item's type.
**Document template — a checklist ID on a document type:**
```text theme={null}
nextedy.checklist.documentSpecification.documentReadyChecklist.documentTemplateId=Specification/Product Spec Template
```
Here `documentSpecification` is the LiveDoc type and `documentReadyChecklist` is the checklist ID. The value is a document path (`Space/DocumentName`), not a work item ID.
**Templates are live, not a one-time copy**
All changes to a checklist template are instantly promoted to every work item, document, test run, or plan referencing it. You don't need to re-apply anything after editing the template — this makes checklist-only templates the preferred option for centrally managed checklists.
### 3. Reference a template from another project (optional)
To reuse a template stored in a different project, prefix the template ID with the project ID:
```text theme={null}
nextedy.checklist.requirement.chkApproved.workItemTemplateId=myOtherProject:WI-124
```
The same pattern works for document templates:
```text theme={null}
nextedy.checklist.checklist.documentTemplateId=myOtherProject:Specification/SpecificationTemplate
```
## Option 2: Use a Polarion built-in work item template
You can also point a checklist at a Polarion built-in work item template, but this path has a known caveat — read the warning below before choosing it.
### 1. Create the template work item
Create a new work item, e.g. with title "TEMPLATE".
### 2. Resolve it out of default views
Mark the template item resolved so it disappears from default views.
### 3. Reference it from the work item type enum
Refer to this item from the `workitem-type-enum`.
**Duplicated checklist items with Polarion built-in templates**
When you use a Polarion built-in work item template, there is a known Polarion bug (not a Nextedy Checklist bug) where copying data from the template to a new item changes the checklist field's format from Text to Richtext, which can produce duplicated checklist items. Nextedy has reported this to Siemens.
**Workaround:**
1. Open the workflow configuration for your work item type.
2. Select the **init** action.
3. Add a function: `ChecklistResetToTemplate`.
4. Add a parameter `checklist` with the value set to the name of your checklist custom field.
```xml theme={null}
chkApproved
```
This resets the checklist immediately after the new item is created, which also fixes the field type. This workaround will no longer be necessary once the underlying Polarion bug is fixed.
## How the checklist syntax works
A checklist template's content is parsed from the referenced work item's, document's, test run's, or plan's field. Each line follows a defined syntax:
| Prefix / position | Meaning |
| ------------------------------------ | --------------------------------------------------------------- |
| (leading text, tab-separated result) | The item's result state and label |
| `/` (leading) | A description line — static, template-author-provided help text |
| `>` (leading) | A note — reviewer-editable, distinct from the description |
| `!` (trailing) | Marks the item as mandatory |
## Common pitfalls
**A template is not automatically shared across work item types**
Checklist templates are configured per work item type — a checklist populated for one type (e.g. User Story) does not automatically carry over to another type (e.g. Epic) using the same checklist ID. Each work item type needing a checklist must have its own explicit `workItemTemplateId` (or `controlField`-based) reference configured, even if the template content itself is reused.
**Reused document templates need per-project reconfiguration**
If you copy a document template between projects, the checklist template / document-type mapping (the configuration properties above) is project-scoped and is not automatically carried over. You need to reconfigure the mapping in each target project.
## Verification
* Open a work item, document, test run, or plan whose type matches your configured `workItemTemplateId` / `documentTemplateId` property.
* You should now see the checklist populated with the items defined in your template work item or template document, including any mandatory markers, descriptions, and notes carried from the template.
## See also
* [Multiple Templates per Type and Reset on Type Change](/checklist/guides/templates/multiple-templates-per-type)
* [Shared and Cross-Project Templates](/checklist/guides/templates/shared-and-document-templates)
* [Set Up a Work Item Checklist](/checklist/guides/setup/work-items)
* [Set Up a Document (LiveDoc) Checklist](/checklist/guides/setup/documents)
* [Configure Gate Enforcement (DoD / DoR) and Freeze on Status](/checklist/guides/workflow-gates-and-freeze)
# Import Checklist Content
Source: https://learn.nextedy.com/checklist/guides/templates/import-a-checklist
Paste a full checklist definition into a template work item in one step, instead of adding items one by one through the UI.
## Import checklist text into a template work item
1. Open the work item that acts as your checklist template.
2. Run the **Text Edit** action on the checklist custom field.
3. In the text editor that opens, paste the checklist definition. Each line you paste is parsed as one checklist item.
4. Save the work item.
**Verify in application**
Each pasted line becomes a new checklist item, but the full line syntax (result/text separators, mandatory markers, notes, or descriptions) is not documented for this specific import flow. Check [Create a Checklist Template](/checklist/guides/templates/create-a-template) and your in-app help for the exact per-line formatting, and confirm it in your Polarion instance before pasting a large checklist.
## Reuse the imported content as a shared template
Once your template work item holds the imported checklist, point other work items or documents at it using a configuration property, so the same imported content is reused everywhere instead of copy-pasted again:
```text theme={null}
nextedy.checklist.requirement.chkApproved.workItemTemplateId=WI-124
```
For a document-level checklist template:
```text theme={null}
nextedy.checklist.documentSpecification.documentReadyChecklist.documentTemplateId=Specification/Product Spec Template
```
**Reuse a single import across every work item type that needs it**
A checklist template is **not** automatically shared across work item types — each type must have its own `workItemTemplateId` property explicitly pointing at the template work item, even when they should use the same imported content. After importing the checklist once into a template work item, add a `nextedy.checklist._TYPEID_._FIELDID_.workItemTemplateId` property for **every** type that needs it (for example, both `epic` and `userstory`), all pointing at the same template ID.
**Polarion built-in templates can duplicate imported items**
If you create the template work item using Polarion's own built-in work item templates feature (rather than just importing text into a plain work item), be aware of a known Polarion bug: copying data from a template to a new item silently converts the field from Text to Richtext, which can duplicate checklist items. The workaround:
1. Open the workflow configuration for the work item type.
2. Select the **init** action.
3. Add the function `ChecklistResetToTemplate`.
4. Add a parameter named `checklist` with the value set to the ID of your checklist custom field.
This resets the checklist immediately after item creation, which also corrects the field type. This is a Polarion platform issue, not a Nextedy Checklist defect, and Nextedy has reported it to Siemens.
## Import into a cross-project template
If the template work item receiving the imported text lives in another project, reference it using the `PROJECTID:WORKITEMID` syntax after importing:
```text theme={null}
nextedy.checklist.requirement.chkApproved.workItemTemplateId=myOtherProject:WI-124
```
See [Shared and Cross-Project Templates](/checklist/guides/templates/shared-and-document-templates) for the full cross-project pattern, including a documented limitation for cross-project document templates.
## Verification
You should now see the pasted lines rendered as individual checklist items on the template work item, in the same order they were pasted. Any work item or document configured with a `workItemTemplateId` / `documentTemplateId` pointing at this template picks up the imported items the next time the template is applied.
## See also
* [Create a Checklist Template](/checklist/guides/templates/create-a-template)
* [Multiple Templates per Type and Reset on Type Change](/checklist/guides/templates/multiple-templates-per-type)
* [Shared and Cross-Project Templates](/checklist/guides/templates/shared-and-document-templates)
* [Configure Gate Enforcement (DoD / DoR) and Freeze on Status](/checklist/guides/workflow-gates-and-freeze)
# Multiple Templates per Type and Reset on Type Change
Source: https://learn.nextedy.com/checklist/guides/templates/multiple-templates-per-type
Configure different checklist templates for the same checklist ID based on a work item type or a custom field value, and automatically reset a checklist to the correct template when a work item's type changes.
**Version requirement**
Control-field-based multiple templates require **Checklist 2.6.0** or later. Resetting a checklist on work item type change requires **Checklist 25.1.0** or later.
## Multiple templates for the same checklist ID, keyed by work item type
By default, the system loads a checklist template depending on the work item or document type:
```text theme={null}
nextedy.checklist.YOUR_WI_TYPE.YOUR_CHECKLIST_ID.workItemTemplateId=EL-120
```
You can specify different template IDs per work item type while keeping the same checklist ID:
```text theme={null}
nextedy.checklist.userstory.testChecklist.workItemTemplateId=CHEC-287
nextedy.checklist.requirement.testChecklist.workItemTemplateId=CHEC-288
```
The checklist ID (`testChecklist`) is identical in both properties — only the work item type prefix (`userstory`, `requirement`) differs, so each type resolves its own template.
## Multiple templates for the same type, keyed by a custom field value
You can also reconfigure which built-in or custom field controls the template selection, so that two work items of the *same* type can load different templates depending on a field value.
**Example scenario:** a work item custom field `requirementType` is an enumeration with two options, `system` or `software`. You want the checklist `requirementReady` to load a different template depending on that value.
### 1. Designate the control field
Set the control field for all work item types:
```text theme={null}
nextedy.checklist.workitem.requirementReady.controlField=requirementType
```
Or scope it to a specific work item type only (here, `requirement`):
```text theme={null}
nextedy.checklist.workitem.requirement.requirementReady.controlField=requirementType
```
### 2. Define a template per control-field value
```text theme={null}
nextedy.checklist.system.requirementReady.workItemTemplateId=EL-120
nextedy.checklist.software.requirementReady.workItemTemplateId=EL-121
```
The value of the `requirementType` field (`system` or `software`) becomes the prefix used to look up the template ID.
### 3. Do the same for documents
The equivalent property for documents is:
```text theme={null}
nextedy.checklist.document.CHECKLIST_ID.controlField=DOCUMENT_CUSTOM_FIELD_ID
```
**All of this lives in Configuration Properties**
All of these configuration properties are stored under **Project Administration > Configuration Properties** — there's no separate template-mapping UI.
**Templates are not automatically shared across work item types**
Configuring a checklist template for one work item type (e.g. User Story) does not make that same checklist ID populate for another type (e.g. Epic). Each work item type needing the checklist must have its own explicit template reference — either a direct `workItemTemplateId` or a `controlField`-based mapping — even when the intent is to reuse the same template content across types.
## Reset the checklist to the template on work item type change
When a work item's type is changed to a different type that has its own checklist template, the existing checklist content (from the old type's template) does not automatically get replaced. To handle this, monitor specific checklist IDs for type-change resets.
### 1. Add the monitoring property
In **Polarion Administration > Configuration Properties**, add a comma-separated list of checklist IDs to monitor on type change:
```text theme={null}
nextedy.checklist.checklistsIdsForTypeChanges=testChecklist,dor
```
If a monitored checklist is not empty and the work item's type changes, the checklist is reset to the template configured for the **new** type.
### 2. Example walkthrough
* A **Userstory** work item uses the checklist `testChecklist` and has some entries checked.
* The work item's type is changed to **Requirement**, which has its own `testChecklist` template (per the type-specific `workItemTemplateId` properties shown above).
* After the type-change action completes, `testChecklist` is reset to the Requirement template, because `testChecklist` was listed in `checklistsIdsForTypeChanges`.
* The checklist now shows only the entries relevant to the Requirement type.
**This exists to work around a Polarion issue**
The type-change reset feature was introduced because of a tracked Polarion issue: the type-change action itself can convert the checklist field from multi-line plain text into rich text. Nextedy has already reported this to Siemens; you may also report it yourself to help prioritize a fix. Until it's fixed, keep the relevant checklist IDs listed in `checklistsIdsForTypeChanges` if your project changes work item types across templates.
## Verification
* Configure two work item types with different `workItemTemplateId` values for the same checklist ID (or a `controlField` mapping) and confirm each type loads its own template content.
* Change a work item's type between two types whose checklist ID is listed in `checklistsIdsForTypeChanges`, and confirm the checklist resets to the new type's template.
* You should now see checklist content that always matches the work item's *current* type and field values, rather than stale content from a template that no longer applies.
## See also
* [Create a Checklist Template](/checklist/guides/templates/create-a-template)
* [Shared and Cross-Project Templates](/checklist/guides/templates/shared-and-document-templates)
* [Set Up a Work Item Checklist](/checklist/guides/setup/work-items)
* [Duplicate, Type-Change, and Formatting Issues](/checklist/guides/troubleshooting/duplicate-and-type-change-issues)
# Shared and Cross-Project Templates
Source: https://learn.nextedy.com/checklist/guides/templates/shared-and-document-templates
Reference a checklist template stored in another Polarion project, for both work item and document (LiveDoc) checklists.
## Reference a template in another project
Checklist templates normally live in the same project as the object that uses them. To point at a template stored in a different project, prefix the template ID with the source project ID and a colon:
```text theme={null}
PROJECTID:TEMPLATEID
```
### Work item templates
1. Open **Administration > Nextedy CHECKLIST** in the project where the checklist is used (the *consuming* project).
2. Add a configuration property in the form:
```text theme={null}
nextedy.checklist._TYPEID_._FIELDID_.workItemTemplateId=myOtherProject:WI-124
```
For example, to reuse a `chkApproved` checklist template stored as `WI-124` in project `myOtherProject` for the `requirement` type:
```text theme={null}
nextedy.checklist.requirement.chkApproved.workItemTemplateId=myOtherProject:WI-124
```
3. Save the property.
### Document (LiveDoc) templates
Use the equivalent `documentTemplateId` property, with the shared-project path pointing at a space/document location in the other project:
```text theme={null}
nextedy.checklist.checklist.documentTemplateId=myOtherProject:Specification/SpecificationTemplate
```
The value after the colon is the **space/document name** path inside the target project, not a work item ID.
At resolution time, the consuming project's `documentTemplateId` property is read and followed across the project boundary to the named space and document in the source project, which then acts as the checklist template source.
**Cross-project document templates are not confirmed to resolve**
There is a known case where a cross-project `documentTemplateId` pointed at a document template in another project and, although the path was configured correctly, **the checklist content did not appear**. No fix or root cause has been confirmed for it. The `PROJECTID:TEMPLATEID` syntax is documented and known to work for **work item** templates; treat cross-project **document** templates as unverified until you confirm the behavior in your own Polarion instance.
## Verify project-level scope
Configuration properties are set per project. If you copy a document template (or an entire document type configuration) into a new project, the `documentTemplateId` / `workItemTemplateId` properties do **not** travel with it automatically — you must re-add the relevant `nextedy.checklist.*` properties in **each** target project.
**Document templates reused across projects need per-project setup**
When document templates are reused across projects, the checklist template / document-type mapping is **not** automatically shared — each project that uses the reused document template needs its own `nextedy.checklist._TYPEID_._FIELDID_.documentTemplateId` (or `workItemTemplateId`) property configured in **Administration > Configuration Properties**. Plan for this step whenever you copy or replicate a document template between projects.
## Combine with per-type or per-field targeting
The same property hierarchy used for local templates applies to shared templates — you can scope the pointer by type, field, or both, exactly as you would for a template inside the same project:
```text theme={null}
# All work items of type 'requirement' pull the 'chkApproved' checklist from another project
nextedy.checklist.requirement.chkApproved.workItemTemplateId=myOtherProject:WI-124
# Any work item type using the 'chkDone' checklist pulls from another project
nextedy.checklist.chkDone.workItemTemplateId=myOtherProject:WI-125
```
See [Create a Checklist Template](/checklist/guides/templates/create-a-template) for the full property hierarchy and how type/field scoping is resolved, and [Multiple Templates per Type and Reset on Type Change](/checklist/guides/templates/multiple-templates-per-type) if you also need to vary the template by a custom field value.
## Verification
You should now see:
* The checklist on the consuming work item or document populated with items from the cross-project template's source work item or document.
* Changes made later to the source template (in the other project) reflected the next time the checklist template is (re)applied.
If the checklist stays empty after configuring a cross-project `documentTemplateId`, treat it as the known limitation above rather than a misconfiguration — double-check the work item case works with the same project pair before spending time debugging the document case.
## See also
* [Create a Checklist Template](/checklist/guides/templates/create-a-template)
* [Multiple Templates per Type and Reset on Type Change](/checklist/guides/templates/multiple-templates-per-type)
* [Import Checklist Content](/checklist/guides/templates/import-a-checklist)
* [Set Up a Document (LiveDoc) Checklist](/checklist/guides/setup/documents)
# Checklist Is Marked Read-Only
Source: https://learn.nextedy.com/checklist/guides/troubleshooting/checklist-readonly
Diagnose why a checklist item can't be changed and fix the cause — standard Polarion field permissions, a misconfigured checklist form extension, or a workflow status freeze.
A checklist can appear read-only for three distinct reasons, and they require different fixes. Work through them in order.
This is expected behavior, not a defect. The checklist custom field can be made read-only the same way any other custom field can:
* **Administration > Work Items > Readonly Fields**
* Field-based permissions in **Administration > User Management > Permissions Management**
If either of these marks the checklist's custom field as read-only, the checklist form extension correctly reflects that — there is nothing to fix in the checklist configuration itself.
**Distinguish checklist-level control from field-level permissions**
A checklist can look read-only in the checklist UI while the same underlying custom field still appears editable when displayed elsewhere (for example, in document columns). If you see that mismatch, don't assume the checklist configuration is broken — check both layers separately: the field's Polarion permissions/read-only-fields setting, and the checklist configuration properties described in Step 4.
If the work item extension responsible for rendering the checklist editor isn't configured correctly, it can't locate the editor on the work item form, and the field renders as if it were read-only even though no permission is blocking it.
Confirm the checklist form extension is set up correctly by following the object-type setup guide for the item you're working with:
* [Set Up a Work Item Checklist](/checklist/guides/setup/work-items)
* [Set Up a Document (LiveDoc) Checklist](/checklist/guides/setup/documents)
* [Set Up a Test Run Checklist](/checklist/guides/setup/test-runs)
* [Set Up a Plan Checklist](/checklist/guides/setup/plans)
**Verify in application**
The exact form-layout XML that wires the checklist form extension into a given work item type isn't covered in this article — confirm your form layout against the relevant setup guide above rather than assuming the extension is present by default.
If Steps 2 and 3 don't explain what you're seeing, the checklist may be intentionally frozen through configuration properties rather than through Polarion permissions.
### Freeze on workflow status
You can freeze the checklist definition so that, once a work item or document reaches a given status, the template is no longer reapplied and the checklist keeps whatever content it already has:
```text theme={null}
nextedy.checklist._TYPEID_._FIELDID_._STATUS_.mergeTemplate
nextedy.checklist._TYPEID_._FIELDID_.mergeTemplateResolved
```
Example — freezing the `dod` checklist once a work item reaches status `reviewed`:
```text theme={null}
nextedy.checklist.dod.reviewed.mergeTemplate=false
nextedy.checklist.dod.mergeTemplateResolved=false
```
**The checklist must be initialized before you freeze it**
Once frozen, the checklist shows only the data stored so far. If you add new template items but never trigger a save that touches the checklist status, those new items will not appear — the work item still has the old, unsynchronized data. Make sure the checklist template has been applied (synchronized into the work item) **before** the status transition that freezes it, for example by attaching the `ChecklistApplyTemplate` workflow function to the transition (see [Configure Gate Enforcement (DoD / DoR) and Freeze on Status](/checklist/guides/workflow-gates-and-freeze)).
### Restrict who can change the checklist structure
Separately from freezing on status, you can restrict who is allowed to add, remove, or edit checklist items (as opposed to simply checking/unchecking them) using:
```text theme={null}
nextedy.checklist._TYPEID_._FIELDID_._STATUS_.adminPermission
```
Accepted values are `@none`, `@all`, or a comma-separated list of user roles (including project roles).
Example — `dod` checklist manageable by `admin` and `project_developer`, but locked once a `userstory` reaches `verified`; `dor` checklist locked except while the `userstory` is in `draft`:
```text theme={null}
# 'dod' checklist can be controlled by global admin and project_developer roles
nextedy.checklist.dod.adminPermission=admin,project_developer
# but when 'userstory' is in status 'verified' the checklist definition cannot be changed at all
nextedy.checklist.dod.verified.adminPermission=@none
# 'dor' checklist cannot be adjusted at all, unless overridden below
nextedy.checklist.userstory.dor.adminPermission=@none
# 'dor' checklist can be changed by anyone only when the work item is in status 'draft'
nextedy.checklist.userstory.dor.draft.adminPermission=@all
```
When `adminPermission` evaluates to `@none` for the current context, users lose the controls to add or delete checklist items, but — unless the field itself is also read-only per Step 2 — they can still mark existing items as checked.
The system evaluates `adminPermission` using the full 4-level precedence, most specific first (shown here for type `userstory`, checklist `dod`, status `accepted`):
1. `nextedy.checklist.userstory.dod.accepted.adminPermission`
2. `nextedy.checklist.dod.accepted.adminPermission`
3. `nextedy.checklist.userstory.dod.adminPermission`
4. `nextedy.checklist.dod.adminPermission`
5. `nextedy.checklist.userstory.accepted.adminPermission`
6. `nextedy.checklist.accepted.adminPermission`
7. `nextedy.checklist.userstory.adminPermission`
8. `nextedy.checklist.adminPermission`
**Starting with version 25.7.0**
Regular users without admin permission for the evaluated context can no longer clear the checklist structure — the **Clear** action is removed from the gear menu icon in that case.
For the full picture of how these properties combine with Polarion permissions, see [Control Who Can Change the Checklist](/checklist/guides/permissions).
## Known limitation: type change can leave the checklist stuck read-only
**Changing a work item or document type after creation can leave the checklist permanently read-only**
This is a recurring case. A work item or document is created from scratch (or created with the wrong type, e.g. a generic type) and its type is later changed to the correct one. After the type change — sometimes triggered by a subsequent status transition such as moving from Draft to InReview — the checklist can remain stuck in read-only mode even though other fields on the same item remain editable. It has been reported more than once and does not currently have a confirmed fix. If you hit this, first rule out Steps 2–4 above (field permissions, form extension setup, and `adminPermission`/`mergeTemplate` properties) — if none of those explain it, treat it as this known limitation rather than a new configuration issue, and capture the exact type-change sequence for support.
## Verification
You should now see one of the following:
* The checklist field is intentionally read-only per **Readonly Fields** or field-based permissions, and this is expected — no further action needed.
* The checklist form extension correctly locates the editor and renders an editable checklist on the work item, document, test run, or plan form.
* The checklist behaves according to your `mergeTemplate` / `mergeTemplateResolved` and `adminPermission` configuration properties — editable when the evaluated context allows it, and frozen only where you intended.
If the checklist is still unexpectedly read-only after working through all four steps, and no type change is involved, continue with [Save Errors and Version Compatibility](/checklist/guides/troubleshooting/save-errors-and-compatibility).
## See also
* [Control Who Can Change the Checklist](/checklist/guides/permissions)
* [Configure Gate Enforcement (DoD / DoR) and Freeze on Status](/checklist/guides/workflow-gates-and-freeze)
* [Set Up a Work Item Checklist](/checklist/guides/setup/work-items)
* [Duplicate, Type-Change, and Formatting Issues](/checklist/guides/troubleshooting/duplicate-and-type-change-issues)
# Duplicate, Type-Change, and Formatting Issues
Source: https://learn.nextedy.com/checklist/guides/troubleshooting/duplicate-and-type-change-issues
Resolve checklist problems that appear after duplicating a work item, changing its type, or moving a document between statuses.
## Reset a checklist automatically on work item type change
By default, when a work item's type is changed, its previously saved checklist state can linger even though the new type may use a different template. Nextedy CHECKLIST includes a save hook that resets checklist values automatically when it detects a type change — but only for checklist IDs you've explicitly opted in.
1. Open **Administration > Configuration Properties**.
2. Add the checklist IDs (custom field IDs) that should be monitored for type changes (available from Checklist version 25.1.0):
```text theme={null}
nextedy.checklist.checklistsIdsForTypeChanges=testChecklist,dor
```
3. Configure a type-specific template for each work item type that uses the same checklist ID:
```text theme={null}
nextedy.checklist.userstory.testChecklist.workItemTemplateId=CHEC-287
nextedy.checklist.requirement.testChecklist.workItemTemplateId=CHEC-288
```
4. Change the work item's type (for example, from **Userstory** to **Requirement**).
If the monitored checklist is not empty and the type actually changes on a persisted item, the checklist automatically resets to the template configured for the new type.
**Only checklist IDs you list are affected**
Only checklist IDs listed in `nextedy.checklist.checklistsIdsForTypeChanges` are watched for type-change resets. If a checklist isn't listed, it keeps its content across a type change even if the new type has its own template configured.
**Verify in application**
`getChecklistsIdsForTypeChanges` is documented in the service API as only available for work items (not modules, test runs, or plans) — confirm document-level type-change behavior separately if you rely on it there.
## Known limitation: checklist stuck read-only after type change
Documents and work items created from scratch and then converted to a different type afterward can be left with a checklist that stays permanently read-only, even though the rest of the item's fields remain editable.
**Known limitation — no confirmed fix**
Creating a document or work item from scratch and then changing its type afterward can leave the checklist stuck in read-only mode indefinitely, while other text fields on the same item remain editable. There is no confirmed fix at present. If you hit this, do not assume it's a permissions misconfiguration on your side — check whether the item was created with its final type from the start (via the correct template) as a workaround, since items created directly with the correct type have not shown the same symptom as reliably.
Related workflow-status interaction: a document created with the wrong type (for example, a generic type) and later switched to the correct type can also become read-only specifically when its status advances (for example, from **Draft** to **InReview**), even though a document created correctly from the template from the start is expected to behave the same way at that status.
**Read-only can stem from status, type, or field permissions — check all three**
When a checklist unexpectedly goes read-only, the cause can be any combination of: the document/work item's current workflow status, whether its type was set correctly from creation or changed later, and standard Polarion field-level permissions (**Administration > Work Items > Readonly Fields** or role-based field permissions). Treat all three as suspects before concluding it's a defect. For general read-only diagnosis steps, see [Checklist Is Marked Read-Only](/checklist/guides/troubleshooting/checklist-readonly).
## Checklist-level read-only vs. field-level editability
A checklist can show as read-only in its own widget while the identical underlying custom field appears editable elsewhere, such as in a document's column view. This is a real, documented mismatch rather than a bug in every case.
1. Confirm the checklist ID and the custom field ID actually refer to the same field you're comparing across views.
2. Recall that the checklist form extension's read-only state and the raw field's Polarion-level editability are controlled independently — a checklist can be locked down via `adminPermission`-style configuration properties (see [Property Hierarchy and Precedence Reference](/checklist/reference/configuration/property-hierarchy-reference)) while the field itself has no Polarion-level read-only flag set, or vice versa.
3. Check both layers separately: the checklist's own admin/edit permission configuration, and the field's Polarion read-only/field-permission settings.
**Don't assume a single cause**
If a checklist is read-only in its widget but the same field is editable in a document column, don't jump straight to "bug." Check the checklist-specific permission configuration first — it's a separate control surface from standard Polarion field permissions, and the two can diverge by design or by misconfiguration.
## Checklist merge preserves recorded results but refreshes other fields on re-sync
When a checklist template is re-applied and merged into an existing checklist, only a matching item's **result** (its result state) is carried over and preserved from the existing, stored item. Other fields on that item — label, mandatory flag, description — are refreshed from the incoming template. See [Template Merge Behavior](/checklist/reference/configuration/template-properties#template-merge-behavior) for the full description of this behavior.
If checklist items appear to keep a stale label or mandatory flag after a template update while the previously recorded result stays exactly as it was, that's expected merge behavior, not a defect — re-apply the template as a fresh reset (rather than a merge) if you need every field, including previously recorded results, replaced, understanding that a reset discards any progress already recorded.
## Verify
You should now see the expected outcome for each scenario:
* A work item whose checklist ID is listed in `nextedy.checklist.checklistsIdsForTypeChanges` resets cleanly to the new type's template after a type change, instead of carrying over stale items.
* A checklist that's stuck read-only after a type change is recognized as a known limitation, with document/work item creation order and workflow status checked as likely contributing factors.
* A mismatch between a checklist's read-only state and the underlying field's editability elsewhere is diagnosed by checking checklist permission configuration and Polarion field permissions as two separate layers.
* A checklist re-synced from its template preserves each item's previously recorded result state, while labels, mandatory flags, and descriptions on matching items refresh to match the template — understood as expected merge behavior rather than a save failure.
## See also
* [Multiple Templates per Type and Reset on Type Change](/checklist/guides/templates/multiple-templates-per-type)
* [Checklist Is Marked Read-Only](/checklist/guides/troubleshooting/checklist-readonly)
* [Save Errors and Version Compatibility](/checklist/guides/troubleshooting/save-errors-and-compatibility)
* [Property Hierarchy and Precedence Reference](/checklist/reference/configuration/property-hierarchy-reference)
# Save Errors and Version Compatibility
Source: https://learn.nextedy.com/checklist/guides/troubleshooting/save-errors-and-compatibility
Diagnose save failures, log noise, and Polarion version-related formatting quirks that affect Nextedy CHECKLIST.
## Diagnose an HTTP 500 on checklist save
When a user checks or unchecks an item and the change doesn't stick, the save request may have failed on the server.
1. Reproduce the action and immediately check the Polarion server log.
2. Look for a stack trace originating from the checklist save path, together with a dump of the request parameters (project, and one of document/testrun/plan/workitem, plus the checklist data).
3. Confirm which target type was involved — the save request only carries **one** of `document`, `testrun`, `plan`, or `workitem`. If more than one happens to be present, the system resolves them in that precedence order (document first, then test run, then plan, then work item), so check that the client is sending the parameter you expect.
4. If the target object (document, test run, plan, or work item) cannot be resolved, or the underlying transaction fails to commit, the server returns a generic HTTP 500 and logs the error with the full parameter dump.
**Use the parameter dump for support tickets**
If you need to escalate a save failure to support, attach the full log entry rather than a screenshot of the error. The server logs every request parameter (project, target IDs, checklist ID) on failure, which is usually enough to pinpoint whether the problem is a missing object, a permission issue, or a transaction conflict.
**Only POST is supported**
The checklist save endpoint only accepts POST requests. If a browser extension, proxy, or custom integration issues a GET or PUT against the same URL, it will always fail — this is expected behavior, not a bug.
## Understand "InvocationTargetException" / "UnresolvableObjectException" in the log
Some deployments see the Polarion log fill up with `InvocationTargetException` errors wrapping an `UnresolvableObjectException` or `UnknownObjectException` for a specific work item, but **only when the work item is created**, not on later edits.
**Known log noise on work item creation**
Every save on a work item passes through a save hook that keeps the checklist's `_summary` field in sync. During **creation**, this hook can attempt to read the object's revision history before the new item is fully resolvable in the repository, which throws `UnresolvableObjectException`/`UnknownObjectException`. This has been observed independently of templates, attachments, links, permissions, or user role (it affects basic users and admins alike).
If you encounter this pattern:
1. Confirm the error only appears on work item **creation**, not on subsequent saves of the same item. That matches the known pattern.
2. Confirm the checklist value itself was saved correctly despite the log entry (open the work item and check the checklist content).
3. If the checklist data is present and correct, treat the log entry as noise from the save hook's summary computation rather than a functional failure.
If you need to rule out the checklist save hook entirely while investigating a save issue, an administrator can disable it globally with the JVM system property:
```text theme={null}
nextedy.checklist.disable.hook=true
```
**Server restart required, and it's an all-or-nothing switch**
`nextedy.checklist.disable.hook` is a **JVM system property**, not a Polarion configuration property — it cannot be set in **Administration > Configuration Properties**. It must be added to the server's startup configuration and requires a full server restart to take effect. While enabled, all checklist save-time processing is skipped, including summary field updates and reset-on-type-change — use it only as a temporary diagnostic step, not a permanent setting.
## Checklist summary fields not updating
The checklist form extension pairs each checklist custom field with a companion summary field that uses the `_summary` suffix convention (for example, a checklist field `dod` pairs with `dod_summary`). Summary computation is not automatic for every checklist — it must first be enabled via the `nextedy.checklist._TYPEID_.checklistsIdsForSummary` configuration property, which lists which checklist field IDs get summarized for a given work item type. Once enabled, the summary text is recomputed automatically every time the work item is saved. See [Summary Field Reference](/checklist/reference/summary-field) for the full setup procedure.
1. Confirm the checklist field ID is listed in `nextedy.checklist._TYPEID_.checklistsIdsForSummary` for the work item's type — a checklist that isn't listed there never gets a computed summary, regardless of naming.
2. Verify the summary field's ID actually follows the `_summary` suffix convention for the checklist field it should reflect.
3. Save the work item again (any save triggers recomputation) and check whether the summary field updates.
4. If summary computation itself throws an error, it's logged but does **not** block the save — check the server log around the time of the save for a stack trace tied to summary computation, separate from any save-error investigation above.
## Version-related formatting issue on work item type change
Changing a work item's type can trigger a separate, previously reported Polarion platform issue where multi-line plain text in the checklist field is converted into rich text.
**Tracked upstream Polarion issue**
This has been reported to Siemens as a Polarion platform issue, not a Checklist defect. If your checklist content appears reformatted (plain text turned into rich text) immediately after a work item type change, this is the likely cause. You may also report the issue to Siemens yourself via your support channel to help prioritize a fix.
To avoid the practical impact of both the reset behavior and the formatting issue when type changes are common in your workflow, see [Multiple Templates per Type and Reset on Type Change](/checklist/guides/templates/multiple-templates-per-type), which documents the `nextedy.checklist.checklistsIdsForTypeChanges` configuration property that resets affected checklists cleanly to the correct type's template.
## Verify
You should now see the expected outcome for each scenario:
* A checklist save that previously failed either succeeds (HTTP 200) or produces a log entry with a full parameter dump you can act on or escalate.
* `InvocationTargetException` / `UnresolvableObjectException` entries appearing only at work item creation, with the checklist data itself saved correctly, are recognized as known log noise rather than a functional defect.
* Summary fields (`_summary`) reflect the current checklist state after every save.
* Checklist content survives a work item type change without unexpected reformatting, or you've documented it as a known, reported Polarion issue.
## See also
* [Checklist Is Marked Read-Only](/checklist/guides/troubleshooting/checklist-readonly)
* [Duplicate, Type-Change, and Formatting Issues](/checklist/guides/troubleshooting/duplicate-and-type-change-issues)
* [Multiple Templates per Type and Reset on Type Change](/checklist/guides/templates/multiple-templates-per-type)
* [Summary Field Reference](/checklist/reference/summary-field)
* [Reference](/checklist/reference/index)
# Configure Gate Enforcement (DoD / DoR) and Freeze on Status
Source: https://learn.nextedy.com/checklist/guides/workflow-gates-and-freeze
Block a workflow transition until mandatory checklist items are checked, and freeze a checklist's definition once it reaches a given status.
## Enforce mandatory items on a transition (DoD / DoR gate)
1. Open the workflow configuration for the work item type (or document/test run type) that carries your Definition of Done (`dod`) or Definition of Ready (`dor`) checklist.
2. On the transition that should be gated, add the workflow function `ChecklistFailIfMandatoryUnchecked`.
3. Set the `checklist` argument to the ID of the checklist custom field. Use a comma-separated list to validate more than one checklist field on the same transition.
```text theme={null}
checklist=dod
```
This function blocks the transition with an error message naming the checklist field if any mandatory item is left unchecked. It runs on work items, documents (LiveDocs), and test runs.
**Verify in application**
The exact wording of the blocking error message is not documented here. Check it in your Polarion instance during setup and note it down, so you can add it to your own troubleshooting notes.
### Require every item, not just mandatory ones
If a checklist should block the transition unless **all** items are checked (not only the ones flagged mandatory), enable the checklist's `allMandatory` configuration so `ChecklistFailIfMandatoryUnchecked` treats every item as gating.
## Apply or re-apply a template as a gate action
Use `ChecklistApplyTemplate` on a transition to (re)populate a checklist field from its configured template as part of the transition action:
```text theme={null}
checklist=dod
```
Calling this on a field that already has data re-applies the template content, so place it on transitions where you intend to reset/refresh the checklist (for example, an "init" action when a work item is created).
## Freeze the checklist definition on a status
By default, a checklist's structure keeps re-syncing to its template. To stop that once a work item (or document/test run) reaches a specific status — so the checklist "freezes" at whatever content was recorded so far — set:
```text theme={null}
nextedy.checklist._TYPEID_._FIELDID_._STATUS_.mergeTemplate
nextedy.checklist._TYPEID_._FIELDID_.mergeTemplateResolved
```
For example, to freeze the `dod` checklist once a work item reaches status `reviewed`:
```text theme={null}
nextedy.checklist.dod.reviewed.mergeTemplate=false
nextedy.checklist.dod.mergeTemplateResolved=false
```
**Freezing only affects future syncs — initialize the checklist first**
A frozen checklist shows only the data already stored on the work item. If you add new items to the template but never re-sync the work item's checklist before it reaches the frozen status, those new items will never appear. Make sure the checklist template has been applied (synchronized) to the work item **before** it reaches the frozen status — for example, by attaching `ChecklistApplyTemplate` to the transition that leads into that status.
## Restrict who can change the checklist structure while frozen
Freezing the merge behavior stops automatic template re-sync, but users can still edit the checklist manually unless you also restrict who can change its structure. Combine freeze with the `adminPermission` configuration property:
```text theme={null}
nextedy.checklist._TYPEID_._FIELDID_._STATUS_.adminPermission
```
Example — the `dor` checklist for `userstory` items can only be changed by anyone while still in `draft`, then locks down:
```text theme={null}
nextedy.checklist.userstory.dor.draft.adminPermission=@all
nextedy.checklist.userstory.dor.adminPermission=@none
```
For the full permission property hierarchy and evaluation order, see [Control Who Can Change the Checklist](/checklist/guides/permissions).
## Reset the checklist to template on a status change
To make an approval-style transition also guarantee the checklist reflects the latest template before locking it down, attach `ChecklistApplyTemplate` to that transition's function list, then apply the freeze properties above on the destination status.
Set the function's `checklist` parameter to a comma-separated list of the checklist custom field IDs you want the transition to (re)apply the template to.
**Verify the checklist is synchronized before marking an item approved**
Attach `ChecklistApplyTemplate` to the same workflow function that marks an item approved (or whatever status triggers the freeze). This guarantees the checklist is synchronized to the latest template version at the moment it becomes frozen, rather than relying on someone having manually refreshed it earlier.
## Make the checklist field fully read-only
In addition to permission-based structure locking, you can mark the underlying custom field itself as read-only using **Administration > Work Items > Readonly Fields**, or field-based permissions under **Administration > User Management > Permissions Management**. A fully read-only field blocks both structure changes and item checking — use this when no further interaction should be possible at all, rather than only blocking structure edits.
## Verification
You should now see:
* The gated transition rejected with an error when mandatory items (or, with `allMandatory` enabled, any item) are left unchecked.
* The checklist structure on a work item in the frozen status staying unchanged even after the template is edited, until the freeze status is reverted or the checklist is explicitly re-applied.
## See also
* [Control Who Can Change the Checklist](/checklist/guides/permissions)
* [Create a Checklist Template](/checklist/guides/templates/create-a-template)
* [Multiple Templates per Type and Reset on Type Change](/checklist/guides/templates/multiple-templates-per-type)
* [Track and Compare Checklist Baselines](/checklist/guides/baselines)
# Checklist
Source: https://learn.nextedy.com/checklist/index
Actionable checklists with templates, workflow gates, and baseline tracking for Polarion.
Welcome to the documentation for Nextedy CHECKLIST, an actionable checklist app for Siemens Polarion ALM. Use Checklist to define, track, and enforce structured checklists on work items, documents, test runs, and plans — turning process compliance into something you can configure, gate, and audit directly inside Polarion.
## Quick Navigation
Set up your first checklist on a work item, plan, or test run in a few guided steps.
Understand result states, templates, the configuration property hierarchy, workflow gates, and baselines.
Task-oriented how-to pages for setup, templates, workflow gates, permissions, baselines, and troubleshooting.
Configuration properties, workflow functions and conditions, and the API surface, documented in full.
Answers to common questions, plus a clear look at current capabilities and limitations.
## Key Features
* Per-item result states: Empty (default), OK, NOK, and Pending (Pending is available only when the conditional state is enabled) — plus a non-selectable Information row type
* Template system for predefined checklists per work item type, document type, or plan
* Workflow functions and conditions for gate enforcement, including all-checked, mandatory-checked, and fail-if-unchecked behavior
* Baseline tracking for frozen checklist snapshots with comparison views
* Multi-object support: work items, documents (LiveDocs), test runs, and plans
* Hierarchical configuration property system with global, type-specific, field-specific, and type+field-specific precedence
* Item notes and custom icons for enhanced checklist context
* Summary field aggregation for reporting and dashboard integration
## Documentation Structure
| Section | Purpose | Start Here |
| --------------------------------------------------- | --------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| [Getting Started](/checklist/getting-started/index) | Learn by doing | [Your First Checklist](/checklist/getting-started/your-first-checklist) |
| [Concepts](/checklist/concepts/index) | Understand how Checklist works | [What Is Nextedy Checklist](/checklist/concepts/what-is-checklist) |
| [Guides](/checklist/guides/index) | Accomplish a specific task | [Installation and Licensing](/checklist/guides/installation) |
| [Reference](/checklist/reference/index) | Look up exact properties and APIs | [Property Hierarchy and Precedence Reference](/checklist/reference/configuration/property-hierarchy-reference) |
| [FAQ](/checklist/faq/index) | Get a quick answer | [General FAQ](/checklist/faq/general) |
## Common Tasks
* [Set up a work item checklist](/checklist/guides/setup/work-items)
* [Set up a document (LiveDoc) checklist](/checklist/guides/setup/documents)
* [Create a checklist template](/checklist/guides/templates/create-a-template)
* [Configure gate enforcement (DoD / DoR) and freeze on status](/checklist/guides/workflow-gates-and-freeze)
* [Track and compare checklist baselines](/checklist/guides/baselines)
* [Export checklists and surface progress in reports](/checklist/guides/reporting-and-export)
* [Control who can change the checklist](/checklist/guides/permissions)
**New to Checklist?**
Start with [Your First Checklist](/checklist/getting-started/your-first-checklist) for a guided walkthrough of setting up a checklist on a work item.
# Checklist, ChecklistItem, and CheckItemResult
Source: https://learn.nextedy.com/checklist/reference/api-model
Reference for the checklist data model classes returned by, and passed to, the checklist service API.
Reference for the checklist data model classes returned by, and passed to, the checklist service API.
## Checklist
Represents a checklist instance: an ordered collection of `ChecklistItem` entries, providing counting, merging, summary text, and export/reset behaviors.
| Name | Type | Default | Description |
| ---------------------------------------- | -------------------------------------------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Checklist(String summaryMessageFormat)` | Constructor | n/a | Constructs a `Checklist` configured with a message-format template used to render its summary text. |
| `DATEFORMAT` | Public static constant (String) | `"yyyy-MM-dd"` | Fixed date format used when serializing checklist data to JSON. |
| `getItems()` | Method — returns `Collection` | n/a | Returns all checklist items currently held, including `Information`-type items (the full, unfiltered set). |
| `getActiveItems()` | Method — returns stream of `ChecklistItem` | n/a | Returns items excluding those with an `INFORMATION` result. This is the basis for all counting/completion logic below. |
| `mergeItemIn(ChecklistItem item)` | Method — returns `ChecklistItem` | n/a | Adds a new item, or — if an item with the same id already exists — updates the existing item's result to match the incoming item's result instead of duplicating it. |
| `isMandatoryChecked()` | Method — returns `boolean` | n/a | `true` only if every mandatory active item has a checked result (`Checked` or `Conditional`). |
| `isAllChecked()` | Method — returns `boolean` | n/a | `true` only if every active item, mandatory or not, has a checked result. |
| `getCheckedCount()` | Method — returns `int` | n/a | Number of active items whose result is a checked state (`Checked` or `Conditional`). |
| `getRejectedCount()` | Method — returns `int` | n/a | Number of active items whose result is `REJECTED`. |
| `getNACount()` | Method — returns `int` | n/a | Number of active items whose result is `NONE` (shown as "NA" in the summary text). |
| `getUncheckedCount()` | Method — returns `int` | See application | Broader than `getNACount()` — includes all unchecked active items, not only those in `NONE` state. |
| `getUncheckedMandatoryCount()` | Method — returns `int` | See application | Count of mandatory active items not yet checked. |
| `getMandatoryCount()` | Method — returns `int` | See application | Count of active items marked mandatory. |
| `getCheckedMandatoryCount()` | Method — returns `int` | See application | Intended to count mandatory active items that are checked, but known to be buggy and undocumented — see warning below. |
| `getAllCount()` | Method — returns `int` | See application | Count of all active items. |
| `getSummaryText()` | Method — returns `String` | n/a | Renders the checklist's summary text using the `summaryMessageFormat` template supplied to the constructor. |
| `toText()` | Method — returns `Text` | n/a | Exports the checklist as its underlying stored text representation. |
| `toJSON()` | Method — returns `String` | n/a | Serializes all items (via `getItems()`, the unfiltered set) to a JSON string using `DATEFORMAT` for any dates. Used internally when rendering checklist data into the form extension/Velocity widget. |
| `uncheckAll()` | Method — returns `void` | n/a | Clears the result of every item, returning the checklist to an unchecked state. Used by the `ChecklistUncheckAll` workflow function. |
**Information items are excluded from all statistics**
Any item with an `INFORMATION` result is excluded from every counting method (`getCheckedCount`, `getMandatoryCount`, `isAllChecked`, etc.) because they are drawn from `getActiveItems()`, not `getItems()`. This explains why an informational row does not affect the completion count shown in the checklist form extension.
**Known limitation — getCheckedMandatoryCount is buggy/undocumented**
`getCheckedMandatoryCount()` is known to be buggy and undocumented. Do not rely on it for accurate counts in custom scripting or reporting; use `getMandatoryCount()` and `getUncheckedMandatoryCount()` together (mandatory total minus unchecked-mandatory) if a checked-mandatory count is needed.
### `summaryMessageFormat` placeholder tokens
The message-format template passed to the `Checklist` constructor supports these placeholder tokens:
| Token | Description |
| -------------------- | ----------------------------------- |
| `checked` | Number of checked (active) items |
| `unchecked` | Number of unchecked (active) items |
| `rejected` | Number of rejected items |
| `NA` | Number of items in `NONE` state |
| `uncheckedMandatory` | Number of unchecked mandatory items |
| `mandatory` | Total number of mandatory items |
| `checkedMandatory` | Number of checked mandatory items |
| `all` | Total number of active items |
**Verify in application**
The exact message-format syntax (e.g. positional `{0}`-style placeholders vs named tokens) is not confirmed — check the literal template syntax in your Polarion instance before authoring a custom `summaryMessageFormat`.
### `mergeItemIn` — template re-sync behavior
Merging happens on every parse: the checklist is seeded from the **template first** (each item's label, mandatory flag, and description come from the template), and then the stored field content is merged in, carrying over only the **result** of each matching item (matched by id). The practical consequence is that the template wins — **label, mandatory flag, and description always refresh from the current template** on re-parse, while a reviewer's recorded result is preserved.
**Template changes propagate to existing items**
If a template's mandatory flag, label, or description changes after items already exist on an object's checklist, those changes **do** reach the existing items the next time the checklist is parsed — only the item's result is kept from the stored content. The template's mandatory flag wins over the one stored on the object.
## ChecklistItem
Represents a single item (row) in a checklist: its label, result state, mandatory flag, description/note text, and template origin.
| Name | Type | Default | Description |
| ------------------------------------------------------------ | --------------------------------- | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `ChecklistItem()` | Constructor | n/a | Default constructor. |
| `ChecklistItem(String label)` | Constructor | n/a | Constructs an item with the given label. The item's `id` defaults to the same value as `label` when constructed this way. |
| `getResult()` / `setResult(CheckItemResult result)` | Accessor pair — `CheckItemResult` | `CheckItemResult.NONE` | Gets or sets the item's current result. `getResult()` defaults to `NONE` if no result has been set. |
| `isChecked()` | Method — returns `boolean` | n/a | `true` if the item's result is a checked state (`Checked` or `Conditional`); `false` if the result is `null` or any other state. An item with no result set is treated as unchecked. |
| `setChecked(boolean checked)` | Method — returns `void` | n/a | Forcibly marks the item's result as `CHECKED`. |
| `isMandatory()` / `setMandatory(boolean mandatory)` | Accessor pair — `boolean` | See application | Gets or sets whether the item must be checked before the checklist (or a mandatory-gated workflow) is considered complete. |
| `isFromTemplate()` / `setFromTemplate(boolean fromTemplate)` | Accessor pair — `boolean` | See application | Gets or sets whether the item originated from a checklist template versus being added manually. |
| `getLabel()` / `setLabel(String label)` | Accessor pair — `String` | n/a | Gets or sets the item's display text. |
| `getId()` / `setId(String id)` | Accessor pair — `String` | Same as `label` when using the single-arg constructor | Gets or sets the item's unique identifier, used as the merge key in `Checklist.mergeItemIn`. |
| `getNote()` / `setNote(String note)` | Accessor pair — `String` | n/a | Gets or sets a free-text note attached to the item — reviewer-editable, rendered with a leading `>` in the underlying text format. |
| `getDescription()` / `setDescription(String description)` | Accessor pair — `String` | n/a | Gets or sets static, template-level guidance text for the item — rendered with a leading `/` in the underlying text format, distinct from the reviewer-editable note. |
**Known limitation — `setChecked(boolean)` ignores its parameter**
`setChecked` always sets the result to `CHECKED` regardless of the boolean value passed. There is no "uncheck a single item" behavior via this method — passing `false` still checks the item. To uncheck items, use `Checklist.uncheckAll()` or set the result explicitly via `setResult(CheckItemResult.NONE)`.
### Note vs. description
| Field | Rendered with | Set by | Purpose |
| ------------- | ------------- | ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `description` | Leading `/` | Template author | Static guidance text explaining what the item means. |
| `note` | Leading `>` | Reviewer, at check time | Free-text detail added when checking/rejecting an item — see [Assign notes to checklist items](/checklist/guides/item-notes) for the UI. |
The **Reply** icon is used to add a note to an item, provided the checklist is editable:
## CheckItemResult
An enum representing the possible result states of a `ChecklistItem`.
| Name | Type | Default | Description |
| -------------------------- | ----------------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `NONE` | Enum constant | — | Character `_`, label `"None"`. The default/unset state. |
| `CHECKED` | Enum constant | — | Character `X`, label `"Checked"`. |
| `REJECTED` | Enum constant | — | Character `O`, label `"Rejected"`. |
| `CONDITIONAL` | Enum constant | — | Character `+`, label `"Conditional"`. Counts as a checked state everywhere `isChecked()` is evaluated (see `Checklist.isMandatoryChecked()`, `isAllChecked()`, `getCheckedCount()` above). Only reachable in the UI when `nextedy.checklist.conditional_enabled=true` (see [Icon, Feature-Toggle, and Baseline Properties](/checklist/reference/configuration/appearance-and-feature-properties)). |
| `INFORMATION` | Enum constant | — | Character `i`, label `"Information"`. Marks a non-actionable annotation row; `Checklist.getActiveItems()` filters out items in this state, which is why they are excluded from every counting method (see the note above `getActiveItems()`). |
| `getCharacter()` | Method — returns `String` | n/a | Returns the single-character code (`_`, `X`, `O`, `+`, or `i`) used in the underlying stored text representation. |
| `getLabel()` | Method — returns `String` | n/a | Returns the human-readable label (`"None"`, `"Checked"`, `"Rejected"`, `"Conditional"`, or `"Information"`). |
| `equalsToString(String v)` | Method — returns `boolean` | n/a | Compares the enum's `label` (not its character code) against a given string for an exact match. |
| `isChecked()` | Method — returns `boolean` | n/a | `true` for `CHECKED` or `CONDITIONAL`. |
| `parse(String str)` | Static method — returns `CheckItemResult` | n/a | Matches a bracketed prefix (`[X]`, `[O]`, `[+]`, `[i]`) at the start of the string to `CHECKED`, `REJECTED`, `CONDITIONAL`, or `INFORMATION` respectively; returns `NONE` for any string that doesn't start with one of those four prefixes (including `[_]` and unrecognized input). |
**UI-facing state names vs. enum constants**
`CheckItemResult` has five constants, and each corresponds to one state a reader sees in the rendered checklist: `NONE` is `Empty`, `CHECKED` is `OK`, `REJECTED` is `NOK`, `CONDITIONAL` is `Pending` (offered only when the conditional state is enabled), and `INFORMATION` is the non-selectable Information row that carries no result and is excluded from completion counts. The four selectable states are the full set — there is no "not applicable" state.
## Underlying text storage format
Checklist state is persisted as plain text in the underlying custom field (not as structured JSON), using this line-based syntax:
* Each item line starts with its result character in square brackets — `[X]`, `[O]`, `[+]`, `[i]`, or `[_]` for `CHECKED`, `REJECTED`, `CONDITIONAL`, `INFORMATION`, or `NONE` respectively.
* An optional `!` immediately follows the closing bracket (before the tab) to mark the item mandatory — for example `[X]!`, not a trailing `!` at the end of the line.
* A tab separates the bracketed result/mandatory marker from the item label text.
* A leading `/` (on its own line, indented under the item) marks a description line.
* A leading `>` (on its own line, indented under the item) marks a note line.
```text theme={null}
[X]!Review requirements traceability
/This item verifies all requirements have upstream links
>Checked against baseline REQ-2024-03
[_]Sign off from safety engineer
```
**Not structured data**
Because checklist state is plain text in a rich-text/text field, any external tool reading the field directly (rather than through `IChecklistService.parse`) must replicate this exact syntax, including the brackets around the result character, the mandatory marker's position immediately after the bracket (not at the end of the line), and the tab separator.
## See also
* [IChecklistService and Velocity Rendering API](/checklist/reference/api-service) — the service that parses text into these objects and stores them back.
* [Summary Field Reference](/checklist/reference/summary-field) — how `Checklist` counts feed into the `_summary` custom field.
# IChecklistService and Velocity Rendering API
Source: https://learn.nextedy.com/checklist/reference/api-service
Reference for the checklist service API surface — the entry point for reading, storing, resetting, and applying templates to checklists from Java workflow functions/conditions and from Velocity (LiveReport / wiki pages).
Reference for the checklist service API surface — the entry point for reading, storing, resetting, and applying templates to checklists from Java workflow functions/conditions and from Velocity (LiveReport / wiki pages).
**Verify in application**
This page documents the API surface as published in the product's API documentation. Method behavior for edge cases not explicitly described below should be verified in the application.
## Overview
## Accessing the service
### From Java (workflow functions and conditions)
```java theme={null}
private static IChecklistService checklistService =
PlatformContext.getPlatform().lookupService(IChecklistService.class);
```
This is the pattern used internally by the `ChecklistUncheckAll` workflow function. Use the same lookup in custom workflow `IFunction` or `ICondition` implementations that need programmatic access to checklist state.
### From Velocity (LiveReport / wiki pages)
The service is exposed directly in the Velocity context as `$checklistService` — no lookup call is required.
```velocity theme={null}
#set( $wi = $trackerService.queryWorkItems("project.id:chldemo AND id:EL-191", "id").iterator().next() )
#set( $cList = $checklistService.parse( $wi, "dor"))
#foreach($i in $cList.getItems())
[#if($i.checked)X#end]. $i.label
$!i.note
#end
```
**LiveReport table fields and querying via Lucene are not confirmed**
No documented mechanism adds checklist progress (for example `1/7 completed`) as a LiveReport table field, or queries per-item checked-state via a Lucene-style query. The Velocity access pattern above — parsing the checklist field inside a script block — is the supported route. Treat a native LiveReport table column for a checklist as unsupported unless you confirm otherwise in your Polarion instance.
## Method reference — IChecklistService
All methods below are declared on the `IChecklistService` interface. Overloads exist per target object type: work item, document (module), test run, and plan — although not every method has an overload for every type (see notes).
| Name | Type | Default | Description |
| -------------------------------- | ---------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `parse` | Method — returns `Checklist` | n/a | Parses the checklist markup stored in a field into a `Checklist` object. Overloaded for `IWorkItem`, `WorkItem`, `IModule`, `ITestRun`, and `IPlan` targets. |
| `store` | Method — returns `void` | n/a | Persists a `Checklist` object, or a raw checklist data `String`, back into a field. Overloaded across `IModule`, `IWorkItem`, `WorkItem`, `ITestRun`, and `IPlan`. |
| `reset` | Method — returns `void` | n/a | Resets/clears the checklist stored on a work item, module, test run, or plan field. |
| `applyTempate` | Method — returns `void` | n/a | Re-syncs a field against its configured checklist template and immediately saves the result (parse-then-store; see the merge-semantics note below — existing progress is preserved, not discarded). **Note the exact method spelling `applyTempate`** (not `applyTemplate`) — this is how it appears in the interface and must be called exactly as spelled. |
| `getChecklistConf` | Method — returns `ChecklistConf` | n/a | Retrieves the configuration object governing the checklist's behavior/appearance for a given field. Overloaded for `WorkItem`, `IWorkItem`, `IModule`, `ITestRun`, and `IPlan`. |
| `getChecklistsIdsForSummary` | Method — returns `String[]` | n/a | Returns the checklist field IDs configured for summary computation on the given target, via `nextedy.checklist._TYPEID_.checklistsIdsForSummary` (see [Summary Field Reference](/checklist/reference/summary-field)). Overloaded for `IWorkItem`, `IModule`, `ITestRun`, and `IPlan`. |
| `getChecklistsIdsForTypeChanges` | Method — returns `String[]` | n/a | Returns the checklist IDs relevant when a work item's type changes. Available only for `IWorkItem` — no module/test run/plan overload. |
| `getDocumentChecklistView` | Method — returns `DocumentChecklistView` | n/a | Returns a fluent Velocity-rendering builder scoped to a **document or work item**: chain `.document(IModule)` or `.workitem(IWorkItem)`, then `.checklist(String)`, optionally `.hideInPdf()`/`.title(String)`, then `.render()`. A LiveReport/wiki-page rendering path, distinct from the checklist form extension (which renders directly on the work item form and does not go through this builder). |
| `getChecklistView` | Method — returns `ChecklistView` | n/a | Returns a fluent Velocity-rendering builder scoped to a **test run or plan**: chain `.testRun(ITestRun)` or `.plan(IPlan)`, then `.checklist(String)`, optionally `.hideInPdf()`/`.title(String)`, then `.render()` — e.g. `$checklistService.getChecklistView().testRun($testRun).checklist("testDone").render()` on a Test Run/Plan Report page. Also a LiveReport/wiki-page rendering path, distinct from the checklist form extension. |
| `getDocumentBaselinesView` | Method — returns `BaselinesView` | n/a | Returns the view used to display checklist baselines (historical/revision comparisons) within a document. |
### `parse` — full signature list
```java theme={null}
Checklist parse(IWorkItem workItem, String field);
Checklist parse(WorkItem workItem, String field);
Checklist parse(IModule module, String field);
Checklist parse(ITestRun testRun, String field);
Checklist parse(IPlan plan, String field);
```
**Test run and plan overloads**
The published IChecklistService API article lists only the `IWorkItem` / `WorkItem` / `IModule` overloads of `parse`. The interface also declares `parse` for `ITestRun` and `IPlan` targets, each merging in the target's own template (test run template via the test run's template test run; plan template via the plan's template plan). The `field` parameter identifies which field on the target stores the checklist markup.
### `store` — full signature list
```java theme={null}
void store(Checklist checklist, WorkItem workItem, String field);
void store(Checklist checklist, IWorkItem workItem, String field);
void store(Checklist checklist, IModule module, String field);
void store(Checklist checklist, ITestRun testRun, String field);
void store(Checklist checklist, IPlan plan, String field);
void store(String data, IModule module, String field);
void store(String data, IWorkItem workItem, String field);
void store(String data, ITestRun testRun, String field);
void store(String data, IPlan plan, String field);
```
**Test run and plan overloads**
Both the `Checklist`-typed and the raw-`String`-typed `store` overloads exist for `ITestRun` and `IPlan`, in addition to `IWorkItem`/`WorkItem`/`IModule`.
### `applyTempate` — full signature list
```java theme={null}
void applyTempate( IWorkItem workItem, String field);
void applyTempate( WorkItem workItem, String field);
void applyTempate( IModule module, String field);
void applyTempate( ITestRun testRun, String field);
void applyTempate( IPlan plan, String field);
```
**Merge semantics — not destructive**
Every `applyTempate` overload behaves as `store(parse(target, field), target, field)` — it re-parses the field (which merges the template into the currently stored content, exactly like a normal `parse` call — see [Template Merge Behavior](/checklist/reference/configuration/template-properties)) and immediately persists the merged result. Calling `applyTempate` on a field that already has data does **not** discard existing progress: items matched by id keep their recorded result, while label/mandatory/description are refreshed from the template. This is different from `reset` below, which discards all existing content unconditionally.
### `reset` — full signature list
```java theme={null}
void reset( IWorkItem workItem, String field);
void reset( WorkItem workItem, String field);
void reset( IModule module, String field);
void reset( ITestRun testRun, String field);
void reset( IPlan plan, String field);
```
**Destructive action**
Resetting a checklist re-parses the template content and saves it, discarding any current checklist progress on that field. There is no undo.
### `getChecklistConf` — full signature list
```java theme={null}
ChecklistConf getChecklistConf(WorkItem workItem, String field);
ChecklistConf getChecklistConf(IWorkItem workItem, String field);
ChecklistConf getChecklistConf(IModule module, String field);
ChecklistConf getChecklistConf(ITestRun testRun, String field);
ChecklistConf getChecklistConf(IPlan plan, String field);
```
**Test run and plan overloads**
`getChecklistConf` has dedicated `ITestRun` and `IPlan` overloads. Each derives `readonly`/`adminPermission` from whether the current user may modify that test run or plan, rather than from the Checklist licence authorisation used on the work item path.
## Worked example — Java workflow function
The `ChecklistUncheckAll` workflow function demonstrates the full lookup → parse → mutate → store cycle. Its target resolution — `context.getTarget()` plus an `instanceof` branch per type — is the same pattern used by every checklist workflow function/condition (see [Workflow Functions and Conditions](/checklist/reference/workflow)):
```java theme={null}
private static IChecklistService checklistService =
PlatformContext.getPlatform().lookupService(IChecklistService.class);
public void execute(ICallContext context, IArguments arguments) {
String chlField = arguments.getAsString("checklist");
if (chlField == null) {
throw new RuntimeException("checklist attribute missing for wf function: ChecklistUncheckAll ");
}
IWorkflowObject workflowObject = context.getTarget();
if (workflowObject instanceof IWorkItem) {
IWorkItem wi = (IWorkItem) workflowObject;
String[] fields = chlField.split(",");
for (int i = 0; i < fields.length; i++) {
Checklist chl = checklistService.parse(wi, fields[i]);
chl.uncheckAll();
checklistService.store(chl, wi, fields[i]);
}
}
if (workflowObject instanceof IModule) {
IModule module = (IModule) workflowObject;
String[] fields = chlField.split(",");
for (int i = 0; i < fields.length; i++) {
Checklist chl = checklistService.parse(module, fields[i]);
chl.uncheckAll();
checklistService.store(chl, module, fields[i]);
}
}
if (workflowObject instanceof ITestRun) {
ITestRun testRun = (ITestRun) workflowObject;
String[] fields = chlField.split(",");
for (int i = 0; i < fields.length; i++) {
Checklist chl = checklistService.parse(testRun, fields[i]);
chl.uncheckAll();
checklistService.store(chl, testRun, fields[i]);
}
}
}
```
**Work item, document, and test run — not plan**
`ChecklistUncheckAll` (like the other workflow functions/conditions on the [Workflow Functions and Conditions](/checklist/reference/workflow) page) branches on `IWorkItem`, `IModule`, and `ITestRun` only — there is no `IPlan` branch, so it is not available as a workflow action on plan transitions.
**Pattern to reuse in custom workflow functions**
The same shape works for custom use cases: call `checklistService.parse(wi, "dod")` to get a `Checklist` object, iterate `ChecklistItem.checked` and `ChecklistItem.label` on its items (for example to create follow-up tasks from checked items), then call `checklistService.reset()` on the work item or module when the checklist needs clearing as part of the same function.
## Worked example — Velocity on a LiveReport or wiki page
```velocity theme={null}
#set( $wi = $trackerService.queryWorkItems("project.id:chldemo AND id:EL-191", "id").iterator().next() )
#set( $cList = $checklistService.parse( $wi, "dor"))
#foreach($i in $cList.getItems())
[#if($i.checked)X#end]. $i.label
$!i.note
#end
```
This queries a single work item, parses its `dor` checklist field, and renders each item's checked state, label, and note.
## Related rendering entry point — checklist form extension
The checklist form extension (the form widget shown on a work item) is wired to `IChecklistService` internally: it calls `parse` to read the current checklist state, and `getChecklistConf` to read the configuration that controls how the widget behaves and renders. The form extension always reflects the current stored checklist state on render — it is a live read, not a cached snapshot.
| Name | Type | Default | Description |
| ------------------ | ------------------------------ | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `checklistId` | Form-layout attribute (String) | See application | Identifies which checklist field on the work item the form extension renders. Required — omitting it produces the runtime error `Checklist ID not set for extension.` |
| `checklistService` | Velocity context binding | n/a | The `IChecklistService` instance itself, exposed in the form extension's rendering context under the key `checklistService`, enabling the template to make further service calls (for example reset or apply-template) directly from the form template. |
**Full extension-tag attributes documented in the setup guide**
The full `` tag — including the `id` (extension implementation ID, e.g. `ChecklistFormExtension`) and `label` (display heading) attributes alongside `checklistId` — is documented with a worked example in [Set Up a Work Item Checklist](/checklist/guides/setup/work-items), not repeated here to avoid duplication.
## Known limitations
* **LiveReport table field / column integration for checklist progress is not confirmed as supported.** There is no built-in field that shows progress (e.g., `1/7 completed`) as a LiveReport table field without writing a Velocity script. The Velocity scripting approach shown above is the confirmed workaround.
* **Direct Lucene-style querying of individual checklist item checked-state is not confirmed as supported.** Per-item state must be read by parsing the field via `IChecklistService.parse` in a script, not via a query filter.
* **Access to `IChecklistService` from scripted JavaScript workflow conditions is not confirmed.** Whether the service can be reached from a JavaScript-based workflow condition — as opposed to Velocity (VTL) or Java — is unconfirmed. Only Java (via `PlatformContext.getPlatform().lookupService`) and Velocity (via `$checklistService`) access are confirmed. Verify JavaScript access in your Polarion instance before relying on it.
## See also
* [Checklist, ChecklistItem, and CheckItemResult](/checklist/reference/api-model) — the data model classes returned by and passed to this service.
* [Summary Field Reference](/checklist/reference/summary-field) — how checklist state is surfaced into a queryable summary field, as an alternative to scripting.
* [Workflow Functions and Conditions](/checklist/reference/workflow) — workflow-level gate enforcement built on top of this service.
# Icon, Feature-Toggle, and Baseline Properties
Source: https://learn.nextedy.com/checklist/reference/configuration/appearance-and-feature-properties
Reference for configuration properties that control checklist item **icons**, product **feature toggles**, general behavior flags, and **baseline** history lookup.
Reference for configuration properties that control checklist item **icons**, product **feature toggles**, general behavior flags, and **baseline** history lookup.
All properties are set in **Administration > Configuration Properties** using the `nextedy.checklist.*` namespace.
## Icon (Result-State) Properties
Each result state's icon is rendered using a Font Awesome CSS class. These properties override the default icon class per state.
| Name | Type | Default | Description |
| ------------------------------------ | ------------------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `nextedy.checklist.checked_sign` | `string` (CSS/icon class) | `far fa-check-square` | Icon class used to render the `Checked` result state icon. |
| `nextedy.checklist.unchecked_sign` | `string` (CSS/icon class) | `far fa-minus-square` | Icon class used to render the unchecked-state icon. |
| `nextedy.checklist.no_sign` | `string` (CSS/icon class) | `far fa-square` | Icon class used to render the `Empty` (None) result-state icon. |
| `nextedy.checklist.conditional_sign` | `string` (CSS/icon class) | `far fa-plus-square` | Icon class used to render the Conditional result-state icon. Only meaningful when `conditional_enabled` (see below) is `true`. |
```text theme={null}
# Example: override the checked icon with a custom Font Awesome class
nextedy.checklist.checked_sign=fas fa-check-double
```
**Font Awesome classes**
Values are raw CSS class strings passed straight through to the rendered icon element. Use valid Font Awesome class names available in your Polarion installation's bundled icon set.
## Feature-Toggle Properties
| Name | Type | Default | Description |
| --------------------------------------- | --------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `nextedy.checklist.conditional_enabled` | `boolean` | `false` | Master toggle controlling whether the Conditional result state is available to users at all. When `false`, the Conditional state and its icon (`conditional_sign`) are not offered. |
| `nextedy.checklist.debug` | `boolean` | `false` | Enables debug mode/logging for Checklist. Intended for admin/support troubleshooting use, not general operation. |
| `nextedy.checklist.searchAttempts` | `integer` | `30` | Number of attempts Checklist makes when searching for a related object (for example, locating a linked work item or document). Tune for performance/retry behavior in search operations. |
```text theme={null}
# Enable the Conditional result state
nextedy.checklist.conditional_enabled=true
# Increase search retry attempts (default 30)
nextedy.checklist.searchAttempts=50
```
**Conditional state depends on the toggle**
The `conditional_sign` icon property has no visible effect unless `nextedy.checklist.conditional_enabled=true` is also set. Configure both together.
## General Behavior Properties
| Name | Type | Default | Description |
| --------------------------------------------------- | --------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `nextedy.checklist._TYPEID_._FIELDID_.allMandatory` | `boolean` | `false` | Shortcut flag that treats every item in a checklist template as mandatory by default, without marking each item individually. Follows the same type/field precedence pattern as other hierarchical properties — see [Template Configuration Properties](/checklist/reference/configuration/template-properties). |
## Baseline Configuration Properties
Baseline properties control which work item type and custom field represent a **baseline** record — a frozen checklist snapshot — used to build the queries behind the baseline history feature.
| Name | Type | Default | Description |
| ------------------------------------------- | ---------------------------- | ---------- | ------------------------------------------------------------------------------------ |
| `nextedy.checklist.baselines.itemType` | `string` (work item type ID) | `btask` | Work item type used to represent a baseline record for checklist history. |
| `nextedy.checklist.baselines.baselineField` | `string` (custom field ID) | `baseline` | Custom field on the baseline item type that stores the baseline/revision identifier. |
```text theme={null}
# Use a custom work item type and field to store baseline snapshots
nextedy.checklist.baselines.itemType=chlBaseline
nextedy.checklist.baselines.baselineField=revisionId
```
These two properties are read together whenever the baseline/history feature builds a Lucene query to:
* find the baseline item matching a specific revision for the current document, or
* find all baseline items (any revision) associated with the current document.
**Result state counting in baselines and summaries**
The Checklist summary field currently counts "not ok" (rejected/red) items together with unchecked/empty items — there is no separate count for "not ok" versus "unchecked/empty" in the summary. See [Summary Field Reference](/checklist/reference/summary-field) for the full counting model. There is also no predefined workflow function to verify that all checklist items are answered as either ok or not-ok; this requires a custom scripted condition built against the checklist API. Treat this as a known limitation when designing baseline-driven audit or compliance comparisons.
## Related Configuration
* [Template Configuration Properties](/checklist/reference/configuration/template-properties) — properties that resolve which checklist content is treated as the template.
* [Permission, Freeze, and Read-Only Properties](/checklist/reference/configuration/permission-and-freeze-properties) — properties controlling who can edit checklist structure and results.
* [Property Hierarchy and Precedence Reference](/checklist/reference/configuration/property-hierarchy-reference) — the general 4-level precedence model shared across hierarchical properties like `allMandatory`.
* [Summary Field Reference](/checklist/reference/summary-field) — how checked, rejected, and mandatory counts are aggregated for reporting.
# Permission, Freeze, and Read-Only Properties
Source: https://learn.nextedy.com/checklist/reference/configuration/permission-and-freeze-properties
Reference for configuration properties and standard Polarion permission mechanisms controlling who can change checklist content and when its structure can be modified.
Reference for configuration properties and standard Polarion permission mechanisms that control **who can change checklist content**, and **when** a checklist's structure or item results can be modified.
There are two distinct use cases covered by this page:
1. Who can mark items as checked/unchecked (change item **results**).
2. Who can define the checklist **structure** — add or remove checklist items (freeze/admin permission).
## Controlling Who Can Check/Uncheck Items
| Mechanism | Type | Default | Description |
| --------------------------------------------------------------------------------------- | -------------------------------------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| Read-only fields (**Administration > Work Items > Readonly Fields**) | Polarion standard permission mechanism | See application | Marks the checklist custom field as read-only so no user can modify it, including checking/unchecking items. |
| Field-based permissions (**Administration > User Management > Permissions Management**) | Polarion standard permission mechanism | See application | Grants or restricts write access to the checklist custom field per role, controlling who can mark checklist items as checked. |
**Standard Polarion permissions, not Checklist-specific**
Marking items as checked is simply a modification of the underlying custom field. This is controlled entirely by standard Polarion field permission mechanisms — not by a `nextedy.checklist.*` configuration property.
## Controlling Who Can Define the Checklist Structure
| Name | Type | Default | Description |
| --------------------------------------------------------------- | -------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `nextedy.checklist._TYPEID_._FIELDID_._STATUS_.adminPermission` | `string` | See application | Controls which users/roles may add, remove, or otherwise edit the **structure** of a checklist (as opposed to just checking items). Commonly tied to a workflow status so the structure can be frozen once a work item leaves a given state. |
`_TYPEID_`, `_FIELDID_`, and `_STATUS_` are all optional segments, giving four levels of specificity (matching the wider [Property Hierarchy and Precedence Reference](/checklist/reference/configuration/property-hierarchy-reference)) plus status-scoping.
### Accepted Values
| Value | Meaning |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------ |
| `@none` | No user, regardless of role, may edit the checklist structure. |
| `@all` | Any user may edit the checklist structure. |
| Comma-separated list of user roles | Only users holding one of the listed roles (including project roles) may edit the checklist structure. |
### Example — Definition of Done / Definition of Ready gating
```text theme={null}
# 'dod' checklist can be controlled by global admin and project_developer roles
nextedy.checklist.dod.adminPermission=admin,project_developer
# but when 'userstory' is in status 'verified' the checklist definition cannot be changed at all
nextedy.checklist.dod.verified.adminPermission=@none
# 'dor' checklist cannot be adjusted at all, unless overridden below
nextedy.checklist.userstory.dor.adminPermission=@none
# 'dor' checklist can be changed by anyone only when the work item is in status 'draft'
nextedy.checklist.userstory.dor.draft.adminPermission=@all
```
After configuring the properties above, the checklist form extension hides the controls for adding, deleting, or editing items whenever the current status does not grant `adminPermission` — but users can still mark existing items as checked:
**Version 25.7.0 and later**
Starting with **version 25.7.0**, regular users without admin permission for the current condition also cannot clear the checklist structure — the **Clear** action is no longer available under the gear menu icon.
## Order of Evaluation — `adminPermission`
The system evaluates the `adminPermission` key in the following order, most specific first, for a given type, checklist field, and status (example: type `userstory`, checklist `dod`, status `accepted`):
The first property key that has a value set wins; evaluation stops at that level.
## Read-Only and Admin Permission Flags (Runtime)
| Name | Type | Default | Description |
| --------------------------------- | --------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `adminPermission` (resolved flag) | `boolean` | See application | The resolved flag, computed from the `adminPermission` property chain above, indicating whether the current user/context has administrative permission over the checklist's structure. |
| `readonly` (resolved flag) | `boolean` | See application | Indicates whether the checklist rendering widget treats the checklist as read-only. There is no dedicated `nextedy.checklist.*.readonly` configuration property — see how it is computed below. |
**How `readonly` is computed — it differs by target type**
There is no dedicated `readonly` configuration property. For a **work item**, `readonly` is computed purely from Checklist license authorization — it does **not** factor in Polarion's own field permissions or workflow state at that layer. For a **document, test run, or plan**, `readonly` additionally factors in Polarion's standard modify-permission check (`can().modify()`) for that target. In all cases, actual enforcement of who can check/uncheck items on a **work item** checklist field still goes through the standard Polarion field-permission mechanisms described under "Controlling Who Can Check/Uncheck Items" above, independently of this resolved flag.
## Document-Level Checklists — Known Limitation
**Freeze and permission syntax for document checklists needs confirmation**
Whether the `adminPermission` freeze/permission syntax documented above (designed around work item type, field, and status) applies identically to **document-level** checklists — or requires different syntax — is not confirmed. Verify this in your Polarion instance before relying on it. A document acting as its own template does automatically grant administrative permission on its own checklist, but the general freeze/permission configuration path for document checklists is not yet documented separately.
## Related Configuration
* [Property Hierarchy and Precedence Reference](/checklist/reference/configuration/property-hierarchy-reference) — the general 4-level precedence model that `adminPermission` extends with a status dimension.
* [Template Configuration Properties](/checklist/reference/configuration/template-properties) — template resolution properties that interact with structure-editing permissions.
* [Icon, Feature-Toggle, and Baseline Properties](/checklist/reference/configuration/appearance-and-feature-properties) — appearance and baseline-related properties.
* [Workflow Functions and Conditions](/checklist/reference/workflow) — workflow functions and conditions that gate transitions based on checklist completion, distinct from structure-edit permissions.
# Property Hierarchy and Precedence Reference
Source: https://learn.nextedy.com/checklist/reference/configuration/property-hierarchy-reference
Exhaustive reference for how Nextedy CHECKLIST resolves configuration properties across global, type-specific, field-specific, and status-specific scopes.
## Property key pattern
All configuration properties are set in **Administration > Configuration Properties** and follow this dot-notation pattern:
```text theme={null}
nextedy.checklist._TYPEID_._FIELDID_.propertyName
```
| Segment | Type | Default | Description |
| -------------- | ------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------ |
| `_TYPEID_` | `string` (optional) | See application | The work item type ID (or document type ID) the property applies to, e.g. `userstory`. Omit to apply to all types. |
| `_FIELDID_` | `string` (optional) | See application | The checklist custom field ID the property applies to, e.g. `dod`. Omit to apply to all checklists. |
| `propertyName` | `string` | N/A | The specific property being set, e.g. `allMandatory`, `adminPermission`. |
**Both segments are optional, independently**
`_TYPEID_` and `_FIELDID_` can each be present or omitted, which is what produces the 4-level precedence below. They are not positionally fixed beyond "type before field" in the key.
## 4-level precedence (type + field specificity)
Documented for the `allMandatory` property, which configures whether all checklist items are treated as mandatory:
| Level | Property Key Example | Scope |
| --------------------------- | --------------------------------------------------- | --------------------------------------------------------------------- |
| 4 (most specific) | `nextedy.checklist.userstory.dod.allMandatory=true` | Applies only to the `dod` checklist on the `userstory` work item type |
| 3 | `nextedy.checklist.dod.allMandatory=true` | Applies to the `dod` checklist for **any** work item type |
| 2 | `nextedy.checklist.userstory.allMandatory=true` | Applies to **any** checklist on the `userstory` work item type |
| 1 (least specific / global) | `nextedy.checklist.allMandatory=true` | Applies to any checklist, any type |
**Verify in application**
The system searches for `allMandatory` in the order shown above — type+field, then field-only, then type-only, then global. The fully expanded 8-step order in the next section is documented for `adminPermission` only; whether other properties follow that same status-aware expansion is not documented. Treat the 4-level example above as the base pattern, and verify anything beyond it in your Polarion instance before relying on it.
For `type=userstory, field=dod, property=allMandatory`, the lookup walks from level 4 down to level 1 in the table above, stopping at the first property key that is actually set, and falling back to the global default only if none of the more specific keys are configured.
## Status-aware precedence (adminPermission)
The `adminPermission` property additionally supports a `_STATUS` segment, extending the pattern to:
```text theme={null}
nextedy.checklist._TYPEID_._FIELDID_._STATUS_.adminPermission
```
| Property | Type | Default | Description |
| --------------------------------------------------------------- | -------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `nextedy.checklist._TYPEID_._FIELDID_._STATUS_.adminPermission` | `string` | See application | Controls who may define/edit the checklist **structure** (add/remove items), optionally scoped to a specific workflow status. |
Accepted values:
| Value | Meaning |
| ---------------------------------- | -------------------------------------------------------------------------------------------------------- |
| `@none` | No one may change the checklist structure at this scope. |
| `@all` | Anyone may change the checklist structure at this scope. |
| Comma-separated list of user roles | Only users holding one of the listed roles (including project roles) may change the checklist structure. |
For a `userstory` type, `dod`/`dor` checklists, and an `accepted` status, the system evaluates `adminPermission` in this exact order:
```text theme={null}
1. nextedy.checklist.userstory.dod.accepted.adminPermission
2. nextedy.checklist.dod.accepted.adminPermission
3. nextedy.checklist.userstory.dod.adminPermission
4. nextedy.checklist.dod.adminPermission
5. nextedy.checklist.userstory.accepted.adminPermission
6. nextedy.checklist.accepted.adminPermission
7. nextedy.checklist.userstory.adminPermission
8. nextedy.checklist.adminPermission
```
**Worked configuration**
```text theme={null}
# 'dod' checklist can be controlled by global admin and project_developer roles
nextedy.checklist.dod.adminPermission=admin,project_developer
# but when 'userstory' is in status 'verified' the checklist definition cannot be changed at all
nextedy.checklist.dod.verified.adminPermission=@none
# 'dor' checklist cannot be adjusted at all for userstory, unless overridden below
nextedy.checklist.userstory.dor.adminPermission=@none
# 'dor' checklist can be changed by anyone only when the work item is in status 'draft'
nextedy.checklist.userstory.dor.draft.adminPermission=@all
```
**adminPermission controls structure, not check/uncheck actions**
`adminPermission` governs who can add, remove, or redefine checklist items. Whether a user can mark existing items as checked is a **separate** concern controlled by standard Polarion permissions — **Administration > Work Items > Readonly Fields** or **Administration > User Management > Permissions Management** on the underlying custom field. Configuring `adminPermission` alone does not lock down check/uncheck actions.
**Version-gated UI behavior**
Starting with **version 25.7.0**, regular users without admin permissions on a given `adminPermission` condition also lose access to the **Clear** action — it's no longer available under the checklist's Gear menu icon. Earlier versions may not hide this control the same way.
## Related non-hierarchical properties
The following properties are read via the same `_TYPEID_._FIELDID_` scoping mechanism, but are listed individually here rather than through a precedence worked example:
| Property | Type | Default | Description |
| ------------------------------------------------------------- | --------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `nextedy.checklist._TYPEID_._FIELDID_.workItemTemplateId` | `string` | See application | Configures the work item ID used as the checklist template for the given type/field scope. If unset, falls back to the work item type's own built-in Polarion template reference — see [Built-in Polarion Work Item Templates](/checklist/reference/configuration/template-properties#built-in-polarion-work-item-templates). |
| `nextedy.checklist._TYPEID_._FIELDID_._STATUS_.mergeTemplate` | `boolean` | `true` | Controls whether the checklist template is merged into the current checklist when the object is in the given status. Set to `false` to freeze the checklist at that status. |
| `nextedy.checklist._TYPEID_._FIELDID_.mergeTemplateResolved` | `boolean` | `false` | Companion property to `mergeTemplate`: when the object has a resolution set, `mergeTemplate` is forced to `false` unless `mergeTemplateResolved=true`. See [Template Configuration Properties](/checklist/reference/configuration/template-properties) for the full merge/freeze mechanism. |
**About the defaults in the table above**
`mergeTemplate` defaults to `true` and `mergeTemplateResolved` to `false`. `workItemTemplateId` has no static default value — it resolves dynamically through the fallback described above, which is why its Default column reads "See application".
## Global (non-hierarchical) properties
These properties are configured without `_TYPEID_`/`_FIELDID_` scoping — they apply plugin-wide:
| Property | Type | Default | Description |
| ------------------------------------------- | ------------------------------- | --------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `nextedy.checklist.debug` | `boolean` | `false` | Enables debug mode/logging for Checklist. Intended for admin/support troubleshooting. |
| `nextedy.checklist.conditional_enabled` | `boolean` | `false` | Master toggle controlling whether the `Conditional` result state is available to users. |
| `nextedy.checklist.searchAttempts` | `integer` | `30` | Number of attempts Checklist makes when searching for a related object (retry tuning for search operations). |
| `nextedy.checklist.checked_sign` | `string` | `far fa-check-square` | Icon class rendered for the `OK`/checked result state. |
| `nextedy.checklist.unchecked_sign` | `string` | `far fa-minus-square` | Icon class rendered for the unchecked result state. |
| `nextedy.checklist.no_sign` | `string` | `far fa-square` | Icon class rendered for the `Empty` (None) result state. |
| `nextedy.checklist.conditional_sign` | `string` | `far fa-plus-square` | Icon class rendered for the conditional result state; only meaningful when `conditional_enabled` is `true`. |
| `nextedy.checklist.baselines.itemType` | `string` | `btask` | Work item type that represents a baseline record for checklist history. |
| `nextedy.checklist.baselines.baselineField` | `string` | `baseline` | Custom field on the baseline item type that stores the baseline/revision identifier. |
| `nextedy.checklist.disable.hook` | `boolean` (JVM system property) | `false` | Globally disables the checklist save hook (summary refresh, reset-on-type-change). **Not** a Polarion configuration property — must be set as a JVM system property and requires a server restart. |
**disable.hook is not a Configuration Property**
Unlike every other property on this page, `nextedy.checklist.disable.hook` cannot be set via **Administration > Configuration Properties**. It is a JVM system property set at the application server level and requires a restart to take effect.
### Type-scoped property — `checklistsIdsForTypeChanges`
**Not actually global — takes a `_TYPEID_` segment**
`checklistsIdsForTypeChanges` is **type-scoped**, not plugin-wide: the key takes a `_TYPEID_` segment — `nextedy.checklist._TYPEID_.checklistsIdsForTypeChanges`, parallel to `checklistsIdsForSummary` (see [Summary Field Reference](/checklist/reference/summary-field)) — and not the bare `nextedy.checklist.checklistsIdsForTypeChanges`.
| Property | Type | Default | Description |
| -------------------------------------------------------- | ------------------------------- | -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `nextedy.checklist._TYPEID_.checklistsIdsForTypeChanges` | `string` (comma-separated list) | `""` (empty — no checklists monitored) | Comma-separated checklist field IDs monitored for work item type changes on the given type; a listed checklist that has content resets to the new type's template on type change. Available from Checklist version 25.1.0. |
## Per-field PDF visibility property
| Property | Type | Default | Description |
| ------------------------------------------------ | --------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `nextedy.checklist._TYPEID_._FIELDID_.hideInPdf` | `boolean` | `false` | Sets the default PDF-export visibility for a specific checklist custom field on a specific work item/document type. If `true`, the checklist is suppressed when the containing document or work item is exported to PDF. |
See [Icon, Feature-Toggle, and Baseline Properties](/checklist/reference/configuration/appearance-and-feature-properties) for related display properties, and [Permission, Freeze, and Read-Only Properties](/checklist/reference/configuration/permission-and-freeze-properties) for the full `adminPermission` and freeze/merge-template behavior.
## Document-level applicability
**Verify in application**
Whether freeze and role-based `adminPermission` settings apply to document-level checklists in the same way as to work item checklists is not documented, and no document-specific syntax beyond the general `_TYPEID_._FIELDID_` pattern is confirmed. Verify document-level behavior in your Polarion instance before relying on it being equivalent to the work item examples above.
## See also
* [Template Configuration Properties](/checklist/reference/configuration/template-properties)
* [Permission, Freeze, and Read-Only Properties](/checklist/reference/configuration/permission-and-freeze-properties)
* [Icon, Feature-Toggle, and Baseline Properties](/checklist/reference/configuration/appearance-and-feature-properties)
* [Reference](/checklist/reference/index)
# Template Configuration Properties
Source: https://learn.nextedy.com/checklist/reference/configuration/template-properties
Reference for configuration properties that control how checklist **templates** are resolved, applied, and enforced across work items, documents (LiveDocs), test runs, and plans.
Reference for configuration properties that control how checklist **templates** are resolved, applied, and enforced across work items, documents (LiveDocs), test runs, and plans.
All properties in this document are set in **Administration > Configuration Properties** using the `nextedy.checklist.*` dot-notation namespace.
**Property hierarchy**
Template properties follow the standard Checklist property hierarchy. See [Property Hierarchy and Precedence Reference](/checklist/reference/configuration/property-hierarchy-reference) for the full 4-level precedence model. This page documents template-specific keys and their exact resolution order where it differs from the general model.
## Work Item Template Properties
| Name | Type | Default | Description |
| --------------------------------------------------------- | ----------------------- | ------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `nextedy.checklist._TYPEID_._FIELDID_.workItemTemplateId` | `string` (work item ID) | See application (no static default — see fallback note below) | ID of the work item whose checklist content is used as the **template** for the checklist stored in `_FIELDID_` on work items of type `_TYPEID_`. `_TYPEID_` and `_FIELDID_` are both optional segments. |
| `nextedy.checklist._TYPEID_._FIELDID_.allMandatory` | `boolean` | `false` | When `true`, treats every checklist item in the resolved checklist as mandatory, regardless of the per-item mandatory flag. |
`_TYPEID_` is a work item type ID (for example `userstory`, `requirement`). `_FIELDID_` is the custom field ID holding the checklist (for example `dod`, `chkApproved`). Both segments are optional and can be omitted independently, which is what produces the 4-level precedence.
**workItemTemplateId falls back to Polarion's built-in item template**
If `workItemTemplateId` is not configured for a given type/field, template resolution falls back to the work item type's own built-in Polarion template reference — the same mechanism described in [Built-in Polarion Work Item Templates](#built-in-polarion-work-item-templates) below. The two mechanisms aren't fully independent alternatives: the config property takes precedence when set, and the built-in template is the fallback when it isn't.
### Precedence example — `allMandatory`
```text theme={null}
nextedy.checklist.userstory.dod.allMandatory=true # applies just for "dod" on story level
nextedy.checklist.dod.allMandatory=true # applies just for "dod" checklist for any work item type
nextedy.checklist.userstory.allMandatory=true # applies to any checklist for the 'userstory' work item type
nextedy.checklist.allMandatory=true # applies to any checklist
```
The system searches for the property in the order shown above — most specific (type + field) first, least specific (global) last.
### Work item template ID example
```text theme={null}
# requirement is the work item type, chkApproved is the checklist custom field ID
nextedy.checklist.requirement.chkApproved.workItemTemplateId=WI-124
# work item type omitted — applies to any type using a "chkDone" checklist field
nextedy.checklist.chkDone.workItemTemplateId=WI-125
```
**Templates are live**
All changes made to a checklist template work item are instantly promoted to every work item, document, test run, or plan that resolves its checklist through that template.
## Document (LiveDoc) Template Properties
| Name | Type | Default | Description |
| --------------------------------------------------------- | ------------------------ | ------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `nextedy.checklist._TYPEID_._FIELDID_.documentTemplateId` | `string` (document path) | See application (no static default — same built-in-template fallback as `workItemTemplateId`, see note below) | Path to the LiveDoc used as the checklist template for a document-scope checklist. `_TYPEID_` here refers to the document (LiveDoc) type ID; `_FIELDID_` is the checklist field/ID on the document. |
```text theme={null}
# documentSpecification is the LiveDoc type, documentReadyChecklist is the checklist ID
nextedy.checklist.documentSpecification.documentReadyChecklist.documentTemplateId=Specification/Product Spec Template
```
Document-level checklist templates are resolved by the checklist form extension when rendering the checklist for a document. A document that is itself designated as the template automatically receives administrative permission over its own checklist structure.
**documentTemplateId falls back to Polarion's built-in document template**
If `documentTemplateId` is not configured for a given type/field, resolution falls back to the document type's own built-in Polarion template reference, mirroring the `workItemTemplateId` fallback described above.
## Cross-Project (Global) Templates
| Name | Type | Default | Description |
| ------------------------------------------------------------------------------ | ----------------------------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `nextedy.checklist._TYPEID_._FIELDID_.workItemTemplateId` (cross-project form) | `string` (`PROJECTID:WORKITEMID`) | See application | Same property as above, but the value is prefixed with a project ID to reference a template work item stored in a **different** Polarion project. |
| `nextedy.checklist._FIELDID_.documentTemplateId` (cross-project form) | `string` (`PROJECTID:Space/DocumentName`) | See application | Same property as the document template property above, but referencing a document template stored in a different project. |
```text theme={null}
# Work item template stored in "myOtherProject"
nextedy.checklist.requirement.chkApproved.workItemTemplateId=myOtherProject:WI-124
# Document template stored in "myOtherProject"
nextedy.checklist.checklist.documentTemplateId=myOtherProject:Specification/SpecificationTemplate
```
**Format**
The cross-project reference format is `PROJECTID:WORKITEMID` for work item templates, or `PROJECTID:Space/DocumentName` for document templates. Omitting the `PROJECTID:` prefix resolves the template within the current project.
## Built-in Polarion Work Item Templates
Checklist also supports Polarion's own built-in work item template mechanism. As noted above, this is the **fallback** template source used when `workItemTemplateId` is not configured for the given type/field — not merely an unrelated alternative:
1. Create a new work item (for example, titled "TEMPLATE").
2. Mark it resolved so it disappears from default views.
3. Reference this item from the work item type enumeration as the type's built-in template.
**Known limitation — duplicated checklist items with Polarion item templates**
When using Polarion's built-in work item template mechanism (rather than `workItemTemplateId`), a bug in current versions of Polarion — not in Checklist — changes the checklist field's format from Text to Richtext when data is copied from the template to the new item. This can result in duplicated checklist items.
**Workaround:**
1. Open the workflow configuration for the affected work item type.
2. Select the **init** action.
3. Add the workflow function `ChecklistResetToTemplate` (see [Workflow Functions and Conditions](/checklist/reference/workflow)).
4. Add a `checklist` parameter with the value set to the name of the checklist custom field.
This resets the checklist immediately after item creation, which also corrects the field type. Nextedy has raised this issue with Siemens; the workaround will not be necessary once it is fixed upstream.
## Template Merge Behavior
| Behavior | Description |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Merge on parse | When a checklist field is parsed, items from the linked template are merged with the existing stored items. |
| Result carried over on merge | If an item with the same ID already exists in the stored checklist, only its **result** is carried over/preserved — other fields (label, mandatory, description) are refreshed from the template. |
| Reset destroys local progress | Applying `ChecklistResetToTemplate` (or the underlying reset operation) discards existing checklist progress and reloads the template content in full. |
**Reset is destructive**
Resetting a checklist to its template overwrites current checklist progress, including all local additions and previously recorded result states. This action cannot be undone from within the checklist form extension.
## Object-Type Template Resolution Summary
**Verify in application**
Test runs and plans resolve their checklist template through the same template reference mechanism, but the admin-facing configuration property names that apply to test runs and plans specifically are not documented here. Confirm the exact property names in your Polarion instance before relying on type-specific behavior beyond what is shown above.
## Related Configuration
* [Property Hierarchy and Precedence Reference](/checklist/reference/configuration/property-hierarchy-reference) — general 4-level precedence model shared across all Checklist configuration properties.
* [Permission, Freeze, and Read-Only Properties](/checklist/reference/configuration/permission-and-freeze-properties) — controlling who can edit a checklist's structure once a template is applied.
* [Icon, Feature-Toggle, and Baseline Properties](/checklist/reference/configuration/appearance-and-feature-properties) — appearance and baseline-related properties.
* [Workflow Functions and Conditions](/checklist/reference/workflow) — `ChecklistApplyTemplate` and `ChecklistResetToTemplate` workflow functions that act on templates during workflow transitions.
# Reference
Source: https://learn.nextedy.com/checklist/reference/index
Technical lookup material for Nextedy CHECKLIST — configuration properties, the workflow function and condition catalog, and the underlying data model.
## Configuration
* [**Property Hierarchy and Precedence Reference**](/checklist/reference/configuration/property-hierarchy-reference) — How the 4-level configuration property precedence (global → type-specific → field-specific → type+field-specific) is resolved.
* [**Template Configuration Properties**](/checklist/reference/configuration/template-properties) — Properties that control template assignment and resolution per checklist, type, and field.
* [**Permission, Freeze, and Read-Only Properties**](/checklist/reference/configuration/permission-and-freeze-properties) — Properties governing who can edit checklist structure or results, and when a checklist freezes.
* [**Icon, Feature-Toggle, and Baseline Properties**](/checklist/reference/configuration/appearance-and-feature-properties) — Icon overrides, feature toggles like the conditional result state, and baseline-related properties.
## Workflow and API
* [**Workflow Functions and Conditions**](/checklist/reference/workflow) — The workflow functions and conditions used to enforce checklist gates on workflow transitions.
* [**IChecklistService and Velocity Rendering API**](/checklist/reference/api-service) — The service API for parsing, storing, and rendering checklists across work items, documents, test runs, and plans.
* [**Checklist, ChecklistItem, and CheckItemResult**](/checklist/reference/api-model) — The data model behind a checklist instance: items, result states, and counting/merge behavior.
* [**Summary Field Reference**](/checklist/reference/summary-field) — How the `_summary` companion field is computed and kept in sync on save.
**Looking for task-based instructions instead?**
Reference pages document exact names and behavior. If you want step-by-step setup instructions, see [Guides](/checklist/guides/index) instead.
## See also
* [Guides](/checklist/guides/index)
* [Concepts](/checklist/concepts/index)
* [FAQ](/checklist/faq/index)
# Summary Field Reference
Source: https://learn.nextedy.com/checklist/reference/summary-field
Documentation for the summary field, a custom field that holds a rendered snapshot of checklist completion, computed automatically on every save.
Documentation for the summary field, a custom field that holds a rendered snapshot of checklist completion, computed automatically on every save.
## Purpose
A summary field is a separate custom field that holds the completion state of a checklist (for example, a count of checked vs. total mandatory items), so that checklist status can be shown or queried without opening the checklist itself.
## Setup
Setting up a summary field is optional and requires three steps.
### Step 1 — Create the summary custom field
| Name | Type | Default | Description |
| ----------------- | ------------------------------------------ | ------- | ------------------------------------------------------------------------------------- |
| Custom field ID | Naming convention: `_summary` | n/a | If the checklist custom field is `dod`, the summary field's ID must be `dod_summary`. |
| Custom field type | `String (single line plain text)` | n/a | Must be a single-line string field, not multi-line text. |
### Step 2 — Make the field read-only
The summary field must be made read-only using the read-only fields configuration page, not via permissions.
**Use the read-only fields configuration, not permissions**
These two mechanisms are distinct, and only one of them is supported here. The summary field's value is computed by the save hook and must not be user-editable, and the supported way to enforce that is the dedicated read-only fields configuration page.
### Step 3 — Enable summary calculation via configuration property
| Name | Type | Default | Description |
| ---------------------------------------------------- | ----------------------------------------------- | -------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `nextedy.checklist._TYPEID_.checklistsIdsForSummary` | Configuration property (comma-separated string) | `""` (empty — no checklists summarized until configured) | Mandatory to enable summary computation. Lists which checklist field IDs should be summarized for this work item type. Set via **Project Administration > Config Properties**. |
Example, for the `userstory` work item type summarizing the `dor` checklist:
```properties theme={null}
nextedy.checklist.userstory.checklistsIdsForSummary=dor
```
**One entry per checklist field ID**
List each distinct checklist field ID you want summarized, separated by commas (for example `dor,dod` to summarize two checklists on the same type). The property does not deduplicate values, so listing the same ID twice (`dor,dor`) has no effect beyond redundancy.
## How the summary is computed
Summary computation happens automatically on every save of the work item, via a save hook that intercepts persistence.
| Name | Type | Default | Description |
| ------------------------------- | ------------------ | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Summary field suffix convention | Naming convention | `_summary` | Every checklist field with summary calculation enabled gets its computed value written to a same-named field with a `_summary` suffix. |
| Computation trigger | Automatic, on save | n/a | The summary value is recomputed and stored every time the work item is saved. No manual recalculation step is needed. |
| Error handling | See application | n/a | If summary computation (or the type-change reset check below) throws, the error is logged but the save still completes — a failure inside the save hook's own processing does not block the underlying save. |
**Automatic reset on type change — only for checklists listed in checklistsIdsForTypeChanges**
When a work item's type changes and the previously saved revision had a different type, the save hook resets (clears) any checklist field that both (a) currently holds data and (b) is listed in `nextedy.checklist._TYPEID_.checklistsIdsForTypeChanges` for the work item's type (see [Property Hierarchy and Precedence Reference](/checklist/reference/configuration/property-hierarchy-reference#type-scoped-property-checklistsidsfortypechanges)) — not every checklist field on the work item unconditionally. This prevents checklist state from a prior type from lingering after a type change.
## Advanced — disabling summary and save-hook processing
| Name | Type | Default | Description |
| -------------------------------- | ----------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `nextedy.checklist.disable.hook` | JVM system property (Boolean) | `false` | When set to `true`, disables all checklist save-hook processing, including summary field computation and reset-on-type-change, globally. Must be set as a JVM system property, not a Polarion project configuration property, and requires a server restart to take effect. |
**Server-wide, not per-project**
This property is not scoped to a project or work item type. It is a JVM-level switch affecting checklist save-hook behavior across the entire server. Use only for troubleshooting or advanced administrative scenarios.
## Reporting and export limitations
Surfacing checklist completion outside the individual work item — in LiveReport tables, dashboards, or exports — has no confirmed built-in mechanism beyond the summary field itself.
**What reporting can and cannot show**
* To get checklist item counts and status into a report or table without opening each work item individually, use the summary field. Once configured per the steps above, it is a normal custom field and can be added as a column or field like any other work item field.
* There is no known native LiveReport table-field integration for per-item checked state. To visualize progress (for example `1/7 completed`) in a LiveReport page, or to query an individual item's checked state, script against `IChecklistService.parse()` in a Velocity block on the LiveReport or wiki page. See [IChecklistService and Velocity Rendering API](/checklist/reference/api-service).
* The summary counter shown at the top of the checklist form extension itself, as opposed to the `_summary` custom field, does not appear to be surfaceable via reporting, columns, or export. Verify this in your Polarion instance before relying on it.
## Summary field vs. Velocity scripting
| Approach | Best for | Limitation |
| -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| Summary field (`_summary` custom field) | Showing checklist completion as a normal field or column value, usable in tables and standard reports without scripting | Only reflects whatever text the save hook renders into the field, not a live, per-item breakdown |
| Velocity scripting via `$checklistService.parse()` | Per-item checked-state, custom progress formatting (for example `X/Y completed`), or logic beyond a static summary string | Requires a LiveReport or wiki page with a Velocity script block, not a plain table column |
## See also
* [Checklist, ChecklistItem, and CheckItemResult](/checklist/reference/api-model) — the `getSummaryText()` method and `summaryMessageFormat` tokens underlying summary rendering.
* [IChecklistService and Velocity Rendering API](/checklist/reference/api-service) — scripting access for per-item progress not covered by the summary field.
* [Template Configuration Properties](/checklist/reference/configuration/template-properties) — related configuration property hierarchy.
# Workflow Functions and Conditions
Source: https://learn.nextedy.com/checklist/reference/workflow
Reference for the workflow functions and workflow conditions that gate Polarion workflow transitions on checklist state — the mechanism behind Definition of Done (DoD) and Definition of Ready (DoR) enforcement.
Reference for the workflow functions and workflow conditions that gate Polarion workflow transitions on checklist state — the mechanism behind Definition of Done (DoD) and Definition of Ready (DoR) enforcement.
All functions and conditions accept a `checklist` argument identifying which checklist custom field(s) to operate on. Multiple checklists can be validated in a single call by supplying a comma-separated list of custom field IDs.
**Functions vs. conditions**
**Workflow functions** are actions: they execute during a transition and can throw a blocking error, apply a template, or mutate checklist state. **Workflow conditions** are guards: they evaluate to true/false to enable or disable a transition, and can supply a human-readable failure message explaining why a transition is unavailable.
## Workflow Functions
Workflow functions are attached to a transition's action list in `workflow.xml`. They execute when the transition runs.
### ChecklistFailIfMandatoryUnchecked
| Field | Value |
| ------------------- | ----------------------------------------------------- |
| Type | Workflow function (`IFunction`) |
| Supported targets | Work item, document (module/LiveDoc), test run |
| Behavior on failure | Throws a user-friendly error, blocking the transition |
**Parameters**
| Name | Type | Required | Default | Description |
| ----------- | ------------------------------------------- | -------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `checklist` | `string` (comma-separated custom field IDs) | Yes | See application | Custom field ID(s) of the checklist(s) to validate. Missing this argument throws `checklist attribute missing for wf function: ChecklistFailIfMandatoryUnchecked`. |
Fails the transition if any mandatory item in any specified checklist is not checked. If the checklist's `allMandatory` configuration is enabled (see [Template Configuration Properties](/checklist/reference/configuration/template-properties)), the transition is also blocked unless **every** item is checked, not only mandatory-flagged ones. On failure, the error message names the specific checklist field (its custom field display name) so users can identify which checklist blocked the transition.
```xml theme={null}
dod
```
### ChecklistFailIfAnyUnchecked
| Field | Value |
| ------------------- | ----------------------------------------------------- |
| Type | Workflow function (`IFunction`) |
| Supported targets | Work item, document (module/LiveDoc), test run |
| Behavior on failure | Throws a user-friendly error, blocking the transition |
**Parameters**
| Name | Type | Required | Default | Description |
| ----------- | ------------------------------------------- | -------- | --------------- | --------------------------------------------------- |
| `checklist` | `string` (comma-separated custom field IDs) | Yes | See application | Custom field ID(s) of the checklist(s) to validate. |
Throws an error if the specified checklist has **any** item not checked (stricter than `ChecklistFailIfMandatoryUnchecked`, which only requires mandatory items).
```xml theme={null}
dor
```
### ChecklistUncheckAll
| Field | Value |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Type | Workflow function (`IFunction`) |
| Supported targets | Work item, document (module/LiveDoc), test run — confirmed from `context.getTarget()` plus an `instanceof IWorkItem`/`IModule`/`ITestRun` branch below, the same pattern used by the other functions/conditions on this page (no `IPlan` branch) |
| Behavior | Clears the checked/result state of every item in the specified checklist(s) |
**Parameters**
| Name | Type | Required | Default | Description |
| ----------- | ------------------------------------------- | -------- | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `checklist` | `string` (comma-separated custom field IDs) | Yes | See application | Custom field ID(s) of the checklist(s) to uncheck. Missing this argument throws `checklist attribute missing for wf function: ChecklistUncheckAll`. |
Unchecks all checklist items, clearing their result state so the checklist reads as not checked, without removing the item definitions themselves.
```xml theme={null}
dod,dor
```
Underlying implementation (for reference — resolves and stores the checklist via the checklist service, once per supported target type):
```java theme={null}
public void execute(ICallContext context, IArguments arguments) {
String chlField = arguments.getAsString("checklist");
if (chlField == null) {
throw new RuntimeException("checklist attribute missing for wf function: ChecklistUncheckAll ");
}
IWorkflowObject workflowObject = context.getTarget();
if (workflowObject instanceof IWorkItem) {
IWorkItem wi = (IWorkItem) workflowObject;
String[] fields = chlField.split(",");
for (int i = 0; i < fields.length; i++) {
Checklist chl = checklistService.parse(wi, fields[i]);
chl.uncheckAll();
checklistService.store(chl, wi, fields[i]);
}
}
if (workflowObject instanceof IModule) {
IModule module = (IModule) workflowObject;
String[] fields = chlField.split(",");
for (int i = 0; i < fields.length; i++) {
Checklist chl = checklistService.parse(module, fields[i]);
chl.uncheckAll();
checklistService.store(chl, module, fields[i]);
}
}
if (workflowObject instanceof ITestRun) {
ITestRun testRun = (ITestRun) workflowObject;
String[] fields = chlField.split(",");
for (int i = 0; i < fields.length; i++) {
Checklist chl = checklistService.parse(testRun, fields[i]);
chl.uncheckAll();
checklistService.store(chl, testRun, fields[i]);
}
}
}
```
### ChecklistResetToTemplate
| Field | Value |
| ----------------- | ---------------------------------------------------------------------------- |
| Type | Workflow function (`IFunction`) |
| Supported targets | Work item, document (module/LiveDoc), test run |
| Behavior | Destructive — replaces current checklist content with the template's content |
**Parameters**
| Name | Type | Required | Default | Description |
| -------------- | ------------------------------------------- | -------- | ------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `checklist` | `string` (comma-separated custom field IDs) | Yes | See application | Custom field ID(s) of the checklist(s) to reset. |
| `skipForUsers` | `string` (comma-separated user IDs) | No | *(unset — reset applies to everyone)* | User IDs for whom the reset is **skipped**: if the user triggering the transition is in this list, the function returns without resetting. Entries are trimmed and empty entries ignored; a malformed value fails open (the reset proceeds). Available from Checklist version 25.10.0. |
Resets the checklist to the state defined by its template, removing all local additions and discarding any recorded progress.
```xml theme={null}
dod
```
**Init-action workaround for built-in Polarion templates**
Adding `ChecklistResetToTemplate` to a work item type's **init** action, with the `checklist` parameter set to the checklist field name, is the documented workaround for a Polarion platform bug that corrupts checklist field formatting when Polarion's own built-in item templates are used. See [Template Configuration Properties](/checklist/reference/configuration/template-properties) for the full workaround procedure.
### ChecklistApplyTemplate
| Field | Value |
| ----------------- | ------------------------------------------------------------- |
| Type | Workflow function (`IFunction`) |
| Supported targets | Work item, document (module/LiveDoc), test run |
| Lifecycle | Executes as an action during a transition, not as a condition |
**Parameters**
| Name | Type | Required | Default | Description |
| ----------- | ------------------------------------------- | -------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `checklist` | `string` (comma-separated custom field IDs) | Yes | See application | Custom field ID(s) that should have their checklist template (re)applied. A missing value throws a configuration error when the action runs. |
Applies the configured checklist template to the specified checklist field(s) on the target object by re-parsing the field (which merges the template into whatever content is already stored) and immediately saving the result.
```xml theme={null}
dod
```
**Merge semantics confirmed — not destructive**
Confirmed directly from `IChecklistService.applyTempate`'s implementation (`store(parse(target, field), target, field)`): calling `ChecklistApplyTemplate` on a field that already has data does **not** discard existing progress. It performs the same merge-on-parse behavior as a normal read (see [Template Merge Behavior](/checklist/reference/configuration/template-properties)) — items matched by id keep their recorded result, while label/mandatory/description are refreshed from the template — then persists that merged result. This is distinct from `ChecklistResetToTemplate` above, which discards all existing content unconditionally.
## Workflow Conditions
Workflow conditions are attached to a transition's condition list. They evaluate to true/false and can gate whether the transition is even offered to the user.
### ChecklistAllChecked
| Field | Value |
| ----------------- | ------------------------------------------------------------------ |
| Type | Workflow condition |
| Supported targets | Work item, document (module/LiveDoc), test run |
| Behavior | Enables the transition only if the checklist has all items checked |
**Parameters**
| Name | Type | Required | Default | Description |
| ----------- | ------------------------------------------- | -------- | --------------- | --------------------------------------------------- |
| `checklist` | `string` (comma-separated custom field IDs) | Yes | See application | Custom field ID(s) of the checklist(s) to evaluate. |
```xml theme={null}
dor
```
### ChecklistMandatoryChecked
| Field | Value |
| ----------------- | ------------------------------------------------------------------------------- |
| Type | Workflow condition |
| Supported targets | Work item, document (module/LiveDoc), test run |
| Behavior | Enables the transition only if all mandatory items in the checklist are checked |
**Parameters**
| Name | Type | Required | Default | Description |
| ----------- | ------------------------------------------- | -------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `checklist` | `string` (comma-separated custom field IDs) | Yes | See application | Custom field ID(s) of the checklist(s) to evaluate. Missing this argument throws `checklist attribute missing for wf condition: ChecklistMandatoryChecked`. |
If the checklist's `allMandatory` configuration is enabled, this condition requires **all** items to be checked, not only mandatory-flagged ones — matching the corresponding behavior of `ChecklistFailIfMandatoryUnchecked`.
```xml theme={null}
dod
```
**User-visible failure messages**
`ChecklistMandatoryChecked` (and conditions like it) can supply a human-readable message naming the incomplete checklist, which Polarion surfaces as a tooltip/explanation on a disabled transition button.
## Practical Example — DoD Gate on Transition to "Done"
```xml theme={null}
dod
dod
```
Combining a condition and a function for the same checklist is a common pattern: the condition hides/disables the transition in the UI until the gate is satisfied, while the function provides a hard server-side guarantee in case the transition is triggered through another path (for example, the REST API).
## Comma-Separated Multi-Checklist Syntax
All functions and conditions on this page accept more than one checklist field by comma-separating custom field IDs in the `checklist` argument:
```text theme={null}
nextedy.checklist multi-field argument example:
checklist=dod,dor,reviewChecklist
```
Each listed checklist field is evaluated independently; for functions, all specified checklists must satisfy the required condition (for example, all-mandatory-checked) for the function to succeed without error.
## Accessing Checklist State Programmatically
Workflow functions and conditions are built on the same checklist service accessible from custom Java code:
```java theme={null}
PlatformContext.getPlatform().lookupService(IChecklistService.class);
```
This is the same access pattern used internally by `ChecklistUncheckAll` and the other built-in functions on this page, and is the documented path for writing **custom** workflow functions or conditions — for example, to check that all checklist questions are answered as either ok or not-ok, since no predefined function currently covers that specific gate. See [IChecklistService and Velocity Rendering API](/checklist/reference/api-service) for the full service reference and additional code examples (parsing a checklist field, reading `ChecklistItem.checked`/`label`, and calling `reset()` from a custom function).
**Known limitation — no built-in 'all answered ok or not-ok' condition**
There is no predefined workflow function or condition that verifies every checklist item has been answered as either ok or not-ok (as distinct from "checked at all"). Achieving this currently requires a custom scripted function or condition written against `IChecklistService`.
## Related Configuration
* [Template Configuration Properties](/checklist/reference/configuration/template-properties) — `workItemTemplateId`, `documentTemplateId`, and `allMandatory`, which interact with `ChecklistApplyTemplate` and `ChecklistResetToTemplate`.
* [Permission, Freeze, and Read-Only Properties](/checklist/reference/configuration/permission-and-freeze-properties) — `adminPermission` properties controlling who can edit checklist structure, distinct from workflow gating.
* [IChecklistService and Velocity Rendering API](/checklist/reference/api-service) — the underlying service API used both internally by these functions and for custom scripting.
* [Checklist, ChecklistItem, and CheckItemResult](/checklist/reference/api-model) — the data model these functions operate on.
* [Summary Field Reference](/checklist/reference/summary-field) — how checklist completion is aggregated for reporting outside of workflow gates.
# Architecture and Data Flow
Source: https://learn.nextedy.com/gantt/concepts/architecture
Nextedy GANTT is an app for Siemens Polarion ALM that embeds an interactive Gantt chart directly into Polarion LiveDoc and Wiki pages.
## Two-Tier Architecture
The Gantt chart operates as a client-server system within Polarion. The **server tier** is a Java plugin that runs inside the Polarion application server. It handles data retrieval, field mapping, calendar resolution, and persistence. The **client tier** is a JavaScript application that renders the interactive chart in the browser, manages user interactions (drag, resize, lightbox editing), and communicates changes back to the server.
Think of it like a spreadsheet application: the server is the database that stores and validates data, while the client is the visual interface where you interact with it.
## Data Loading Sequence
When a Polarion page containing a Gantt chart loads, the following sequence occurs:
1. **Initialization** -- The server reads chart parameters (data source, field mappings, calendar settings) and resolves the configuration into a typed configuration object
2. **Data retrieval** -- The server queries Polarion for work items matching the configured dataset, resolves parent-child relationships using the configured `parentRoles`, and builds dependency links from `dependsRoles`
3. **Task conversion** -- Each work item is converted into a task object with properties like `start_date`, `end_date`, `duration`, `progress`, `parent`, and `type`. Custom fields listed in the field filter are included as additional fields
4. **Calendar resolution** -- If working calendars are enabled (`wCal_GLOBAL`), the server computes working hours per day for each resource, including user calendars and team assignments
5. **JSON serialization** -- The complete dataset (tasks, links, resource collections, and load statistics) is serialized to JSON and sent to the client
6. **Client rendering** -- The JavaScript application parses the JSON, applies the configuration, and renders the Gantt chart with its grid, timeline, and optional resource view
## The Data Payload
The server returns a structured JSON payload containing four key sections:
| Section | Content | Purpose |
| --------------- | ------------------------------------- | ---------------------------------------------------------------- |
| `data` | Array of task objects | Work items or plan items to display as task bars |
| `links` | Array of link objects | Dependency relationships (FS, SS, FF, SF) between tasks |
| `collections` | Map with `resources` and `loadInfo` | Resource definitions and capacity metadata for the resource view |
| Load statistics | Item counts, errors, server load time | Footer status bar showing what was loaded and any issues |
The load statistics track how many items were loaded, skipped (due to limits), filtered, hidden, or unresolvable. When tasks reference work items that cannot be accessed (due to permissions or deletion), they appear as unresolvable items in the error count.
## Configuration Flow
Configuration reaches the Gantt through two channels, each with a different scope:
* **Per-instance parameters** are set on each Gantt chart through the Polarion page editor. They control data source, field mappings, visual options, and feature toggles for that specific chart. Examples: `Start Field`, `End Field`, `Parent Role`, `Show Resource View`.
* **Administration properties** are set globally via Polarion Configuration Properties (`nextedy.gantt.*`). They control system-wide behavior like auto-scheduling defaults, calendar project references, and license caching. Examples: `nextedy.gantt.default.auto_scheduling`, `nextedy.gantt.workitemCalendar.projectId`.
For more on how these two layers interact, see [Configuration Layers and Precedence](/gantt/concepts/configuration-hierarchy).
**Per-instance parameters take precedence**
When the same setting is available at both levels (such as the today's date override), the per-instance parameter value takes precedence over the administration property.
## Persistence Model
Gantt uses an optimistic persistence model. When you drag a task bar, resize it, or edit fields in the lightbox, the changes are staged locally in the browser. A modified indicator appears on affected tasks. Changes are only written back to Polarion when you click **Save** in the toolbar.
The save operation sends each modified task to the server, which updates the corresponding Polarion work item fields: `startField`, `endField`, `durationField`, `progressField`, `resourceField`, and any custom fields from the field filter. Dependency link changes (add or remove) update Polarion work item link roles.
**Concurrent editing**
The Gantt uses a last-save-wins model. If two users edit the same work item simultaneously, the last save overwrites the previous one. There is no built-in conflict detection for concurrent edits.
## Scripting Extension Points
Gantt provides server-side scripting hooks for customization:
* **Item Script** -- A server-side JavaScript snippet that executes for each work item during data loading. The script receives the source work item object and the task object being built, allowing you to read additional fields and pass custom data to the client. This is commonly used for custom color logic, computed labels, or baseline date injection.
* **Page Script** -- A server-side **Apache Velocity** template that executes once during page rendering, with access to the Gantt configuration and the Polarion page context (projects, users, plans, work items). Its rendered output is embedded into the widget as JavaScript. Used for dynamic configuration adjustments.
The Item Script runs in a server-side JavaScript environment and the Page Script as a server-side Velocity template -- both prepare data before it reaches the client, not in the browser. A client-side **Gantt Config Script** and a server-side **Markers Script** are also available (see the scripting reference).
### Scripting Is Privileged
Gantt is implemented as a Polarion **restricted widget**: adding or reconfiguring a chart -- including its scripts -- requires elevated permissions. Regular users work with preconfigured charts but cannot change configuration or inject scripts.
Scripts are restricted to trusted roles and are **not sandboxed** beyond that role restriction. They run on the server with access to the Polarion Open and Rendering APIs, so treat a Gantt configuration as administrative code rather than a user preference:
* A Page Script's rendered output is embedded into the widget **as JavaScript**, so any work item data it interpolates has to be escaped for that context. Prefer Polarion's Rendering API, which applies built-in HTML sanitization, over raw Open API access for values you render.
* The limits that govern how many items a chart loads and renders have deliberately conservative defaults. Raising them can affect Polarion's performance noticeably, so evaluate the change outside production first.
For the cross-product picture -- the shared responsibility model between Polarion and Nextedy products, secure development practices, and the administrator checklist -- see [Product Security](/overview/security-and-privacy/product-security).
## Related Topics
* [Product Overview](/gantt/concepts/overview) -- High-level introduction to Gantt capabilities and use cases
* [Data Mapping and Field Resolution](/gantt/concepts/data-mapping) -- How work item fields connect to Gantt scheduling properties
* [Working Calendars and Scheduling](/gantt/concepts/working-calendars) -- How calendar data is resolved and sent to the client
* [Item Color Logic -- Static, Dynamic, and Progress Colors](/gantt/concepts/item-color-logic) -- How Item Script customizes task appearance
# Auto-Scheduling and Dependency Propagation
Source: https://learn.nextedy.com/gantt/concepts/auto-scheduling
Nextedy GANTT supports automatic scheduling, a constraint-based mode where task dates are recalculated based on dependency links whenever a predecessor changes.
## The Core Idea
Imagine a project with three tasks connected in sequence: Design, Build, and Test. If Design slips by two days, Build must also start two days later, which pushes Test by the same amount. Without auto-scheduling, you would need to manually adjust each task. With auto-scheduling enabled, moving Design automatically shifts Build and Test to maintain the dependency constraints.
Auto-scheduling updates the start date of a successor task according to the end date of its predecessor each time a change occurs. This allows you to maintain the project schedule by specifying relationships between tasks with no need to set dates manually.
When Design is moved to Jan 3 - Jan 7, auto-scheduling adjusts:
* Build shifts to Jan 8 - Jan 14
* Test shifts to Jan 15 - Jan 19
## How It Works
Auto-scheduling is triggered only when you change a task or modify a dependency link. It does not continuously run in the background. When you drag a task bar, resize it, or edit dates in the lightbox, the Gantt evaluates all downstream dependencies and adjusts successor dates to satisfy the constraints.
The propagation follows dependency link types:
| Dependency type | Constraint |
| --------------------- | -------------------------------------------- |
| Finish-to-Start (FS) | Successor starts after predecessor finishes |
| Start-to-Start (SS) | Successor starts when predecessor starts |
| Finish-to-Finish (FF) | Successor finishes when predecessor finishes |
| Start-to-Finish (SF) | Successor finishes when predecessor starts |
The most common type is Finish-to-Start (FS), where the successor cannot begin until the predecessor is complete.
**Dependency link conflict highlighting**
When auto-scheduling is disabled and a successor's start date is planned before the predecessor finishes, the Gantt highlights the conflict visually. This helps you spot scheduling violations even in manual scheduling mode.
## Enabling and Controlling Auto-Scheduling
Auto-scheduling is controlled at the server level via the administration property `nextedy.gantt.default.auto_scheduling`. When set to `true`, the Gantt opens with auto-scheduling enabled by default.
Users can toggle auto-scheduling on and off at runtime using the toolbar toggle button. This allows switching between automatic constraint enforcement and manual date editing within the same session.
### Per-Task Overrides
In complex projects, you may want auto-scheduling for most tasks but need certain tasks (such as milestones or fixed-date deliverables) to remain pinned. The Gantt supports per-task override flags:
* **`enforceAutoMode`** -- Forces auto-scheduling for a specific task, even if the global setting is off
* **`blockAutoMode`** -- Prevents auto-scheduling from moving a specific task, even if the global setting is on
These flags enable mixed scheduling strategies where top-level milestones remain fixed while lower-level tasks are automatically adjusted.
**Hierarchical scheduling complexity**
When combining auto-scheduling with parent-child hierarchies, the behavior can become complex. Moving a parent task propagates to children, which in turn may trigger dependency propagation on their successors. If you need to prevent auto-scheduling on top-level work items while allowing it on lower levels, consider using a combination of readonly mode for top-level items and per-task `blockAutoMode` flags.
## Interaction with Drag Children
The `dragChildren` configuration controls whether child tasks move together with their parent when the parent is dragged. When both `dragChildren` and auto-scheduling are enabled:
1. Dragging the parent moves all children by the same offset
2. Auto-scheduling then recalculates any successors of those children
This two-step behavior means that moving a parent task can cascade changes throughout the project schedule.
## Interaction with Working Calendars
When [working calendars](/gantt/concepts/working-calendars) are enabled, auto-scheduling respects non-working days. If a predecessor finishes on Friday and the successor has a Finish-to-Start dependency, the successor will start on Monday (skipping the weekend) rather than Saturday. This applies to all calendar exceptions including holidays and per-user off days.
## What Auto-Scheduling Does Not Do
Auto-scheduling operates on the client side during the current editing session. It does not:
* Run automatically when Polarion data changes outside the Gantt (e.g., another user modifies dates via the Polarion work item form)
* Detect concurrent editing conflicts -- the last save wins
* Automatically resolve resource overallocation
Auto-scheduling recalculates dates based on dependency constraints only. For resource capacity analysis, see [Resource Load Calculation Modes](/gantt/concepts/resource-load-modes).
## Related Topics
* [Critical Path Analysis](/gantt/concepts/critical-path) -- Identifying which tasks determine the project end date
* [Date Range Conflict Detection and Resolution](/gantt/concepts/date-conflict-detection) -- Parent-child date containment enforcement
* [Working Calendars and Scheduling](/gantt/concepts/working-calendars) -- How calendars affect scheduling calculations
# Baselines and Schedule Comparison
Source: https://learn.nextedy.com/gantt/concepts/baselines
Nextedy GANTT supports baseline comparison -- the ability to overlay a historical version of your schedule on top of the current one, revealing how task dates have shifted over time.
## What Is a Baseline?
A baseline is a snapshot of task dates at a specific point in time. When you compare the current schedule against a baseline, each task shows two bars: the current (actual) bar representing today's plan, and a secondary baseline bar showing where the task was scheduled at the comparison point.
If the current bar extends to the right of the baseline bar, the task has slipped. If the current bar is shorter or shifted earlier, the task is ahead of the original plan. This visual comparison makes schedule drift immediately obvious without needing to compare spreadsheets or read through change logs.
## Three Comparison Modes
The Gantt provides three ways to select a historical comparison point, each suited to different scenarios:
| Mode | Source | Best for |
| ------------------ | ------------------------------------------- | ------------------------------------------------ |
| **Date** | A specific calendar date (e.g., 2025-01-15) | Comparing against a known milestone date |
| **Named baseline** | A Polarion baseline (named snapshot) | Comparing against an official project checkpoint |
| **Revision** | A Polarion SVN revision number | Comparing against a precise configuration state |
### Comparison by Date
You select a date, and the Gantt retrieves each task's start date and duration as they were on that date. This is the simplest mode -- useful for ad-hoc comparisons like "How did the plan look at the start of this quarter?"
The Gantt passes a `_baselineDate` parameter to the server, which looks up the historical values and returns them alongside the current data as `planned_start_date` and `planned_duration` fields.
### Comparison by Named Baseline
Polarion supports creating named baselines -- formal snapshots of a project's state at a specific point. The Gantt retrieves available baselines from the server and presents them in a dropdown. When you select a baseline, the Gantt loads task data as it existed at that baseline's revision.
Named baselines are particularly useful for contractual or regulatory scenarios where you need to demonstrate how the plan has evolved relative to an approved checkpoint.
### Comparison by Revision
For the most precise comparison, you can enter a specific SVN revision number. This is useful when you know the exact configuration state you want to compare against -- for example, the revision that was used for a particular delivery or review. If the specified revision does not exist in the task data, the Gantt displays an error.
**Newly added tasks**
When comparing against a historical point, tasks that were created after the comparison date are marked with a "NEW" badge. This helps you quickly identify work items that have been added to the scope since the baseline was established -- a key indicator of scope creep.
## Persistent vs. One-Time Comparison
The Gantt supports two baseline display modes:
**Persistent baselines** are configured through the `Show Baselines` parameter. When enabled, the Gantt automatically loads baseline data every time it opens. You configure a default comparison point -- either a relative date (e.g., "T-minus 30 days"), a specific date, or a date supplied via a page parameter. This mode is ideal for dashboard pages where you always want to see schedule drift.
The `Compare to date` sub-parameter only appears when `Show Baselines` is enabled, following the Gantt's progressive parameter disclosure pattern.
**One-time comparison** is triggered from the toolbar using the Compare with History button. This opens a dialog where you select one of the three comparison modes (date, named baseline, or revision) and click Compare. The baseline overlay appears for the current session only and is not persisted when the page is reloaded.
**Unsaved changes**
The Compare with History dialog cannot be opened when the Gantt has unsaved changes. Save or discard your edits before initiating a comparison. This prevents confusion between unsaved modifications and historical differences.
### Interaction Between Modes
When `Show Baselines` is configured for persistent display and a user triggers a one-time comparison with a different date, the one-time comparison takes precedence. The baseline display refreshes to show the user-selected comparison point instead of the preconfigured one. This allows users to temporarily explore different historical points without changing the widget configuration.
## Baseline Data Fields
When baseline comparison is active, the server includes two additional fields in each task's data response:
| Field | Content |
| -------------------- | ---------------------------------------------------------------- |
| `planned_start_date` | The task's start date as of the comparison point |
| `planned_duration` | The task's duration (in working days) as of the comparison point |
These fields drive the rendering of the secondary baseline bar behind the current task bar. If a task did not exist at the comparison point, these fields are absent and no baseline bar is rendered for that task.
## The API Approach
For advanced baseline scenarios, you can use the Item Script API to populate baseline fields from custom sources. Instead of relying on the built-in date/baseline/revision comparison, you can write a script that loads baseline values from dedicated custom fields on each work item.
This approach is useful when baselines are captured through workflow transitions rather than Polarion's baseline mechanism. For example, a workflow action "Approve Schedule" could copy the current `start` and `duration` values into `initial_start` and `initial_duration` fields. The Item Script then loads these item-specific baseline values, providing a per-task comparison rather than a single point-in-time snapshot.
## Visual Representation
The baseline bar appears as a secondary, typically lighter-colored bar rendered behind the main task bar. The visual difference between the two bars communicates:
* **Baseline bar extends further right** than the current bar -- the task was originally planned to take longer (or end later) than it currently does
* **Current bar extends further right** than the baseline bar -- the task has slipped past its original end date
* **Bars are identical** -- the task is on track with no schedule change
* **Only a current bar exists (no baseline)** -- the task was added after the comparison point (shown with a "NEW" badge)
## Interaction with Other Features
Baseline comparison interacts with several Gantt capabilities:
* **Critical path** -- You can compare the current [critical path](/gantt/concepts/critical-path) against a baseline to see how the critical path has shifted over time
* **Working calendars** -- Baseline duration values use the same [working calendar](/gantt/concepts/working-calendars) rules as current durations, ensuring the comparison accounts for non-working days
* **Date range conflicts** -- [Date range conflict detection](/gantt/concepts/date-conflict-detection) operates on current task dates only; baseline dates do not trigger conflict warnings
## Related Topics
* [Auto-Scheduling and Dependency Propagation](/gantt/concepts/auto-scheduling) -- How dependency-driven changes create the schedule drift that baselines reveal
* [Critical Path Analysis](/gantt/concepts/critical-path) -- Comparing current and historical critical paths
* [Configuration Layers and Precedence](/gantt/concepts/configuration-hierarchy) -- Where baseline settings are configured
# Capacity Modifiers and Team Capacity
Source: https://learn.nextedy.com/gantt/concepts/capacity-modifiers
Nextedy GANTT includes a capacity modifier system that reduces a resource's effective working hours to account for unplanned work and future uncertainty.
## The Problem Capacity Modifiers Solve
In practice, a team member assigned 100% to a team does not spend 100% of their time on planned tasks. Meetings, emails, code reviews, and ad-hoc requests consume a significant portion of each day. Additionally, work planned far into the future carries more uncertainty than work starting next week -- estimates for distant tasks tend to be less reliable.
Capacity modifiers formalize these two reductions into measurable percentages that the Gantt applies to resource load calculations. Instead of guessing that "people are probably busy with other things," you configure explicit values that adjust the resource view to reflect realistic availability.
## Two-Factor Capacity Adjustment
The Gantt supports two capacity modifier fields, referred to as Modifier A and Modifier B, each serving a distinct purpose:
### Modifier A -- Unplanned Work
Modifier A represents the percentage of time a resource spends on unplanned activities: meetings, emails, support requests, and other non-project work. This modifier applies to all planned work regardless of when it is scheduled -- past, present, or future.
For example, if Modifier A is set to 20%, a resource with an 8-hour working day has only 6.4 effective hours available for planned tasks.
### Modifier B -- Future Uncertainty
Modifier B represents the uncertainty inherent in work planned for the future. Unlike Modifier A, Modifier B only applies to tasks scheduled beyond a configurable day threshold from today. Work that is imminent (within the threshold) is considered firm and is not reduced by this modifier.
For example, if Modifier B is set to 15% and the day limit is 10 days, tasks starting 10 or more days from today have an additional 15% reduction applied on top of Modifier A. Tasks starting within the next 9 days are only affected by Modifier A.
The combined formula is:
| Component | Effect |
| ---------------- | ------------------------------------------------------------ |
| Base hours | Calendar-defined working hours (e.g., 8h) |
| After Modifier A | `base * (1 - modA/100)` -- always applied |
| After Modifier B | `base * (1 - (modA + modB)/100)` -- applied beyond day limit |
**Additive, not multiplicative**
Modifiers A and B are added together before being applied as a single percentage reduction. If Modifier A is 20% and Modifier B is 15%, the total reduction for future tasks is 35%, yielding `8 * (1 - 0.35) = 5.2` effective hours -- not `8 * 0.8 * 0.85 = 5.44`.
## The Day Limit Concept
The `nextedy.gantt.capacityModifierBFieldDayLimit` administration property controls when Modifier B kicks in. It defines a time horizon in days from today:
* Tasks scheduled **within** the day limit use only Modifier A
* Tasks scheduled **beyond** the day limit use Modifier A + Modifier B combined
This creates a two-tier capacity model where near-term work is planned at higher confidence (only unplanned overhead deducted) and long-term work includes an additional uncertainty buffer.
If the day limit is set to `-1` or is not configured, Modifier B applies to all tasks regardless of scheduling date.
## Where Capacity Modifiers Are Defined
Capacity modifiers are defined as custom fields on Team work items in Polarion. Each Team work item can have its own Modifier A and Modifier B values, allowing different teams to reflect different working patterns.
| Administration Property | Purpose |
| ---------------------------------------------- | -------------------------------------------------------- |
| `nextedy.gantt.useTeamCapacityModifiers` | Enables the capacity modifier system |
| `nextedy.gantt.capacityModifierAField` | Name of the custom field holding Modifier A percentage |
| `nextedy.gantt.capacityModifierBField` | Name of the custom field holding Modifier B percentage |
| `nextedy.gantt.capacityModifierBFieldDayLimit` | Number of days from today after which Modifier B applies |
**Team assignment prerequisite**
Capacity modifiers require [team assignments](/gantt/concepts/team-assignments) to be configured. The modifier values are read from Team work items, so the team assignment infrastructure (Team and Team Assignment work item types, assignment link roles) must be in place before capacity modifiers can take effect.
## How Modifiers Flow into the Resource View
When capacity modifiers are enabled, the [resource view](/gantt/concepts/resource-load-modes) reflects the adjusted capacity in its workload calculations:
1. The Gantt loads the user's base working hours from their [working calendar](/gantt/concepts/working-calendars) (or the global calendar)
2. Team assignment percentages are applied to determine how much of those hours go to the current team
3. Capacity modifiers further reduce the effective hours based on unplanned work and uncertainty factors
4. The resource view cells show workload against these reduced effective hours
This means a cell that would show "within capacity" without modifiers might turn red (over-capacity) once modifiers are applied, because the available hours are lower than the raw calendar suggests.
## Interaction with Team Filtering
When the Gantt is filtered to a specific team, the resource view shows capacity data only for that team's assignments. Capacity modifiers defined on the selected team are applied, while modifiers from other teams the user belongs to are excluded from the calculation. This ensures the resource view accurately reflects the capacity picture for the team being analyzed.
**Equipment assignments**
Equipment assignment capacity follows a different setup than team assignments. When an assigned user has no available working days in their calendar, the Gantt highlights those tasks to indicate a capacity problem. Equipment and user assignments should be documented and configured separately.
## Practical Example
Consider a team where members typically spend 20% of their time in meetings and administrative tasks (Modifier A = 20), and estimates for work more than two weeks out carry about 10% uncertainty (Modifier B = 10, day limit = 10):
| Time horizon | Modifier A | Modifier B | Total reduction | Effective hours (8h day) |
| -------------- | ---------- | ---------- | --------------- | ------------------------ |
| Within 10 days | 20% | 0% | 20% | 6.4h |
| Beyond 10 days | 20% | 10% | 30% | 5.6h |
The resource view uses 6.4 hours as the capacity baseline for near-term cells and 5.6 hours for cells further in the future, providing a more realistic picture of true availability.
## Related Topics
* [Working Calendars and Scheduling](/gantt/concepts/working-calendars) -- How base working hours are determined
* [Team Assignments and Cross-Team Planning](/gantt/concepts/team-assignments) -- How team allocation percentages layer on top of calendars
* [Resource Load Calculation Modes](/gantt/concepts/resource-load-modes) -- How capacity feeds into workload calculations
# Configuration Layers and Precedence
Source: https://learn.nextedy.com/gantt/concepts/configuration-hierarchy
Nextedy GANTT uses a layered configuration system where settings can be defined at multiple levels.
## Three Layers of Configuration
Think of the configuration hierarchy like CSS specificity -- the most specific setting wins. Gantt resolves every configurable property by checking three layers in order:
### Layer 1: Built-in Defaults
Every configurable property has a hardcoded default value. These defaults provide a working Gantt chart out of the box without any configuration. Key defaults include:
| Property | Default Value |
| ----------------- | ---------------- |
| Default scale | `W` (Week view) |
| Progress coloring | `true` |
| Drag children | `true` |
| Show today marker | `true` |
| Max items | `100` |
| Start field | `gantt_start` |
| Duration field | `gantt_duration` |
| Progress field | `gantt_progress` |
| Show unplanned | `true` |
| Undo steps | `10` |
### Layer 2: Administration Properties
Administrators can override defaults system-wide or per-project by setting **Configuration Properties** in Polarion's administration console (**Administration > Configuration Properties**). These properties follow a naming convention:
* **General properties** -- `nextedy.gantt.` applies globally regardless of Gantt mode.
* **Work Items Gantt defaults** -- `nextedy.gantt.workitems.default.` sets defaults for Work Items Gantt instances.
* **Plans Gantt defaults** -- `nextedy.gantt.plans.default.` sets defaults for Plans Gantt instances.
For example, to make auto-scheduling default to enabled across all Work Items Gantt instances in a project:
```
nextedy.gantt.default.auto_scheduling=true
```
Or to change the default scale for all Work Items Gantt instances:
```
nextedy.gantt.workitems.default.scale=M
```
**When Administration Defaults Apply**
Administration property defaults are used as the **initial value** when you add a new Gantt chart to a page. Once the chart is placed, its own parameter values take precedence. Changing an administration default does not retroactively update existing charts that already have explicit values set.
### Layer 3: Per-Instance Parameters
Per-instance parameters are set directly on each Gantt chart through the Polarion wiki page editor. They represent the most specific level of configuration and always take precedence when set.
These parameters are organized into sections in the configuration panel:
* **Data set** -- which work items or plans to display
* **Data Mapping** -- field mappings for start, end, duration, progress
* **Work Item Types** -- presentation modes, parent rules, create-new settings
* **Resource View** -- resource field, load mode, allocation colors
* **Working Calendars** -- global calendar, user calendars, team assignments
* **Advanced** -- scripts, read-only mode, always-edit, toolbar visibility
## Properties That Only Exist at One Level
Some configuration properties exist only as administration properties and cannot be set per instance:
| Property | Scope | Purpose |
| ---------------------------------------------------- | ---------- | ---------------------------------------------- |
| `nextedy.gantt.default.auto_scheduling` | Admin only | Toggle auto-scheduling default |
| `nextedy.gantt.default.critical_path` | Admin only | Toggle critical path visualization default |
| `nextedy.gantt.workitems.default.forward_dependency` | Admin only | Reverse dependency direction |
| `nextedy.gantt.workitems.default_duration` | Admin only | Default task duration in days (default: 10) |
| `nextedy.gantt.workitems.default.link_lag` | Admin only | Default dependency link lag (default: 0) |
| `nextedy.gantt.workitems.resolved_readonly` | Admin only | Prevent editing resolved items (default: true) |
| `nextedy.gantt.teamManagementProjectId` | Admin only | External team management project |
| `nextedy.gantt.workitemCalendar.projectId` | Admin only | Work item calendar project |
Conversely, certain settings are only available as per-instance parameters because they are inherently instance-specific (e.g., the data set query, scripts, sidebar fields).
## Progressive Disclosure in the Configuration Panel
The parameter editor uses progressive disclosure to reduce complexity. Sub-parameters are only visible when their parent feature is enabled:
* **Load User Calendars** appears only when **Use Working Calendar** is enabled
* **Load Team Assignments** appears only when **Load User Calendars** is enabled
* **Deadline Field** and **Passed Deadline Color** appear only when **Show Deadlines** is enabled
* **Compare to date** appears only when **Show Baselines** is enabled
This cascading visibility means you will not see advanced options until you enable the features they belong to.
## Gantt Config Script and Item Script
Beyond the structured parameter system, Gantt provides scripting hooks for advanced customization. The two that interact with configuration are:
* **Gantt Config Script** -- client-side JavaScript executed once during chart initialization. Configures global chart behavior (colors, working hours, scale settings).
* **Item Script** -- server-side JavaScript executed for each work item during data loading. Customizes individual task properties (colors, dates, read-only flags).
(A server-side **Markers Script** and a **Page Script** are also available -- see [Architecture and Data Flow](/gantt/concepts/architecture) and the scripting reference.)
Scripts provide the most flexibility but bypass the standard configuration validation. They execute in addition to -- not instead of -- the configuration hierarchy.
A Gantt chart can become read-only from three different sources: (1) the `readonly` parameter is set to true, (2) the current user is not licensed, or (3) a Polarion baseline snapshot is active. All three conditions are checked independently and any one will trigger read-only mode.
## Related Pages
* [Architecture and Data Flow](/gantt/concepts/architecture) -- how configuration flows from server to client
* [User Settings and Local Storage Persistence](/gantt/concepts/user-settings-persistence) -- how per-user preferences layer on top
* [Data Mapping and Field Resolution](/gantt/concepts/data-mapping) -- the field mapping subset of configuration
# Critical Path Analysis
Source: https://learn.nextedy.com/gantt/concepts/critical-path
Nextedy GANTT can highlight the critical path in your project schedule -- the longest chain of dependent tasks that determines the earliest possible completion date.
## What Is the Critical Path?
The critical path is the sequence of dependency-linked tasks with zero float (slack). Float is the amount of time a task can be delayed without pushing back the project end date. Tasks on the critical path have no float: if any of them slips, the project completion date slips by the same amount.
Consider a project with two parallel work streams converging at a final milestone:
In this example, the path Design > Build > Release takes 15 days, while Design > Documentation > Release takes 8 days. The critical path is Design > Build > Release because it is the longest chain. Documentation has 7 days of float -- it could slip by a week without affecting the release date.
## How the Gantt Calculates It
Critical path analysis requires dependency links to be defined between tasks. The Gantt evaluates all dependency chains and identifies the longest path from the earliest start to the latest finish across the entire task set. Tasks on this path receive a distinct visual highlight.
The calculation is deterministic: given the same dependency structure and task durations, the critical path is always the same. It cannot be manually overridden or customized -- it is a mathematical property of the schedule.
**Dependency links required**
Critical path highlighting only works when dependency links are configured via the `Dependency Role` parameter. Without dependencies, no chain exists to analyze, and no tasks are highlighted.
## Enabling Critical Path Highlighting
Critical path highlighting is toggled from the Gantt toolbar using the critical path toggle button. When enabled, tasks on the critical path are visually marked with a distinct color (red by default), making them immediately identifiable against non-critical tasks.
The toggle can be activated and deactivated during a session without reloading data. The critical path is recalculated dynamically as you make changes -- if you drag a task and the critical path shifts, the highlighting updates immediately.
## How Critical Path Selection Works
A common question is how the Gantt selects which tasks are on the critical path when multiple paths have similar lengths. The critical path always displays on the final scheduled task that determines the project end date, and traces backward through the dependency structure. The selection is based purely on the dependency graph and task durations:
| Factor | Effect on critical path |
| ----------------------------- | ------------------------------------------------------------------- |
| Longer task duration | More likely to be on the critical path |
| More sequential dependencies | Longer chain, more likely critical |
| Parallel paths | Only the longest parallel branch is critical |
| Finish-to-Finish dependencies | Both tasks may be critical if the FF link is the binding constraint |
**Critical path and auto-scheduling**
Critical path highlighting works independently of [auto-scheduling](/gantt/concepts/auto-scheduling). You can highlight the critical path in manual scheduling mode to identify which tasks need the most attention, even without automatic date propagation.
## Practical Implications
Understanding the critical path helps with several project management decisions:
* **Risk management** -- Tasks on the critical path carry the highest schedule risk. Assign your most reliable resources to them and monitor them closely.
* **Resource allocation** -- When resources are limited, prioritize critical path tasks over tasks with float.
* **Schedule compression** -- To shorten the project duration, you must shorten the critical path. Adding resources to non-critical tasks does not help.
* **What-if analysis** -- Toggle critical path highlighting on, then experiment with moving tasks or changing durations to see how the critical path shifts.
## Interaction with Other Features
Critical path analysis interacts with several other Gantt capabilities:
* **Working calendars** -- When calendars are enabled, task durations account for non-working days, which may change which path is longest
* **Baselines** -- You can compare the current critical path against a baseline to see how the critical path has shifted over time
* **Presentation modes** -- Tasks with the `Derived Schedule` presentation mode derive their dates from children. Their position on the critical path depends on their children's dates
## Related Topics
* [Auto-Scheduling and Dependency Propagation](/gantt/concepts/auto-scheduling) -- How dependencies drive date recalculation
* [Date Range Conflict Detection and Resolution](/gantt/concepts/date-conflict-detection) -- Detecting parent-child date violations
* [Baselines and Schedule Comparison](/gantt/concepts/baselines) -- Comparing current and historical schedules
# Data Mapping and Field Resolution
Source: https://learn.nextedy.com/gantt/concepts/data-mapping
Nextedy GANTT does not store scheduling data in its own database. Instead, it reads from and writes to standard Polarion work item fields.
## The Translation Layer
Think of data mapping as a translation dictionary between two systems. Polarion stores work item data in custom fields with names like `plannedStart`, `gantt_duration`, or `cf_end`. The Gantt chart needs to know which of these fields represents the task start, which represents the end, and which represents the duration. Data mapping provides this translation.
When the Gantt chart loads, the server reads each work item's mapped fields and constructs a task object with standardized properties -- `start_date`, `end_date`, `duration`, and `progress`. When a user drags a task bar or edits dates in the lightbox, the Gantt writes the changes back to the same mapped Polarion fields.
## Core Field Mappings
The Data Mapping section of the configuration parameters defines five key mappings:
| Parameter | Purpose | Default Value | Supported Field Types |
| --------------- | ------------------------------- | ---------------- | ------------------------------------ |
| `startField` | Task start date | `gantt_start` | Date, DateTime, String |
| `endField` | Task end date | *(none)* | Date, DateTime, String |
| `durationField` | Task duration | `gantt_duration` | Integer, String |
| `progressField` | Completion percentage (0.0-1.0) | `gantt_progress` | Float, String |
| `resourceField` | Assigned user or team | *(varies)* | User, Enumeration, Multi Enumeration |
The Gantt requires at least two of the three scheduling fields: `startField`, `endField`, and `durationField`. The three valid combinations are: Start + End, Start + Duration, or End + Duration. If you provide only one, the Gantt displays an error and the chart does not render.
## How Duration Is Calculated
When you provide all three fields (start, end, and duration), the Gantt uses the start and end dates as the authoritative source and recalculates duration from them. When you provide only two fields, the third is derived:
* **Start + Duration** -- The end date is calculated by adding the duration to the start date.
* **End + Duration** -- The start date is calculated by subtracting the duration from the end date.
* **Start + End** -- The duration is calculated from the difference between start and end.
Duration precision affects how this calculation works. In standard mode, durations are measured in **days**. In high-precision mode (`Duration Precision = High (Hours)`), durations are measured in **hours**, and date fields should use DateTime rather than Date types to preserve time information.
When switching from day precision to hour precision, existing duration values are reinterpreted. A stored value of `8` that previously meant 8 days will be treated as 8 hours (1 working day) after the switch.
## Progress Field Format
The `progressField` stores completion as a float between 0.0 and 1.0, where 0.0 means no progress and 1.0 means fully complete. The Gantt renders this as the filled portion of the task bar. Multiplying by 100 gives the percentage displayed in the lightbox and grid columns.
For production use, a **Float** custom field type is recommended for the progress field. String-type fields work but may have precision limitations.
## Dependency Link Mapping
Beyond scheduling fields, the Gantt maps work item link roles to dependency and hierarchy relationships:
* **`parentRoles`** -- Polarion link role IDs that define parent-child hierarchy. Work items linked through these roles appear in a tree structure in the Gantt grid.
* **`dependsRoles`** -- Polarion link role IDs that define finish-to-start dependencies. Work items linked through these roles display dependency arrows on the chart.
The Gantt supports four dependency types -- Finish-to-Start (FS), Start-to-Start (SS), Finish-to-Finish (FF), and Start-to-Finish (SF) -- with optional lag time. Advanced dependency metadata (type and lag) is stored in a `gantt_dependency_metadata` custom field as JSON, separate from the native Polarion link role.
## Task Type Resolution
Each work item is rendered as one of three visual types based on its configuration:
* **Task** -- A standard task bar with directly editable start and end dates
* **Project** -- A summary bar whose dates are derived from its children (not directly editable)
* **Milestone** -- A diamond marker representing a single point in time
The task type is determined by the **Gantt Presentation Mode** setting in the Work Item Types Configuration, not by the Polarion work item type itself. This means you can configure the same Polarion type (e.g., `workpackage`) to render differently depending on context.
For more about presentation modes, see [Presentation Modes -- Task, Project, and Milestone](/gantt/concepts/presentation-modes).
## The Server-to-Client Pipeline
When a Gantt page loads, the server resolves all field mappings into a unified configuration object that is serialized to JSON and sent to the client. This object contains the resolved field names, default values, and display settings. The client uses this configuration to parse the task data, render the chart, and handle user edits.
Understanding this pipeline helps explain why changes to field mappings require a page reload to take effect -- the mapping is resolved once at render time and cached for the session.
## Related Pages
* [Configuration Layers and Precedence](/gantt/concepts/configuration-hierarchy) -- where field mapping defaults come from
* [Presentation Modes -- Task, Project, and Milestone](/gantt/concepts/presentation-modes) -- how task type affects scheduling behavior
* [Architecture and Data Flow](/gantt/concepts/architecture) -- the full rendering pipeline
# Date Range Conflict Detection and Resolution
Source: https://learn.nextedy.com/gantt/concepts/date-conflict-detection
Nextedy GANTT enforces date containment between parent and child tasks.
## Why Date Containment Matters
In hierarchical project scheduling, parent tasks represent containers for their children. A "Development Phase" spanning January through March logically contains all its child tasks. If a child task "Integration Testing" is scheduled for April, the parent-child relationship no longer makes sense -- the parent appears to end before all its work is complete.
Without conflict detection, these inconsistencies accumulate silently. Users drag tasks around, resize durations, and update dates without realizing they have broken containment rules. The Gantt's date range conflict detection catches these violations in real time, ensuring the schedule remains logically consistent.
## How Conflict Detection Works
The conflict detection system evaluates parent-child date relationships across the entire task hierarchy. It operates in two directions:
The detection system performs two distinct checks:
| Check | Direction | What it detects |
| -------------------------------- | ---------------------------- | -------------------------------------------------------------------------- |
| Child out of parent range | Upward through ancestors | A child task whose start or end date falls outside its parent's date range |
| Parent has children out of range | Downward through descendants | A parent task that has one or more children extending beyond its own dates |
These checks are not limited to the immediate parent-child pair. The system recursively checks all ancestor levels, so a deeply nested task is validated against every ancestor in the hierarchy, not just its direct parent.
### Independent Start and End Checks
The conflict detection system can check start dates and end dates independently. The configuration options `rangeConflict.checkStart` and `rangeConflict.checkEnd` control which boundaries are enforced. This flexibility allows you to enforce only end-date containment (useful when child tasks can start before the parent's official start) or only start-date containment, depending on your scheduling methodology.
## When Conflicts Are Detected
Conflict detection runs at three points during a Gantt session:
1. **On data load** -- When the Gantt first loads, all tasks are scanned for existing conflicts. Parent tasks with out-of-range children are immediately highlighted.
2. **During drag and resize** -- As you drag a task bar or resize it, the Gantt evaluates the new position in real time. If the task moves outside its parent's range, the conflict indicator appears immediately. If you move it back within range, the indicator clears.
3. **In the lightbox** -- When editing dates in the lightbox, validators check that the new dates respect parent-child containment. If a child's dates would extend beyond the parent, an error message describes the parent's date range. Similarly, if a parent's dates would exclude existing children, the lightbox shows a warning.
**Enabling conflict detection**
Date range conflict detection requires the `rangeConflict.enabled` configuration to be set to `true`. When disabled, no conflict checks are performed and tasks can be freely positioned regardless of parent-child containment.
## Visual Conflict Indicators
When a conflict is detected, the Gantt applies visual indicators to the affected tasks:
* **Parent tasks** with out-of-range children receive a conflict highlight and display a tooltip message indicating the children range conflict
* **Child tasks** outside their parent's range can optionally be highlighted using the `rangeConflict.highlightChild` configuration. When enabled, both the parent and the offending child receive the conflict styling. When disabled, only a subtle indicator is shown on the child
The visual highlighting is reactive -- it appears the moment a drag creates a conflict and disappears the moment the task returns within its parent's range.
## Automatic Conflict Resolution
Beyond detection, the Gantt includes an automatic resolution system that adjusts dates to eliminate conflicts after drag and resize operations. When resolution is active:
* **Dragging a child past its parent's boundary** causes the parent's date range to expand automatically, growing to accommodate the child's new position
* **Resizing a child beyond its parent's end date** triggers the same parent expansion
* **Resolution propagates hierarchically** -- if expanding the parent causes it to exceed its own parent's range, that grandparent is also expanded, and so on up the tree
This means that moving a leaf-level task can cascade adjustments all the way up to the root of the hierarchy, keeping the entire tree consistent.
**Resolution vs. detection**
Conflict resolution (automatic date adjustment) and conflict detection (visual warnings) are separate systems. Detection shows you where problems exist. Resolution fixes them automatically. In some configurations, you may want detection without automatic resolution -- this lets users see conflicts and decide how to address them manually.
## Interaction with Working Calendars
Date range conflict calculations respect [working calendars](/gantt/concepts/working-calendars) when evaluating boundaries. Tasks that start or end on weekends are adjusted to the nearest working day before the conflict status is evaluated. This prevents false positives where a task technically ends on a Saturday (a non-working day) but its effective end is the preceding Friday, which may still fall within the parent's range.
## Interaction with Other Features
Date range conflict detection interacts with several other Gantt capabilities:
* **Auto-scheduling** -- When [auto-scheduling](/gantt/concepts/auto-scheduling) propagates date changes through dependency links, the resulting positions are checked for parent-child conflicts. Auto-scheduling resolves dependency constraints; conflict detection resolves containment constraints.
* **Drag children** -- When the drag-children toolbar toggle is enabled, dragging a parent moves all children by the same offset. Since children move with the parent, containment is preserved and no conflicts arise from the move itself.
* **Critical path** -- [Critical path analysis](/gantt/concepts/critical-path) operates independently of conflict detection. A task can be on the critical path and also have a date range conflict.
## Related Topics
* [Auto-Scheduling and Dependency Propagation](/gantt/concepts/auto-scheduling) -- How dependency constraints interact with containment enforcement
* [Critical Path Analysis](/gantt/concepts/critical-path) -- Identifying the schedule-determining task chain
* [Working Calendars and Scheduling](/gantt/concepts/working-calendars) -- How calendar boundaries affect conflict evaluation
# Concepts
Source: https://learn.nextedy.com/gantt/concepts/index
Nextedy GANTT is a general-purpose project scheduling app for Siemens Polarion ALM. It is highly configurable and supports waterfall, agile, hybrid, and scaled agile methodologies.
## Product Fundamentals
* [**Product Overview**](/gantt/concepts/overview) -- What Gantt is, who uses it, and how it connects to Polarion ALM.
* [**Work Items Gantt vs Plans Gantt**](/gantt/concepts/work-items-vs-plans-gantt) -- The two scheduling modes: one for individual work items, another for Polarion Plans as scheduling containers.
* [**Architecture and Data Flow**](/gantt/concepts/architecture) -- How data flows between the Polarion server and the browser: loading, rendering, and persistence.
## Scheduling and Dependencies
* [**Auto-Scheduling and Dependency Propagation**](/gantt/concepts/auto-scheduling) -- How dependency links drive automatic date recalculation when tasks move.
* [**Critical Path Analysis**](/gantt/concepts/critical-path) -- Identifying the longest chain of dependent tasks that determines the earliest project completion date.
* [**Date Range Conflict Detection and Resolution**](/gantt/concepts/date-conflict-detection) -- How the Gantt detects and resolves parent-child date range violations.
* [**Data Mapping and Field Resolution**](/gantt/concepts/data-mapping) -- How Polarion work item fields map to Gantt scheduling properties like start date, end date, and duration.
## Resources and Capacity
* [**Resource Load Calculation Modes**](/gantt/concepts/resource-load-modes) -- The four methods for computing resource utilization: item count, time, remaining estimate, and allocation.
* [**Working Calendars and Scheduling**](/gantt/concepts/working-calendars) -- How working calendars define non-working days, per-user schedules, and calendar exceptions.
* [**Team Assignments and Cross-Team Planning**](/gantt/concepts/team-assignments) -- Managing team membership, allocation percentages, and cross-project resource visibility.
* [**Capacity Modifiers and Team Capacity**](/gantt/concepts/capacity-modifiers) -- How capacity modifier fields reduce effective availability for resource planning.
## Visualization
* [**Presentation Modes -- Task, Project, and Milestone**](/gantt/concepts/presentation-modes) -- The visual modes that control how a work item type appears on the Gantt chart.
* [**Item Color Logic -- Static, Dynamic, and Progress Colors**](/gantt/concepts/item-color-logic) -- How task bar colors are determined from progress, scripts, and work item properties.
* [**Baselines and Schedule Comparison**](/gantt/concepts/baselines) -- Comparing the current schedule against historical snapshots using dates, named baselines, or revisions.
## Configuration
* [**Configuration Layers and Precedence**](/gantt/concepts/configuration-hierarchy) -- How system-wide defaults, per-instance parameters, and user preferences interact.
* [**User Settings and Local Storage Persistence**](/gantt/concepts/user-settings-persistence) -- How the Gantt remembers personal preferences like zoom level and column widths between sessions.
If you are new to Nextedy GANTT, begin with [Product Overview](/gantt/concepts/overview) to understand the product, then read [Work Items Gantt vs Plans Gantt](/gantt/concepts/work-items-vs-plans-gantt) to choose the right mode for your project.
If you are new to Gantt, begin with [Product Overview](/gantt/concepts/overview) to understand the product, then read [Work Items Gantt vs Plans Gantt](/gantt/concepts/work-items-vs-plans-gantt) to choose the right mode for your project.
# Item Color Logic -- Static, Dynamic, and Progress Colors
Source: https://learn.nextedy.com/gantt/concepts/item-color-logic
Nextedy GANTT uses color to communicate task status at a glance. A red task bar tells you something is overdue. A gray bar means the work is resolved.
## Dynamic Colors (Progress Coloring)
By default, Gantt applies **dynamic progress coloring**. The chart evaluates each task's scheduling status against today's date and the task's progress, then automatically assigns a color:
| Color | Meaning | Condition |
| -------------- | ------------------------ | ------------------------------------------------------- |
| **Red** | Overdue | End date is in the past, task is still unresolved |
| **Orange** | Progress behind schedule | End date is in the future, but progress indicates delay |
| **Blue** | On track | Task is unresolved, schedule and progress look healthy |
| **Gray** | Resolved | Task has a resolution value (completed in Polarion) |
| **Light blue** | Unplanned | Task has no scheduled start date (defaults to today) |
| **Green** | Project item | Task is configured as a "project" presentation mode |
Dynamic coloring is controlled by the `progressColoring` parameter, which defaults to `true`. When enabled, the Gantt evaluates each task on every render and applies the appropriate color automatically.
**How Resolution Is Determined**
The Gantt determines whether a task is "resolved" by checking if the Polarion work item has a **resolution value** set. This is configured in the Polarion workflow -- statuses that should count as "resolved" must have resolution values defined. If your custom statuses do not set resolution values, tasks in those statuses will not appear gray even if they are logically complete.
## Static Colors (Script-Controlled)
When you need full control over task bar colors -- for example, coloring tasks by type, assignee, or a custom field -- you switch to **static coloring** by disabling progress colors:
```javascript theme={null}
// In Widget Properties > Advanced > Gantt Config Script:
gantt.config.show_progress_colors=false;
```
With progress colors disabled, every task renders with the default blue color unless you explicitly assign colors through an **Item Script**. In the Item Script, you use `task.color` to set the CSS color for each task:
```javascript theme={null}
// In Widget Properties > Advanced > Item Script:
if(wi.getType().getId()==="workpackage" && wi.getStatus().getId()==="draft") {
task.color = "#bfbfbf";
}
```
The `task.color` property overrides all automatic coloring and gives you direct control.
## The task.color vs task.taskColor Distinction
This is the most common source of confusion when working with item colors. There are two different properties:
* **`task.color`** -- Overrides the task bar color completely, regardless of progress status. Use this with **static coloring** (when `show_progress_colors=false`).
* **`task.taskColor`** -- Changes only the **default blue color** that applies to on-track, unresolved tasks. Dynamic progress colors (red, orange, gray) still override it.
| Property | Works with dynamic colors? | Overrides overdue/resolved colors? |
| ---------------- | -------------------------------------- | ----------------------------------- |
| `task.color` | Only when `show_progress_colors=false` | Yes -- full override |
| `task.taskColor` | Yes | No -- only changes the default blue |
**Common Pitfall: taskColor on Past Items**
If you use `task.taskColor` to set a custom color, it only applies to tasks that would normally appear blue (on-track, unresolved). Tasks with end dates in the past will still appear red because the progress coloring system overrides `taskColor`. To color all tasks regardless of status, disable progress colors and use `task.color` instead.
## Customizing Default Progress Colors
If you want to keep dynamic coloring but change the specific colors used, configure the default colors via **Gantt Config Script** or **Configuration Properties**:
```javascript theme={null}
// In Gantt Config Script:
gantt.config.progress_color_overdue = "red";
gantt.config.progress_color_progressdue = "orange";
gantt.config.progress_color_resolved = "gray";
```
Alternatively, set these as administration properties for system-wide defaults:
```
nextedy.gantt.default.progress_color_overdue=red
nextedy.gantt.default.progress_color_progressdue=orange
nextedy.gantt.default.progress_color_resolved=gray
```
You can also configure the color and foreground color for unplanned items:
```
nextedy.gantt.workitems.unplanned_color=#c7cffb
nextedy.gantt.workitems.unplanned_color_fg=#001379
```
## No-Working-Days Flagging
Starting with version 25.10.2, the Gantt visually flags tasks in red when the assigned user has **no available working days** during the scheduled period. This helps planners immediately identify unrealistic schedules caused by calendar conflicts.
## Resource Allocation Marker Colors
The resource view has its own color system, separate from task bar colors. Resource allocation markers use the `resourceMarkersColorConfig` to define colors for within-capacity (green by default) and over-capacity (red by default) states. These colors can be customized through the widget configuration.
## Choosing Your Approach
Use this decision framework to pick the right coloring strategy:
* **Keep dynamic colors** if you want automatic visual feedback about schedule health (most teams prefer this).
* **Customize dynamic colors** if you want the automatic behavior but with your brand's color palette.
* **Switch to static colors** if you need to color tasks by type, assignee, priority, or any other custom logic that is unrelated to schedule status.
## Related Pages
* [Configuration Layers and Precedence](/gantt/concepts/configuration-hierarchy) -- where color defaults are set
* [Architecture and Data Flow](/gantt/concepts/architecture) -- how scripts execute during rendering
# Product Overview
Source: https://learn.nextedy.com/gantt/concepts/overview
Nextedy GANTT is a project scheduling app for Siemens Polarion ALM.
## What Gantt Does
At its core, Gantt turns Polarion work items into a visual timeline. You see your tasks as bars on a chart, connected by dependency links, grouped by hierarchy, and colored by status. Drag a task to reschedule it. Resize it to change the duration. The Gantt handles the rest — recalculating dependent dates, respecting working calendars, and persisting changes back to Polarion.
This is not a standalone tool. Gantt operates entirely within Polarion. Your data stays in Polarion work items and plans. The Gantt reads from and writes to the same fields your team already uses. There is no separate database, no data synchronization, and no import/export step.
## Key Capabilities
## Who Uses Gantt
Gantt serves different roles in different ways:
* **Project managers** use it for timeline planning, milestone tracking, and schedule comparison. They create baselines, monitor the critical path, and adjust schedules through drag-and-drop.
* **Team leads** use the resource view to balance workload across team members, identify overallocation, and plan capacity across sprints and iterations.
* **Engineers and contributors** use it to see where their tasks fit in the broader timeline, understand dependencies, and update progress directly on the chart.
* **Administrators** configure the Gantt for their organization — setting up working calendars, defining field mappings, establishing default behaviors, and writing scripts for custom logic.
## A General-Purpose Scheduling Tool
Gantt is not locked to a specific methodology. It works equally well for:
* **Waterfall projects** where tasks follow a strict sequence with clear phase gates
* **Agile projects** where iterations and sprints need timeline visibility alongside the backlog
* **Hybrid approaches** combining fixed milestones with iterative development
* **SAFe and scaled agile** where release trains, program increments, and cross-team coordination require a shared timeline view
The two built-in modes — **Work Items Gantt** for task-level scheduling and **Plans Gantt** for release and iteration planning — cover both detailed task management and high-level portfolio views.
## Highly Configurable
Almost every aspect of Gantt can be tailored to your organization's needs:
* **Field mapping** — The Gantt reads from whichever Polarion fields you designate for start date, end date, duration, progress, and resource. You are not limited to predefined fields.
* **Presentation modes** — Each work item type can appear as a task bar, a summary (project) bar, a milestone diamond, or a group header.
* **Color logic** — Task colors can be driven by progress status (dynamic mode), by scripts (static mode), or by any combination of work item properties.
* **Scripting API** — Four scripting hooks extend the Gantt: the **Item Script** (server-side JavaScript, per task) customizes appearance and computed values; the **Gantt Config Script** (client-side JavaScript) sets global chart behavior; the **Markers Script** (server-side JavaScript) adds timeline markers; and the **Page Script** (server-side Velocity) provides dynamic configuration with full Polarion API access.
* **Working calendars** — Define global holidays, per-user schedules, calendar exceptions, and team capacity multipliers.
* **Layered configuration** — System-wide defaults can be overridden per-instance, allowing administrators to establish conventions while giving teams flexibility.
For a detailed explanation of the configuration system, see [Configuration Layers and Precedence](/gantt/concepts/configuration-hierarchy).
## How It Connects to Polarion
Gantt does not have its own data store. It reads directly from Polarion work items and plans, and writes changes back to the same fields. This means:
* **No data synchronization** — What you see in the Gantt is exactly what Polarion stores. There is no lag, no import step, no risk of data divergence.
* **Full traceability** — Every change the Gantt makes to a work item is a standard Polarion field update, tracked in the work item's history.
* **Permission-aware** — The Gantt respects Polarion's permission model. Users can only edit what Polarion allows them to edit.
* **Embedded experience** — The Gantt appears directly in Polarion pages (LiveDocs, Wiki pages), alongside other Polarion content. Teams do not need to switch to a separate application.
## Next Steps
* **[Work Items Gantt vs Plans Gantt](/gantt/concepts/work-items-vs-plans-gantt)** — Understand the two scheduling modes and choose the right one for your project.
* **[Auto-Scheduling and Dependency Propagation](/gantt/concepts/auto-scheduling)** — Learn how dependency links drive automatic date recalculation.
* **[Architecture and Data Flow](/gantt/concepts/architecture)** — Explore the technical architecture: how data flows between Polarion and the Gantt chart.
# Presentation Modes -- Task, Project, and Milestone
Source: https://learn.nextedy.com/gantt/concepts/presentation-modes
Nextedy GANTT renders each work item as one of four visual types depending on its configured **Gantt Presentation Mode**.
## The Four Presentation Modes
Each work item type in your Gantt chart is assigned a presentation mode through the **Work Item Types Configuration** panel in the chart parameters. The four available modes are:
| Mode | Display Label | Visual Appearance | Date Behavior |
| -------------------- | ---------------- | ----------------- | ---------------------------------------------------------------- |
| **Item** | Item | Standard task bar | Dates come from data mapping fields; directly editable |
| **Derived Schedule** | Derived Schedule | Standard task bar | Dates computed from child extents; not directly editable |
| **Milestone** | Milestone | Diamond symbol | Single target date; no duration |
| **Auto-Mode** | Auto-Mode | Varies | Automatically selects Item or Derived Schedule based on children |
### Item Mode
Item is the default presentation mode. Work items in this mode appear as standard task bars whose start and end dates come directly from the configured data mapping fields (e.g., `startField`, `endField`). Users can drag, resize, and edit these tasks freely in edit mode.
This mode is appropriate for any work item that has its own independently managed schedule -- individual tasks, features, user stories, or any leaf-level work.
### Derived Schedule Mode
Derived Schedule mode is designed for parent containers. Rather than storing their own start and end dates, these items compute their schedule from the extents of their children. The task bar stretches from the earliest child start date to the latest child end date.
Because dates are derived, these items are **not directly editable** on the Gantt chart. Dragging or resizing is disabled. To change the parent's schedule, you adjust its children's dates instead.
This mode is useful for work packages, epics, or any container type where the parent's timeline should automatically reflect the aggregate schedule of its contents.
### Milestone Mode
Milestones appear as diamond symbols on the Gantt chart, representing a single point in time with no duration. They are commonly used for deadlines, review gates, release dates, or any significant target date.
A milestone uses only a target date -- there is no start-to-end range. In the lightbox, you edit a single date field rather than separate start and end fields.
### Auto-Mode
Auto-Mode is a convenience setting that automatically determines the presentation based on whether the work item has children. If a work item has child items linked through the configured parent roles, it behaves as a Derived Schedule (summary bar). If it has no children, it behaves as an Item (standard task bar).
This is particularly useful when a single work item type (e.g., `workpackage`) can serve as both a leaf task and a parent container depending on the project structure.
Auto-Mode works best when your project hierarchy is not strictly defined in advance. If a work package might or might not have sub-items depending on the project phase, Auto-Mode ensures it always renders correctly without manual reconfiguration.
## Default Type Configuration
Out of the box, the Gantt defines three default work item types with their presentation modes:
| Work Item Type | Default Presentation Mode | Purpose |
| -------------- | ------------------------- | --------------------------------------- |
| `feature` | Item | Leaf tasks shown as standard bars |
| `workpackage` | Derived Schedule | Parent containers shown as summary bars |
| `release` | Milestone | Release milestones shown as diamonds |
These defaults serve as a starting reference. You can add, modify, or remove type configurations through the **Work Item Types Configuration** panel to match your project's work item taxonomy.
## How Presentation Mode Affects Editing
The presentation mode directly determines what editing actions are available:
| Action | Item | Derived Schedule | Milestone | Auto-Mode |
| ------------------------- | ---- | ---------------------- | ----------------- | ------------------- |
| Drag to move | Yes | No | Yes | Depends on children |
| Resize to change duration | Yes | No | No | Depends on children |
| Edit dates in lightbox | Yes | No | Yes (single date) | Depends on children |
| Progress bar | Yes | Computed from children | No | Depends on children |
## Interaction with Parent Mode
Presentation mode works alongside **Parent Mode**, which controls where in the hierarchy a work item type can be placed:
* **No Parent (Root Item)** -- can only exist at the top level
* **Parent Allowed (Anywhere)** -- can be placed at any hierarchy level
* **Parent Required (Child Only)** -- must be nested under another item
Together, Presentation Mode and Parent Mode define the complete behavior of a work item type in the Gantt chart -- how it looks, where it sits in the hierarchy, and how its dates are managed.
## Related Pages
* [Data Mapping and Field Resolution](/gantt/concepts/data-mapping) -- how dates flow into task bars
* [Configuration Layers and Precedence](/gantt/concepts/configuration-hierarchy) -- where type configuration lives
* [Work Items Gantt vs Plans Gantt](/gantt/concepts/work-items-vs-plans-gantt) -- how Plans Gantt handles type configuration differently
# Resource Load Calculation Modes
Source: https://learn.nextedy.com/gantt/concepts/resource-load-modes
Nextedy GANTT includes a resource view that displays how work is distributed among team members over time.
## Four Calculation Modes
The Gantt offers four modes for computing resource load, each suited to different planning strategies. The mode is selected via the `Resource Load Calculation` parameter.
| Mode | Internal value | Cell shows | Best for |
| --------------------- | -------------- | ------------------------------- | --------------------------------- |
| Leaf Items Count | `num` | Number of leaf-level work items | Simple task-based tracking |
| Estimate + Spent | `time` | Total hours (remaining + spent) | Complete effort picture |
| Remaining Estimate | `remaining` | Remaining hours only | Forward-looking capacity planning |
| Assignment Allocation | `allocation` | Percentage of team assignment | Team-based allocation tracking |
### Leaf Items Count
The simplest mode. Each leaf-level work item (a work item with no children) assigned to a resource counts as "1" in the load calculation. Parent work items are excluded because their children already represent the actual work.
For example, if Robert has two leaf-level tasks scheduled for the same week, his resource view cell for that week shows "2". This mode does not consider task duration or estimated effort -- it is purely a count of assigned items.
The `Items per resource` parameter sets the threshold above which a cell turns red to indicate overallocation. If the limit is 3 and a resource has 4 items in a period, the cell turns red.
### Estimate + Spent
This mode sums the remaining estimate and time already spent on each work item, providing a complete picture of both planned and actual effort. The total effort is distributed evenly across the scheduled days of the task.
For example, if a task has 80 hours of time spent and 16 hours of remaining estimate over a 10-day schedule, the total is 96 hours. Dividing by 10 days yields 9.6 hours per day shown in the resource view.
**Effort distribution**
The Gantt distributes effort evenly across the full task duration. It does not weight spent time toward past days or remaining time toward future days. This is a design choice that provides a consistent view, but it may differ from user expectations.
### Remaining Estimate
This mode considers only the effort still required to complete each task, ignoring time already spent. The remaining estimate is spread across the scheduled days starting from today and into the future only.
For example, a task with 6 days of remaining estimate scheduled across 10 calendar days yields 4.8 hours per day. Past days show no load since the remaining work is projected forward.
This mode is especially useful for forecasting. It answers the question: "How much work does each person still need to deliver?"
### Assignment Allocation
This mode uses team-based assignment percentages rather than individual work item estimates. Each user is assigned a percentage of work within each team (via team assignment work items), and the resource view shows the combined allocation across all teams.
For example, if Mark is assigned 35% in Team Alpha and 10% in Team Beta, his total allocation is 45% for the overlapping period. If the total exceeds 100%, the cell turns red to indicate overallocation.
This mode requires [team assignments](/gantt/concepts/team-assignments) to be configured and the `Load Team Assignments` calendar option to be enabled.
## How Working Calendars Affect Calculations
When [working calendars](/gantt/concepts/working-calendars) are enabled, the resource load calculations respect non-working days and per-user schedules. The available working hours per day are determined by the user's calendar (or the global calendar as a fallback). A standard day provides 8 working hours by default.
For the time-based modes (Estimate + Spent and Remaining Estimate), the calculation uses each resource's actual available hours when computing how many hours a task occupies within a given day. For example, if a user's calendar shows only 4 hours on Fridays, the allocated hours for that day are halved compared to a standard 8-hour day.
Days marked as non-working (weekends, holidays, time-off) appear as grey cells in the resource view, indicating zero available capacity.
## Color Coding
Resource view cells use color coding to communicate workload status at a glance:
| Color | Meaning |
| ------------------------- | ------------------------------------------- |
| Green (default `#4CAF50`) | Within capacity -- workload is acceptable |
| Red/Orange | Over capacity -- resource is overallocated |
| Grey | Unavailable -- non-working day per calendar |
The color thresholds are configurable via the resource markers color configuration, which accepts CSS color values for the `ok` (within-capacity) and `over` (over-capacity) states.
**Resolution status affects calculations**
The resource load calculation considers work item resolution status, not just remaining time. Switching from Estimate + Spent to Remaining mode can change visible values because the modes use different fields. Be sure to understand which Polarion fields drive each mode before comparing results.
## Choosing the Right Mode
Most teams start with **Leaf Items Count** for its simplicity, then move to **Remaining Estimate** or **Estimate + Spent** as they adopt time tracking in Polarion. **Assignment Allocation** is best suited for organizations that manage team capacity through formal assignment percentages.
## Related Topics
* [Working Calendars and Scheduling](/gantt/concepts/working-calendars) -- How calendars define available hours per resource
* [Capacity Modifiers and Team Capacity](/gantt/concepts/capacity-modifiers) -- How capacity modifiers reduce effective availability
* [Team Assignments and Cross-Team Planning](/gantt/concepts/team-assignments) -- Setting up team-based resource management
# Team Assignments and Cross-Team Planning
Source: https://learn.nextedy.com/gantt/concepts/team-assignments
Nextedy GANTT introduces a dynamic approach to team management that goes far beyond Polarion's built-in static user-project allocations.
## Why Teams Need More Than Enums
In standard Polarion, a team is typically just an enumeration value -- a label attached to a work item. This approach answers the question "which team owns this task?" but leaves critical resource planning questions unanswered:
* **Who** is actually working on a given team?
* **How much** of their time is allocated to this team versus others?
* **When** does this allocation start and end?
Polarion's built-in **Time-split Assignments** (Administration > Users) allows defining a user's allocation percentage to a *project*, but not to a *team* within that project. If multiple teams share a single project, or if team membership changes over time, the static allocation model falls short.
## Teams as Work Items
Gantt solves this by introducing two new work item types: **Team** and **Team Assignment**. Rather than relying on static enumerations, teams become fully functional Polarion work items with all the traceability and flexibility that comes with them.
| Work Item Type | Purpose | Key Fields |
| ------------------- | --------------------------------------------- | ----------------------------------------------------- |
| **Team** | Represents a team entity (e.g., Alpha, Beta) | Title, capacity modifiers |
| **Team Assignment** | Links an assignee to a team for a time period | Assignee, start date, end date, allocation percentage |
Team assignment work items are linked to their parent team using a dedicated **assignment** link role. Each assignment specifies who is on the team, for how long, and at what percentage of their capacity.
**Unlinked Assignments Are Ignored**
Every Team Assignment work item **must be linked** to a parent Team work item. Assignments without a parent team are silently excluded from capacity calculations, which can cause unexpected gaps in the resource view.
## How Capacity Flows Through the System
The capacity calculation follows a clear hierarchy. When the Gantt chart loads, it resolves each user's available hours by layering multiple inputs:
For example, if John has an 8-hour working day and a 50% team assignment, his effective capacity for that team is 4 hours per day. If capacity modifiers further reduce this, the final effective hours will be even lower.
## Allocation Percentage and Overallocation
The allocation percentage on each Team Assignment drives the resource view display. The resource view shows allocation markers for each user per time period, where **100% represents a full working day**. When a user's total allocation across all teams exceeds 100% on any given day, the resource view flags this as overallocation with a red marker.
Consider a scenario where Mark is assigned to two teams:
* **Team Alpha**: 60% from May 1 to May 15
* **Team Beta**: 80% from May 9 to May 20
Between May 9 and May 15, Mark's total allocation is 140% -- clearly overallocated. The Gantt resource view surfaces this conflict immediately, allowing project managers to adjust either the allocation percentages or the time periods.
## Cross-Project Team Management
Teams often span multiple Polarion projects. Gantt supports this through an **external team management project** -- a single dedicated project that holds all Team and Team Assignment work items. Other projects reference this central project to pull team data into their Gantt charts.
The configuration property `nextedy.gantt.teamManagementProjectId` points to the project where team work items reside. If this property is not set, Gantt looks for teams in the current project. For organizations with teams spanning multiple projects, centralizing team definitions provides a single source of truth for capacity planning.
Showing teams from several projects on one cross-project Gantt -- here `Gantt_Teams` and `WEBINAR_TEAMS` together -- makes overallocations across the whole organization visible in a single resource view:
## Capacity Modifiers
Teams can define **capacity modifiers** that account for time spent on unplanned work. Two modifier fields are available:
* **Capacity Modifier A** (`nextedy.gantt.capacityModifierAField`) -- Represents the percentage of time consumed by unplanned work (meetings, emails, support). Applied to all tasks regardless of when they are scheduled.
* **Capacity Modifier B** (`nextedy.gantt.capacityModifierBField`) -- Represents uncertainty in future planning. Applied only to tasks scheduled beyond a configurable day limit (`nextedy.gantt.capacityModifierBFieldDayLimit`).
The effective capacity formula is: `effectiveCapacity = base * (1 - (modA + modB) / 100)`. This provides a realistic view of available capacity that accounts for the inevitable overhead of day-to-day work.
To learn more about capacity modifiers, see [Capacity Modifiers and Team Capacity](/gantt/concepts/capacity-modifiers).
## Configurable Work Item Type IDs
Starting with version 25.5.0, the work item type IDs used for teams and assignments are configurable via context properties:
* `nextedy.gantt.teamWorkItemType` -- defaults to `team`
* `nextedy.gantt.teamAssignmentWorkItemType` -- defaults to `teamAssignment`
This allows organizations that use different naming conventions to integrate with the team assignment system without renaming their existing work item types.
**Lightbox Behavior**
When creating a Team Assignment through the Gantt lightbox, the **Assignee** and **Assignment** (percentage) fields are automatically marked as required. The lightbox title updates dynamically to reflect the selected user and allocation percentage. Note that the "automatic" assignee option is not available for team assignments -- only explicit users can be selected.
## Related Pages
* [Capacity Modifiers and Team Capacity](/gantt/concepts/capacity-modifiers) -- understand modifier fields and formulas
* [Resource Load Calculation Modes](/gantt/concepts/resource-load-modes) -- how allocation mode computes load
* [Working Calendars and Scheduling](/gantt/concepts/working-calendars) -- the base calendar layer beneath team assignments
# User Settings and Local Storage Persistence
Source: https://learn.nextedy.com/gantt/concepts/user-settings-persistence
Nextedy GANTT remembers your personal view preferences -- zoom level, column widths, column visibility, and grid panel width -- so you do not need to reconfigure the chart every time you open a page.
## What Gets Saved
The Gantt chart persists the following user-level settings:
| Setting | What It Controls | When It Saves |
| --------------------- | ----------------------------------------------------------------------------- | ---------------------------------------------------------- |
| **Zoom scale** | The active timescale level (e.g., Week, Month, Day) | When you change the zoom level via the toolbar or menu |
| **Column widths** | The pixel width of each grid column | When you resize a column by dragging its border |
| **Grid width** | The overall width of the left grid panel (split point between grid and chart) | When you drag the grid/chart divider |
| **Column visibility** | Which columns are shown or hidden | When you toggle columns via the column header context menu |
These settings are distinct from the configuration parameters set by administrators. Configuration parameters define the defaults and available features; user settings represent each user's personal customization on top of those defaults.
## How Storage Works
User settings are stored in the browser's **localStorage**, keyed by a combination of:
* The **document URL** (the Polarion page containing the Gantt chart)
* The **setting name** (e.g., SCALE, GRID)
* A **version identifier** that prevents stale settings from older Gantt versions from persisting
This key structure means that your zoom preference on one Gantt page is independent of your zoom preference on another. Each Gantt chart on each page maintains its own set of user preferences.
## The Settings Lifecycle
When a Gantt page loads, the initialization process follows this sequence:
1. **Configuration parameters** are resolved from the server (admin defaults + per-instance values).
2. **User settings** are loaded from localStorage.
3. User settings **override** the configuration defaults where applicable. For example, if the default scale is `W` (Week) but the user previously set it to `M` (Month), the chart loads in Month view.
4. The Gantt renders with the combined configuration.
When the user changes a setting (e.g., switches zoom to Quarter view), the new value is immediately saved to localStorage. On the next page load, the Quarter view is restored.
## Resetting to Defaults
If you want to clear your personal preferences and return to the configured defaults, use the **Reset view** action in the toolbar. This clears all user settings from localStorage for the current Gantt chart, reverting zoom, column widths, column visibility, and grid width to their original state.
**Troubleshooting Unexpected Views**
If your Gantt chart loads with an unexpected zoom level or column layout, it may be because a previously saved user preference is overriding the configured defaults. Use the **Reset view** toolbar action to clear saved preferences and start fresh.
## Browser and Session Scope
Because user settings are stored in **localStorage** (not on the server), they have the following characteristics:
* **Per-browser**: Settings are specific to the browser you are using. If you switch from Chrome to Firefox, your preferences do not follow.
* **Per-device**: Settings do not sync between your desktop and laptop.
* **Persistent**: Settings survive browser restarts and page reloads. They are not cleared when you log out of Polarion.
* **Clearable**: Clearing your browser's site data or localStorage will remove saved Gantt preferences.
**Version-Aware Storage**
The Gantt includes a version identifier in its storage keys. When a new version of the Gantt introduces changes to the settings format, the version is incremented, and any stale settings from the previous version are effectively ignored. This prevents compatibility issues after an upgrade.
## Column Visibility Persistence
The column context menu (accessible by right-clicking any column header) allows you to show or hide individual columns. These visibility choices are persisted in localStorage alongside other user settings. The first column (typically the task title) is always visible and cannot be hidden.
After hiding columns and reloading the page, your hidden columns remain hidden. This persistence applies to both built-in columns and custom columns defined in the configuration.
## Interaction with Configuration Parameters
User settings sit on top of the configuration hierarchy described in [Configuration Layers and Precedence](/gantt/concepts/configuration-hierarchy). The precedence order is:
1. **User settings** (localStorage) -- highest priority for supported settings
2. **Per-instance parameters** -- per-chart configuration
3. **Administration properties** -- system/project defaults
4. **Built-in defaults** -- hardcoded fallbacks
This means a user can always override the zoom level or column layout set by the administrator, but they cannot change features that are not exposed as user settings (such as enabling auto-scheduling or switching the resource load mode).
## Related Pages
* [Configuration Layers and Precedence](/gantt/concepts/configuration-hierarchy) -- the full configuration precedence chain
* [Architecture and Data Flow](/gantt/concepts/architecture) -- how settings flow through the rendering pipeline
# Work Items Gantt vs Plans Gantt
Source: https://learn.nextedy.com/gantt/concepts/work-items-vs-plans-gantt
Nextedy GANTT provides two distinct modes for visualizing project schedules in Polarion: the **Work Items Gantt** and the **Plans Gantt**.
## Two Modes, Two Data Models
The fundamental difference is the data source. The Work Items Gantt reads from Polarion work items directly. The Plans Gantt reads from Polarion Plans (releases, iterations, sprints) and optionally displays work items nested within those plans.
Think of it this way: the Work Items Gantt is like scheduling individual deliverables on a timeline, while the Plans Gantt is like scheduling the containers (milestones, releases, sprints) that group those deliverables.
## Work Items Gantt
The Work Items Gantt widget (`Gantt (Work Items)`) is the primary scheduling tool. It displays Polarion work items as task bars on an interactive timeline with full support for:
* **Field mappings** for start date, end date, duration, and progress via configurable `Start Field`, `End Field`, `Duration Field`, and `Progress Field` parameters
* **Hierarchical display** using `Parent Role` to define which Polarion link roles establish parent-child relationships
* **Dependency links** using `Dependency Role` to define which link roles create scheduling dependencies (the first selected role is used when creating new links by dragging)
* **Baselines** for comparing the current schedule against historical snapshots
* **Resource view** with capacity planning and multiple load calculation modes
* **Working calendars** for calendar-aware scheduling
The data source is a standard Polarion dataset configured via the chart parameters. You define which work items appear using queries, collections, or scope filters.
| Aspect | Work Items Gantt |
| ------------ | --------------------------------- |
| Data source | Polarion work items |
| Hierarchy | Link roles (configurable) |
| Dependencies | Link roles with FS/SS/FF/SF types |
| Date fields | Configurable custom fields |
| Resources | Assignee field or custom field |
| Baselines | Supported |
## Plans Gantt
The Plans Gantt widget (`Gantt (Plans)`) renders Polarion Plans as first-class entities on the Gantt chart. Plans appear as top-level bars, and sub-plans can be loaded to multiple levels using the `Load Children` parameter.
Key characteristics of the Plans Gantt:
* **Plans as bars** -- Each Polarion Plan (release, iteration, sprint) appears as a task bar with its own start and end dates
* **Plan hierarchy** -- Sub-plans appear as children of their parent plan. The `Load Children` parameter controls how many levels deep the hierarchy goes (0 means only top-level plans)
* **Optional work items** -- The `Show Plan Work Item` section enables displaying work items within plans, with separate field mappings for `Start Field`, `End Field`, `Duration Field`, `Progress Field`, `Parent Role`, and `Dependency Role`
* **Show Unplanned** -- Plans without dates can optionally appear at today's date in gray, or be hidden entirely
* **Longer timescales** -- Plans typically use weekly, monthly, or yearly scales rather than the daily scale common in Work Items Gantt
Plans themselves do not support typed dependency links. Only work items displayed within plans can have dependency arrows. Dependency link operations are delegated to the underlying work item relationships.
## When to Use Each Mode
| Use case | Recommended mode |
| ----------------------------- | ---------------- |
| Sprint task scheduling | Work Items Gantt |
| Resource capacity planning | Work Items Gantt |
| Release and iteration roadmap | Plans Gantt |
| Cross-team release planning | Plans Gantt |
| Detailed dependency tracking | Work Items Gantt |
| Portfolio-level overview | Plans Gantt |
The Plans Gantt excels at portfolio planning where you need to see how releases, iterations, and their contained work items fit together over time. A typical hierarchy might look like:
* Release (Plan) > Iteration (Plan) > Work Package (Work Item) > Task (Work Item)
The `Load Children` parameter controls how deep into this hierarchy the Gantt loads. Setting it to 3 loads all four levels in this example.
## Presentation Modes Apply to Both
Both chart modes support [Presentation Modes](/gantt/concepts/presentation-modes) that control how individual work item types are rendered. A work item can appear as a regular task bar (`Item`), a summary bracket (`Derived Schedule`), a diamond milestone (`Milestone`), or be automatically determined based on whether it has children (`Auto-Mode`).
Users sometimes expect the Plans Gantt to display full parent-child work item hierarchies within a plan. Currently, plans can show their direct work items, but nested work item hierarchies under those items have limitations. If you need deep work item hierarchy display, use the Work Items Gantt with appropriate `Parent Role` and `Load Children` configuration.
## Combining Both Views
Many teams use both modes on different Polarion pages. A project manager might use the Plans Gantt for release-level roadmap planning and the Work Items Gantt for detailed sprint scheduling. Since both read from the same Polarion data, changes made in one view are reflected in the other on the next load.
## Related Topics
* [Architecture and Data Flow](/gantt/concepts/architecture) -- How data flows between server and client for both chart modes
* [Data Mapping and Field Resolution](/gantt/concepts/data-mapping) -- How fields are configured differently for each mode
* [Presentation Modes -- Task, Project, and Milestone](/gantt/concepts/presentation-modes) -- Visual display options for work item types
# Working Calendars and Scheduling
Source: https://learn.nextedy.com/gantt/concepts/working-calendars
Nextedy GANTT supports working calendars that define which days and hours count as working time.
## Why Working Calendars Matter
Consider a task estimated at 5 working days starting on a Thursday. Without a working calendar, the Gantt schedules it to end on Monday (5 calendar days later, including the weekend). With a working calendar that defines a standard Monday-Friday work week, the Gantt skips Saturday and Sunday, correctly scheduling the task to end on the following Wednesday.
Working calendars also affect the resource view. When a user is on vacation, their calendar marks those days as non-working, and the resource view reflects zero available capacity for that period. This prevents the Gantt from showing misleading workload data.
## Three-Level Calendar Cascade
The Gantt resolves working calendars through a three-level cascade, where each level adds specificity:
1. **Global calendar** -- The base calendar defining standard working hours for the organization (typically Monday-Friday, 8 hours per day). Enabled via the `Use Working Calendar` (`wCal_GLOBAL`) parameter.
2. **User calendars** -- Per-user overrides loaded from Polarion calendar work items. Each user can have different working days, hours, and exceptions. Enabled via `Load User Calendars` (`wCal_USER`), which depends on `Use Working Calendar` being active.
3. **Team assignments** -- Capacity percentages from team assignment work items that further reduce a user's effective availability. Enabled via `Load Team Assignments` (`wCal_ASSIGNMENTS`), which depends on `Load User Calendars` being active.
These three levels are progressively enabled -- each subsequent level requires the previous one to be active first.
**Progressive parameter disclosure**
In the widget parameter editor, the `Load User Calendars` option only appears after `Use Working Calendar` is enabled. Similarly, `Load Team Assignments` only appears after `Load User Calendars` is enabled. This cascading visibility prevents configuration errors.
## Calendar Work Item Types
Working calendars are defined using four Polarion work item types in a dedicated calendar project:
| Work item type | Purpose | Effect |
| -------------- | ----------------------------------------- | ----------------------------------------------------------------- |
| **Calendar** | Defines regular working hours per weekday | Sets the base schedule (e.g., Mon 08:00-16:00) |
| **Time Off** | Marks date ranges as non-working | Removes days from scheduling (holidays, vacations) |
| **Time On** | Overrides Time Off for specific users | Adds working days back (e.g., user works during a public holiday) |
| **Tweak** | Adjusts working hours for a date range | Changes daily hours without changing working/non-working status |
### Calendar Inheritance
A user calendar can inherit base hours from a global calendar via the `inherits from` work item link role. The user calendar then only needs to specify the days that differ from the global schedule. For example, if the global calendar defines 8-hour workdays Monday through Friday, a user calendar that inherits from it only needs to specify that Wednesdays are off for that user.
The resolution order for each day is: base (inherited) calendar > regular weekday hours > tweaks > exceptions (Time Off / Time On). This means Time On overrides Time Off, and tweaks adjust hours within an already-working day.
### Weekday Hour Format
Each calendar work item has seven weekday fields (Monday through Sunday). The format is `HH:mm,HH:mm` to specify work start and end times. Use `-` to mark a day as explicitly non-working. Leave the field empty to inherit from the parent calendar.
## Connecting Calendars to Projects
Working calendars live in a dedicated Polarion project. To connect this calendar project to a scheduling project, two administration properties must be set:
* `nextedy.gantt.workitemCalendar.projectId` -- The project ID of the calendar project
* `nextedy.gantt.workitemCalendar.globalID` -- The work item ID of the calendar that serves as the global (company-wide) calendar
**Both projects need the configuration**
These properties must be set in both the calendar project and every project that uses the calendar. Missing this configuration is a common setup issue.
## Calendar Caching and Performance
The `Previous Years to Load` and `Next Years to Load` parameters control how many years of calendar data are pre-computed. More years means more working-day data is available for long-range views, but at the cost of increased startup time and memory usage. For most use cases, 1-2 years in each direction is sufficient.
The `Cache Working Calendars` (`UseCache`) parameter enables server-side caching of computed calendar data. When enabled, repeated Gantt loads reuse cached data instead of recomputing calendars from work items. After making changes to calendar work items, the cache must be cleared using the **Clear Calendar Cache** toolbar button or the `api/clearCalendarCache` endpoint.
**Calendar holder**
The administration property `nextedy.gantt.calendarHolder` specifies a Polarion user ID whose calendar work item is used as the global working calendar. This is an alternative to `workitemCalendar.globalID` for organization-wide calendar configuration.
## How Calendars Affect the Gantt
When calendars are enabled, several Gantt behaviors change:
* **Duration calculations** skip non-working days -- a 5-day task avoids weekends and holidays
* **Off-day cell highlighting** marks non-working days with a visual background in the timeline
* **Resource view cells** show grey for unavailable days
* **Auto-scheduling** respects calendar boundaries when propagating dates
* **Resource load calculations** use actual available hours per user instead of a flat 8 hours
Users without a Polarion calendar get a zero-capacity calendar, showing no available hours in workload calculations. Ensure every resource in the Gantt has either a personal calendar or inherits from the global calendar.
## Related Topics
* [Resource Load Calculation Modes](/gantt/concepts/resource-load-modes) -- How calendars influence workload calculations
* [Capacity Modifiers and Team Capacity](/gantt/concepts/capacity-modifiers) -- How team assignments layer on top of calendars
* [Auto-Scheduling and Dependency Propagation](/gantt/concepts/auto-scheduling) -- How calendars affect dependency-driven scheduling
# FAQ
Source: https://learn.nextedy.com/gantt/faq/index
Find answers to common questions about Nextedy GANTT organized by topic.
Gantt is a Gantt chart app for Siemens Polarion ALM that provides interactive project scheduling, resource management, dependency tracking, and visual timeline planning. It embeds directly into Polarion LiveDoc and Wiki pages as a configurable widget, enabling teams to plan and track work items on a visual timeline without leaving the ALM environment.
Gantt delivers standard Polarion widgets, so every Polarion user can access the Gantt widgets. Any Polarion user with the license and permission to edit work items (or Plans) can edit tasks using the Gantt widget. Any Polarion user who can create a LiveDoc report page can configure and set up the Gantt widgets. See [Licensing and User Access](/gantt/getting-started/licensing) for setup details.
Yes, the evaluation period is limited to 30 days from the date of installation. If you need more time, contact Nextedy to request an extended time-limited license. Upon expiration, the software automatically disables itself, and you must obtain a license certificate for continued use.
**Need more evaluation time?**
Reach out to Nextedy support before your 30-day evaluation expires to request an extension.
No, currently only one Gantt widget is supported per report page. If you need to display multiple views, create separate Polarion pages for each Gantt widget instance.
Work Items Gantt displays individual Polarion work items as task bars on the Gantt chart, allowing you to schedule, link, and track individual tasks. Plans Gantt displays Polarion Plans as containers, enabling cross-team and release planning views. See [Set Up a Basic Gantt Chart](/gantt/getting-started/setup-basic-gantt) and [Set Up a Plans Gantt Chart](/gantt/getting-started/setup-plans-gantt) for setup instructions.
The table below summarizes the main feature areas available in Gantt:
| Feature Area | Description |
| ------------- | ------------------------------------------------------------------ |
| Scheduling | Auto-scheduling, dependency links, critical path analysis |
| Resources | Resource view, capacity planning, load modes, working calendars |
| Visualization | Baselines, configurable columns, timescales, export to PNG |
| Editing | Lightbox inline editor, drag-and-resize task bars, undo/redo |
| Scripting | Item scripts and page scripts for custom colors, markers, behavior |
| Plans | Plans Gantt mode for plan-level scheduling and cross-team views |
For detailed guidance on each area, browse the [Guides](/gantt/guides/index) and [Concepts](/gantt/concepts/index) sections.
Start by installing Gantt following the [Install Gantt](/gantt/getting-started/installation) tutorial, then explore the [demo project](/gantt/getting-started/demo-project) to see a working Gantt chart with pre-configured tasks, dependency links, and resources. The [Getting Started](/gantt/getting-started/index) section walks you through setup step by step.
The [Reference](/gantt/reference/index) section contains complete documentation of all widget parameters, administration properties, and configuration options. For task-oriented walkthroughs, visit the [Guides](/gantt/guides/index) section.
Auto-scheduling automatically updates the start date of dependent tasks based on the end dates of their predecessors. When you move a task or modify a dependency link, all connected successor tasks are rescheduled to satisfy the dependency constraints. You can toggle auto-scheduling on and off using the toolbar button. To set the default state, configure the `nextedy.gantt.default.auto_scheduling` project-level property. See [Create Your First Dependency Link](/gantt/getting-started/first-dependency) for a practical walkthrough.
Yes, you can use a combination of techniques to control scheduling at different levels. Set top-level items to `readonly` mode to prevent auto-scheduling from moving them, while allowing child tasks to reschedule automatically. You can also use the `enforceAutoMode` and `blockAutoMode` task-level flags to override the global auto-scheduling setting on individual tasks.
**Hierarchical scheduling strategy**
For waterfall projects, pin milestone and top-level items using `blockAutoMode`, then let auto-scheduling handle lower-level task dependencies.
Gantt uses a last-save-wins approach for concurrent editing. There is no built-in real-time conflict detection between simultaneous users. When two users edit the same task, the most recently saved version takes effect. Plan your editing workflows to minimize overlapping changes on the same work items.
**Concurrent editing**
Coordinate with your team to avoid editing the same tasks simultaneously. The last save always overwrites previous changes.
Dependency links define finish-to-start relationships between tasks. When auto-scheduling is enabled, moving a predecessor task automatically pushes its successors forward. If a successor's start date is planned before its predecessor finishes, the Gantt chart highlights the conflict visually. You configure dependency link roles using the `dependsRoles` widget parameter.
Critical path analysis highlights the longest chain of dependent tasks in your project. Tasks on the critical path are visually marked in the Gantt chart so you can identify which tasks directly affect the project end date. Toggle critical path highlighting using the toolbar button. Critical path requires dependency links to be defined between tasks.
Yes, dependency links support lag time. Lag allows you to introduce a delay between the end of a predecessor task and the start of its successor. This is useful for modeling real-world delays such as review periods or material procurement lead times.
**Verify in application**
Configure lag values when creating or editing dependency links in the Gantt chart.
Hour-precision scheduling switches the Gantt from day-level to hour-and-minute-level task planning. When enabled via the `highPrecision` configuration, task start and end times include specific hours, enabling sub-day scheduling. This mode is required for accurate resource load calculations at hourly granularity. Note that date display in columns automatically adjusts when high-precision mode is active.
The following table summarizes the key scheduling features and their configuration:
| Feature | Configuration | Description |
| --------------------- | --------------------------------------- | ------------------------------------------ |
| Auto-scheduling | `nextedy.gantt.default.auto_scheduling` | Dependency-driven date recalculation |
| Critical path | Toolbar toggle | Highlights longest dependency chain |
| Hour precision | `highPrecision` widget parameter | Sub-day scheduling with hours/minutes |
| Dependency links | `dependsRoles` widget parameter | Finish-to-start task relationships |
| Block auto-schedule | `blockAutoMode` per task | Pins individual tasks against auto changes |
| Enforce auto-schedule | `enforceAutoMode` per task | Forces auto-scheduling on individual tasks |
The Gantt chart does not support manual drag-and-drop task reordering. Instead, use the sort-by-field functionality to order tasks by any configured column such as start date, priority, or work item ID. Configure the sort behavior through the widget parameters.
**Verify in application**
Task sorting is controlled through widget parameter configuration. Check the reference documentation for available sort options.
Enable the resource view by setting the `showResourceView` widget parameter to `true`. This displays a resource allocation panel below the Gantt chart, showing per-resource workload markers across the project timeline. See [View Resource Allocation](/gantt/getting-started/first-resource-view) for a step-by-step setup guide.
The Gantt resource view supports four load calculation modes controlled by the `resourceLoadMode` configuration property:
| Mode | Value | Description |
| --------------------- | ------------ | ------------------------------------------------------------ |
| Task count | `num` | Shows the number of tasks assigned per resource per day |
| Allocated hours | `time` | Shows total allocated working hours per resource per day |
| Remaining hours | `remaining` | Shows remaining available capacity (total minus allocated) |
| Allocation percentage | `allocation` | Shows utilization as a percentage, color-coded by load level |
Use `allocation` mode to quickly identify overloaded resources. Cells turn red when a resource is allocated beyond their available capacity.
Resource allocation markers use configurable color thresholds defined by the `resourceMarkersColorConfig` property. This configuration includes an `ok` color for within-capacity states and an `over` color for overallocated states. When using allocation mode, cells are color-coded based on whether the resource's utilization exceeds their available working hours.
Yes, use the resource hiding toggle in the toolbar to hide resources with no visible tasks in the current view. This reduces visual clutter when working with large resource pools. The toggle dynamically re-evaluates which resources have active tasks and shows or hides them accordingly.
The Gantt chart uses working calendars to determine available working hours per resource per day. Each resource can have a per-user working calendar assigned via a `calendar` work item type in Polarion. The calendar defines regular weekly hours per weekday in `HH:mm,HH:mm` format, with `-` marking non-working days. Calendars support inheritance, so a child calendar inherits base hours from a parent and can override specific days.
Working hours for a specific date are resolved in this order: base calendar, then regular weekday hours, then schedule tweaks, then exceptions (time off / time on).
Yes, working calendars support three types of exceptions linked via the `affects` link role:
* **Time off** -- marks specific dates as non-working (holidays, PTO)
* **Time on** -- marks specific dates as working days (overriding regular non-working days)
* **Schedule tweak** -- adjusts working hours for a date range without changing the working/non-working status, using `workstart` and `workend` fields
Exception work items must be linked to the calendar via the `affects` link role for the system to recognize them.
Configure the `nextedy.gantt.calendarHolder` server property with a Polarion user ID. The system uses the `calendar` work item assigned to that user as the global working calendar. This is useful for establishing organization-wide working hours without assigning calendars to each individual user.
Ensure the calendar work item has a valid `From` and `To` date range that covers your project's scheduling period.
Yes, the Gantt supports team-based assignment mode via the `teamAssignments` configuration property. When enabled, the lightbox shows a team picker instead of a user picker for resource assignment. Related properties include `teamCustomField`, `teamAssignmentStartField`, `teamAssignmentEndField`, and `teamAssignmentCapacityField` for defining the team assignment data model.
The Gantt evaluation period is limited to 30 days from the date of installation. If you need additional time for evaluation, contact Nextedy support to request an extended time-limited license. Upon expiration, the software automatically disables itself until you obtain a valid license certificate.
**Evaluation expiry**
The Gantt widget will stop functioning after the 30-day evaluation period. Plan your evaluation timeline accordingly and reach out for an extension before it expires.
Yes, trial licenses can be extended beyond the initial 30-day period. Contact Nextedy support to request a continuation of your evaluation. This is useful when your team needs more time to complete the evaluation process or when procurement timelines are longer than expected.
Gantt uses a subscription-based licensing model for new licenses. Perpetual licenses are available only as upgrades for existing customers. Edit access is controlled by the `nextedy_gantt_users` group -- members are Editors, everyone else has read-only Reviewer access (see [Licensing and User Access](/gantt/getting-started/licensing)).
For the technical license-file types (Primary/Secondary Evaluation, Perpetual, Test) and their expiry behavior, see [License Types and Evaluation Periods](/gantt/reference/license-types).
Yes, licenses can be used on both nodes of a multi-node Polarion deployment. There is no restriction on deploying your Gantt license across clustered or high-availability Polarion server configurations.
When the Gantt license is invalid or expired, a license status panel appears at the top of the Gantt widget with an appropriate message and contact information. The panel displays one of three states: valid (`ok`), approaching expiry (`warning`), or expired (`expired`). The license status is checked once at startup when the widget loads.
An expired license prevents the Gantt widget from functioning entirely, displaying a license panel with contact information. Expired maintenance means your license is still active, but you are no longer entitled to software updates or new feature releases. You can continue using the currently installed version, but you cannot upgrade to newer versions until maintenance is renewed.
You can access the Gantt administration settings by clicking the gear icon in the Gantt widget footer. This opens the administration page where you can view and manage license configuration. The Gantt version number is also displayed in the widget footer for reference.
For complete licensing setup instructions, see [Licensing and User Access](/gantt/getting-started/licensing).
**Verify in application**
This page covers the scripting API at a high level. Verify specific script syntax and available variables in the Gantt application and [Reference](/gantt/reference/index) documentation.
Gantt supports two types of scripts: **item scripts** and **page scripts**. Item scripts run against individual tasks and can modify their appearance, such as changing task bar colors or adding markers. Page scripts run once when the Gantt chart loads and can modify global behavior, configuration, and register custom editors or markers.
Item scripts allow you to customize individual task bars based on work item properties. Common use cases include applying conditional color coding based on status or priority, adding visual markers to specific tasks, and modifying task labels. Item scripts execute on the server side with access to the task data and Polarion work item fields.
Page scripts run at page load time and provide access to the Gantt configuration, editor registry, and marker utilities. You can use page scripts to register custom column editors, add timeline markers (such as milestone dates or sprint boundaries), and modify configuration values before the Gantt chart initializes.
| Script Type | Runs | Scope | Common Use Cases |
| ----------- | ------------ | ------------------- | -------------------------------------------------- |
| Item script | Per task | Individual task bar | Color coding, markers, label customization |
| Page script | Once at load | Entire Gantt chart | Custom editors, timeline markers, config overrides |
Page scripts can add custom vertical line markers to the Gantt timeline using the marker utilities exposed through the scripting API. Markers are commonly used to indicate today's date, milestone deadlines, sprint boundaries, or plan due dates. The "Today" marker is built in and displayed by default.
**Verify in application**
Check the scripting reference for the exact API to add custom markers, including available styling options.
Yes, item scripts are the primary mechanism for applying conditional task bar colors. You can write logic that reads work item fields (such as status, priority, or a custom field) and returns a CSS color value to apply to the task bar. This lets you visually distinguish different categories of work items on the Gantt chart.
Yes, page scripts can register custom inline column editors through the editor registry. These custom editors appear in the Gantt grid columns and allow users to edit task fields using specialized input controls beyond the default text and date editors.
**Verify in application**
Custom editor registration must occur before the Gantt chart initializes. Refer to the scripting reference for the editor registration API.
For more on Gantt capabilities, see the [Concepts](/gantt/concepts/index) and [Guides](/gantt/guides/index) sections.
**Verify in application**
This page provides an overview of configuration concepts. Refer to the [Reference](/gantt/reference/index) section for complete property documentation.
Gantt uses two levels of configuration. **Widget parameters** are set per-widget instance on the Polarion page and control the behavior of that specific Gantt chart. **Administration properties** are set globally in the Polarion administration panel and apply to all Gantt widgets across the project or server. Widget parameters take precedence over administration properties when both define the same setting.
| Configuration Level | Scope | Set Where | Example |
| ----------------------- | ---------------------- | ----------------------------- | --------------------------------------- |
| Widget parameter | Per widget instance | Polarion page widget editor | `showResourceView`, `readonly` |
| Administration property | Project or server-wide | Polarion Administration panel | `nextedy.gantt.default.auto_scheduling` |
Field mappings tell the Gantt which Polarion work item fields to use for task start dates, end dates, duration, and progress. You need at least two of the three date fields configured: `startField` + `endField`, `startField` + `durationField`, or `endField` + `durationField`. The Gantt validates these mappings at render time and displays an error message if the combination is invalid.
**Required field mappings**
You must configure at least two of `startField`, `endField`, and `durationField`. The Gantt widget will not render without a valid field mapping combination.
Set the **Dependency Role** parameter (`dependsRoles`) to specify which Polarion link role IDs represent finish-to-start dependencies between tasks. Work items connected with these link roles appear as dependency arrows in the Gantt chart. Similarly, use **Parent Role** (`parentRoles`) to define which link roles represent parent-child hierarchical relationships displayed in the Gantt tree structure.
The work items shown in the Gantt are selected by the **Work Items** dataset parameter (query, collection, or scope) -- there is no dedicated work item type parameter. Restrict the displayed type by writing the query accordingly, for example `type:workpackage`. See [Work Items Gantt Widget Parameters](/gantt/reference/widget-parameters/work-items-gantt) for the dataset parameter. To control how each work item type renders (as a task bar, summary, or milestone), set the **Gantt Presentation Mode** per type in the **Work Item Types Configuration**.
**Verify in application**
The exact work item type IDs available depend on your Polarion project configuration. Check your project's work item type definitions.
Yes, enable the **Read-only** parameter (`readonly`) to disable all editing capabilities. This hides the Edit button and prevents drag, resize, and add-task operations. Conversely, enable always-edit mode (`alwaysedit`) if you want the Gantt to always be in edit mode without requiring users to click an Edit button first.
The **Resource Field** parameter (`resourceField`) specifies which Polarion work item field is used as the assigned resource. This drives both the resource view display and the resource filter functionality. The field can be set to the assignee field, a category field, or a custom field depending on your resource management model.
For full setup instructions, see [Set Up a Basic Gantt Chart](/gantt/getting-started/setup-basic-gantt) and the [Reference](/gantt/reference/index) documentation.
**Verify in application**
This page covers editing workflows at a high level. Consult the [Guides](/gantt/guides/index) section for detailed how-to instructions.
Click the **Edit** button in the Gantt toolbar to enter edit mode. Once in edit mode, you can drag task bars to change dates, resize them to adjust duration, and create dependency links between tasks. All changes are tracked as pending until you explicitly save. If `alwaysedit` is enabled via widget parameters, the Gantt is always in edit mode and no Edit button is shown.
Click the **Save** button in the toolbar to persist all pending changes to Polarion. The save operation sends all modified tasks and dependency links to the server in a single transaction. A progress indicator appears during the save process. If there are no unsaved changes, the save button has no effect.
| Action | How | Notes |
| --------------- | ----------------------------------- | ----------------------------------------- |
| Enter edit mode | Click **Edit** in toolbar | Not needed if `alwaysedit` is `true` |
| Move a task | Drag the task bar horizontally | Changes start and end dates |
| Resize a task | Drag the right edge of the task bar | Changes duration or end date |
| Save changes | Click **Save** in toolbar | Persists all pending edits to Polarion |
| Undo changes | Use undo in the toolbar | Multi-step undo of date changes and moves |
The lightbox is an inline editing dialog that opens when you double-click a task bar or click the edit icon on a task. It provides form fields for editing task properties such as dates, duration, progress, assigned resources, and custom fields. Changes made in the lightbox are applied to the task when you confirm and are included in the next save operation.
Yes, Gantt supports multi-step undo and redo for task date changes, moves, and resizes. Use the undo/redo controls to step back through your editing history before saving. Once you save, changes are committed to Polarion and can no longer be undone through the Gantt undo feature.
**Undo before saving**
Always review your changes before clicking Save. Undo is only available for unsaved edits made in the current editing session.
Gantt uses a last-save-wins approach. There is no real-time conflict detection between concurrent editors. If two users modify the same task, the version saved last overwrites previous changes. Coordinate with your team to avoid editing the same work items at the same time.
**No concurrent edit detection**
Plan your editing workflows to minimize overlap. The most recently saved version always takes effect.
Yes, set the `readonly` widget parameter to `true` to make the entire Gantt chart read-only. For more granular control, individual tasks can be set to read-only mode, which prevents drag, resize, and edit operations on those specific tasks while keeping the rest of the chart editable.
**Verify in application**
Per-task read-only control may be configured through item scripts or task properties. Check the reference documentation for available options.
Yes, when the `maximize` widget parameter is set to `true`, a fullscreen toggle button appears in the toolbar. Clicking it expands the Gantt chart to fill the browser window, providing more screen space for viewing and editing large project schedules.
For editing setup details, see [Set Up a Basic Gantt Chart](/gantt/getting-started/setup-basic-gantt).
**Verify in application**
This page covers visualization features at a high level. Refer to the [Reference](/gantt/reference/index) section for detailed property documentation.
Gantt supports baselines for comparing your current schedule against a saved snapshot. The Compare with History feature allows you to select a historical date, a named baseline, or a specific revision number. When active, baseline bars appear below the actual task bars, showing the originally planned start and end dates alongside the current dates.
Yes, Gantt provides an export-to-PNG feature accessible from the toolbar. The export panel renders the Gantt chart as an image and provides download and print buttons. You can apply date filtering to control which portion of the schedule is included in the export.
**PDF export not supported**
The Gantt widget cannot be exported to PDF format. Use the PNG export feature for sharing static schedule snapshots.
Task bar colors can be set in two ways. Each work item type has a default color that is automatically applied to its task bars. For more dynamic control, use item scripts to apply conditional color logic based on work item fields such as status, priority, or custom attributes. See [Scripting Questions](/gantt/faq/scripting) for more on item scripts.
| Method | Scope | Configuration |
| ---------------------------- | -------------------------- | --------------------------------------------- |
| Work item type default color | All tasks of a type | Polarion work item type settings |
| Item script color logic | Per task, conditional | Custom item script with color return value |
| `color` / `taskColor` field | Per task, from field value | Map a custom field to the task color property |
The Gantt grid supports configurable columns with multiple template types including start date, end date, deadline, owner/assignees, duration, progress, and custom columns. The assignee column supports two display modes: `initials` (showing user initials in circles) and `fullname` (showing full names). A special workload column appears when you select a resource in the resource view.
Click the hamburger menu icon in the first column header of the Gantt grid. This opens a menu with options for column visibility, timescale selection, and navigation settings. You can show or hide columns and adjust the timescale granularity from this menu.
Yes, set the `hideToolbar` widget parameter to `true` to hide the entire toolbar. When the toolbar is hidden and you are in edit mode, a floating save button appears as a fallback so you can still save your changes.
**Verify in application**
When using `hideToolbar`, ensure users have an alternative way to access essential functions like save and refresh.
Set the `onlyLeafTasks` widget parameter to `true` to display only leaf-level tasks (tasks with no children). Parent summary tasks are hidden from the Gantt chart, giving you a flat view of all actionable work items without the hierarchical grouping.
The Gantt chart uses several visual indicators to communicate task status at a glance:
* **Progress fill** -- the filled portion of each task bar shows completion percentage
* **Overdue deadlines** -- deadline column values turn red when the task is past due
* **Risk indicator** -- tasks at risk (past end date) are highlighted with a warning color
* **Conflict markers** -- tasks with parent-child date range conflicts display a visual conflict indicator
* **Unplanned indicator** -- tasks with no scheduled dates appear with a special unplanned marker
For additional display customization, explore the [Guides](/gantt/guides/index) section.
**How widget parameters are named**
These FAQs refer to widget parameters by their internal identifier (for example `readonly`, `showResourceView`, `dependsRoles`). In the Polarion page **widget editor** you set them through their Title Case labels -- `readonly` appears as **Read-only**, `showResourceView` as **Show Resource View**, `dependsRoles` as **Dependency Role**, and so on. See [Work Items Gantt Widget Parameters](/gantt/reference/widget-parameters/work-items-gantt) and [Data Mapping Parameters](/gantt/reference/widget-parameters/data-mapping) for the full label-to-identifier reference.
**Can't find your answer?**
Check the [Reference](/gantt/reference/index) section for detailed property documentation, or browse the [Guides](/gantt/guides/index) for step-by-step instructions. For additional support, [submit a support ticket](https://support.nextedy.com/support/tickets/new).
# Explore the Demo Project
Source: https://learn.nextedy.com/gantt/getting-started/demo-project
This tutorial walks you through installing and exploring the Nextedy GANTT demo project.
## What You Will Achieve
After completing this tutorial, you will have:
* A demo Polarion project created from the Gantt Demo template
* A pre-configured Gantt chart with sample tasks, hierarchy, and dependencies
* Hands-on experience navigating the Gantt chart interface
## Prerequisites
* [Gantt installed](/gantt/getting-started/installation) on your Polarion server
* Polarion administrator access (required to create projects from templates)
1. Log in to Polarion as an administrator
2. Navigate to **Polarion Administration** (click the gear icon in the top navigation)
3. In the left sidebar, select **Nextedy GANTT > Setup**
You should see the Setup page, which confirms Gantt is installed, shows the installed and latest version, and provides **Download Page** and **Changelog** buttons plus on-screen instructions for creating the demo project.
1. On the Setup page, follow the on-screen instructions to create a new project
2. On the second page of the wizard, select the **Nextedy GANTT Demo** template from the project template list
3. Enter a project name and complete the project creation wizard
**Template Auto-Installation**
The Nextedy GANTT Demo template is automatically registered in Polarion when Gantt is installed. If you do not see the template in the project creation wizard, verify that Gantt is properly installed by checking the [installation steps](/gantt/getting-started/installation).
You should see a new project in your Polarion project list.
1. Open the newly created demo project
2. In the left navigator, select **Gantt** (the demo's pre-configured Gantt page; it also appears under **Documents & Pages**)
You should see a fully populated Gantt chart with:
* Sample work items displayed as task bars on the timeline
* Parent-child hierarchy showing grouped items
* Dependency links drawn as arrows between related tasks
* A toolbar with zoom controls, edit toggle, and action buttons
Take a few minutes to familiarize yourself with the key elements of the Gantt chart:
| Element | Description |
| --------------------- | ------------------------------------------------------------------- |
| **Task bars** | Horizontal bars representing work items, positioned on the timeline |
| **Grid columns** | Left-side table showing work item details (ID, title, dates) |
| **Dependency arrows** | Lines connecting dependent tasks |
| **Today marker** | Vertical red line indicating the current date |
| **Toolbar** | Top bar with zoom, edit, save, and filter controls |
| **Footer** | Bottom bar showing item count and version |
Try these interactions:
1. **Zoom in/out** using the toolbar zoom buttons or the hamburger menu > Set Scale
2. **Scroll the timeline** by clicking and dragging the timeline background
3. **Click a task bar** to see work item details in the sidebar
4. **Expand/collapse** parent items by clicking the triangle icon next to their name
**Edit Mode**
Click the **Edit** button in the toolbar to enter edit mode. In edit mode, you can drag task bars to reschedule, resize them to change duration, and create new dependency links by dragging between task connection points.
To understand how the demo Gantt is configured:
1. Enter page edit mode (click **Edit** on the Polarion page)
2. Click the widget **gear icon** to open the widget parameters
3. Review the configured settings: Query, Type, Parent Role, Dependency Role, and Load Children
This gives you a reference configuration you can replicate in your own projects.
## What the Demo Includes
The demo project template pre-populates your project with:
* **Sample work items** of various types (epics, user stories, tasks) with dates and assignments
* **Dependency links** between work items showing finish-to-start relationships
* **A pre-configured Gantt wiki page** with the Work Items Gantt widget already set up
* **Parent-child relationships** demonstrating hierarchical display
**Verify in application**
The exact contents of the demo project may vary by Gantt version. Explore the project's work items and plans to see all available sample data.
## Next Steps
* [Set Up a Basic Gantt Chart](/gantt/getting-started/setup-basic-gantt) -- create your own Gantt widget in an existing project
* [Set Up a Plans Gantt Chart](/gantt/getting-started/setup-plans-gantt) -- configure the Plans Gantt for release-level planning
* [Create Your First Dependency Link](/gantt/getting-started/first-dependency) -- learn to create dependencies interactively
* [Licensing and User Access](/gantt/getting-started/licensing) -- configure user access and manage licenses
# Create Your First Dependency Link
Source: https://learn.nextedy.com/gantt/getting-started/first-dependency
This tutorial shows you how to create dependency links between tasks in your Nextedy GANTT chart.
## What You Will Achieve
After completing this tutorial, you will have:
* A configured dependency role in your Gantt widget
* A dependency link created between two tasks using the graphical link builder
* An understanding of link direction and the four dependency types
## Prerequisites
* [Gantt installed](/gantt/getting-started/installation) on your Polarion server
* A working Gantt chart with at least two work items (see [Set Up a Basic Gantt Chart](/gantt/getting-started/setup-basic-gantt))
* Edit permissions on the Gantt page
Before you can create dependency links, you need to tell the Gantt chart which Polarion link role represents a dependency relationship.
1. Enter page edit mode by clicking **Edit** on the Polarion page
2. Open the widget parameters by clicking the widget gear icon
3. Find the **Dependency Role** parameter under **Work Items**
4. Click **Select** and add `depends_on` (or your project's dependency link role) from the left list to the right
5. Click **OK**, then **Apply**
You should see the Gantt chart reload. If any work items already have dependency links in Polarion, arrows now appear between them.
**Multiple Dependency Roles**
You can select multiple link roles. If you select more than one, the first role in the list is used when creating new dependency links via the graphical builder.
1. Click the **Edit** button in the Gantt toolbar
You should see the toolbar change to show the save and cancel buttons, and task bars become interactive (draggable, resizable).
1. Hover over the source task bar (the predecessor task). You should see small circles appear on the left and right edges of the task bar.
2. Click and drag from the **right circle** of the source task
3. Drop onto the **left circle** of the target task (the successor task)
An arrow now appears connecting the two tasks, flowing from the predecessor to the successor. This creates a **finish-to-start** dependency link, meaning the target task cannot start until the source task finishes.
Click the **Save** button in the Gantt toolbar to persist the dependency link to Polarion.
After saving, the dependency link is stored as a Polarion work item link using the configured dependency role.
## Understanding Link Direction
Polarion's default `depends_on` link role points from a dependent item to its source (the opposite direction from standard Gantt convention). The Gantt chart automatically reverses the arrow direction so that dependency arrows flow correctly from predecessor to successor.
If your project uses a different link role where the source already points to the dependent item, you can configure this using the `nextedy.gantt.workitems.default.forward_dependency` administration property.
## Dependency Types
The Gantt chart supports four standard dependency types:
| Type | Code | Description |
| ------------------------- | ---- | ---------------------------------------------------- |
| **Finish-to-Start (FS)** | `0` | Target cannot start before source finishes (default) |
| **Start-to-Start (SS)** | `1` | Target cannot start before source starts |
| **Finish-to-Finish (FF)** | `2` | Target cannot finish before source finishes |
| **Start-to-Finish (SF)** | `3` | Target cannot finish before source starts |
**Enabling Advanced Dependency Types**
By default, only finish-to-start dependencies are available. To enable all four types, set the following administration property:
```
nextedy.gantt.default.advanced_dependencies=true
```
This property is set in **Project / Repository Administration > Configuration Properties**. Advanced dependency types (SS, FF, SF) require Gantt version **4.4.0** or later. See the [Dependency Types Reference](/gantt/reference/dependency-types) for full details.
## Dependency Constraint Violations
When auto-scheduling is enabled and a dependency constraint is violated (for example, a successor task starts before its predecessor finishes), the Gantt chart displays a **red dotted line** beneath the offending task. To resolve the violation, move the task to satisfy the dependency rules.
**Hidden Dependencies**
If a dependency link connects to a task that is hidden from the current Gantt view (due to filtering or max items), the dependency is ignored by the Gantt as if it does not exist. The task with the missing dependency continues to function normally, with a tooltip indicating the missing connection.
## Disabling Dependency Link Creation
If you want to display existing dependency links but prevent users from creating new ones, add the following to your widget's **Gantt Config Script** parameter:
```javascript theme={null}
gantt.config.drag_links = false;
```
## Next Steps
* [View Resource Allocation](/gantt/getting-started/first-resource-view) -- enable the resource view to monitor team workload
* [Set Up a Plans Gantt Chart](/gantt/getting-started/setup-plans-gantt) -- configure Plans Gantt for release planning
* Explore [Guides](/gantt/guides/index) for advanced dependency configuration, lag time, and auto-scheduling
# View Resource Allocation
Source: https://learn.nextedy.com/gantt/getting-started/first-resource-view
This tutorial walks you through enabling and exploring the resource view in your Nextedy GANTT chart.
## What You Will Achieve
After completing this tutorial, you will have:
* The resource view enabled below your Gantt chart
* Resource allocation markers displaying workload per team member
* An understanding of load calculation modes and overallocation indicators
## Prerequisites
* [Gantt installed](/gantt/getting-started/installation) on your Polarion server
* A working Gantt chart with work items assigned to users (see [Set Up a Basic Gantt Chart](/gantt/getting-started/setup-basic-gantt))
* Edit permissions on the Gantt page
1. Enter page edit mode by clicking **Edit** on the Polarion page
2. Open the widget parameters by clicking the widget gear icon
3. Scroll to the **Resource View** section
4. Set **Show Resource View** to **Yes**
Additional parameters appear after enabling the resource view:
| Parameter | Purpose | Default |
| ----------------------------- | --------------------------------------------------- | ---------------- |
| **Items per resource** | Over-allocation threshold for leaf items count mode | 1 |
| **View Height** | Default height of the resource panel in pixels | 250 |
| **Resource Field** | Which work item field identifies the resource | `assignee` |
| **Resource Label** | Column header text for resources | Name |
| **Show Unassigned** | Display a row for unassigned work items | No |
| **Resource Load Calculation** | How workload is computed | Leaf Items Count |
5. Click **Apply**
You should see a new panel appear below the Gantt chart showing one row per resource (team member), with colored markers indicating workload for each time period.
The resource view displays:
* **Resource rows**: one row per team member (or per value of the configured resource field)
* **Item count**: the number of work items assigned to each resource
* **Workload cells**: colored cells aligned with the timeline, showing allocation per time period
* **Color indicators**: green cells indicate allocation within capacity, red cells indicate overallocation
**Adjustable Height**
You can resize the resource view by dragging the horizontal divider line between the Gantt chart and the resource panel. The **View Height** parameter sets the initial height.
The resource view supports four load calculation modes, each suited to different planning needs:
### Leaf Items Count
Counts how many leaf-level work items (items with no children) are assigned to each resource per time period. Each item counts as one unit regardless of estimated effort. The cell turns red when the count exceeds the **Items per resource** threshold.
### Estimate + Spent
Sums the remaining estimate and time already spent on each item. This total effort is distributed evenly across the task's scheduled days, providing a comprehensive workload view that accounts for both completed and pending work.
### Remaining Estimate
Shows only the remaining effort required to complete each task. Past effort (time already spent) is excluded. Effort is distributed from today forward across the remaining scheduled days. This mode is useful for forecasting future workload.
### Assignment Allocation
Uses team-based assignment percentages to calculate workload. Each team member's allocation across teams and projects is summed. When total allocation exceeds 100%, the cell turns red to indicate overallocation. This mode requires team assignment configuration.
**Choosing the Right Mode**
For simple task tracking, **Leaf Items Count** is the easiest starting point. For effort-based planning with time tracking, use **Estimate + Spent** or **Remaining Estimate**. For team capacity management, use **Assignment Allocation**.
By default, the resource view uses the `assignee` field to identify resources. You can change this to any custom field:
1. In the widget parameters, find **Resource Field**
2. Change it to a different field (for example, a custom team field or enum field)
3. Click **Apply**
The resource view reloads, showing rows based on the selected field's values instead of assignees.
To see work items that have no resource assigned:
1. In the widget parameters, set **Show Unassigned** to **Yes**
2. Click **Apply**
A new row labeled "Unassigned" appears in the resource view, collecting all work items with no value in the resource field. This helps you spot unallocated work during planning.
Click **Apply** to confirm the widget parameters, then save the Polarion page.
## Reading the Resource View
| Visual Indicator | Meaning |
| ---------------- | -------------------------------------------------------------- |
| Green cell | Allocation within capacity |
| Red cell | Overallocation detected |
| Number in cell | Workload value (items, hours, or percentage depending on mode) |
| Tooltip on hover | Details about which work items contribute to the load |
Work items that are filtered out of the Gantt view may still affect resource calculations depending on configuration. If a parent work item has no visible children due to filtering, it may be counted as a leaf item in load calculations.
## Next Steps
* [Licensing and User Access](/gantt/getting-started/licensing) -- configure user groups for edit access
* [Update to the Latest Version](/gantt/getting-started/update-gantt) -- keep your Gantt installation current
* Explore [Guides](/gantt/guides/index) for advanced resource configuration, cross-team setup, and resource hiding
# Getting Started
Source: https://learn.nextedy.com/gantt/getting-started/index
Welcome to the Nextedy GANTT getting started tutorials. These step-by-step guides walk you through installation, initial configuration, and key features so you can be productive with the Gantt chart in Polarion.
Download, deploy, and verify Gantt on your Polarion ALM server.
Create a Work Items Gantt widget with hierarchy, queries, and field mappings.
Display Polarion Plans as Gantt bars with work items nested underneath.
Install the pre-configured demo project to see a working Gantt chart immediately.
Connect tasks with dependency arrows and configure dependency roles.
Enable the resource view to monitor workload distribution across your team.
Check for updates and upgrade your Gantt installation safely.
Understand license types, evaluation periods, and user group configuration.
**New to Gantt?**
Start with [Install Gantt](/gantt/getting-started/installation) and then [Explore the Demo Project](/gantt/getting-started/demo-project) to see a fully configured Gantt chart before building your own.
# Install Gantt
Source: https://learn.nextedy.com/gantt/getting-started/installation
This tutorial walks you through the complete installation of Nextedy GANTT on your Polarion server.
## What You Will Achieve
After completing this tutorial, you will have:
* Gantt installed in your Polarion server's extensions directory
* A production or evaluation license in place
* The Polarion configuration cache cleared for clean extension loading
* A running Polarion server with the Gantt widget available in the widget picker
## Prerequisites
* **Polarion ALM** installed and accessible (administrator access required)
* **Server filesystem access** to the Polarion installation directory
* **Downloaded distribution** -- download `nextedy_gantt.zip` from [https://gantt.nextedy.com/download/](https://gantt.nextedy.com/download/)
This installation requires a Polarion server restart. Plan for a brief maintenance window if this is a production environment.
## Installation Steps
### Step 1: Unpack the Distribution
Unzip the downloaded `nextedy_gantt.zip` file on your local machine or directly on the server.
```text theme={null}
unzip nextedy_gantt.zip
```
You should see a folder named `com.nextedy.polarion.gantt` containing the extension files.
### Step 2: Copy the Extension Folder to Polarion
Copy the `com.nextedy.polarion.gantt` folder into your Polarion extensions directory:
```text theme={null}
POLARION_INSTALL_LOCATION/polarion/extensions/
```
After copying, the directory structure should look like:
```text theme={null}
POLARION_INSTALL_LOCATION/
polarion/
extensions/
com.nextedy.polarion.gantt/ <-- new folder
```
### Step 3: Install the License File
If you have a production license, copy the `gantt_lic.json` file to the Polarion license directory:
```text theme={null}
[POLARION_INSTALL]/polarion/license/gantt_lic.json
```
Or you can add it later easily from the Administration UI.\
In this case, once Gantt is installed, go to Polarion Administration - Nextedy GANTT - License, and attach the license file.
If you do not have a production license, Gantt runs in evaluation mode for 30 days. You can install the license later without reinstalling it.
### Step 4: Clear the Configuration Cache
Delete the Polarion configuration cache directory:
```text theme={null}
[POLARION_INSTALL]/data/workspace/.config
```
This step is required after every installation or update. The `.config` directory only holds plugin cache data and is automatically rebuilt on startup. Skipping this step is the most common cause of the Gantt widget not appearing after installation.
### Step 5: Restart the Polarion Server
Restart your Polarion server using your standard procedure (service restart, application server restart, etc.).
After the server starts, you should see Gantt listed in the Polarion administration panel.
### Step 6: Verify the Installation
1. Open **Administration** and navigate to **Nextedy GANTT > Setup**. The Setup page confirms Gantt installed successfully and shows the **Installed Version** alongside the **Latest Version** (for example, `26.6.2.202606151920`), with an up-to-date indicator when current. From here you can also open the **Changelog**, the plugin **Download Page**, and **Create Demo Project**.
2. As a quick functional check, open any Polarion wiki page (LivePage) in **Edit** mode, click **Add Widget**, and confirm the Gantt widgets appear in the picker -- **Work Items > Gantt (Work Items)** and **Plans > Gantt (Plans)** (they are also grouped under the **Nextedy** category).
3. Add a Gantt widget (or open a page that already has one); its footer displays the installed version, e.g. **Nextedy GANTT 26.6.2**.
To explore a ready-made chart, install the [demo project](/gantt/getting-started/demo-project).
## Installation Summary
| Step | Action | Verification |
| ---- | ----------------------------------- | ------------------------------------------------------------------------------------------------------------- |
| 1 | Unzip `nextedy_gantt.zip` | `com.nextedy.polarion.gantt` folder exists |
| 2 | Copy to `polarion/extensions/` | Folder visible in extensions directory |
| 3 | Copy license to `polarion/license/` | `gantt_lic.json` in license directory |
| 4 | Delete `data/workspace/.config` | Directory removed |
| 5 | Restart Polarion | Server starts without errors |
| 6 | Verify installation | **Administration > Nextedy GANTT > Setup** shows installed version; Gantt widgets appear in the widget picker |
## Troubleshooting
If you see a message indicating the Gantt widget is not available after installation, the most common cause is a missing cache clear. Follow these steps:
1. Stop the Polarion server
2. Delete `[POLARION_INSTALL]/data/workspace/.config`
3. Start the Polarion server
If the issue persists after clearing the cache, contact [Nextedy support](https://support.nextedy.com/support/tickets/new) with your server logs.
**Quick Verification**
After installation, the Gantt widget appears in the Polarion widget picker under **Work Items > Gantt (Work Items)** and **Plans > Gantt (Plans)**. If you do not see these entries, repeat Step 4 and restart.
## Next Steps
* [Explore the Demo Project](/gantt/getting-started/demo-project) -- install the pre-configured demo project to see a working Gantt chart
* [Set Up a Basic Gantt Chart](/gantt/getting-started/setup-basic-gantt) -- create your own Gantt widget from scratch
* [Licensing and User Access](/gantt/getting-started/licensing) -- configure user groups and manage licenses
# Licensing and User Access
Source: https://learn.nextedy.com/gantt/getting-started/licensing
This tutorial explains the Nextedy GANTT licensing model and guides you through configuring user access so your team members can view and edit Gantt charts.
## What You Will Achieve
After completing this tutorial, you will have:
* An understanding of the Gantt licensing model (evaluation, subscription, perpetual)
* The `nextedy_gantt_users` user group configured with the correct members
* All team members with the appropriate level of Gantt access (edit or read-only)
## Prerequisites
* [Gantt installed](/gantt/getting-started/installation) on your Polarion server
* Polarion **Global Administration** access for user management
* A valid license file (or running in evaluation mode)
## Step 1: Understand the License Types
Gantt offers the following license models:
| License Type | Description | Duration |
| ---------------- | ---------------------------------------------- | ------------------------- |
| **Evaluation** | Full functionality for testing | 30 days from installation |
| **Subscription** | Annual license with updates included | 1 year (renewable) |
| **Perpetual** | One-time purchase (upgrade licenses available) | Permanent |
**Subscription Model**
New licenses are available as subscriptions only. Perpetual licenses are available for existing customers as upgrade licenses.
The table above describes the **commercial** models (how you acquire a license). For the **technical** license-file types and states the product recognizes -- Evaluation (Primary), Evaluation (Secondary), Perpetual, and Test -- and their expiry behavior, see [License Types and Evaluation Periods](/gantt/reference/license-types).
The license status is visible on the **Nextedy GANTT > License** administration page and in the Gantt widget footer. When the license is invalid or expired, a license panel appears at the top of the Gantt chart with a link to obtain a valid license.
## Step 2: Install the License File
If you received a production license, install it either way:
* **Upload from the admin page (no restart):** open **Polarion Administration > Nextedy GANTT > License** and drag-and-drop the license file onto the drop zone (or click it to select the file).
* **Or place it on the server:** copy `gantt_lic.json` to `[POLARION_INSTALL]/polarion/license/`, then restart the Polarion server (or reload licenses from the admin page).
Then open **Polarion Administration > Nextedy GANTT > License** to verify the license status. The page summarizes the seat usage (for example, "set up for 30 server users") and shows the license details (type, expiry, maintenance expiry, licensee).
**Evaluation Expiry**
After the 30-day evaluation period expires, Gantt is automatically disabled. If you need more evaluation time, contact Nextedy to receive an extended evaluation license.
## Step 3: Configure the User Group
Gantt uses a dedicated Polarion user group to control which users have edit access to the Gantt chart. Users not in this group see the Gantt in read-only (Reviewer) mode.
1. Navigate to **Global Administration > User Management > Users**
2. Locate the group named `nextedy_gantt_users`
3. Add all users who need **edit access** to this group
**Group Creation**
If the `nextedy_gantt_users` group does not exist, create it manually in the Polarion user management interface. The group name must be exactly `nextedy_gantt_users`.
## Step 4: Reload Licenses
After updating the user group:
1. Navigate to **Polarion Administration > Nextedy GANTT > License**
2. This page reloads all active licenses and applies the updated user access rights
Users in the `nextedy_gantt_users` group now have edit access. All other users see the Gantt in read-only mode.
## Understanding Access Levels
| Access Level | Can View | Can Edit | Can Save | User Group Required |
| ------------ | -------- | -------- | -------- | ------------------------------- |
| **Editor** | Yes | Yes | Yes | Member of `nextedy_gantt_users` |
| **Reviewer** | Yes | No | No | Not required |
When a user has only Reviewer access, the Gantt chart displays in read-only mode. The Edit button is hidden, and task bars cannot be dragged, resized, or modified.
**Automatic Read-Only**
The Gantt chart also enters read-only mode automatically when viewing a Polarion baseline snapshot, regardless of user group membership.
## Step 5: Verify User Access
1. Log in as a user who is a member of `nextedy_gantt_users`
2. Open a Gantt chart page
3. Confirm the **Edit** button is visible in the toolbar
4. Enter edit mode and verify you can drag task bars
Then verify the restricted access:
1. Log in as a user who is **not** in the `nextedy_gantt_users` group
2. Open the same Gantt chart page
3. Confirm the Gantt displays in read-only mode with no Edit button
## License and Access Summary
| Component | Location | Purpose |
| --------------------------- | ---------------------------------------- | ------------------------------- |
| `gantt_lic.json` | `[POLARION_INSTALL]/polarion/license/` | License file |
| `nextedy_gantt_users` group | Global Administration > Users | Edit access control |
| License page | Administration > Nextedy GANTT > License | License status and reload |
| License panel | Gantt widget header | Warning when license is invalid |
## Multi-Node Deployment
If you run Polarion in a multi-node (clustered) deployment, the same license file can be used on both nodes. Copy `gantt_lic.json` to the license directory on each server node.
## Troubleshooting Access Issues
If a user cannot edit the Gantt chart despite being in the `nextedy_gantt_users` group:
1. Navigate to the **Nextedy GANTT > License** page to reload licenses
2. Verify the user is listed in the `nextedy_gantt_users` group in Global Administration
3. Ask the user to log out and log back in to refresh their session
4. If issues persist, contact [support@nextedy.com](mailto:support@nextedy.com)
## Next Steps
* [Set Up a Basic Gantt Chart](/gantt/getting-started/setup-basic-gantt) -- configure your first Gantt widget
* [Update to the Latest Version](/gantt/getting-started/update-gantt) -- keep your installation current
* Explore the [FAQ](/gantt/faq/index) for common licensing questions
# Set Up a Basic Gantt Chart
Source: https://learn.nextedy.com/gantt/getting-started/setup-basic-gantt
This tutorial guides you through creating a Work Items Nextedy GANTT chart from scratch in your Polarion project.
## What You Will Achieve
After completing this tutorial, you will have:
* A Polarion Info Page with a Work Items Gantt widget
* Filtered work items displayed as task bars on the Gantt chart
* Parent-child hierarchy showing grouped work items
* Dependency roles configured for linking tasks
## Prerequisites
* [Gantt installed](/gantt/getting-started/installation) on your Polarion server
* A Polarion project with existing work items (or use the E-Library template)
* Edit permissions on the project's Documents & Pages
If you are evaluating Gantt, consider starting with the [demo project](/gantt/getting-started/demo-project) first. It provides a pre-configured Gantt chart you can explore immediately.
This tutorial follows a project created from the **E-Library** template, so you can repeat each step and reach the same result. Start by creating a new project and selecting the E-Library template from the template list.
1. Open your Polarion project
2. Navigate to **Documents & Pages**
3. Select a space (for example, **Default Space**)
4. Click **Expand Tools** in the upper toolbar
5. Click the **Gear** button and select **Create New**
6. Choose **Info or LiveReport Page**
7. Enter a title (for example, "Project Nextedy Gantt") and click **Create**
You should see an empty page with the widget picker available on the right side.
In the widget picker on the right side of the page:
1. Expand the **Work Items** category
2. Select **Gantt (Work Items)**
3. The widget loads onto your page, displaying all work items in the project
**Two Widget Types**
Polarion shows two Gantt widgets: **Gantt (Work Items)** under the Work Items category displays individual work items. **Gantt (Plans)** under the Plans category displays Polarion Plans. For this tutorial, use the Work Items variant.
By default, the Gantt loads all work items in the project. To show specific types:
1. Open the widget parameters (click the **Edit** button on the page, then the widget gear icon)
2. In the **Query** section, click the **+** button to add a filter
3. Select **Type** from the filter options
4. Choose the work item types you want to display (for example, **Epic** and **Release**)
5. Click **Apply**
You should see only the selected work item types displayed as task bars on the Gantt chart.
To use the Gantt chart in full-page mode:
1. In the widget parameters, scroll to the **Advanced** section
2. Set **Maximize Gantt View** to **Yes**
3. Click **Apply**
The Gantt chart now fills the entire page area, giving you maximum working space.
The hierarchy of items on the Gantt chart is derived from work item link roles.
1. In the widget parameters, find **Parent Role**
2. Click **Select** and add the relevant link role (for example, `has_parent`) from the left list to the right
3. Set **Load Children** to `1` to display one level of child items
4. Click **Apply**
With **Load Children** set to `1` but no parent role configured yet, the chart does not change -- the hierarchy is driven by the parent role.
Select the parent role that links the items (for example, `has_parent`, which goes from Epic to User Story) and move it from the left list to the right.
You should see child work items nested beneath their parents in the Gantt chart. Setting **Load Children** back to `0` hides the hierarchy again.
If you need deeper hierarchy (for example, Epic > User Story > Task), increase **Load Children** to `2` and add additional parent roles (for example, `implements`).
| Load Children | Result |
| ------------- | ----------------------------------------------- |
| `0` | Only top-level items, no hierarchy |
| `1` | One level of children (e.g., Epic > User Story) |
| `2` | Two levels (e.g., Epic > User Story > Task) |
Dependency links are derived from work item link roles, just like parent-child relationships.
1. In the widget parameters, find **Dependency Role**
2. Click **Select** and add the dependency link role (for example, `depends_on`)
3. Click **Apply**
You should see dependency arrows drawn between linked work items on the Gantt chart. The first selected dependency role is used when creating new dependency links by dragging between task bars.
You can also control how items are created by setting the **Parent Mode** and representation mode per type -- for example, allowing an Epic to have a parent only of the same Epic type, while a User Story (representation mode **Item**) can have an Epic as its parent.
Before saving, note that the start date fields are Gantt settings rather than work item fields. Until you schedule the tasks, every item starts on **Today**.
Click the **Save** button on the Polarion page toolbar to persist your widget configuration.
**Save Both Levels**
Widget parameter changes require saving the page in Edit mode. If you navigate away without saving, your configuration changes are lost.
With the configuration saved, you can make the Gantt look organized by scheduling the tasks. Click the **Edit** button to start.
At this point every item is still unscheduled, which you can confirm by hovering over each one.
As you drag scheduled tasks into the past, the parent bar moves with them because it has a derived schedule that always spans all of its children.
By default each task is scheduled for 10 days. Use the small white dots on either side of a task bar to drag it longer or shorter.
Change the duration of the first task to 5 days by dragging the white dots, repeat for the remaining tasks, then save.
To order the tasks from the nearest start date to the latest, open **Nextedy Gantt Widget Parameters > Sort by** and change it from **ID** to **gantt\_start**, then apply and save.
Increasing **Load Children** from `1` to `2` loads the Tasks again, revealing a red-dotted background on some of them.
The red-dotted background marks unscheduled tasks with dependency links; hovering shows a "Dependency constraint violation" message where a link runs from the end of one task to the start of others.
Schedule the tasks so the first one ends before the dependent tasks start, which resolves the violations and keeps your team aware of task dependencies.
## Key Widget Parameters Summary
| Parameter | Purpose | Example Value |
| ----------------------- | ------------------------------- | ----------------- |
| **Query / Type** | Filter which work items appear | `Epic`, `Release` |
| **Parent Role** | Define parent-child hierarchy | `has_parent` |
| **Load Children** | Depth of child loading | `1` or `2` |
| **Dependency Role** | Define dependency relationships | `depends_on` |
| **Maximize Gantt View** | Full-page display | `Yes` |
## Next Steps
* [Set Up a Plans Gantt Chart](/gantt/getting-started/setup-plans-gantt) -- display Polarion Plans as top-level Gantt items
* [Create Your First Dependency Link](/gantt/getting-started/first-dependency) -- learn to create dependencies interactively
* [View Resource Allocation](/gantt/getting-started/first-resource-view) -- enable the resource view to track team workload
* [Explore the Demo Project](/gantt/getting-started/demo-project) -- see a fully configured example
# Set Up a Plans Gantt Chart
Source: https://learn.nextedy.com/gantt/getting-started/setup-plans-gantt
This tutorial guides you through creating a Plans Nextedy GANTT chart that displays Polarion Plans as first-class Gantt items.
## What You Will Achieve
After completing this tutorial, you will have:
* A Plans Gantt widget showing Polarion Plans as top-level task bars
* Nested sub-plans displayed beneath parent plans
* Work items shown within their parent plans
* A multi-level Gantt view suitable for release and iteration planning
## Prerequisites
* [Gantt installed](/gantt/getting-started/installation) on your Polarion server
* A Polarion project with existing Plans (releases, iterations, or sprints)
* Edit permissions on the project's Documents & Pages
The Plans Gantt widget uses a different data model than the Work Items Gantt. Plans are Polarion's built-in planning containers (releases, iterations, sprints). If you need to schedule individual tasks, use the [Work Items Gantt](/gantt/getting-started/setup-basic-gantt) instead.
1. Open your Polarion project
2. Navigate to **Documents & Pages**
3. Select a space (for example, **Default Space**)
4. Click **Expand Tools**, then the **Gear** button, and select **Create New**
5. Choose **Info/LiveReport Page** and enter a title (for example, "Release Roadmap")
6. Click **Create**
You should see an empty page ready for widget configuration.
In the widget picker on the right side of the page:
1. Expand the **Plans** category
2. Select **Gantt (Plans)**
3. The widget loads, displaying plans from your project
The Plans Gantt widget appears under a different category than the Work Items Gantt. Make sure you select **Gantt (Plans)** from the **Plans** section.
1. Open the widget parameters
2. In the **Plans** data set section, configure the scope to show plans with a specific template (for example, **Release**)
3. Click **Apply**
You should see only plans matching the selected template displayed as task bars on the Gantt chart.
To display child plans (for example, iterations beneath releases):
1. In the widget parameters, set **Load Children** to `2` to load two levels of plan hierarchy
2. Click **Apply**
You should see a hierarchy like:
| Level | Example |
| ----- | --------------------------- |
| 0 | Release (e.g., Version 2.0) |
| 1 | Iteration (e.g., Sprint 35) |
| 2 | Work Items (if enabled) |
To display the actual work items contained in each plan:
1. In the widget parameters, find the **Show Plan Work Item** section
2. Set **Enable Show Items** to **Yes**
3. Configure the field mappings for the work items:
* **Start Field**: the work item field holding the start date
* **End Field**: the work item field holding the end date
* **Duration Field**: the work item field holding duration
4. Set the **Parent Role** to define how work item hierarchy is resolved within plans
5. Click **Apply**
You should now see work items displayed as task bars beneath their parent plan bars.
**Scale Setting**
Plans Gantt charts typically use longer time scales. Set the **Scale** parameter to `W` (week) or `M` (month) for a better overview of release timelines.
If your work items have dependency relationships with work items:
1. In the **Show Plan Work Item** section, find **Dependency Role**
2. Select the link role used for dependencies (for example, `depends_on`)
3. Click **Apply**
Dependency arrows now appear between work items within the Plans Gantt view.
Fine-tune the Plans Gantt view:
1. Set **Sort by** to control the order of plans (default is `id`)
2. Set **Show Unplanned** to **Yes** if you want to see plans without dates (they appear at today's date in gray)
3. Enable **Maximize View** in the Advanced section for full-page display
4. Click **Apply** and save the page
**Verify in application**
Work item creation from within Plans Gantt may be limited to the lowest plan level. If you need to create work items at multiple plan levels, consider using separate Gantt widgets for each level.
## Plans Gantt Parameter Summary
| Parameter | Purpose | Default |
| ----------------------- | ------------------------------- | ------------- |
| **Plans Data Set** | Which plans to display | Project scope |
| **Load Children** | Depth of sub-plan loading | `0` |
| **Show Plan Work Item** | Display work items within plans | Disabled |
| **Sort by** | Plan sort order | `id` |
| **Show Unplanned** | Show undated plans | Disabled |
| **Scale** | Timeline scale | `W` (week) |
## Next Steps
* [Set Up a Basic Gantt Chart](/gantt/getting-started/setup-basic-gantt) -- learn the Work Items Gantt for task-level scheduling
* [Create Your First Dependency Link](/gantt/getting-started/first-dependency) -- connect tasks with dependency arrows
* [View Resource Allocation](/gantt/getting-started/first-resource-view) -- monitor team workload across plans
# Update to the Latest Version
Source: https://learn.nextedy.com/gantt/getting-started/update-gantt
This tutorial guides you through checking for updates and upgrading your Nextedy GANTT installation to the latest version.
## What You Will Achieve
After completing this tutorial, you will have:
* Checked your current installed version against the latest available release
* Downloaded and installed the latest Gantt version
* A running Polarion server with the updated Gantt version
## Prerequisites
* [Gantt installed](/gantt/getting-started/installation) on your Polarion server
* Server filesystem access to the Polarion installation directory
* Polarion administrator access
**Server Restart Required**
Updating Gantt requires stopping and restarting the Polarion server. Plan for a brief maintenance window.
You can find the currently installed version in two places:
**From the Gantt admin page:**
1. Open **Polarion Administration**
2. Navigate to **Nextedy GANTT > Setup**
3. The current version is displayed on the page
**From any Gantt widget:**
The footer of any Gantt chart widget displays the installed version number.
Open **Polarion Administration > Nextedy GANTT > Setup**. The page automatically shows both the **Installed Version** and the **Latest Version**, with an up-to-date indicator (✅ **Up-to-date**) when you are current. If the latest version is newer than the installed one, an update is available.
The Setup page also provides a **Download Page** button (to fetch the latest distribution) and a **Changelog** button.
**Privacy Note**
The version check fetches version information from the Nextedy download server. No scripts are executed from the download server, and no data from your installation is transmitted.
Download the latest `nextedy_gantt.zip` from:
```
https://gantt.nextedy.com/download/
```
Stop your Polarion server using your standard procedure:
```bash theme={null}
service polarion stop
```
Or use your application server's management interface.
Delete the existing Gantt extension directory:
```
[POLARION_INSTALL]/polarion/extensions/com.nextedy.polarion.gantt
```
**Backup First**
Consider backing up the old extension directory before deletion. This allows you to roll back quickly if the update causes unexpected issues.
Follow the same steps as a fresh installation:
1. Unzip the downloaded `nextedy_gantt.zip`
2. Copy the `com.nextedy.polarion.gantt` folder to `[POLARION_INSTALL]/polarion/extensions/`
**Update the license only if it changed**
Most updates reuse your existing license. If you also received a new `gantt_lic.json` (for example, after renewing a subscription), copy it to `[POLARION_INSTALL]/polarion/license/` now -- otherwise leave the existing license in place.
Delete the Polarion configuration cache:
```
[POLARION_INSTALL]/data/workspace/.config
```
**Critical Step**
This step is required on every update. The `.config` directory holds plugin cache data and must be cleared to pick up the new extension version. Skipping this step is the most common cause of issues after updating.
Start your Polarion server:
```bash theme={null}
service polarion start
```
1. Open **Polarion Administration > Nextedy GANTT > Setup**
2. Confirm the displayed version matches the version you downloaded
3. Open any existing Gantt chart and verify it loads correctly
The Gantt chart footer should also display the new version number.
## Update Process Summary
## Update Checklist
| Step | Action | Done |
| ---- | -------------------------------------------------- | ---- |
| 1 | Note current version | |
| 2 | Download latest `nextedy_gantt.zip` | |
| 3 | Stop Polarion server | |
| 4 | Delete `com.nextedy.polarion.gantt` directory | |
| 5 | Copy new `com.nextedy.polarion.gantt` from zip | |
| 6 | Delete `[POLARION_INSTALL]/data/workspace/.config` | |
| 7 | Copy license file if updated | |
| 8 | Start Polarion server | |
| 9 | Verify version in admin panel | |
## Troubleshooting After Update
If the Gantt chart shows a loading screen or fails to render after updating:
1. Verify that `[POLARION_INSTALL]/data/workspace/.config` was deleted
2. Check the Polarion server logs for extension loading errors
3. Open the browser developer console and look for JavaScript errors
4. If issues persist, contact [Nextedy support](https://support.nextedy.com/support/tickets/new) with your server logs, browser console output, and configuration details
**Version-Specific Fixes**
Some releases contain critical bug fixes. If you encounter issues with a specific version, check the Nextedy changelog for known issues and consider updating to the latest patch release.
## Next Steps
* [Licensing and User Access](/gantt/getting-started/licensing) -- verify license status after updating
* [Set Up a Basic Gantt Chart](/gantt/getting-started/setup-basic-gantt) -- configure new features available in the updated version
* [Explore the Demo Project](/gantt/getting-started/demo-project) -- review demo data for new feature examples
# Configure Capacity Modifier Fields
Source: https://learn.nextedy.com/gantt/guides/calendars/capacity-modifier-fields
Reduce effective resource capacity using two percentage-based modifier fields on Team work items, enabling accurate workload calculations for partially allocated resources in Nextedy GANTT.
## Prerequisites
* Working calendars enabled in the Gantt widget (see [Set Up Work Item Calendars](/gantt/guides/calendars/work-item-calendar))
* Team assignments configured with the appropriate work item type
* Access to **Administration > Configuration Properties**
Capacity modifiers use two custom fields on your Team work items. Each field holds a percentage value (0-100) representing a capacity reduction.
Add the following properties under **Administration > Configuration Properties**:
```
nextedy.gantt.capacityModifierAField=capacityModA
nextedy.gantt.capacityModifierBField=capacityModB
```
Replace `capacityModA` and `capacityModB` with the actual field IDs on your Team work items.
| Property | Purpose | Example Value |
| ---------------------------------------------- | ----------------------------------------------------------- | -------------- |
| `nextedy.gantt.capacityModifierAField` | Field ID for modifier A (permanent reduction) | `capacityModA` |
| `nextedy.gantt.capacityModifierBField` | Field ID for modifier B (time-limited reduction) | `capacityModB` |
| `nextedy.gantt.capacityModifierBFieldDayLimit` | Number of days from today within which modifier B is zeroed | `30` |
The Gantt calculates effective capacity using both modifiers:
```
effectiveCapacity = base * (1 - (capModA + capModB) / 100)
```
For example, if a resource has 8 working hours per day, modifier A is 25%, and modifier B is 10%:
```
effectiveCapacity = 8 * (1 - (25 + 10) / 100) = 8 * 0.65 = 5.2 hours
```
Modifier B includes a time-horizon feature: within a specified number of days from today, modifier B is zeroed out. This allows you to model scenarios where a future capacity reduction is planned but should not affect near-term scheduling.
```
nextedy.gantt.capacityModifierBFieldDayLimit=30
```
With this setting, modifier B is applied only to dates more than 30 days in the future. For dates within the next 30 days, only modifier A affects the capacity calculation.
**Using Modifiers for Different Scenarios**
Use modifier A for permanent capacity reductions (such as part-time allocation to the project) and modifier B for planned future changes (such as an upcoming role change or project transition). The day-limit ensures near-term planning uses current capacity while long-term planning reflects the expected change.
To activate team-level capacity modifiers, add this property:
```
nextedy.gantt.useTeamCapacityModifiers=true
```
When enabled, team modifiers (fields A and B) reduce effective resource capacity in the resource view. The modifiers are read from the Team work item that each user is assigned to.
**Field Must Exist on Work Items**
The fields specified by `nextedy.gantt.capacityModifierAField` and `nextedy.gantt.capacityModifierBField` must exist as custom fields on the Team work item type. If the fields are missing, the modifiers are silently ignored and capacity is calculated without reduction.
Open the Gantt widget parameters and navigate to **Working Calendars**:
1. Set **Use Working Calendar** to **Yes**
2. Set **Load User Calendars** to **Yes**
3. Set **Load Team Assignments** to **Yes**
The capacity modifiers are applied during calendar building, combining the base working hours from the user's calendar with the percentage reductions from the user's Team work item.
**Multiple Assignments Stack Additively**
When a user has multiple team assignment work items, the capacity contributions from all assignments are summed together with the user's calendar to build their effective daily capacity. Keep the total across all assignments realistic (typically not exceeding 100%) -- additive stacking can otherwise overstate a user's availability and hide real overallocation.
## Verify
You should now see that resource view allocation markers reflect the reduced capacity for users with modifier fields set on their team assignments. A resource with a 25% modifier A shows 6 hours of available capacity per day (instead of 8), and tasks assigned to that resource display higher utilization percentages accordingly.
## See Also
* [Set Up Work Item Calendars](/gantt/guides/calendars/work-item-calendar)
* [Customize Working Hours per Resource](/gantt/guides/calendars/working-hours-per-resource)
* [Set Up the Resource View](/gantt/guides/resources/resource-view)
* [Configure Resource Fields](/gantt/guides/resources/resource-field-configuration)
* [Set Up Team Assignments Gantt](/gantt/guides/resources/team-assignments-gantt)
# Use Calendars from Another Project
Source: https://learn.nextedy.com/gantt/guides/calendars/cross-project-calendar
Share a centralized work item calendar project across multiple Polarion projects so that resource availability, time off, and capacity constraints are consistent in every Nextedy GANTT instance.
## Prerequisites
* A dedicated calendar project with work item calendars already configured (see [Set Up Work Item Calendars](/gantt/guides/calendars/work-item-calendar))
* Access to **Administration > Configuration Properties** in both the calendar project and each consuming project
In your calendar project, find the following values:
* **Project ID**: The Polarion project ID of the calendar project (visible in the URL or project settings)
* **Global Calendar Work Item ID**: The ID of the Calendar-type work item used as the global (company) calendar
Add these properties in the calendar project under **Administration > Configuration Properties**:
```
nextedy.gantt.workitemCalendar.projectId=CalendarProject
nextedy.gantt.workitemCalendar.globalID=CAL-1
```
Replace `CalendarProject` with the actual project ID and `CAL-1` with the actual global calendar work item ID.
In **every** project that should use the shared calendar, add the **same** properties under **Administration > Configuration Properties**:
```
nextedy.gantt.workitemCalendar.projectId=CalendarProject
nextedy.gantt.workitemCalendar.globalID=CAL-1
```
**Must Be Set on Both Sides**
These properties must be present in **both** the calendar project and every consuming project. If a consuming project is missing the properties, its Gantt will not load calendar data from the shared project.
In each consuming project's Gantt widget, navigate to the **Working Calendars** section in the widget parameters:
1. Set **Use Working Calendar** to **Yes**
2. Set **Load User Calendars** to **Yes**
3. Optionally enable **Load Team Assignments** for team-scoped capacity
These options are interdependent and revealed in order: enabling **Use Working Calendar** exposes **Load User Calendars**, which in turn exposes **Load Team Assignments**:
The Gantt looks up each resource's calendar in the shared calendar project by matching the **Assignee** field on Calendar work items to the resource's Polarion user ID.
Cross-project calendar resolution involves querying work items in another project, which can be slow on large installations. Enable caching to improve performance:
```
nextedy.gantt.workingCalendar.useCache=true
```
**Performance on Large Installations**
Enable `nextedy.gantt.workingCalendar.useCache=true` in each consuming project's configuration properties. Clear the cache using the **Clear Calendar Cache** toolbar button (which appears when caching is active), or via the `api/clearCalendarCache` endpoint.
## How Calendar Resolution Works
When the Gantt loads in a consuming project:
1. The Gantt reads `nextedy.gantt.workitemCalendar.projectId` to determine the source project
2. For each resource, it searches for a **Calendar** work item in the source project where the **Assignee** matches the user and the **From/To** date range contains today
3. If a user calendar is found, it loads the regular working hours and all linked exceptions (Time Off, Time On, Tweak) via the **affects** link role
4. If no user calendar is found, the global calendar (specified by `nextedy.gantt.workitemCalendar.globalID`) is used as the fallback
For example, a **Time Off** ("New Time Off John Holiday") is defined under John's Calendar in the central calendar project:
In the consuming project, those exact dates appear as grey non-working spaces for John, and a work item scheduled over them does not overwrite the holiday:
**Assignee Field Required**
Each user-specific calendar in the shared project must have the **Assignee** field set to the correct Polarion user. Without this, the Gantt cannot match calendars to resources in consuming projects.
## Verify
You should now see that time off and custom working hours defined in the central calendar project appear as grey markers and adjusted capacity values in the resource view of each consuming project's Gantt chart.
A **Tweak** in the central calendar -- here "New Tweak Mark" on Mark's Calendar, limiting his capacity for those days -- is another exception that flows through to consuming projects:
Because the tweak lowers Mark's available capacity below his assigned workload, the consuming project's resource view flags those days with red overallocation bubbles, and the tooltip reports him overallocated by 0.1 against a total capacity of 2:
## See Also
* [Set Up Work Item Calendars](/gantt/guides/calendars/work-item-calendar)
* [Import Calendars from CSV](/gantt/guides/calendars/csv-calendar-import)
* [Customize Working Hours per Resource](/gantt/guides/calendars/working-hours-per-resource)
* [Configure Capacity Modifier Fields](/gantt/guides/calendars/capacity-modifier-fields)
* [Troubleshooting Calendar Integration Issues](/gantt/guides/troubleshooting/calendar-issues)
# Import Calendars from CSV
Source: https://learn.nextedy.com/gantt/guides/calendars/csv-calendar-import
Load resource capacity data from an external CSV file instead of from Polarion users, enabling integration with external planning tools in Nextedy GANTT.
## Prerequisites
* Access to the Polarion server file system (to place the CSV file)
* Access to **Administration > Configuration Properties**
Create a semicolon-delimited CSV file with the following column order:
| Column | Description | Example |
| ------------ | ------------------------- | ----------- |
| `PROJECT_ID` | Polarion project ID | `MyProject` |
| `USER_ID` | Polarion user ID | `jsmith` |
| `YEAR` | Calendar year | `2025` |
| `START` | Start day of year (1-366) | `60` |
| `END` | End day of year (1-366) | `90` |
| `CAPACITY` | Working hours per day | `8` |
Each row defines a capacity period for one user. Set `CAPACITY` to `0` for non-working periods.
**Day-of-Year Values**
The `START` and `END` columns use day-of-year numbers (1 = January 1; December 31 is day 365, or day 366 in a leap year). You can calculate these from dates in a spreadsheet before exporting.
Place the file at the following path on the Polarion server:
```
/.polarion/nextedy/resource-capacity.csv
```
This is the fixed path that the Gantt reads from. The file must be accessible to the Polarion server process.
Add the following property under **Administration > Configuration Properties**:
```
nextedy.gantt.loadResourcesFromCsv=true
```
This tells the Gantt to load resource definitions from the CSV file instead of from Polarion users.
**CSV Loading Message**
When the CSV file is being parsed for the first time, the Gantt widget displays a message: **"CSV User Calendar is loading, it may take few minutes..."**. This is expected behavior during the initial load.
Open the Gantt widget parameters and navigate to **Working Calendars**:
1. Set **Use Working Calendar** to **Yes**
2. Set **Load User Calendars** to **Yes**
For improved performance on repeated page loads, enable server-side caching:
```
nextedy.gantt.workingCalendar.useCache=true
```
The cache persists between page loads. After updating the CSV file, clear the cache to load the new data.
**Cache Clearing**
After replacing the CSV file, you must clear the calendar cache for changes to take effect. Use the **Clear Calendar Cache** toolbar button (shown when caching is enabled) or the `api/clearCalendarCache` endpoint.
## CSV File Example
```
MyProject;jsmith;2025;1;120;8
MyProject;jsmith;2025;121;125;0
MyProject;jsmith;2025;126;365;8
MyProject;mdoe;2025;1;365;6
```
In this example:
* **jsmith** works 8 hours per day, except days 121-125 (a vacation week with 0 hours)
* **mdoe** works 6 hours per day all year
## Verify
You should now see grey allocation markers in the resource view on days where the CSV defines zero capacity for a user. Days with reduced hours display the correct capacity values in the resource markers.
## See Also
* [Set Up Work Item Calendars](/gantt/guides/calendars/work-item-calendar)
* [Use Calendars from Another Project](/gantt/guides/calendars/cross-project-calendar)
* [Customize Working Hours per Resource](/gantt/guides/calendars/working-hours-per-resource)
* [Set Up the Resource View](/gantt/guides/resources/resource-view)
# Calendars
Source: https://learn.nextedy.com/gantt/guides/calendars/index
Nextedy GANTT working calendars control how non-working days, holidays, and per-user schedules affect task scheduling and resource capacity calculations.
Load global non-working days from the Polarion working calendar into the Gantt chart.
Enable per-user working calendars to reflect individual schedules, vacations, and custom working hours.
Use dedicated Polarion work items to define calendars with Time Off, Time On, and Tweak entries.
Import working calendar definitions from CSV files for large installations or external schedule sources.
Reference a centralized calendar project from multiple Polarion projects for consistent scheduling.
Define different working hours for individual resources to match part-time or shift schedules.
Apply capacity modifiers to adjust effective resource availability using custom fields.
**Calendar Configuration Order**
Working calendar settings are interdependent. First enable **Use Working Calendar**, which reveals **Load User Calendars**, which in turn reveals **Load Team Assignments**. Configure them in this order to progressively add calendar detail to your Gantt chart.
# Load Holidays and Non-Working Days
Source: https://learn.nextedy.com/gantt/guides/calendars/load-holidays
Configure Nextedy GANTT to load non-working days from the Polarion working calendar so that holidays and time-off periods are reflected in the Gantt chart and resource view.
Before configuring the Gantt, define your holidays and non-working days in the Polarion working calendar:
1. Navigate to **Administration > Working Calendar** in your Polarion project
2. Select the dates you want to mark as non-working (holidays, company closures)
3. Save the calendar changes
Open the Gantt widget parameters and locate the **Working Calendars** section:
1. Set **Use Working Calendar** to `Yes`
This is the master toggle that enables calendar-aware scheduling. When enabled, the Gantt respects non-working days when calculating task durations and resource capacity.
**Progressive Disclosure**
The Working Calendars settings are interdependent. Setting **Use Working Calendar** to `Yes` reveals the **Load User Calendars** option. Enabling that reveals **Load Team Assignments**. Each toggle progressively adds more calendar detail.
To load the non-working days into the Gantt view, add the following to the widget parameters under **Advanced > Gantt Config Script**:
```
$workingCalendar.loadNotWorkingDays(2025).loadNotWorkingDays(2026).buildConfiguration()
```
Adjust the years to cover the time range you need. Each `.loadNotWorkingDays(year)` call loads holiday data for that specific year.
**Load Only the Years You Need**
Loading calendar data for each year adds to the initial page load time. Load only the years relevant to your project timeline to keep performance optimal. For most projects, loading the current year and the next year is sufficient.
For a more permanent configuration, set the year range in the Working Calendars widget parameters:
| Parameter | Description | Recommended Value |
| -------------------------- | ----------------------------------------------- | ----------------- |
| **Next Years to Load** | Number of future years of calendar data to load | 1-2 |
| **Previous Years to Load** | Number of past years of calendar data to load | 1 |
Higher values ensure calendar data is available for long-range planning but increase startup time.
## How Non-Working Days Appear
Once configured, non-working days are reflected in the Gantt in several ways:
* **Timeline cell highlighting** -- off-day cells receive a visual highlight distinguishing them from working days
* **Resource view** -- grey markers appear in the resource view for days where a user is unavailable
* **Duration calculations** -- when auto-scheduling is enabled, non-working days are skipped when computing task durations
**Global Non-Working Days Cannot Be Overridden per User**
If you mark a date as a global non-working day in the Polarion calendar, it is **not** possible to override it with a personal exception. A global Time Off applies to all users. To allow per-user exceptions, use the Work Item Calendar approach instead where Time On work items can override global Time Off.
**Calendar Cache After Changes**
If you modify the Polarion working calendar after the Gantt has been loaded, the changes may not appear immediately due to server-side caching. Enable the **Cache Working Calendars** widget parameter for performance, but remember to clear the cache after making calendar changes using the administration API endpoint.
## Verification
You should now see:
* Non-working days highlighted in the Gantt chart timeline
* Grey markers in the resource view on holiday dates
* Task duration calculations skipping non-working days when auto-scheduling is active
## See Also
* [Load User Calendars](/gantt/guides/calendars/user-calendars)
* [Set Up Work Item Calendars](/gantt/guides/calendars/work-item-calendar)
* [Use Calendars from Another Project](/gantt/guides/calendars/cross-project-calendar)
* [Highlight Off-Days in the Timeline](/gantt/guides/visualization/off-day-highlighting)
* [Troubleshooting Calendar Integration Issues](/gantt/guides/troubleshooting/calendar-issues)
# Load User Calendars
Source: https://learn.nextedy.com/gantt/guides/calendars/user-calendars
Enable per-user working calendars in Nextedy GANTT so that individual vacation days, custom schedules, and reduced working hours are reflected in the resource view and capacity calculations.
Each user who needs a personalized schedule must have calendar data configured in Polarion. There are two approaches:
**Polarion Working Calendar** -- Add schedule exceptions (vacations, half-days) directly in the Polarion Administration working calendar for each user.
**Work Item Calendar** -- Create dedicated Calendar work items with Time Off, Time On, and Tweak entries. See [Set Up Work Item Calendars](/gantt/guides/calendars/work-item-calendar) for the full setup.
Open the Gantt widget parameters and configure the **Working Calendars** section in this order:
1. Set **Use Working Calendar** to `Yes` (master toggle)
2. Set **Load User Calendars** to `Yes` (appears after enabling step 1)
The settings are interdependent -- each option is only visible when its parent is enabled.
| Parameter | Depends On | Effect |
| ------------------------- | -------------------------- | ------------------------------------------------------ |
| **Use Working Calendar** | -- | Enables calendar-aware scheduling globally |
| **Load User Calendars** | Use Working Calendar = Yes | Loads per-user calendars for individual capacity |
| **Load Team Assignments** | Load User Calendars = Yes | Adds team assignment capacity on top of user calendars |
Set the calendar data range to cover your project timeline:
* **Next Years to Load** -- How many future years of calendar data to pre-compute (recommended: 1-2)
* **Previous Years to Load** -- How many past years to include (recommended: 1)
**Performance Impact**
Loading more years increases startup time and memory usage. For most projects, loading 1 future year and 1 previous year provides adequate coverage. Only increase this for long-running programs.
For installations with many users, enable server-side caching:
1. Set **Cache Working Calendars** to `Yes` in the widget parameters
2. Or set the global property `nextedy.gantt.workingCalendar.useCache` to `true`
**Clear Cache After Calendar Changes**
The calendar cache persists between page loads. After modifying user calendars in Polarion, clear the cache using the **Clear Calendar Cache** toolbar button or the `api/clearCalendarCache` endpoint.
## How User Calendars Affect the Gantt
Once enabled, user calendars affect the Gantt in several ways:
**Resource view capacity** -- Each user's effective working hours are calculated from their individual calendar. Days where a user is on vacation show as grey (unavailable) markers. Overallocation detection accounts for reduced capacity on partial days.
**Off-day cell highlighting** -- When a user has a non-working day, the corresponding timeline cell in their resource row receives a visual highlight, distinguishing it from regular working days.
**Duration calculations** -- When auto-scheduling is enabled, the Gantt skips non-working days for each user individually. A task assigned to a user on vacation is extended to account for their absence.
**Version Compatibility**
Versions 25.7.0 through 25.8.0 had a regression where work items missing fields required by a workflow action could fail to load on the Gantt, which can also leave resource rows incomplete. If items or their allocations are not loading as expected, update to version 25.9.0 or later.
## Work Item Calendar Integration
If you are using Work Item Calendars instead of the built-in Polarion calendar, configure these global properties under **Administration > Configuration Properties**:
```
nextedy.gantt.workitemCalendar.projectId=
nextedy.gantt.workitemCalendar.globalID=
```
Replace `` with the project ID containing your calendar work items, and `` with the work item ID of the global calendar.
**Apply to Both Projects**
This configuration must be set in both the calendar project and any projects that reference it.
The Work Item Calendar system supports four entry types:
* **Calendar** -- Defines default working hours per weekday (global or per-user)
* **Time Off** -- Marks non-working periods (vacations, holidays)
* **Time On** -- Overrides Time Off for specific users who need to work during global holidays
* **Tweak** -- Adjusts working hours for specific dates (half-days, overtime)
## Verification
You should now see:
* User-specific non-working days reflected as grey markers in the resource view
* Reduced capacity shown on partial working days (such as half-day Fridays)
* Overallocation indicators accounting for each user's individual calendar
* Off-day highlighting in timeline cells matching each user's schedule
## See Also
* [Load Holidays and Non-Working Days](/gantt/guides/calendars/load-holidays)
* [Set Up Work Item Calendars](/gantt/guides/calendars/work-item-calendar)
* [Use Calendars from Another Project](/gantt/guides/calendars/cross-project-calendar)
* [Customize Working Hours per Resource](/gantt/guides/calendars/working-hours-per-resource)
* [Troubleshooting Calendar Integration Issues](/gantt/guides/troubleshooting/calendar-issues)
# Set Up Work Item Calendars
Source: https://learn.nextedy.com/gantt/guides/calendars/work-item-calendar
Configure a dedicated Polarion project with work item-based calendars to manage user-specific schedules, holidays, and capacity adjustments for accurate resource planning in Nextedy GANTT.
## Prerequisites
* A Polarion project created from the **Gantt Calendars** template (or manually configured with the required work item types)
* Access to **Administration > Configuration Properties** on both the calendar project and consuming projects
1. Download the Gantt package from [gantt.nextedy.com/download/](https://gantt.nextedy.com/download/)
2. Locate `nextedy_gantt.zip/com.nextedy.polarion.gantt/template/WorkItemsCalendarTemplate.zip`
3. Upload it as a Project Template via the **Project Templates** global administration page
4. Create a new project based on the **Gantt Calendars** template
The template pre-configures four work item types:
| Work Item Type | ID | Purpose |
| -------------- | --------------- | -------------------------------------------------------------------------- |
| **Calendar** | `calendar` | Defines regular weekly working hours (global or per-user) |
| **Time Off** | `timeoff` | Marks non-working periods (holidays, vacations) |
| **Time On** | `timeon` | Overrides Time Off for specific users who must work |
| **Tweak** | `scheduletweak` | Adjusts working hours for a date range without changing working/off status |
Add the following properties under **Administration > Configuration Properties** in your calendar project:
```
nextedy.gantt.workitemCalendar.projectId=
nextedy.gantt.workitemCalendar.globalID=
```
Replace `` with the project ID of your calendar project and `` with the ID of a Calendar-type work item to use as the global calendar.
**Apply to Both Projects**
You must set these properties on **both** the calendar project and any projects that consume it. If the consuming project does not have these properties, calendar data will not load.
1. In your calendar project, create a new work item of type **Calendar**
2. Set the weekday fields using the format `HH:mm,HH:mm` (for example, `09:00,17:00` for an 8-hour workday)
3. Set Saturday and Sunday to `-` (explicitly non-working)
4. Leave the **Assignee** field empty for a global calendar
5. Set the **From** and **To** date fields to define the calendar's validity period
**Weekday Field Format**
Use `HH:mm,HH:mm` for working hours, `-` for explicitly non-working days, or leave empty to inherit from a parent calendar.
1. Create a new **Calendar** work item for each user
2. Link it to the global calendar using the **inherits from** link role so it inherits the base schedule
3. Set the **Assignee** field to the target Polarion user
4. Override only the weekday fields that differ from the global calendar (leave others empty to inherit)
**Assignee Required**
User calendars must have the **Assignee** field set. Without it, the Gantt cannot match the calendar to the correct resource.
Link exception work items to the appropriate calendar using the **affects** link role:
* **Time Off**: Create for vacations or holidays. Link to the global calendar for company-wide holidays, or to a user calendar for individual time off.
* **Time On**: Override a Time Off period for a specific user who must work during a global holiday.
* **Tweak**: Adjust hours for a date range. Set both `workstart` and `workend` fields to define the modified work window.
Open the Gantt widget parameters and navigate to the **Working Calendars** section:
1. Set **Use Working Calendar** to **Yes**
2. Set **Load User Calendars** to **Yes**
3. Optionally enable **Load Team Assignments** for team-scoped capacity
**Progressive Disclosure**
The Working Calendars settings are interdependent. **Load User Calendars** only appears after enabling **Use Working Calendar**, and **Load Team Assignments** only appears after enabling both.
## Verify
You should now see grey markers in the resource view for days where users are unavailable. If a user has a Tweak reducing their capacity, the resource view shows the reduced hours and highlights overload with a red indicator.
## See Also
* [Use Calendars from Another Project](/gantt/guides/calendars/cross-project-calendar)
* [Import Calendars from CSV](/gantt/guides/calendars/csv-calendar-import)
* [Customize Working Hours per Resource](/gantt/guides/calendars/working-hours-per-resource)
* [Configure Capacity Modifier Fields](/gantt/guides/calendars/capacity-modifier-fields)
* [Troubleshooting Calendar Integration Issues](/gantt/guides/troubleshooting/calendar-issues)
# Customize Working Hours per Resource
Source: https://learn.nextedy.com/gantt/guides/calendars/working-hours-per-resource
Override the default working hours for individual resources using either a global setting or a custom script function in Nextedy GANTT.
## Approach 1: Set a Uniform Value for All Resources
To change the default working hours for every resource in the project, use one of these methods:
### Option A: Gantt Config Script (Per Widget)
Add the following in **Widget Properties > Advanced > Gantt Config Script**:
```javascript theme={null}
gantt.config.workingHoursPerDay=7
```
This sets 7 working hours per day for all resources in this specific Gantt widget.
### Option B: Administration Property (Per Project or Server)
Add the following in **Administration > Configuration Properties**:
```
nextedy.gantt.workingHoursPerDay=7
```
This applies to all Gantt widgets in the project (or globally if set at the server level).
| Method | Scope | Set In |
| ---------------------------------- | ----------------- | -------------------------------------------------- |
| `gantt.config.workingHoursPerDay` | Single widget | Widget Properties > Advanced > Gantt Config Script |
| `nextedy.gantt.workingHoursPerDay` | Project or server | Administration > Configuration Properties |
## Approach 2: Different Hours per Resource (Script Function)
For scenarios where different users have different working hours, define a custom function in the **Gantt Config Script**:
```javascript theme={null}
gantt.config.workingHoursPerDayFunction = (resource) => {
if (resource === "jsmith") {
return 4;
}
if (resource === "mdoe") {
return 6;
}
return 8;
};
```
This function receives the resource ID (Polarion user ID) and returns the number of working hours for that user. The Gantt uses this value when calculating capacity in the resource view.
**Dynamic Script with Velocity**
The Gantt Config Script supports Velocity preprocessing on the server. You can use `$trackerService` to query work items and dynamically build the function. For example, read resource capacity from a custom work item and generate the JavaScript function body at render time.
### Example: Velocity-Powered Resource Hours
```javascript theme={null}
gantt.config.workingHoursPerDayFunction = (resource) => {
#set($resources = $trackerService.queryWorkItems("type:teamAssignment", "id"))
var mapping = {
#foreach($wi in $resources)
"$wi.getAssignees().iterator().next().getId()": $wi.getCustomField("hoursPerDay").get(),
#end
};
return mapping[resource] || 8;
};
```
**Verify in application**
The Velocity-based approach depends on your project's specific work item types and custom fields. Test the generated JavaScript output in the browser console to confirm correct values.
## How It Affects the Resource View
The working hours value determines the **capacity denominator** in resource view calculations:
* **Time mode**: Shows allocated hours vs. available hours per day
* **Remaining mode**: Shows remaining capacity (available minus allocated)
* **Allocation mode**: Shows percentage (allocated / available \* 100)
When a resource has a custom value of 4 hours per day instead of the default 8, the resource view reflects this reduced capacity. A task assigned 4 hours fills the entire day for that resource.
**Interaction with Working Calendars**
If you also use work item calendars or CSV calendars, the per-resource working hours from those calendars take precedence over the `workingHoursPerDayFunction`. The script function acts as a fallback when no calendar-based hours are available for a resource.
## Verify
You should now see that resource view capacity markers reflect the customized hours per resource. Resources with reduced hours show higher utilization percentages for the same amount of assigned work.
## See Also
* [Set Up Work Item Calendars](/gantt/guides/calendars/work-item-calendar)
* [Import Calendars from CSV](/gantt/guides/calendars/csv-calendar-import)
* [Configure Capacity Modifier Fields](/gantt/guides/calendars/capacity-modifier-fields)
* [Set Up the Resource View](/gantt/guides/resources/resource-view)
* [Write Gantt Config Scripts](/gantt/guides/scripting/gantt-config-script)
# Configure Advanced Dependency Types (FS, SS, FF, SF)
Source: https://learn.nextedy.com/gantt/guides/dependencies/advanced-dependency-types
Configure Nextedy GANTT to use all four dependency types -- Finish-to-Start, Start-to-Start, Finish-to-Finish, and Start-to-Finish -- instead of defaulting every link to Finish-to-Start.
## Prerequisites
* Gantt version **4.4.0** or later (the version that added mapping of advanced dependencies to Polarion link roles)
* A Dependency Role already configured in the widget parameters (see [Create and Configure Dependency Links](/gantt/guides/dependencies/create-dependency-links))
Open **Project / Repository Administration > Configuration Properties** and add:
```
nextedy.gantt.default.advanced_dependencies=true
```
This tells the Gantt to preserve the specific dependency type when you create or edit a link. Without this property, every dependency link is automatically converted to Finish-to-Start.
When advanced dependency types are enabled, the Gantt stores type and lag information in a custom field called `gantt_dependency_metadata`. End users should not see or edit this field directly.
1. Open **Administration > Form Configuration** for the relevant work item types.
2. Locate the `gantt_dependency_metadata` field.
3. Mark it as **hidden** so it does not appear on work item forms.
**Do not delete the metadata field**
Removing or renaming `gantt_dependency_metadata` will cause the Gantt to lose all advanced dependency type information. Always keep the field -- just hide it from users.
By default, all four dependency types share the same Polarion link role. If your project requires separate link roles for each type, add the following to **Configuration Properties**:
```
nextedy.gantt.workitems.linkRoles.finish_to_start=your_FS_role_id
nextedy.gantt.workitems.linkRoles.start_to_start=your_SS_role_id
nextedy.gantt.workitems.linkRoles.finish_to_finish=your_FF_role_id
nextedy.gantt.workitems.linkRoles.start_to_finish=your_SF_role_id
```
Replace each value with the actual Polarion link role ID used in your project.
**Multiple link roles per type**
You can specify a comma-separated list of link role IDs if different work item types use different dependency roles. For example:
```
nextedy.gantt.workitems.linkRoles.finish_to_finish=dependency_feature_ff,dependency_task_ff
```
## Dependency Types Reference
| Type | Code | Constraint |
| ------------------------- | ---- | ---------------------------------------- |
| **Finish-to-Start (FS)** | `0` | Target cannot start before source ends |
| **Start-to-Start (SS)** | `1` | Target cannot start before source starts |
| **Finish-to-Finish (FF)** | `2` | Target cannot end before source ends |
| **Start-to-Finish (SF)** | `3` | Target cannot end before source starts |
All constraints allow the target to shift later -- they define the earliest possible start or finish, not an exact alignment.
1. Enter **Edit mode** on the Gantt chart.
2. Drag from the link circle on one task bar to another task bar to create a dependency link.
3. The dependency type is assigned based on which edge (start or end) you drag from and drop onto.
**Hidden or unloaded dependencies are ignored**
If dependency links are not loaded due to item limits or filtering, the Gantt ignores them entirely. This affects both visualization and auto-scheduling calculations.
When a dependency constraint is violated -- for example, a Start-to-Finish link where the target task ends before the source task starts -- the Gantt displays a **red dotted line** beneath the incorrectly positioned task bar.
To resolve the violation, drag the affected task bar so its dates satisfy the dependency constraint.
## Verification
You should now see:
* Dependency arrows drawn between tasks reflecting the specific type (FS, SS, FF, or SF)
* The link type preserved when you save and reload the Gantt chart
* Red dotted violation indicators appearing when a task position violates its dependency constraint
## See Also
* [Create and Configure Dependency Links](/gantt/guides/dependencies/create-dependency-links)
* [Configure Link Lag and Delay](/gantt/guides/dependencies/link-lag)
* [Dependency Metadata Storage](/gantt/guides/dependencies/dependency-metadata)
* [Configure Auto-Scheduling](/gantt/guides/scheduling/configure-auto-scheduling)
# Create and Configure Dependency Links
Source: https://learn.nextedy.com/gantt/guides/dependencies/create-dependency-links
Set up Nextedy GANTT to display and manage task dependencies by configuring link roles, creating links visually, and controlling link direction.
## Step 1: Configure the Dependency Role
Before you can create dependency links, tell the Gantt which Polarion link role represents task dependencies:
1. Open the page in edit mode and access **Widget Properties**.
2. Navigate to **Work Items > Dependency Role**.
3. Select one or more link roles that represent dependency relationships (e.g., `depends_on`).
If you select multiple link roles, the **first selected role** is used when you create new dependency links by dragging on the chart.
**No dependency role = no links**
If the Dependency Role parameter is left empty, no dependency arrows are displayed in the Gantt chart, and users cannot create new links.
## Step 2: Create a Dependency Link Visually
With the Dependency Role configured and the Gantt in edit mode:
1. Hover over a task bar to reveal the link handle circles at the left and right edges.
2. Click and drag from one task's link handle to another task.
3. Release the mouse on the target task to create the dependency link.
An arrow appears between the two task bars, showing the dependency relationship.
## Step 3: Understand Link Direction
By default, Polarion's `depends_on` link role connects the dependent item to its source. Gantt automatically **reverses the arrow direction** so it displays correctly on the Gantt chart (from predecessor to successor).
If your Polarion project uses a custom link role where the source points to the dependent item, set the following configuration property in **Administration > Configuration Properties**:
```
nextedy.gantt.workitems.default.forward_dependency=true
```
## Dependency Types
The default dependency type is **Finish-to-Start (FS)**: the successor cannot start until the predecessor finishes. For advanced dependency types (SS, FF, SF), see [Configure Advanced Dependency Types (FS, SS, FF, SF)](/gantt/guides/dependencies/advanced-dependency-types).
| Type | Code | Meaning |
| ---------------- | ---- | --------------------------------------------------- |
| Finish-to-Start | FS | Successor cannot start before predecessor finishes |
| Start-to-Start | SS | Successor cannot start before predecessor starts |
| Finish-to-Finish | FF | Successor cannot finish before predecessor finishes |
| Start-to-Finish | SF | Successor cannot finish before predecessor starts |
**Dependency links apply to work items only**
Dependency links are supported between work items in the Work Items Gantt. Plans in the Plans Gantt use parent-child relationships only and do not support direct dependency links between plan items.
**Violated dependencies show a red dotted line**
When a dependency constraint is violated (e.g., a successor starts before its predecessor finishes in an FS relationship), the Gantt displays a red dotted line under the incorrectly positioned task. Move the task to satisfy the dependency rules to resolve the warning.
## Step 4: Delete a Dependency Link
To remove a dependency link:
1. Enter edit mode.
2. Click on the dependency arrow between two tasks.
3. Confirm the deletion when prompted.
The Polarion link between the two work items is also removed.
## Verification
You should now see:
* Dependency arrows displayed between linked tasks on the Gantt chart
* The ability to create new links by dragging between task bars in edit mode
* Arrows pointing from predecessor to successor in the correct direction
## See Also
* [Create Your First Dependency Link](/gantt/getting-started/first-dependency)
* [Configure Advanced Dependency Types (FS, SS, FF, SF)](/gantt/guides/dependencies/advanced-dependency-types)
* [Configure Link Lag and Delay](/gantt/guides/dependencies/link-lag)
* [Disable Dependency Linking](/gantt/guides/dependencies/disable-linking)
* [Configure Auto-Scheduling](/gantt/guides/scheduling/configure-auto-scheduling)
# Dependency Metadata Storage
Source: https://learn.nextedy.com/gantt/guides/dependencies/dependency-metadata
Understand how Nextedy GANTT stores advanced dependency type and lag information in the `gantt_dependency_metadata` custom field, and configure it correctly for your project.
## What the Metadata Field Stores
When you enable [advanced dependency types](/gantt/guides/dependencies/advanced-dependency-types), the Gantt needs to store two additional pieces of information for each dependency link that Polarion's native link roles do not capture:
* **Dependency type** -- which of the four types (FS, SS, FF, SF) the link uses
* **Lag** -- how many days of delay or lead time apply to the link
This information is persisted in a custom field called `gantt_dependency_metadata` on the work item. The field stores a JSON-serialized map that associates each linked target work item ID with its dependency type code and lag value.
The `gantt_dependency_metadata` field must be defined as a custom field on the relevant work item types before advanced dependency data can be stored -- the Gantt does not create Polarion custom field definitions for you. Some project templates (such as the Gantt Demo) already include it. Confirm it exists, and create it if it does not:
1. Navigate to **Administration > Custom Fields** for your project.
2. Search for `gantt_dependency_metadata`.
3. If it is missing, add it; verify it is of type **String** or **Text**.
**Do not rename or delete this field**
The Gantt reads and writes to this field by its exact ID `gantt_dependency_metadata`. Renaming, deleting, or changing its type will cause all advanced dependency type and lag data to be lost.
The metadata field contains a JSON structure that is not meant for manual editing. Hide it from work item forms:
1. Open **Administration > Form Configuration** for each relevant work item type.
2. Locate `gantt_dependency_metadata` in the field list.
3. Set it to **hidden** so it does not appear on the form layout.
| Action | Result |
| --------------------- | ------------------------------------------------------------------------------ |
| Field visible on form | Users may accidentally edit or clear the JSON, breaking dependency metadata |
| Field hidden on form | Metadata is managed exclusively by the Gantt, preventing accidental corruption |
If you have not already done so, add the following to **Project / Repository Administration > Configuration Properties**:
```
nextedy.gantt.default.advanced_dependencies=true
```
Without this property, the Gantt does not read or write to the metadata field, and all dependency links default to Finish-to-Start (type `0`).
## How Data Flows
When you create or modify a dependency link in the Gantt chart:
1. The Gantt creates (or updates) a Polarion work item link using the configured link role.
2. The Gantt writes the dependency type code and lag value into the `gantt_dependency_metadata` field on the source work item as a JSON entry keyed by the target work item ID.
3. When the chart loads, the Gantt reads the metadata field to restore the correct dependency type and lag for each link.
When you delete a dependency link:
1. The Polarion work item link is removed.
2. The corresponding entry in `gantt_dependency_metadata` is also removed.
**Metadata survives link role changes**
If you change the Dependency Role configuration, existing metadata entries remain in the custom field. The Gantt will re-associate them with the new link role on the next load.
## Verification
You should now see:
* The `gantt_dependency_metadata` field listed in your project's custom fields
* The field hidden from work item forms
* Advanced dependency types (SS, FF, SF) and lag values preserved correctly after saving and reloading the Gantt chart
## See Also
* [Configure Advanced Dependency Types (FS, SS, FF, SF)](/gantt/guides/dependencies/advanced-dependency-types)
* [Configure Link Lag and Delay](/gantt/guides/dependencies/link-lag)
* [Create and Configure Dependency Links](/gantt/guides/dependencies/create-dependency-links)
# Disable Dependency Linking
Source: https://learn.nextedy.com/gantt/guides/dependencies/disable-linking
Prevent users from creating or editing dependency links in the Nextedy GANTT chart while keeping existing dependencies visible.
## When to Disable Linking
You may want to disable dependency link creation when:
* The Gantt chart is used for read-only reporting
* Dependencies are managed exclusively in Polarion rather than on the chart
* You want to prevent accidental link creation during drag operations
## Method 1 -- Remove the Dependency Role
The simplest way to hide all dependency links entirely is to leave the **Dependency Role** widget parameter empty.
1. Open the page in **Edit mode**.
2. Click the widget gear icon to open **Widget Parameters**.
3. Navigate to the **Dependency Role** parameter.
4. Ensure no link roles are selected.
5. Click **Apply**.
With no Dependency Role configured, the Gantt will not display any dependency arrows and users cannot create new links.
**This hides existing dependencies**
Removing the Dependency Role hides all dependency arrows from the chart. The underlying Polarion work item links are not deleted -- they are simply not displayed.
## Method 2 -- Disable Drag-to-Link Only
If you want to keep existing dependency links **visible** but prevent users from creating new ones by dragging, use a Gantt Config Script:
1. Open the page in **Edit mode**.
2. Open **Widget Parameters > Advanced > Gantt Config Script**.
3. Add the following line:
```javascript theme={null}
gantt.config.drag_links = false;
```
4. Click **Apply**.
This disables the link creation handles (the circles at the start and end of each task bar) while still rendering all existing dependency arrows.
## Comparison of Methods
| Method | Existing Links Visible | New Links Allowed | Link Handles Shown |
| --------------------------------- | :--------------------: | :---------------: | :----------------: |
| Empty Dependency Role | No | No | No |
| `gantt.config.drag_links = false` | Yes | No | No |
| Both configured (normal) | Yes | Yes | Yes |
**Combine with readonly mode**
If you want a fully read-only Gantt chart with no editing at all, enable the `readonly` widget parameter. This disables all editing including dependency link creation, task dragging, and resizing.
**Plans Gantt does not support dependency links**
Dependency links apply to work items only. In Plans Gantt mode, plans have parent-child relationships but do not support direct dependency links between them.
## Verification
You should now see:
* **Method 1:** No dependency arrows drawn on the Gantt chart
* **Method 2:** Existing dependency arrows visible, but no link creation circles appear when hovering over task bars in edit mode
## See Also
* [Create and Configure Dependency Links](/gantt/guides/dependencies/create-dependency-links)
* [Configure Advanced Dependency Types (FS, SS, FF, SF)](/gantt/guides/dependencies/advanced-dependency-types)
* [Write Gantt Config Scripts](/gantt/guides/scripting/gantt-config-script)
# Dependencies
Source: https://learn.nextedy.com/gantt/guides/dependencies/index
Nextedy GANTT supports dependency links between tasks that drive scheduling logic, critical path analysis, and auto-scheduling behavior.
Set up dependency roles, create links visually by dragging between task bars, and configure link direction.
Enable and configure all four dependency types beyond the default Finish-to-Start.
Add lag (delay) or lead time between dependent tasks to model realistic scheduling gaps.
Prevent users from creating new dependency links in the Gantt chart while preserving existing ones.
Understand how advanced dependency type and lag information is stored in Polarion work item fields.
**New to dependencies?**
If you have not created a dependency link before, start with the [Create Your First Dependency Link](/gantt/getting-started/first-dependency) tutorial for a step-by-step introduction.
# Configure Link Lag and Delay
Source: https://learn.nextedy.com/gantt/guides/dependencies/link-lag
Add lag (delay) or lead (overlap) time between dependent tasks in Nextedy GANTT so that a successor starts a specified number of days after -- or before -- its predecessor finishes.
## Prerequisites
* Advanced dependency types enabled (`nextedy.gantt.default.advanced_dependencies=true`)
* The `gantt_dependency_metadata` custom field exists on your work item types (see [Dependency Metadata Storage](/gantt/guides/dependencies/dependency-metadata))
## How Lag Works
Each dependency link carries an optional **lag** value measured in days:
| Lag Value | Effect |
| --------------------- | ------------------------------------------------------------------ |
| `0` (default) | Successor starts immediately per the dependency constraint |
| Positive (e.g., `2`) | Successor is delayed by 2 days after the constraint is met |
| Negative (e.g., `-1`) | Successor can start 1 day before the constraint is met (lead time) |
Lag is stored alongside the dependency type in the `gantt_dependency_metadata` custom field on the work item.
1. Enter **Edit mode** on the Gantt chart.
2. Double-click a dependency link arrow between two tasks to open the link editor.
3. Set the **Lag** field to the desired number of days. Use a positive number for delay or a negative number for lead time.
4. Click **Save** to apply the change.
**Verify in application**
The exact UI for editing lag may vary by Gantt version. If double-clicking the link arrow does not open an editor, check that your Gantt version supports lag editing.
After saving, reload the Gantt page. Hover over the dependency link arrow to see a tooltip displaying the link type, role name, and lag value.
**Lag values may reset on older versions**
Some earlier Gantt versions had an issue where lag values were not persisted correctly and would reset to 0 on page refresh. If you experience this behavior, update to the latest Gantt version and verify that the `gantt_dependency_metadata` custom field is properly configured.
When [auto-scheduling](/gantt/guides/scheduling/configure-auto-scheduling) is enabled, the Gantt takes lag into account when calculating successor start dates. A Finish-to-Start link with a lag of 3 means the successor will be scheduled to start 3 working days after the predecessor finishes.
**Use negative lag for overlapping tasks**
If two tasks can partially overlap -- for example, testing can begin 2 days before development finishes -- set a negative lag value (e.g., `-2`) on the Finish-to-Start dependency link between them.
## Verification
You should now see:
* The lag value displayed in the dependency link tooltip
* The successor task bar shifted by the specified number of days relative to the predecessor
* Lag values preserved after saving and reloading the Gantt chart
## See Also
* [Configure Advanced Dependency Types (FS, SS, FF, SF)](/gantt/guides/dependencies/advanced-dependency-types)
* [Dependency Metadata Storage](/gantt/guides/dependencies/dependency-metadata)
* [Configure Auto-Scheduling](/gantt/guides/scheduling/configure-auto-scheduling)
* [Create and Configure Dependency Links](/gantt/guides/dependencies/create-dependency-links)
# Configure Additional Fields in Create Dialog
Source: https://learn.nextedy.com/gantt/guides/editing/additional-dialog-fields
Add custom Polarion fields to the Nextedy GANTT create and edit dialog so users can fill in project-specific data without leaving the Gantt chart.
## Prerequisites
* Gantt version **25.3.1** or later
* Access to the Gantt widget parameter configuration (editor or admin role)
1. Open the Gantt page in edit mode.
2. Open **Parameters** (click the ⚙️ settings icon in the toolbar or access the wiki page parameter editor).
3. Navigate to **Work Item Types Configurations**.
4. Select the **Item Type** you want to configure.
1. Locate the **Additional Dialog Fields** section within the selected type configuration.
2. Click to add fields. You can select from available Polarion custom fields defined in your project.
3. Reorder fields by dragging them in the selection list. The order determines how fields appear in the dialog.
## Supported Field Types
| Field Type | Supported Since | Notes |
| ------------------------------------- | --------------- | ----------------------------------------------------------------- |
| String | 25.3.1 | Single-line text input |
| Integer | 25.3.1 | Validated numeric input |
| Float | 25.3.1 | Decimal numeric input |
| Boolean | 25.3.1 | Single checkbox |
| Multi-line Text | 25.3.1 | Text area |
| Duration | 25.3.1 | Polarion work-time notation (e.g., `2d 4h`) |
| Enumerations (single and multi-value) | 25.3.1 | Dropdown or multi-select picker |
| Category | 25.3.1 | Category enumeration |
| Date | 25.5.1 | Date picker |
| Date time | 25.5.1 | Date + time picker |
| Assignee | 25.5.1 | User picker (useful when Resource is mapped to a different field) |
| Custom Fields mapped as Resources | 25.5.1 | Resource-mapped custom fields |
| Planned In | 25.7.0 | Plan assignment picker |
**Currently unsupported:** Rich-text, Dependent Enumerations, Priority, Time Point, and complex fields (comments, attachments, Linked Work Items, hyperlinks).
**Unsupported field detection**
If you add an unsupported field type, the system displays a warning and ignores the field. You do not need to check compatibility manually.
For example, adding the unsupported **Priority** field to the dialog configuration:
The field is ignored and the following warning is shown:
Starting with version **25.7.0**, fields required by the initial workflow transition are enforced in the dialog. If a required field is missing from your Additional Dialog Fields configuration, a warning appears in the editor view.
For example, an initial action named **Set Area** is added with the **Area** field marked as required:
Because the required **Area** field is not included in the dialog configuration, the following warning appears in the edit view:
Ensure all fields required by the workflow's initial action are included in the dialog configuration.
**Field conflict with Data Mapping**
Fields already used in Data Mapping (such as `startField`, `endField`, `durationField`, `resourceField`, or `progressField`) cannot be added to Additional Dialog Fields. The system prevents this and displays an error. Remove the field from Data Mapping first, or use a different field.
For example, the **Duration** field is already used in the Data Mapping configuration:
Adding that same field to the dialog configuration triggers an error:
Custom fields in the dialog can have default values pre-populated when creating a new work item. Default values are supported for:
* **Enum (select)** fields: pre-selected option
* **Text (textarea)** fields: pre-filled text
* **Float (input)** fields: pre-filled numeric value
**Auto-assignment rules**
Since version **25.6.0**, Polarion auto-assignment rules are automatically applied when creating work items from the Gantt chart. The correct assignee is set without manual input.
The dialog enforces these validation rules:
* **Field permissions**: Read-only or editable access is determined by Polarion role permissions, not dialog configuration.
* **Required fields**: Fields marked as required must be filled before saving. The save button is disabled until all required fields have values.
* **Inline validation**: Numeric fields (integer, float) show inline error text when non-numeric characters are entered.
If work item creation fails, the Gantt does not refresh, allowing you to correct the data and retry. Alternatively, you can create the work item via the standard Polarion form and copy the data.
Once a custom field is added to the dialog through Parameters, it appears when creating or editing a Work Item. For example, an Enumeration-type **Department** custom field added to the dialog:
When creating or editing a Work Item, the newly added **Department** dropdown appears in the dialog:
A simple String-type custom field behaves the same way in the dialog:
## Verification
You should now see the configured fields appear in the create/edit dialog when you click ➕ **New** and select the configured work item type. Required fields display a red asterisk, and the save button enables only after all required fields are filled.
## See Also
* [Use the Lightbox Inline Editor](/gantt/guides/editing/lightbox-editor)
* [Track and Calculate Progress](/gantt/guides/editing/progress-tracking)
* [Configure Resource Fields](/gantt/guides/resources/resource-field-configuration)
# Configure Drag Children Behavior
Source: https://learn.nextedy.com/gantt/guides/editing/drag-children
This guide shows you how to control whether child tasks move together with their parent when you drag a parent task bar in Nextedy GANTT.
## Prerequisites
* A Gantt widget with parent-child task hierarchy configured via the **Parent Role** parameter
* Edit mode access
## Understand the `dragChildren` Widget Parameter
The `dragChildren` widget parameter controls whether dragging a parent task automatically moves all its child tasks by the same offset. When enabled, the entire subtree shifts together, preserving the relative schedule. When disabled, only the parent moves and children stay at their original dates.
| Parameter | Type | Default | Description |
| -------------- | ------- | ------- | --------------------------------------------- |
| `dragChildren` | Boolean | `true` | Move child tasks together with parent on drag |
## Enable or Disable Drag Children
1. Open the Polarion page containing the Gantt widget
2. Edit the widget properties
3. Set the **Drag Children** parameter:
* **Yes** (default) -- children move with parent
* **No** -- only the parent task moves; children remain at their original dates
## Toggle Drag Children at Runtime
You can also toggle this behavior during an active edit session using the toolbar:
1. Enter Edit mode by clicking **Edit** in the toolbar
2. Locate the **Drag Children** toggle button in the toolbar
3. Click it to switch between moving children together or leaving them independent
This is useful when you need to move a parent to a new time slot without disrupting individually scheduled children.
## Range Conflict Detection
When you drag tasks independently (with `dragChildren` disabled), child tasks may end up outside their parent's date range. The Gantt can detect and highlight these conflicts:
* Conflicting tasks receive a visual warning style (highlighted border)
* Both the parent and the out-of-range child are marked
* Conflict highlighting clears automatically when the task is moved back within the parent's range
* Range conflict checks respect the working calendar when evaluating boundaries
**Range conflict is disabled by default**
Range conflict detection requires explicit enablement. The default configuration has `rangeConflict.enabled = false`. When enabled, you can further control detection with `rangeConflict.checkStart` and `rangeConflict.checkEnd` to check start date, end date, or both.
## Automatic Conflict Resolution
When a child task is dragged outside its parent's date range, the Gantt can automatically resolve the conflict by expanding the parent's range to accommodate the child's new position. This resolution works hierarchically -- all ancestor tasks in the tree are adjusted, not just the immediate parent. The same resolution applies when a task is resized beyond its parent's boundaries.
**Lock specific items from dragging**
To prevent certain work items from being moved at all, use an **Item Script** to set `task.readonly = true` for specific work item types. For example, to lock user stories while allowing tasks to be dragged:
```javascript theme={null}
if (wi.getType().getId() === 'userstory') {
task.readonly = true;
}
```
This approach lets you protect parent items from accidental rescheduling while keeping children editable.
**Drag-and-drop between parents not supported**
The Gantt does not support drag-and-drop to move a task from one parent to another. To change a task's parent, edit the parent link directly through the work item form in Polarion or use the lightbox.
## Verify Your Configuration
1. Enter Edit mode in the Gantt
2. Drag a parent task bar to a new date
3. If `dragChildren` is enabled, you should now see all child task bars shift by the same number of days
4. If `dragChildren` is disabled, only the parent bar moves and children remain in place
5. Toggle the **Drag Children** toolbar button and repeat the test to confirm the toggle works
## See Also
* [Prevent Tasks from Moving Outside Parent Range](/gantt/guides/scheduling/prevent-moving-out-of-parent) for parent-bound scheduling constraints
* [Derive Parent Schedule from Children](/gantt/guides/scheduling/parent-derived-schedule) for the inverse pattern
* [Configure Auto-Scheduling](/gantt/guides/scheduling/configure-auto-scheduling) for dependency-driven date propagation
* [Perform What-If Analysis Without Saving](/gantt/guides/scheduling/what-if-analysis) for exploring schedule changes safely
# Editing
Source: https://learn.nextedy.com/gantt/guides/editing/index
Nextedy GANTT provides multiple ways to edit work item data directly within the Gantt chart, from inline field editing to the full lightbox editor.
Open and configure the lightbox for editing work item fields directly from the Gantt chart.
Add custom fields to the create dialog that appears when adding new work items.
Configure progress tracking, display the progress bar, and use drag handles for quick updates.
Edit task fields directly in the grid columns without opening the lightbox.
Reverse or re-apply recent changes during an editing session.
Control whether child tasks move together with their parent during drag operations.
Manage unsaved edits and prevent data loss from Polarion session timeouts.
**Edit Mode vs. Read-Only**
The Gantt chart supports three editing modes: **standard** (click Edit to enter edit mode), **always edit** (tasks are immediately draggable), and **read-only** (no editing allowed). Configure the mode through widget parameters or administration properties.
# Use Inline Cell Editing
Source: https://learn.nextedy.com/gantt/guides/editing/inline-cell-editing
This guide explains how to edit task fields directly in the Nextedy GANTT grid columns without opening the lightbox.
**Verify in application**
This page is based on source code analysis. Some UI behaviors described here may vary depending on your version. Verify the editing experience in your Gantt installation.
## Prerequisites
* A Gantt widget with grid columns configured
* Edit mode enabled (click the **Edit** button in the toolbar)
## How Inline Cell Editing Works
Inline cell editing lets you click directly on a grid cell to modify its value. Each column can have an associated editor type that determines the input widget shown when editing. The Gantt supports four editor types:
| Editor Type | Input Widget | Use Case |
| ----------- | ------------------- | ---------------------------------------------- |
| `text` | Text input field | Free-text fields like titles or descriptions |
| `number` | Numeric input field | Duration, percentage, or numeric custom fields |
| `date` | Date picker | Start date, end date, or deadline fields |
| `select` | Dropdown menu | Enumeration fields like status or priority |
Each editor uses a `mapTo` property that links the editor to the underlying task property it reads from and writes to.
## Built-In System Column Editors
The Gantt includes several built-in system columns with pre-configured inline editors:
| System Column | Editor Type | Behavior |
| ------------- | ---------------------- | ------------------------------------------------------------- |
| `start_date` | Date picker | Opens a date picker mapped to the configured start field |
| `end_date` | Date picker (end date) | Validates that end date is not before start date |
| `duration` | Duration editor | Accepts day values; changes update the end date automatically |
| `progress` | Number (0-100) | Accepts values 0-100; internally stored as 0.0-1.0 |
| `deadline` | None (read-only) | Not editable inline; use the lightbox or Polarion directly |
| `owner` | None (read-only) | Not editable inline; use the lightbox to change assignments |
## Configure Grid Columns with Editors
To add columns to the Gantt grid, configure the **Table** section in the widget parameters:
1. Open the Polarion page containing the Gantt widget
2. Edit the widget properties
3. Locate the **Table** configuration section
4. Set the grid `WIDTH` parameter to control the overall grid panel width in pixels
5. Configure the **FIRST\_COL** settings for the task title column:
* `showId` -- display the work item ID prefix (e.g., `WI-123:`)
* `showTitle` -- display the work item title text
* `showIcon` -- display the work item type icon
6. Add additional columns using the **COLUMNS** list
**Verify in application**
The exact widget parameter names for column configuration may vary by version. Check the widget parameter editor in your Polarion page for the available column settings.
## Edit a Cell Value
1. Ensure the Gantt is in **Edit mode** (click **Edit** in the toolbar)
2. Click on an editable grid cell -- the appropriate editor opens based on the column type
3. Modify the value:
* For **text** and **number** editors: type the new value
* For **date** editors: select the date from the picker
* For **select** editors: choose an option from the dropdown
4. Press **Enter** or click outside the cell to confirm
5. The updated value writes back to the task property defined by the editor's `mapTo` field
**Changes propagate immediately**
When you confirm an inline edit in the grid, the new value propagates immediately to the visible columns and the timeline without requiring a full Gantt reload.
**Read-only columns**
The `deadline` and `owner` system columns do not have inline editors. To modify these fields, double-click the task bar to open the lightbox or edit the work item directly in Polarion.
## Verify Your Configuration
After configuring columns with editors:
1. Enter Edit mode in the Gantt
2. Click on a `start_date` or `duration` cell
3. You should now see the inline editor open with the current value pre-filled
4. Change the value and press Enter -- the task bar position should update immediately in the timeline
## See Also
* [Configure Grid Columns](/gantt/guides/visualization/columns) for detailed column setup
* [Manage Column Visibility](/gantt/guides/visualization/column-visibility) to show or hide columns
* [Use the Lightbox Inline Editor](/gantt/guides/editing/lightbox-editor) for full work item field editing
* [Configure Additional Fields in Create Dialog](/gantt/guides/editing/additional-dialog-fields) to customize the new-item dialog
# Use the Lightbox Inline Editor
Source: https://learn.nextedy.com/gantt/guides/editing/lightbox-editor
Edit work item fields directly from the Nextedy GANTT chart using the lightbox, without navigating to the Polarion work item form.
## Open the Lightbox
1. Enter **Edit mode** by clicking the **Edit** button in the toolbar.
2. Double-click any task bar in the Gantt chart. The lightbox opens as an inline editor overlay.
The lightbox displays the core fields by default: **Title**, **Assignee** (the configured resource field), and **Schedule** -- the start date, the duration, and the computed end date grouped together. A **Progress** field and any additional custom fields appear when they are configured (custom fields via **Additional Dialog Fields** in the Work Item Types Configuration).
Outside Edit mode (View Mode), clicking a Work Item opens its details in the **Work Item Properties** sidebar (status, estimates, time spent, due date, assignees). Users with edit access can change these fields and click **Save** in the sidebar; Reviewers see them read-only.
### Skip View Mode with Always Edit
To open the Gantt directly in Edit mode, enable **Always Edit** per widget via **Widget Properties > Work Items Sidebar > Always Edit** (set to **YES**):
If the **Edit** button is missing from the toolbar, check that **Always Edit** is set to **NO** and that **Read-only** is set to **NO** under **Work Item Parameters > Advanced**:
## Edit Fields in the Lightbox
The lightbox supports the following field types:
| Field Type | Input Control | Notes |
| ----------------- | ------------------ | ----------------------------------------------- |
| `TEXT` | Text input | Single-line string values |
| `INTEGER` | Numeric input | Validates integer-only input |
| `FLOAT` | Numeric input | Accepts decimal values |
| `DATE` | Date picker | Day/month/year selectors |
| `DATETIME` | Date + time picker | Includes time selector in hour-precision mode |
| `DURATION` | Duration input | Polarion work-time notation (e.g., `2d 4h 30m`) |
| `SELECT` | Dropdown | Single enumeration value |
| `MULTISELECT` | Multi-picker | Multiple enumeration values |
| `SINGLE_CHECKBOX` | Checkbox | Boolean toggle |
| `RICH_TEXT` | Text area | Multi-line text |
**Fractional duration notation**
The duration field accepts fractional input such as `1 1/2d 10h`. The value is normalized and stored after save. Invalid formats trigger an inline "Invalid format" error message.
Which fields are shown is configurable. Admins set the default sidebar fields for everyone via **Widget Properties > Work Items Sidebar > Sidebar Fields**:
Individual users can personalize what they see using the **Select Fields** (gear) button in the sidebar. These choices apply only to that user and to all Work Items of the same type:
## Change the Parent Task
The lightbox includes a **parent task dropdown** that lists eligible parent tasks based on your Work Item Types Configuration. Select a new parent to reparent the task directly from the editor. Selecting "no parent" detaches the task and makes it a root-level item.
## Validate and Save
Click the 💾 **Save** button to persist your changes. The lightbox runs validation before saving:
* **Required fields** marked with a red asterisk must be filled. The save button remains disabled until all required fields have values.
* **Date range validation** ensures child task dates stay within the parent task's date range. If violated, an inline error message displays the allowed parent date range.
* **Numeric validation** shows an inline error for non-numeric input in integer and float fields.
**Parent bounds constraint**
If you set a duration or date range that places the task outside its parent's boundaries, you will see the error message "cannot be scheduled outside" and the save button is disabled. Adjust the dates or remove the parent assignment to resolve this.
## Create a New Task via the Lightbox
1. Click the ➕ **New** dropdown in the toolbar.
2. Select the work item type to create.
3. The lightbox opens with default field values pre-populated from your configuration.
4. Fill in the required fields and click **Save**.
For new tasks, the save button is disabled until all required fields are completed. The delete button does not appear when creating a new task.
## Delete a Task
When editing an existing task, the lightbox displays a **Delete** button. Clicking it removes the task after a confirmation prompt.
**Verify in application**
The delete behavior depends on your Gantt configuration. Verify whether deletion removes the work item itself or only the dependency link.
## Verification
You should now see your changes reflected immediately on the Gantt chart after saving. Updated field values appear in the grid columns, and modified dates shift the task bar position on the timeline.
## See Also
* [Configure Additional Fields in Create Dialog](/gantt/guides/editing/additional-dialog-fields)
* [Track and Calculate Progress](/gantt/guides/editing/progress-tracking)
* [Use Inline Cell Editing](/gantt/guides/editing/inline-cell-editing)
* [Prevent Tasks from Moving Outside Parent Range](/gantt/guides/scheduling/prevent-moving-out-of-parent)
# Track and Calculate Progress
Source: https://learn.nextedy.com/gantt/guides/editing/progress-tracking
This guide shows you how to display, calculate, and customize task progress in Nextedy GANTT using the built-in progress field, drag interaction, and scripting.
## Prerequisites
* A Gantt widget configured with a **Progress Field** mapping (default: `gantt_progress`)
* Edit mode access to modify widget parameters
## Understand the Progress Field
The `progressField` widget parameter specifies which Polarion work item field stores the completion percentage. Progress values are stored as a float between `0.0` (not started) and `1.0` (complete). The Gantt chart displays this as a filled portion inside the task bar.
| Property | Default Value | Description |
| ------------------ | ---------------- | ------------------------------------------------- |
| `progressField` | `gantt_progress` | Work item field storing progress (0.0-1.0) |
| `drag_progress` | `true` | Enable or disable progress drag on task bars |
| `progressColoring` | `true` | Color-code task bars based on progress percentage |
The `progress` system column displays the value as 0-100 in the grid, while the internal task model stores it as 0.0-1.0.
Progress drag is enabled by default (`gantt.config.drag_progress = true`). To prevent users from adjusting progress by dragging the task bar, disable it in the Gantt Config Script with `gantt.config.drag_progress = false;`.
## Control Progress Drag
Progress drag is on by default. To set it explicitly (or re-enable it where a Config Script turned it off), use the Gantt Config Script:
1. Open the Polarion page containing the Gantt widget
2. Edit the widget properties
3. Navigate to **Advanced > Gantt Config Script**
4. Add the following line:
```javascript theme={null}
gantt.config.drag_progress = true;
```
The progress drag handle is only visible when the Gantt is in **Edit mode**. Click the **Edit** button in the toolbar before attempting to drag the progress bar.
## Calculate Progress from Time Estimates
For short-to-mid-term items where you want to compute progress automatically based on time tracking data, use an **Item Script**:
1. Navigate to **Widget Properties > Advanced > Item Script**
2. Add the following script:
```javascript theme={null}
var all = (wi.getRemainingEstimate() != null
? wi.getRemainingEstimate().getHours() : 0)
+ (wi.getTimeSpent() != null
? wi.getTimeSpent().getHours() : 0);
var done = (wi.getTimeSpent() != null
? wi.getTimeSpent().getHours() : 0);
if (wi.getResolution() != null) {
task.progress = 1;
} else if (all == 0) {
task.progress = 0;
} else {
task.progress = done / all;
}
var progressString = (wi.getTimeSpent() != null ? wi.getTimeSpent() : "0h")
+ " | "
+ (wi.getRemainingEstimate() != null ? wi.getRemainingEstimate() : "0h")
+ " (" + Math.round(task.progress * 100) + " %)";
task.getFields().put("progressString", progressString);
```
This script computes progress as `timeSpent / (remainingEstimate + timeSpent)`. Resolved items automatically show 100% progress.
To limit progress calculation to a specific type (for example, `workpackage`), wrap the script in a type check: `if (wi.getType().getId() === 'workpackage') { ... }`.
3. Disable manual drag when using automatic calculation. In **Advanced > Gantt Config Script**, add:
```javascript theme={null}
gantt.config.drag_progress = false;
```
## Show Progress Text on Task Bars
To display the calculated progress alongside the task bar, add the following to **Advanced > Gantt Config Script**:
```javascript theme={null}
gantt.templates.rightside_text = function(start, end, task) {
return (task.progress > 0
? "Progress: " + Math.round(task.progress * 100)
+ " % (" + task.fields.progressString + ") "
: "");
};
```
This renders a label to the right of each task bar showing the progress percentage and time breakdown.
## Calculate Epic or Plan Progress
For parent items like epics or plans, you can compute progress as the ratio of resolved children to total children. Use this **Item Script** pattern for Plans Gantt:
```javascript theme={null}
var allitems = trackerService.queryWorkItems(
"PLAN:(" + plan.getProjectId() + "/" + plan.getId() + ")", "id").size();
var openitems = trackerService.queryWorkItems(
"PLAN:(" + plan.getProjectId() + "/" + plan.getId()
+ ") AND HAS_VALUE:resolution", "id").size();
if (allitems > 0) {
task.progress = openitems / allitems;
} else {
task.progress = 0;
}
task.getFields().put("progressString", openitems + " / " + allitems + " done");
```
## Verify Your Configuration
After applying the scripts:
1. Open the Gantt chart and enter **Edit mode**
2. You should now see the progress bar filled proportionally inside each task bar
3. If you enabled `rightside_text`, the progress percentage and time breakdown appear to the right of each task bar
4. If you enabled `drag_progress = true`, hover over a task bar to see the drag handle appear on the progress boundary
## See Also
* [Calculate Progress with Scripts](/gantt/guides/scripting/progress-calculation-scripts) for advanced calculation patterns
* [Customize Progress-Related Coloring](/gantt/guides/visualization/progress-coloring) to color-code task bars by progress
* [Configure Right-Side Text on Task Bars](/gantt/guides/visualization/right-side-text) for additional text formatting
* [Compute Plan Progress](/gantt/guides/plans/plan-progress) for Plans Gantt progress setup
# Use Undo and Redo
Source: https://learn.nextedy.com/gantt/guides/editing/undo-redo
This guide shows you how to reverse and replay changes in Nextedy GANTT using the built-in undo and redo functionality.
**Verify in application**
This page is based on source code analysis. Some UI details may vary depending on your version. Verify the behavior in your Gantt installation.
## Prerequisites
* A Gantt widget in Edit mode
* Undo/redo is loaded automatically at Gantt startup -- no additional configuration is required
## How Undo and Redo Works
The Gantt maintains a history of changes made during an edit session. Each time you move a task bar, resize a task, or modify a value, the action is recorded. You can step backward through these changes with **Undo** and forward again with **Redo**.
| Setting | Default Value | Description |
| ------------ | ------------- | ---------------------------------------------------- |
| `undo_steps` | `10` | Maximum number of changes stored in the undo history |
The undo history is cleared when you exit Edit mode or save your changes.
## Use the Undo and Redo Buttons
1. Click **Edit** in the Gantt toolbar to enter Edit mode
2. Make one or more changes -- for example, drag a task bar to a new date
3. Click the **Undo** button in the toolbar to reverse the last change
4. Click the **Redo** button to reapply a previously undone change
5. Continue undoing or redoing as needed, up to the `undo_steps` limit
**Undo buttons visible only in Edit mode**
The Undo and Redo buttons appear in the toolbar **only** when the Gantt is in Edit mode. If you do not see them, click the **Edit** button first.
## Change the Undo History Depth
By default, the Gantt stores up to 10 undo steps. To increase or decrease this limit, modify the Gantt Config Script:
1. Open the Polarion page containing the Gantt widget
2. Edit the widget properties
3. Navigate to **Advanced > Gantt Config Script**
4. Set the `undo_steps` property:
```javascript theme={null}
gantt.config.undo_steps = 25;
```
This allows up to 25 undo operations in a single edit session.
**Verify in application**
Higher undo step values consume more browser memory. For large Gantt charts with many tasks, test the impact of increasing this value on client-side performance.
## Interaction with Editing Modes
The availability of undo and redo depends on your editing configuration:
| Configuration | Undo/Redo Available | Notes |
| ---------------------------- | ---------------------- | ----------------------------------------------------------- |
| Default (Edit/Close buttons) | Yes, in Edit mode only | Buttons appear after clicking Edit |
| `alwaysedit = true` | Yes, always visible | Gantt is always in edit mode |
| `readonly = true` | No | All editing is disabled |
| `hideToolbar = true` | Not in toolbar | Toolbar is hidden; `hideToolbar` forces `alwaysedit = true` |
**What-if analysis with undo**
Use undo as a lightweight what-if tool. Drag tasks to explore schedule alternatives, then undo all changes to return to the original state without saving. For a more structured approach, see [Perform What-If Analysis Without Saving](/gantt/guides/scheduling/what-if-analysis).
## Verify Your Configuration
1. Enter Edit mode in the Gantt
2. Drag a task bar to a new date position
3. Click **Undo** in the toolbar
4. You should now see the task bar return to its original position
5. Click **Redo** to move it back to the new position
## See Also
* [Handle Unsaved Changes and Session Timeout](/gantt/guides/editing/unsaved-changes) for understanding change persistence
* [Configure the Toolbar and Menus](/gantt/guides/layout/toolbar-configuration) for toolbar button visibility
* [Perform What-If Analysis Without Saving](/gantt/guides/scheduling/what-if-analysis) for exploring schedule alternatives
* [Use the Lightbox Inline Editor](/gantt/guides/editing/lightbox-editor) for editing work item fields
# Handle Unsaved Changes and Session Timeout
Source: https://learn.nextedy.com/gantt/guides/editing/unsaved-changes
This guide explains how Nextedy GANTT protects your work from accidental data loss and how to recover from session timeouts during editing.
## How Unsaved Change Protection Works
The Gantt tracks every modification you make during an edit session -- dragging task bars, resizing durations, editing fields in the lightbox, and creating new tasks. When the Gantt detects unsaved changes and you attempt to navigate away, it intervenes to prevent data loss.
## Navigation Protection
The Gantt intercepts three types of navigation when you have unsaved changes:
| Navigation Type | Protection | Dialog |
| ----------------------------- | ------------------------------- | --------------------------------------- |
| Close browser tab / window | Browser beforeunload event | Browser's built-in "Leave site?" prompt |
| Click a link on the page | Link click interception | "Discard changes?" confirmation dialog |
| Browser back / forward button | History navigation interception | "Discard changes?" confirmation dialog |
When any of these events occur:
1. The Gantt checks whether there are unsaved changes (dirty state)
2. If changes exist, a confirmation dialog appears
3. Choose **Cancel** to stay on the page and continue editing
4. Choose **Discard** (or leave the page) to abandon unsaved changes
**Save frequently during long editing sessions**
The Gantt undo history stores up to `10` changes by default. For complex rescheduling involving many tasks, save periodically to avoid losing work if the browser crashes or the session expires.
## Save Your Changes
To persist your edits to Polarion:
1. Click the **Save** button in the Gantt toolbar (or the floating save button if the toolbar is hidden)
2. A progress indicator appears during the save operation
3. After a successful save, the dirty state clears and navigation protection is removed
4. If no changes exist, the save button does nothing
## Recover from Session Timeout
When your Polarion session expires while you are editing the Gantt -- for example, due to SSO logout or inactivity timeout -- the save operation may fail.
**SSO logout recovery (v24.9.2+)**
Starting with version 24.9.2, the Gantt displays a clear notification when your session has expired during editing. To recover your unsaved work:
1. Open a new browser tab
2. Log in to Polarion in the new tab
3. Return to the Gantt tab
4. Click **Save** again -- your changes are preserved in the browser and will save successfully with the new session
**Older versions may lose data on session timeout**
In versions before 24.9.2, a session timeout during editing could result in a save failure without clear feedback. Update to the latest version for improved session management. See [Update to the Latest Version](/gantt/getting-started/update-gantt).
## Dirty State Tracking
The Gantt maintains a dirty state flag that indicates whether any unsaved changes exist. This flag drives several behaviors:
* The **Save** button becomes active when changes are pending
* Navigation protection activates when dirty state is `true`
* The dirty state clears after a successful save or when you explicitly discard changes
* Each individual task also tracks its own dirty state, enabling the Gantt to identify which specific work items need updating
## Interaction with Editing Modes
| Configuration | Unsaved Change Protection |
| ---------------------------- | ------------------------------------------------- |
| Default (Edit/Close buttons) | Active during edit mode; clears on Close Editing |
| `alwaysedit = true` | Always active when changes exist |
| `readonly = true` | Not applicable -- no editing possible |
| `hideToolbar = true` | Active; a floating save button appears for saving |
## Verify Your Configuration
1. Enter Edit mode and drag a task bar to a new date
2. Try to navigate to another page by clicking a link
3. You should now see a "Discard changes?" confirmation dialog
4. Click **Cancel** to return to the Gantt, then click **Save** to persist your change
## See Also
* [Use Undo and Redo](/gantt/guides/editing/undo-redo) for reversing changes before saving
* [Troubleshooting Save Failures](/gantt/guides/troubleshooting/save-failures) for resolving save errors
* [Configure the Toolbar and Menus](/gantt/guides/layout/toolbar-configuration) for toolbar and save button visibility
* [Perform What-If Analysis Without Saving](/gantt/guides/scheduling/what-if-analysis) for exploring changes without committing
# Use Dynamic Queries with Page Parameters
Source: https://learn.nextedy.com/gantt/guides/filtering/dynamic-queries
This guide shows you how to configure Nextedy GANTT widget queries that respond dynamically to Polarion page parameter selections, letting users switch between data sets without editing the widget configuration.
## Prerequisites
* Your Gantt page must be a **LiveReport** page (page parameters are a LiveReport feature).
* The widget query type must be set to **Lucene + Velocity** (not pure Lucene).
**Page parameters require Lucene + Velocity query type**
Page parameters only work when the Gantt widget query is configured as **Lucene + Velocity**. If you use a pure Lucene query, Velocity expressions like `$pageParameters` are not processed and the filter will not apply.
1. Open your Gantt LiveReport page in **Edit** mode.
2. Navigate to the page parameter configuration area.
3. Add a new page parameter. For example, create a parameter with:
* **ID**: `department`
* **Type**: Enum (or any appropriate type for your use case)
* **Label**: Department
In the Gantt widget configuration, set the **Query Type** to **Lucene + Velocity**, then enter a query that uses the page parameter value:
```velocity theme={null}
type:task AND department.KEY:($pageParameters.department.toLucene())
```
The `$pageParameters.department.toLucene()` expression converts the selected page parameter value into a valid Lucene query fragment.
**Use `.toLucene()` for safe query conversion**
Always use the `.toLucene()` method on page parameter values to ensure proper escaping and formatting in the Lucene query string.
Page parameters can also drive the Gantt time range. Create `start` and `end` date parameters, then reference them in **Advanced > Gantt Config Script**:
```javascript theme={null}
gantt.config.start_date = new Date($widgetContext.pageParameters.start.value.time);
gantt.config.end_date = new Date($widgetContext.pageParameters.end.value.time);
```
Replace `start` and `end` with your actual parameter IDs if they differ.
When filtering by a page parameter, you may want to display parent items above the filtered work items for context. Use a **Page Script** to traverse parent links and include them in the query:
```velocity theme={null}
#set($parentLinkRole = "parent")
#set($parents = $objectFactory.newSet())
#foreach($i in $transaction.workItems.search.query(
"department.KEY:$pageParameters.department.toLucene()").sort(id))
#if(!$i.isUnresolvable() && $i.can().read())
#foreach($p in $i.fields.linkedWorkItems.direct)
#set($pItem = $p.fields.workItem)
#if(!$pItem.isUnresolvable() && $pItem.can().read()
&& $parentLinkRole.equals($p.fields.role.optionId))
#set($n = $parents.add($pItem.reference.id))
#end
#end
#end
#end
#set($parentQ = "id:(")
#foreach($id in $parents)
#set($parentQ = "$parentQ $id")
#end
#set($parentQ = "$parentQ )")
$!pageContext.put("parentQ", $parentQ)
```
Then include the parent query in the widget query field to add the parent items to the Gantt chart.
## Common Use Cases
| Use Case | Parameter Type | Query Pattern |
| -------------------- | -------------- | ---------------------------------------------------------- |
| Filter by department | Enum | `department.KEY:($pageParameters.department.toLucene())` |
| Filter by team | Enum | `team.KEY:($pageParameters.team.toLucene())` |
| Filter by date range | Date | `gantt.config.start_date = new Date(...)` in Config Script |
| Filter by plan level | Enum | Use page parameter to select which plan to display |
## Verification
After configuring dynamic queries, you should now see:
* A page parameter dropdown or selector on your LiveReport page.
* Changing the parameter value reloads the Gantt with a filtered set of work items.
* The funnel icon in the footer reflects any time range filter applied via page parameters.
## See Also
* [Use Gantt Filters](/gantt/guides/filtering/gantt-filters)
* [Configure Page Parameters](/gantt/guides/layout/page-parameters)
* [Write Page Scripts with Velocity](/gantt/guides/scripting/page-script)
* [Configure Multiple Plan Levels](/gantt/guides/plans/plan-level-configuration)
# Filter by Resource and Allocation
Source: https://learn.nextedy.com/gantt/guides/filtering/filter-by-resource
This guide explains how to filter the Nextedy GANTT chart by resource assignee and allocation markers to focus on a specific team member's workload.
## Prerequisites
* The resource view must be enabled in the widget parameters (**Show Resource View** set to **Yes**).
* Work items must have assignees (or the configured **Resource Field** must be populated).
## Filter by Clicking a Resource Name
1. Locate the resource view panel below the Gantt chart timeline.
2. Click the name of the resource (assignee) you want to filter by.
3. The Gantt chart updates to show only rows where that resource is assigned.
4. The selected resource row receives a visual highlight in the resource view.
Parent tasks and dependency-linked tasks remain visible to preserve the scheduling context, even if they are not directly assigned to the filtered resource.
**Scope the resource view to team assignments**
To make allocation markers reflect team-level assignments and capacity rather than individual user calendars, load the Gantt with the `loadTeamAssignments=true` URL parameter (see [URL Parameters Reference](/gantt/reference/url-parameters)). To focus on a single person's workload, click that resource's allocation bubble in the resource view as described below.
## Filter by Allocation Bubble
Clicking an allocation marker cell (bubble) in the resource view filters the Gantt to show work items for a specific resource within a specific time period.
### Workload Column
When filtering by allocation bubble with **Resource Load Calculation** set to **Remaining Estimate** or **Estimate + Spent**, a **selectedWorkload** column appears in the table view showing the planned effort (in hours) for each contributing item.
Since version 25.4.2, allocation bubble filtering works with **all** load calculation modes. However, the per-task effort column only appears for estimate-based modes.
| Load Calculation Mode | Allocation Bubble Filter | Effort Column Shown |
| --------------------- | ------------------------ | ------------------- |
| Leaf Items Count | Yes (since 25.4.2) | No |
| Estimate + Spent | Yes (since 25.4.1) | Yes |
| Remaining Estimate | Yes (since 25.4.1) | Yes |
| Assignment Allocation | Yes (since 25.4.2) | No |
**Collapsed trees expand automatically**
When you filter by allocation bubble, collapsed parent items automatically expand so you can view all affected items and their individual allocations.
## Use Resource Checkboxes
Each resource row in the resource view has a checkbox. Toggle these checkboxes to include or exclude specific resources from the filter. Combining checkbox selections with allocation marker clicks lets you refine the filter to show tasks for multiple resources.
**Leaf task filtering affects workload calculations**
Filtered work items without visible children are treated as leaf items in resource load calculations. If you filter out child tasks, parent items may appear in the workload count. Configure the resource view parameters carefully to ensure accurate workload reporting.
## Clear the Resource Filter
To remove the resource filter and show all items again:
1. Click the **Filter by Item** toolbar button to toggle off the active filter.
2. The funnel icon in the footer disappears and all rows become visible again.
## Verification
After applying a resource filter, you should now see:
* Only work items assigned to the selected resource (plus their parent and dependent items for context).
* The selected resource row highlighted in the resource view.
* The footer showing the filtered row count (for example, "Gantt Rows: 4 of 10").
* The funnel icon tooltip describing the active resource filter.
## See Also
* [Use Gantt Filters](/gantt/guides/filtering/gantt-filters)
* [Set Up the Resource View](/gantt/guides/resources/resource-view)
* [Configure Resource Fields](/gantt/guides/resources/resource-field-configuration)
* [Configure Resource Allocation Marker Colors](/gantt/guides/visualization/resource-marker-colors)
* [Hide Inactive Resources](/gantt/guides/resources/resource-hiding)
# Use Gantt Filters
Source: https://learn.nextedy.com/gantt/guides/filtering/gantt-filters
This guide shows you how to apply item, resource, time range, and allocation filters in Nextedy GANTT to focus the chart on the work items that matter most.
## Filter Types Overview
| Filter Type | Trigger | Available Since |
| --------------------------- | ------------------------------------------ | --------------- |
| Time range | Gantt Config Script | All versions |
| Filter by item | Select items, then click toolbar button | 25.4.1 |
| Filter by resource | Click a resource name in the resource view | 25.4.1 |
| Filter by allocation bubble | Click an allocation marker cell | 25.4.1 |
When any filter is active, a **funnel icon** appears in the Gantt footer. Hover over the funnel icon to see a tooltip describing the currently applied filter (time range, by item, resource, or allocation).
## Filter by Time Range
Set a fixed time range in **Advanced > Gantt Config Script** to limit which work items are visible on the chart:
```javascript theme={null}
gantt.config.start_date = new Date(2024, 11, 10);
gantt.config.end_date = new Date(2025, 7, 20);
```
**JavaScript months are zero-based**
In JavaScript `Date` objects, months start at 0 (January = 0, December = 11). The example above sets the range from **10 December 2024** to **20 August 2025**.
### Use Page Parameters for Dynamic Time Ranges
To let users select the time range interactively, create `start` and `end` page parameters on your LiveReport page, then reference them in the Gantt Config Script:
```javascript theme={null}
gantt.config.start_date = new Date($widgetContext.pageParameters.start.value.time);
gantt.config.end_date = new Date($widgetContext.pageParameters.end.value.time);
```
Replace `start` and `end` with the IDs of your page parameters if you named them differently. See [Use Dynamic Queries with Page Parameters](/gantt/guides/filtering/dynamic-queries) for more details.
## Filter by Item
1. Click one or more work items in the Gantt chart to select them.
2. Click the **Filter by Item** button in the toolbar.
3. The chart displays only the selected items and their related items (parents, children, and dependencies).
To clear the filter, click the **Filter by Item** toolbar button again to toggle it off.
## Filter by Resource
Click on a specific resource (assignee) name in the resource view to filter the chart to only rows where that resource is assigned. This helps you focus on an individual team member's workload.
**Resource filtering preserves context**
When filtering by resource, parent and dependent tasks remain visible to maintain the scheduling context. The filtered resource's tasks are highlighted while related items stay accessible.
## Filter by Allocation Bubble
Click an allocation bubble (marker cell) in the resource view to filter by a specific resource within a specific time period. This shows which work items contribute to that resource's workload in the selected day, week, or month.
When the **Resource Load Calculation** is set to **Remaining Estimate** or **Estimate + Spent**, a workload column appears in the table view showing the planned effort (in hours) per task. Since version 25.4.2, filtering by allocation bubble works with all load calculation modes, but the per-task effort column only appears for estimate-based modes.
**Collapsed trees expand automatically**
When you filter by allocation bubble, any collapsed parent items automatically expand so you can see all affected items and their allocations.
## Footer Indicators
The Gantt footer shows the number of visible rows versus the total (for example, "Gantt Rows: 4 of 10"). When items are hidden by a filter or by collapsed parent rows, the funnel icon appears. Hover over it to see which filter is active and why items are hidden.
## Verification
After applying a filter, you should now see:
* The funnel icon in the footer indicating an active filter.
* Only the matching work items visible in the chart.
* The footer row count reflecting the filtered set (for example, "Gantt Rows: 4 of 10").
* Hovering over the funnel icon displays a tooltip describing the active filter.
## See Also
* [Filter by Resource and Allocation](/gantt/guides/filtering/filter-by-resource)
* [Set the Gantt Time Range](/gantt/guides/scheduling/set-time-range)
* [Use Dynamic Queries with Page Parameters](/gantt/guides/filtering/dynamic-queries)
* [Configure the Toolbar and Menus](/gantt/guides/layout/toolbar-configuration)
* [Set Up the Resource View](/gantt/guides/resources/resource-view)
# Filtering and Sorting
Source: https://learn.nextedy.com/gantt/guides/filtering/index
Nextedy GANTT provides several ways to filter and sort work items in the chart, helping you focus on the tasks that matter most.
Apply item, resource, and allocation filters using the toolbar filter controls to focus the chart on specific work items.
Filter the Gantt view by resource assignee and workload allocation markers to see a specific team member's tasks.
Control the sort order of work items in the Gantt chart using the Sort By widget parameter and configuration properties.
Build Velocity-based queries that respond to page parameter selections, letting users switch data sets without editing the widget.
Configure the maximum number of items loaded into the Gantt to maintain performance with large work item queries.
**Combine filtering with dynamic queries**
For the most flexible Gantt views, use [page parameters](/gantt/guides/layout/page-parameters) to let users choose which data set to load, then apply Gantt filters to further refine the visible items within that set.
# Manage Large Datasets with Max Items
Source: https://learn.nextedy.com/gantt/guides/filtering/max-items
This guide explains how to configure the maximum number of work items loaded into the Nextedy GANTT chart to maintain performance when working with large queries.
**Verify in application**
This page has thin source coverage. Some behaviors described here are based on code analysis and may vary by version. Verify settings in your application.
## Understanding the Max Items Limit
The Gantt widget limits the number of work items loaded from the server to prevent performance degradation with large data sets. When the query returns more items than the configured maximum, excess items are skipped and not displayed on the chart.
The default limit is **100** items.
## Configure Max Items Per Widget
Set the **Max Items** widget parameter on your Gantt widget to control how many items are loaded:
1. Open your Gantt page in **Edit** mode.
2. In the widget parameter sidebar, locate the **Max Items** field.
3. Enter the desired maximum number of items (for example, `200` or `500`).
4. Click **Apply** to save the change.
## Configure the System-Wide Default
Administrators can set the default max items value for all new Gantt widgets using a configuration property in **Administration > Configuration Properties**:
```
nextedy.gantt.workitems.default.max_items=100
```
Once a widget is added to a page, the widget-level parameter value takes precedence over the system default.
## Load Information Indicators
When the Gantt loads data, it tracks several metrics about the loading process:
| Metric | Description |
| ---------------- | ------------------------------------------------------------ |
| Items | Total number of work items loaded and displayed |
| Skipped | Items that exceeded the max items limit |
| Filtered | Items removed by active filters (time range, resource, etc.) |
| Hidden | Items hidden due to collapsed parent rows |
| Unresolvable | Items that could not be read (permissions or data issues) |
| Errors | Count of items that encountered loading errors |
| Server load time | Time taken by the server to process the data request |
The Gantt footer displays the visible row count versus the total (for example, "Gantt Rows: 80 of 120"). If items are skipped due to the max items limit, the funnel icon appears in the footer to alert you.
## Choosing the Right Value
Consider these factors when setting the max items limit:
* **Performance**: Higher values increase page load time and memory usage. Charts with hundreds of items may become slow to render and interact with.
* **Usability**: Very large charts are difficult to navigate visually. Consider using [filters](/gantt/guides/filtering/gantt-filters) or [dynamic queries](/gantt/guides/filtering/dynamic-queries) to narrow the data set instead of increasing the limit.
* **Server load**: Each additional item requires server-side processing for date calculations, resource allocation, and dependency resolution.
**Use filters instead of increasing max items**
Rather than setting a very high max items value, use [page parameters](/gantt/guides/filtering/dynamic-queries) or [Gantt filters](/gantt/guides/filtering/gantt-filters) to narrow the query to a manageable set of work items. This provides better performance and a more focused view.
## Verification
After configuring the max items parameter, you should now see:
* The Gantt chart loading up to the specified number of items.
* The footer row count reflecting the loaded items versus the total query results.
* A funnel icon in the footer if items were skipped due to the max items limit.
## See Also
* [Use Gantt Filters](/gantt/guides/filtering/gantt-filters)
* [Use Dynamic Queries with Page Parameters](/gantt/guides/filtering/dynamic-queries)
* [Troubleshooting Performance Issues](/gantt/guides/troubleshooting/performance)
* [Configure the Toolbar and Menus](/gantt/guides/layout/toolbar-configuration)
# Configure Item Sorting
Source: https://learn.nextedy.com/gantt/guides/filtering/sorting
This guide shows you how to control the sort order of work items in the Nextedy GANTT chart using widget parameters and configuration properties.
## Set the Sort By Widget Parameter
The primary way to control sorting is through the **Sort By** widget parameter on the Gantt widget:
1. Open your Gantt page in **Edit** mode.
2. In the widget parameter sidebar, locate the **Sort By** field.
3. Enter the Polarion field ID you want to sort by (for example, `id`, `title`, `priority`, or a custom field ID).
4. Click **Apply** to save the change.
The default value for the Sort By parameter is `id`, which sorts work items by their Polarion work item ID.
## Configure the Default Sort Order
Administrators can set the system-wide default sort field using configuration properties. This default applies to all new Gantt widgets until overridden at the widget level.
### Work Items Gantt
Set the default sort field in **Administration > Configuration Properties**:
```
nextedy.gantt.workitems.default.sort_by=id
```
### Plans Gantt
For Plans Gantt widgets, the sort parameter also defaults to `id`:
```
nextedy.gantt.plans.default.sort_by=id
```
## Sort Children by ID
By default, child work items follow the sort order defined by the Sort By parameter. To force child items to always sort by their work item ID regardless of the parent-level sort, set the following configuration property:
```
nextedy.gantt.sort_children_by_id=true
```
The default value is `false`.
| Configuration Property | Purpose | Default |
| ----------------------------------------- | --------------------------------------- | ------- |
| `nextedy.gantt.workitems.default.sort_by` | Default sort field for Work Items Gantt | `id` |
| `nextedy.gantt.plans.default.sort_by` | Default sort field for Plans Gantt | `id` |
| `nextedy.gantt.sort_children_by_id` | Force child items to sort by ID | `false` |
**Manual drag-and-drop sorting is not supported**
The Gantt chart does not support manual reordering of items by dragging rows. Sorting is always determined by the configured Sort By field. If you need different sort orders for different views, create separate Gantt pages with different Sort By values.
**Multi-field sorting**
You can sort by multiple fields by specifying them in the Sort By parameter. The primary sort field takes precedence, with secondary fields used to break ties.
**PlannedIn sorting as a secondary field**
Using the `plannedIn` field as a secondary sort criterion has known limitations. If you experience unexpected ordering when combining `plannedIn` with other sort fields, try using `plannedIn` as the primary sort instead.
## Verification
After changing the Sort By parameter, you should now see:
* Work items reordered according to the specified field value.
* Child items following the parent-level sort order (or sorted by ID if `nextedy.gantt.sort_children_by_id` is `true`).
* The sort order persisting across page reloads.
## See Also
* [Use Gantt Filters](/gantt/guides/filtering/gantt-filters)
* [Use Dynamic Queries with Page Parameters](/gantt/guides/filtering/dynamic-queries)
* [Configure Grid Columns](/gantt/guides/visualization/columns)
* [Configure Page Parameters](/gantt/guides/layout/page-parameters)
# Guides
Source: https://learn.nextedy.com/gantt/guides/index
The Nextedy GANTT guides provide task-oriented instructions for configuring and customizing your Gantt chart.
## Scheduling
[**Configure Auto-Scheduling**](/gantt/guides/scheduling/configure-auto-scheduling) -- Enable dependency-driven automatic date recalculation.
[**Set the Gantt Time Range**](/gantt/guides/scheduling/set-time-range) -- Limit the visible timeline to a specific date range.
[**Schedule in Hours Instead of Days**](/gantt/guides/scheduling/hour-precision) -- Switch to hour-level duration precision.
[**Derive Parent Schedule from Children**](/gantt/guides/scheduling/parent-derived-schedule) -- Make parent task bars auto-adjust to child extents.
[**Derive Schedule from Polarion Plans**](/gantt/guides/scheduling/plan-derived-schedule) -- Pull task dates from plan assignments.
[**Prevent Tasks from Moving Outside Parent Range**](/gantt/guides/scheduling/prevent-moving-out-of-parent) -- Enforce parent boundary constraints.
[**Perform What-If Analysis Without Saving**](/gantt/guides/scheduling/what-if-analysis) -- Experiment with schedule changes before committing.
[**Disable Date Rounding on Drag**](/gantt/guides/scheduling/date-rounding) -- Allow precise date placement when dragging tasks.
## Dependencies
[**Create and Configure Dependency Links**](/gantt/guides/dependencies/create-dependency-links) -- Set up task-to-task dependency arrows.
[**Configure Advanced Dependency Types (FS, SS, FF, SF)**](/gantt/guides/dependencies/advanced-dependency-types) -- Use all four dependency relationship types.
[**Configure Link Lag and Delay**](/gantt/guides/dependencies/link-lag) -- Add lead or lag time between linked tasks.
[**Disable Dependency Linking**](/gantt/guides/dependencies/disable-linking) -- Turn off dependency creation in the chart.
[**Dependency Metadata Storage**](/gantt/guides/dependencies/dependency-metadata) -- Understand how dependency data is persisted.
## Resources
[**Set Up the Resource View**](/gantt/guides/resources/resource-view) -- Enable the resource allocation panel.
[**Configure Resource Fields**](/gantt/guides/resources/resource-field-configuration) -- Map the assignee field for resource tracking.
[**Set Up a Cross-Team Gantt Chart**](/gantt/guides/resources/cross-team-gantt) -- Visualize multiple teams on one chart.
[**Set Up Team Assignments Gantt**](/gantt/guides/resources/team-assignments-gantt) -- Configure team-based capacity tracking.
[**Set Up a Release Gantt with Teams**](/gantt/guides/resources/release-gantt-with-teams) -- Combine release planning with team views.
[**Configure External Team Management Project**](/gantt/guides/resources/external-team-management) -- Source team data from a central project.
[**Hide Inactive Resources**](/gantt/guides/resources/resource-hiding) -- Remove empty rows from the resource view.
[**Mark Tasks Without Resource Allocation**](/gantt/guides/resources/no-allocation-marking) -- Flag unassigned tasks visually.
## Calendars
[**Load Holidays and Non-Working Days**](/gantt/guides/calendars/load-holidays) -- Configure global off-days.
[**Load User Calendars**](/gantt/guides/calendars/user-calendars) -- Enable per-user scheduling calendars.
[**Set Up Work Item Calendars**](/gantt/guides/calendars/work-item-calendar) -- Use work items as calendar definitions.
[**Import Calendars from CSV**](/gantt/guides/calendars/csv-calendar-import) -- Bulk-load calendar data from files.
[**Use Calendars from Another Project**](/gantt/guides/calendars/cross-project-calendar) -- Share calendars across projects.
[**Customize Working Hours per Resource**](/gantt/guides/calendars/working-hours-per-resource) -- Set different hours per user.
[**Configure Capacity Modifier Fields**](/gantt/guides/calendars/capacity-modifier-fields) -- Account for unplanned work overhead.
## Visualization
[**Configure Item Colors**](/gantt/guides/visualization/configure-colors) -- Control task bar color logic.
[**Customize Progress-Related Coloring**](/gantt/guides/visualization/progress-coloring) -- Adjust overdue and progress colors.
[**Configure the Time Scale**](/gantt/guides/visualization/timescale) -- Set zoom levels and header formats.
[**Configure Grid Columns**](/gantt/guides/visualization/columns) -- Add and arrange grid columns.
[**Manage Column Visibility**](/gantt/guides/visualization/column-visibility) -- Show and hide columns per user.
[**Show Deadlines and Due Dates**](/gantt/guides/visualization/deadlines) -- Display deadline markers on the chart.
[**Configure Milestone Work Items**](/gantt/guides/visualization/milestones) -- Set up milestone diamond markers.
[**Create and Configure Markers**](/gantt/guides/visualization/markers) -- Add vertical timeline markers.
[**Compare Schedule with Baselines**](/gantt/guides/visualization/baselines-comparison) -- Show planned vs actual schedule.
[**Configure Resource Allocation Marker Colors**](/gantt/guides/visualization/resource-marker-colors) -- Customize resource view colors.
[**Configure Right-Side Text on Task Bars**](/gantt/guides/visualization/right-side-text) -- Display labels beside task bars.
[**Customize Text Inside Task Bars**](/gantt/guides/visualization/text-inside-bars) -- Control bar label content.
[**Adjust Gantt Row Height**](/gantt/guides/visualization/row-height) -- Change the height of task rows.
[**Use Classic Project Brackets View**](/gantt/guides/visualization/classic-project-brackets) -- Switch to bracket-style parent bars.
[**Use Square Task Borders**](/gantt/guides/visualization/square-task-borders) -- Replace rounded corners with square edges.
[**Customize Gantt Tooltips**](/gantt/guides/visualization/tooltips) -- Configure hover tooltip content.
[**Highlight Off-Days in the Timeline**](/gantt/guides/visualization/off-day-highlighting) -- Shade non-working days.
## Editing
[**Use the Lightbox Inline Editor**](/gantt/guides/editing/lightbox-editor) -- Edit work item fields directly in the Gantt.
[**Configure Additional Fields in Create Dialog**](/gantt/guides/editing/additional-dialog-fields) -- Add fields to the new item form.
[**Track and Calculate Progress**](/gantt/guides/editing/progress-tracking) -- Manage task completion percentages.
[**Use Inline Cell Editing**](/gantt/guides/editing/inline-cell-editing) -- Edit values directly in grid cells.
[**Use Undo and Redo**](/gantt/guides/editing/undo-redo) -- Reverse and replay editing actions.
[**Configure Drag Children Behavior**](/gantt/guides/editing/drag-children) -- Control child movement on parent drag.
[**Handle Unsaved Changes and Session Timeout**](/gantt/guides/editing/unsaved-changes) -- Protect work during editing.
## Layout and Navigation
[**Use Fullscreen and Maximize Mode**](/gantt/guides/layout/fullscreen-mode) -- Expand the Gantt to fill the screen.
[**Configure Page Parameters**](/gantt/guides/layout/page-parameters) -- Pass dynamic values to the widget.
[**Scroll to Today on Load**](/gantt/guides/layout/scroll-to-today) -- Auto-navigate to the current date.
[**Configure the Toolbar and Menus**](/gantt/guides/layout/toolbar-configuration) -- Customize toolbar buttons.
[**Use Multiple Gantt Widgets**](/gantt/guides/layout/multiple-widgets) -- Place several Gantt charts on one page.
[**Print and Export to PNG**](/gantt/guides/layout/print-and-export) -- Generate printable output.
## Filtering and Sorting
[**Use Gantt Filters**](/gantt/guides/filtering/gantt-filters) -- Filter visible tasks by text or criteria.
[**Filter by Resource and Allocation**](/gantt/guides/filtering/filter-by-resource) -- Narrow the view to specific users.
[**Configure Item Sorting**](/gantt/guides/filtering/sorting) -- Control task ordering in the grid.
[**Use Dynamic Queries with Page Parameters**](/gantt/guides/filtering/dynamic-queries) -- Build parameterized data sets.
[**Manage Large Datasets with Max Items**](/gantt/guides/filtering/max-items) -- Limit loaded items for performance.
## Scripting
[**Write Item Scripts**](/gantt/guides/scripting/item-script-basics) -- Customize individual task properties.
[**Write Gantt Config Scripts**](/gantt/guides/scripting/gantt-config-script) -- Configure chart-wide behavior.
[**Write Page Scripts with Velocity**](/gantt/guides/scripting/page-script) -- Use server-side scripting.
[**Color Logic Script Examples**](/gantt/guides/scripting/color-logic-scripts) -- Practical color customization scripts.
[**Calculate Progress with Scripts**](/gantt/guides/scripting/progress-calculation-scripts) -- Derive progress from custom logic.
[**Create Markers with Scripts**](/gantt/guides/scripting/marker-scripts) -- Add dynamic timeline markers.
[**Migrate Scripts for Polarion 2304+**](/gantt/guides/scripting/script-migration-2304) -- Update scripts for new Polarion versions.
[**Debug Script Errors**](/gantt/guides/scripting/debug-scripts) -- Troubleshoot script issues.
## Plans Gantt
[**Show Plans and Work Items Together**](/gantt/guides/plans/plans-and-work-items) -- Display plan bars with nested work items.
[**Compute Plan Progress**](/gantt/guides/plans/plan-progress) -- Calculate plan completion percentages.
[**Sync Work Item Dates to Plans**](/gantt/guides/plans/sync-to-plans) -- Align work item schedules with plan boundaries.
[**Configure Multiple Plan Levels**](/gantt/guides/plans/plan-level-configuration) -- Set up nested plan hierarchies.
## Troubleshooting
[**Troubleshooting Installation Issues**](/gantt/guides/troubleshooting/installation-issues) -- Resolve setup problems.
[**Troubleshooting Blank or Non-Loading Gantt**](/gantt/guides/troubleshooting/blank-gantt) -- Fix empty chart displays.
[**Troubleshooting Save Failures**](/gantt/guides/troubleshooting/save-failures) -- Diagnose save errors.
[**Troubleshooting Script Errors**](/gantt/guides/troubleshooting/script-errors) -- Debug script failures.
[**Troubleshooting Reviewer Access Issues**](/gantt/guides/troubleshooting/reviewer-access) -- Fix permission problems.
[**Troubleshooting Today Marker Position**](/gantt/guides/troubleshooting/today-marker-position) -- Correct date marker issues.
[**Troubleshooting Performance Issues**](/gantt/guides/troubleshooting/performance) -- Optimize chart loading.
[**Troubleshooting Calendar Integration Issues**](/gantt/guides/troubleshooting/calendar-issues) -- Fix calendar configuration.
## Integration
[**Import Dependencies from MS Project**](/gantt/guides/integration/ms-project-import) -- Bring in external project data.
[**Configure Gantt Workflow Conditions**](/gantt/guides/integration/polarion-workflow-conditions) -- Integrate with Polarion workflows.
[**Apply Custom CSS to the Gantt Widget**](/gantt/guides/integration/custom-css-styling) -- Style the chart with CSS.
If you have not set up a Gantt widget yet, start with the [Getting Started](/gantt/getting-started/index) tutorials before diving into these guides.
# Apply Custom CSS to the Gantt Widget
Source: https://learn.nextedy.com/gantt/guides/integration/custom-css-styling
Customize the visual appearance of the Nextedy GANTT chart by injecting CSS styles through Polarion script block widgets on the same page.
## How CSS Styling Works
The Gantt chart renders inside an iframe embedded in your Polarion wiki page. CSS styles defined in a **Script block** widget on the same page are automatically copied into the Gantt iframe, allowing you to override default styling for task bars, text, grid columns, and other visual elements.
1. Open your Gantt wiki page in edit mode
2. Add a **Script - block** widget to the page (from the Widgets panel)
3. Place it anywhere on the page (it does not need to be adjacent to the Gantt widget)
Insert your CSS inside a `
```
* **Positioning**: Modify `top` and `bottom` values to adjust vertical alignment
* **Appearance**: Customize `color` and `font-size` to match your style
### Change Font Color of Task Labels
```html theme={null}
```
### Style Completed Items with Strikethrough
Use an item script to add a CSS class to completed items, then target that class:
```html theme={null}
```
**Combine CSS with item scripts**
For dynamic styling based on work item properties (e.g., status, priority), use an item script to set a CSS class on the task, then target that class in your CSS. See [Write Item Scripts](/gantt/guides/scripting/item-script-basics) for details.
Row and task heights are controlled via the Gantt Config Script (not CSS). Navigate to the widget parameters, open **Advanced > Gantt Config Script**, and add:
```javascript theme={null}
gantt.config.task_height = 20;
gantt.config.row_height = 22;
```
| Property | Description | Recommendation |
| ------------- | ---------------------------------------- | -------------------------------------- |
| `task_height` | Height of the task bar in pixels | Set slightly smaller than `row_height` |
| `row_height` | Height of each row in the grid and chart | Minimum 2px more than `task_height` |
**Task height must be smaller than row height**
If `task_height` is equal to or greater than `row_height`, task bars may overlap or render incorrectly.
## Common CSS Targets
| CSS Selector | Element | Use Case |
| ---------------------- | ------------------------ | --------------------------- |
| `.gantt_task_line` | Task bar container | Background color, borders |
| `.gantt_task_content` | Text inside task bar | Font size, color, alignment |
| `.gantt_side_content` | Text beside task bar | Right-side labels |
| `.gantt_tree_content` | Grid cell text | Grid column font styling |
| `.gantt_task_progress` | Progress fill inside bar | Progress bar color |
**CSS changes may break on upgrade**
Custom CSS relies on internal CSS class names that may change between Gantt versions. Test your custom styles after each upgrade and adjust selectors as needed.
## Verification
You should now see:
* The Gantt chart renders with your custom styles applied
* Text colors, font sizes, and positioning match your CSS definitions
* Row and task heights reflect your Gantt Config Script settings
## See Also
* [Configure Item Colors](/gantt/guides/visualization/configure-colors)
* [Configure Right-Side Text on Task Bars](/gantt/guides/visualization/right-side-text)
* [Adjust Gantt Row Height](/gantt/guides/visualization/row-height)
* [Write Item Scripts](/gantt/guides/scripting/item-script-basics)
* [Write Gantt Config Scripts](/gantt/guides/scripting/gantt-config-script)
# Integration
Source: https://learn.nextedy.com/gantt/guides/integration/index
Nextedy GANTT integrates with external tools and Polarion platform features to extend the Gantt chart beyond its default capabilities.
Bring MS Project dependency structures into Polarion for use in the Gantt chart.
Enforce dependency-aware status gates in Polarion workflows using Gantt link roles.
Style task bars, text, and layout elements using CSS injected through Polarion script blocks.
**Looking for scripting?**
For programmatic customization using JavaScript item scripts, config scripts, and Velocity page scripts, see the [Scripting](/gantt/guides/scripting/index) section.
# Import Dependencies from MS Project
Source: https://learn.nextedy.com/gantt/guides/integration/ms-project-import
Transfer dependency relationships from Microsoft Project into Polarion so that Nextedy GANTT can display and schedule tasks based on the imported links.
**Verify in application**
There is no native one-click import from MS Project. This workflow requires exporting XML from MS Project and using the Polarion REST API to create work items and dependency links.
## Prerequisites
* MS Project file with tasks and dependency links defined
* Access to the Polarion REST API
* A Polarion project with the target work item types and link roles configured
* Dependency roles configured in the Gantt widget parameters
1. Open your project in Microsoft Project
2. Navigate to **File > Save As**
3. Select **XML Format (.xml)** as the file type
4. Save the file to a local directory
The exported XML contains task definitions, durations, start/end dates, and predecessor relationships with dependency types (FS, SS, FF, SF).
MS Project uses four dependency types that map to Gantt dependency link types:
| MS Project Type | Code | Gantt Equivalent | Description |
| ---------------- | ---- | ------------------ | ------------------------------------------- |
| Finish-to-Start | FS | `finish_to_start` | Successor starts after predecessor finishes |
| Start-to-Start | SS | `start_to_start` | Both tasks start together |
| Finish-to-Finish | FF | `finish_to_finish` | Both tasks finish together |
| Start-to-Finish | SF | `start_to_finish` | Successor finishes when predecessor starts |
**Link role configuration required**
Before importing, ensure your Polarion project has link roles defined for each dependency type you plan to import. The Gantt **Dependency Role** widget parameter must reference these link roles for dependencies to appear on the chart.
Parse the MS Project XML and create corresponding Polarion work items using the Polarion REST API:
1. Extract task names, start dates, end dates, and durations from the XML
2. For each task, create a work item in Polarion with the mapped fields matching your Gantt data mapping configuration (e.g., `gantt_start`, `gantt_duration`)
3. Record the mapping between MS Project task IDs and Polarion work item IDs
For each predecessor relationship in the MS Project XML:
1. Look up the Polarion work item IDs for both the predecessor and successor tasks
2. Create a typed work item link using the appropriate link role
3. Set the dependency type based on the MS Project relationship type mapping
**First link role is the default**
When configuring the **Dependency Role** widget parameter, the first selected role is used when creating new dependency links by dragging in the Gantt chart. Place your most common dependency type first.
1. Open your Gantt wiki page in edit mode
2. Open the widget parameters
3. Set the **Dependency Role** to include the link roles you used during import
4. Set the **Parent Role** if you also imported parent-child hierarchies
5. Save and reload the page
## Verification
You should now see:
* Imported tasks displayed as task bars on the Gantt chart
* Dependency arrows drawn between linked tasks matching the original MS Project relationships
* Auto-scheduling (if enabled) respecting the imported dependency structure
## See Also
* [Create and Configure Dependency Links](/gantt/guides/dependencies/create-dependency-links)
* [Configure Advanced Dependency Types (FS, SS, FF, SF)](/gantt/guides/dependencies/advanced-dependency-types)
* [Configure Auto-Scheduling](/gantt/guides/scheduling/configure-auto-scheduling)
# Configure Gantt Workflow Conditions
Source: https://learn.nextedy.com/gantt/guides/integration/polarion-workflow-conditions
Enforce dependency-aware workflow gates in Polarion so that a work item cannot transition to a new status unless its Nextedy GANTT predecessors are in an allowed state.
## Prerequisites
* Gantt installed and configured with dependency roles
* Polarion administrator access to edit workflow configurations
* Dependency links already established between work items
## How the Condition Works
The Gantt workflow condition checks all work items linked to the transitioning item via specified dependency link roles. If any linked predecessor is not in one of the allowed status states, the workflow transition is blocked.
**Dependency-type aware**
The condition is aware of Gantt dependency types. For forward-link checking, items connected via `start-to-finish` or `start-to-start` dependency types are excluded from the check because they do not need to finish first. Only `finish-to-start` dependencies are enforced in the forward direction.
1. Navigate to **Administration > Work Items > Workflow**
2. Select the work item type whose workflow you want to modify
3. Locate the transition where you want to add the dependency gate
1. Click on the target transition to edit it
2. In the **Conditions** section, add a new condition
3. Select **`GanttDependenciesStatusCondition`** from the list of available conditions (it appears under that exact ID, alongside the built-in conditions such as `LinkedWorkItem` and `FieldNonEmpty`)
The condition accepts the following parameters:
| Parameter | Type | Required | Description |
| ----------------- | ------------------------ | ------------------------------------------------- | --------------------------------------------------------------------------- |
| `link.roles` | String (comma-separated) | At least one of `link.roles` or `back.link.roles` | Link role IDs for forward-linked work items to check |
| `back.link.roles` | String (comma-separated) | At least one of `link.roles` or `back.link.roles` | Link role IDs for back-linked work items to check |
| `valid.states` | String (comma-separated) | Yes | Work item status IDs that linked items must be in for the condition to pass |
### Configuration Example
To require all predecessors (via the `depends_on` link role) to be in `done` or `closed` status before a work item can move to `in_progress`:
```
link.roles=depends_on
valid.states=done,closed
```
To check both forward and backward links:
```
link.roles=depends_on
back.link.roles=depends_on
valid.states=done,closed
```
**Use status IDs, not display names**
The `valid.states` parameter accepts Polarion status **IDs** (e.g., `done`, `in_progress`), not the human-readable display names (e.g., "Done", "In Progress"). Check your workflow configuration for the correct status IDs.
* **`link.roles`** checks items that the current work item links **to** (forward direction)
* **`back.link.roles`** checks items that link **back to** the current work item (reverse direction)
Use `link.roles` when your dependency links point from the dependent item to its predecessor. Use `back.link.roles` when links point from the predecessor to the dependent item.
**Security across permission boundaries**
The condition runs with elevated system privileges, ensuring that dependency gates are enforced even when the current user cannot see all linked work items. Hidden links cannot bypass the status gate.
## Verification
You should now see:
* When attempting to transition a work item whose predecessors are not in the allowed states, the transition is blocked with a validation message
* When all predecessors meet the status requirements, the transition proceeds normally
* The condition respects dependency type semantics, only enforcing finish-to-start dependencies in the forward check
## See Also
* [Create and Configure Dependency Links](/gantt/guides/dependencies/create-dependency-links)
* [Configure Advanced Dependency Types (FS, SS, FF, SF)](/gantt/guides/dependencies/advanced-dependency-types)
* [Configure Auto-Scheduling](/gantt/guides/scheduling/configure-auto-scheduling)
# Use Fullscreen and Maximize Mode
Source: https://learn.nextedy.com/gantt/guides/layout/fullscreen-mode
This guide shows you how to expand the Nextedy GANTT widget to fill the full browser viewport for an immersive planning experience.
## Prerequisites
* A Gantt widget placed on a Polarion LiveDoc or Wiki page
* Permission to edit widget parameters
## Choose a Display Mode
The Gantt supports three display modes depending on how you want the widget to appear on the page:
| Mode | Configuration | Behavior |
| ---------------------- | ------------------------------------------ | ----------------------------------------------------------------- |
| **Embedded (default)** | No `maximize` or `height` set | Widget renders at its natural size within the page layout |
| **Fixed height** | Set the `height` widget parameter (pixels) | Widget renders at a specific pixel height, ignoring viewport size |
| **Maximize** | Set `maximize = true` | Widget expands to fill the entire browser viewport |
## Enable Maximize Mode
1. Open the Polarion page containing the Gantt widget
2. Edit the widget properties
3. Navigate to **Advanced > Maximize** and set it to **Yes**
4. Save the page
The widget now fills the full working area of the Polarion page. The Gantt chart occupies the entire viewport, with the toolbar at the top providing access to all controls.
**Remove empty paragraphs around the widget**
When using maximize mode, ensure there are no additional empty paragraphs or other whitespace content above or below the Gantt widget on the page. Extra whitespace can cause layout issues that prevent the widget from properly filling the viewport.
## Set a Fixed Height
If you want the Gantt to occupy a specific area on the page alongside other content:
1. Edit the widget properties
2. Set the `height` widget parameter to a pixel value (for example, `600`)
3. Leave `maximize` turned off
This is useful when embedding the Gantt in a page that contains other widgets or text content above and below.
## Features Unlocked by Maximize Mode
Enabling maximize mode provides access to features that are not available in embedded mode:
* **Page Parameters button** ⚙️ -- The `tb_parameters` toolbar button only appears when the Gantt is in maximized view. This button opens the Page Parameters panel, allowing users to modify query filters and other parameters without editing the page.
* **Session keep-alive** -- The Gantt starts a polling loop that keeps the Polarion session active while the chart is open, preventing session timeout during long planning sessions.
* **Viewport-responsive resizing** -- The Gantt automatically adjusts its height when the browser window is resized to continue filling the full viewport.
**Recommended setup for dedicated Gantt pages**
Create a single LiveDoc page (for example, named "Nextedy Gantt") with only the Work Items Gantt widget. Set `maximize = true` to make the widget fill the entire working area. This provides the best user experience for daily schedule management.
## Combine Maximize with Page Parameters
When you need both maximize mode and dynamic page parameters (for example, letting users select a version number to filter work items):
1. Add a **Page Parameters** widget to the page
2. Add the **Gantt widget** to the page -- keep `maximize` turned **OFF** initially
3. Add your page parameters and reference them in the Gantt query
4. Test the page to confirm filtering works correctly
5. Now enable **Advanced > Maximize** on the Gantt widget
After enabling maximize, the ⚙️ **Page Parameters** button appears in the Gantt toolbar. Users click this button to open the Page Parameters panel and change filter values without leaving the maximized view.
**Access page parameters from Item Script**
You can also read page parameter values programmatically in an Item Script using:
```javascript theme={null}
config.getPageParameters().get("pageParamId")
```
Replace `pageParamId` with the ID of your page parameter.
## Verify Your Configuration
1. Open the Polarion page containing the Gantt widget
2. You should now see the Gantt chart filling the entire browser viewport
3. The toolbar appears at the top with all configured buttons
4. If you configured page parameters, the ⚙️ Page Parameters button should be visible in the toolbar
5. Resize the browser window -- the Gantt should adjust its height automatically
## See Also
* [Configure Page Parameters](/gantt/guides/layout/page-parameters) for detailed page parameter setup
* [Configure the Toolbar and Menus](/gantt/guides/layout/toolbar-configuration) for toolbar button visibility
* [Use Multiple Gantt Widgets](/gantt/guides/layout/multiple-widgets) for pages with multiple Gantt instances
* [Print and Export to PNG](/gantt/guides/layout/print-and-export) for exporting the maximized view
# Layout and Navigation
Source: https://learn.nextedy.com/gantt/guides/layout/index
Control how your Nextedy GANTT widget appears on the page, customize the toolbar, configure page-level parameters, and manage print and export options.
Expand the Gantt widget to fill the full browser window or Polarion working area for a distraction-free planning experience.
Place multiple Gantt widgets on a single Polarion page, each with independent data sources and configurations.
Add dynamic filters and query parameters to the Gantt widget using the Polarion Page Parameters panel.
Export the Gantt chart as a PNG image or send it to a printer for offline review and sharing.
Automatically scroll the Gantt timeline to today's date when the chart loads, keeping the current schedule in view.
Customize which buttons appear in the Gantt toolbar, configure context menus, and control toolbar visibility.
**Start with fullscreen mode**
For the best editing experience, enable the `maximize` widget parameter so the Gantt expands to fill the available space. This unlocks additional features like the page parameters panel and provides more room for the timeline and grid columns.
# Use Multiple Gantt Widgets
Source: https://learn.nextedy.com/gantt/guides/layout/multiple-widgets
This guide explains the current limitations of placing multiple Nextedy GANTT widgets on a single page and provides workarounds for viewing different data sets side by side.
## Single Widget Per Page
Only one Gantt widget is supported on a single Polarion report page. Placing a second widget on the same page is not supported due to the resource-intensive nature of the Gantt chart rendering engine.
**Do not add multiple Gantt widgets to one page**
Adding more than one Gantt widget to the same report page causes conflicts and is not supported. The chart requires exclusive control of the page layout, event handlers, and data processing pipeline.
## Workaround Strategies
Use one of the following approaches to view different Gantt data sets without placing multiple widgets on the same page.
### Option 1: Use Separate Documents
Create dedicated Polarion LiveDoc or Wiki pages for each Gantt view you need. For example:
| Page | Purpose | Query |
| ------------------------ | ------------------------ | -------------------------------------- |
| `Release-Planning-Gantt` | Release-level scheduling | Work items in current release plan |
| `Team-Gantt` | Team workload view | Work items assigned to a specific team |
| `Sprint-Gantt` | Sprint-level detail | Work items in the active sprint |
Each page hosts its own Gantt widget with independent widget parameters, query configuration, and scale settings. You can navigate between them using Polarion page links.
### Option 2: Use Dynamic Queries with Page Parameters
Instead of creating separate pages for each data set, configure a single Gantt page with page parameters that dynamically change the displayed data. This approach lets you switch between different views on the same page by changing parameter values.
1. Open your Gantt page in **Edit** mode.
2. Configure the widget query type to **Lucene + Velocity**.
3. Use page parameters in the query to filter work items dynamically:
```velocity theme={null}
type:task AND assignee.id:($pageParameters.team.toLucene())
```
4. Add a page parameter control so users can select different teams or plan levels from a dropdown.
**Dynamic queries as a multi-view solution**
Page parameters effectively replace the need for multiple widgets. A single page with a team or plan-level parameter dropdown lets users switch views instantly without navigating away. See [Use Dynamic Queries with Page Parameters](/gantt/guides/filtering/dynamic-queries) for full configuration steps.
### Option 3: Use Plans Gantt for Multi-Level Views
If your goal is to see work items across multiple plan levels, the Plans Gantt widget can display plans and their work items together in a single hierarchical view. Configure the **Show Plan Work Item** section to display work items beneath each plan bar.
See [Show Plans and Work Items Together](/gantt/guides/plans/plans-and-work-items) for setup instructions, or [Configure Multiple Plan Levels](/gantt/guides/plans/plan-level-configuration) to display nested plan hierarchies.
## Choosing the Right Approach
## Verification
After applying your chosen workaround, you should now see:
* **Separate pages**: Each page loads its own Gantt widget independently with the correct query results.
* **Page parameters**: Changing the parameter dropdown reloads the Gantt with the filtered data set.
* **Plans Gantt**: Plans appear as parent bars with work items nested beneath them.
## See Also
* [Use Dynamic Queries with Page Parameters](/gantt/guides/filtering/dynamic-queries)
* [Configure Page Parameters](/gantt/guides/layout/page-parameters)
* [Show Plans and Work Items Together](/gantt/guides/plans/plans-and-work-items)
* [Configure Multiple Plan Levels](/gantt/guides/plans/plan-level-configuration)
* [Use Fullscreen and Maximize Mode](/gantt/guides/layout/fullscreen-mode)
# Configure Page Parameters
Source: https://learn.nextedy.com/gantt/guides/layout/page-parameters
This guide shows you how to add dynamic user inputs to your Nextedy GANTT widget using Polarion Page Parameters, enabling users to filter and customize the Gantt view without editing the page.
**Since: Version 4.6.0**
## Prerequisites
* A Gantt widget on a Polarion LiveDoc or Wiki page
* Permission to edit page and widget parameters
* Understanding of Polarion query syntax
## How Page Parameters Work
Page parameters let users provide input values -- such as a version number, team name, or date range -- that dynamically modify the Gantt query. Instead of hard-coding filters into the widget configuration, you define parameters that users can change at runtime.
## Set Up Page Parameters
Follow these four steps to configure page parameters with a maximized Gantt view:
### Step 1: Add the Page Parameters Widget
1. Edit the Polarion page
2. Add a **Page Parameters** widget to the top of the page
3. Add the **Gantt widget** below it
4. **Keep Maximize turned OFF** on the Gantt widget at this stage
### Step 2: Define Your Parameters
1. In the Page Parameters widget, add the parameters you need (for example, a "Version" dropdown or a "Team" text input)
2. In the Gantt widget configuration, reference the page parameters in your query
### Step 3: Test the Configuration
1. Save the page and view it in normal mode
2. Set different parameter values in the Page Parameters widget at the top
3. Verify that the Gantt data updates to reflect the selected filters
### Step 4: Enable Maximize Mode
1. Edit the page again
2. Set the Gantt widget's **Advanced > Maximize** parameter to **Yes**
3. Save the page
The Page Parameters widget is now hidden behind the ⚙️ **Settings** toolbar button. Users click this button to open the parameters panel within the maximized Gantt view.
**Use Lucene + Velocity query type**
Page parameters only work when the Gantt widget's query is configured as **Lucene + Velocity** type. If you use a pure Lucene query, page parameter substitution will not function. Change the query type to Lucene + Velocity in the widget's data set configuration.
## The Page Parameters Toolbar Button
The `tb_parameters` toolbar button (displayed as a ⚙️ Settings icon) appears **only** when the Gantt is in maximized view. Clicking it opens a modal dialog where users can:
* View and modify all defined page parameters
* Apply changes that reload the Gantt with updated filters
* Close the dialog by clicking the X button or pressing **Escape**
| Condition | Parameters Button Visible |
| ----------------------------------------- | --------------------------------------------- |
| `maximize = true` and page has parameters | Yes |
| `maximize = false` | No (parameters widget shown directly on page) |
| `MaximizeGanttView=false` URL parameter | No (forces non-maximized mode) |
**Dynamic query switching for non-admin users**
Use page parameters to let regular users switch between different query configurations. For example, create a dropdown parameter with preset filter options (e.g., "My Tasks", "Team Tasks", "All Tasks") and reference it in the Gantt query using Velocity syntax.
## Access Page Parameters from Scripts
You can read page parameter values in an **Item Script** to customize task appearance based on user-selected parameters:
```javascript theme={null}
config.getPageParameters().get("pageParamId")
```
Replace `pageParamId` with the ID of the parameter defined in the Page Parameters widget.
**Enum field naming convention**
When using enum-type page parameters for filtering or sorting, include the field ID in the enum field name. This ensures the Gantt widget correctly maps the selected value to the query filter.
## Verify Your Configuration
1. Open the Gantt page in maximized view
2. You should now see the ⚙️ Settings button in the toolbar
3. Click the Settings button to open the Page Parameters panel
4. Select a different parameter value and observe the Gantt data reloading with the updated filter
5. Press **Escape** or click the X button to close the panel
## See Also
* [Use Fullscreen and Maximize Mode](/gantt/guides/layout/fullscreen-mode) for maximize mode configuration
* [Use Dynamic Queries with Page Parameters](/gantt/guides/filtering/dynamic-queries) for advanced query patterns
* [Use Gantt Filters](/gantt/guides/filtering/gantt-filters) for built-in filtering options
* [Write Page Scripts with Velocity](/gantt/guides/scripting/page-script) for Velocity-based customization
# Print and Export to PNG
Source: https://learn.nextedy.com/gantt/guides/layout/print-and-export
This guide walks you through exporting your Nextedy GANTT chart as a PNG image and printing it to PDF using the built-in export panel.
## Export to PNG
The Gantt toolbar includes a **Print / Export to Image** button that captures the current chart view as a full-resolution PNG file.
1. Open the Gantt page you want to export.
2. Set the **Scale** to the level you need (for example, `W` for weekly or `M` for monthly) so the chart shows the desired date range.
3. Click the **Print / Export to Image** button in the toolbar.
4. The export panel opens, rendering the entire Gantt chart as an image.
5. Click **Download** to save the image as `gantt.png` to your local machine.
**Adjust the scale before exporting**
The export captures the chart at the current zoom level. Switch to a wider scale (such as `M` or `Q`) to fit more of the timeline into the exported image, or use a narrow scale (such as `D`) for detailed views of a shorter time range.
## Print to PDF
To print the Gantt chart to a PDF file, use the browser's built-in print dialog:
1. Click the **Print / Export to Image** button in the toolbar.
2. In the export panel, click **Print**.
3. The browser's native print dialog opens with the Gantt image pre-loaded.
4. Select **Save as PDF** (or your preferred printer) as the destination.
5. Set the page size to **A0** or another large format to accommodate the full chart width.
6. Choose **Landscape** orientation for best results.
7. Click **Print** or **Save**.
To close the export panel without downloading or printing, click **Close**.
## Print from a Cloned Page
For precise control over the printed layout, clone your Gantt page and configure it specifically for printing:
| Step | Action |
| ---- | ----------------------------------------------------------------------- |
| 1 | Clone your Gantt page to create a dedicated print version |
| 2 | Open the cloned page and enter **Edit** mode |
| 3 | Ensure **Maximize** mode is turned **off** |
| 4 | Go to **Sidebar > Page Properties** and set the minimal width to `5000` |
| 5 | Set the Gantt **Scale** to the desired level (e.g., `W`) |
| 6 | Save the page |
| 7 | Click the **Print / Export to Image** toolbar button |
| 8 | Close the system print dialog if it appears |
| 9 | Wait for the page to fully render |
| 10 | Click **Print** and select **A0** page size |
| 11 | Choose **Print to PDF** as the output |
**Disable maximize mode for printing**
Fullscreen (maximize) mode interferes with the print layout. Always turn off maximize mode on your print-dedicated page before exporting. See [Use Fullscreen and Maximize Mode](/gantt/guides/layout/fullscreen-mode) for details.
**Export can be labor-intensive for large charts**
For Gantt charts with many work items, the export process requires careful zoom and page-size adjustments. Experiment with the Scale parameter and page width to find the best balance between readability and chart coverage.
## Verification
After completing the export, you should now see:
* A `gantt.png` file in your downloads folder (for PNG export).
* A PDF file containing the full Gantt chart (for print-to-PDF).
* The chart image matches the scale and time range you configured before exporting.
## See Also
* [Use Fullscreen and Maximize Mode](/gantt/guides/layout/fullscreen-mode)
* [Configure the Time Scale](/gantt/guides/visualization/timescale)
* [Configure the Toolbar and Menus](/gantt/guides/layout/toolbar-configuration)
* [Troubleshooting Performance Issues](/gantt/guides/troubleshooting/performance)
# Scroll to Today on Load
Source: https://learn.nextedy.com/gantt/guides/layout/scroll-to-today
This guide shows you how to automatically scroll the Nextedy GANTT timeline to today's date when the chart loads, and how to configure the today marker.
## Use the Toolbar Button
The Gantt toolbar includes a **Go to today** button that scrolls the timeline to the current date with a single click. You can also access this action by right-clicking on the time scale header area and selecting the scroll-to-today option from the context menu.
## Scroll to Today Automatically on Load
To make the Gantt always center on today's date when the page loads, add a script to the Gantt Config Script:
1. Open the Polarion page containing the Gantt widget
2. Edit the widget properties
3. Navigate to **Advanced > Gantt Config Script**
4. Add one of the following scripts:
**Option 1 -- Scroll after all data loads:**
```javascript theme={null}
gantt.attachEvent("onLoadEnd", function() {
gantt.showDate(new Date());
});
```
**Option 2 -- Scroll after each render cycle:**
```javascript theme={null}
gantt.attachEvent("onDataRender", function() {
gantt.showDate(new Date());
});
```
**Choose the right event**
Use `onLoadEnd` if you want the scroll to happen once when data finishes loading. Use `onDataRender` if you want the view to re-center after every render (for example, after filtering or expanding/collapsing tasks). For most use cases, `onLoadEnd` is sufficient.
## Configure the Today Marker
The today marker is a vertical line on the Gantt timeline indicating the current date. You can show or hide it using the `showTodayMarker` widget parameter.
| Parameter | Default | Description |
| --------------------------- | ------- | --------------------------------------------------- |
| `showTodayMarker` | `true` | Display a vertical line on today's date |
| `nextedy.gantt.today.color` | `gray` | Color of the today marker (administration property) |
To hide the today marker:
1. Edit the widget properties
2. Navigate to **Advanced > Show Today Marker**
3. Set it to **No**
**Today marker shows server time**
The today marker position is determined by the **server's date and time**, not the user's local time. If your Polarion server is in a different timezone than your users, the today marker may appear to be a day off. This is expected behavior. See [Troubleshooting Today Marker Position](/gantt/guides/troubleshooting/today-marker-position) for details.
## Combine with Collapse on Load
A common configuration pattern combines scroll-to-today with starting the Gantt in a collapsed state. To start with all task groups collapsed, add the following to your **Item Script**:
```javascript theme={null}
task.open = false;
```
This collapses all parent tasks on load. Users can then expand groups as needed while the timeline is already centered on today's date.
## Verify Your Configuration
1. Reload the Polarion page containing the Gantt widget
2. You should now see the timeline automatically scrolled so that today's date is in the visible area
3. If `showTodayMarker` is enabled, a vertical line marks today's date on the timeline
4. Click the **Go to today** toolbar button to confirm it scrolls to the same position
## See Also
* [Troubleshooting Today Marker Position](/gantt/guides/troubleshooting/today-marker-position) for timezone-related marker issues
* [Configure the Time Scale](/gantt/guides/visualization/timescale) for adjusting the zoom level
* [Create and Configure Markers](/gantt/guides/visualization/markers) for adding custom date markers
* [Write Gantt Config Scripts](/gantt/guides/scripting/gantt-config-script) for more configuration script examples
* [Set the Gantt Time Range](/gantt/guides/scheduling/set-time-range) for controlling the overall visible date range
# Configure the Toolbar and Menus
Source: https://learn.nextedy.com/gantt/guides/layout/toolbar-configuration
Customize the Nextedy GANTT toolbar buttons, context menus, and hamburger menu to match your team's workflow and hide unused controls.
## Toolbar Overview
The Gantt toolbar contains the following button groups, each conditionally visible based on your configuration:
| Button | Visibility Condition | Description |
| ---------------------------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Edit** / **Close Editing** | Hidden when `readonly=true` or `alwaysedit=true` | Enters or exits edit mode |
| 💾 **Save** | Visible in edit mode only | Persists pending edits to Polarion |
| **Undo** / **Redo** | Visible in edit mode only | Reverses up to `undo_steps` changes (default: 10) |
| ➕ **New** | Visible when at least one type has `enableCreate=true` | Dropdown to create new work items or plans of an enabled type |
| **Collapse All** / **Expand All** | Always visible | Collapses or expands all parent rows in the grid |
| 🔍 **Zoom In** / **Zoom Out** | Always visible | Steps the timeline scale in or out |
| **Go to Today** | Always visible | Scrolls the timeline to today's date |
| **Filter by Item** | Visible when items are selected | Filters the chart to the selected work items and their related items (parents, children, and dependencies) |
| **Search** | Always visible | Text filter by work item ID or title |
| **Fit to Page** | Always visible | Fits the Gantt to the available working area |
| **Compare with History** | Always visible | Compares the current schedule against a previous (historical) version of the items |
| **Toggle Automated Scheduling** | Visible in edit mode | Turns auto-scheduling on/off, so moving a predecessor reschedules its successors (see [Configure Auto-Scheduling](/gantt/guides/scheduling/configure-auto-scheduling)) |
| **Toggle Critical Path Visualization** | Visible in edit mode | Highlights the critical path (the longest dependency chain) |
| **Toggle Dragging Children with Parent** | Visible in edit mode | Whether moving a parent also moves its children (mirrors the hamburger-menu option) |
| **Toggle Hide No-Task Resources** | Visible when the resource view is shown | Hides resource rows that have no allocated tasks |
| **Refresh** | Always visible | Reloads Gantt data from the server (also in the hamburger menu) |
| **Print / Export** | Always visible | Opens the export panel for PNG or print |
| **Mark Differences** | Visible with derived schedule types | Highlights items with unsynchronized dates |
| **Clear Calendar Cache** | Visible when `useCalendarCache=true` | Clears server-side calendar cache and reloads |
| ⚙️ **Parameters** | Visible in maximized view only | Opens the Page Parameters panel |
**Verify in application**
The exact set of visible toolbar buttons depends on the widget configuration, the installed version, and whether the resource view is enabled. Button labels above match the in-product tooltips. Hover any toolbar icon to confirm its action in your installation.
## Hide the Toolbar Entirely
Set the widget parameter `hide_toolbar` to `true` to hide the complete toolbar. You can also set this as a default via the configuration property:
```
nextedy.gantt.workitems.default.hide_toolbar=true
```
**Per-widget override**
The widget parameter value overrides the global configuration property. Set `hide_toolbar=false` on a specific widget to show the toolbar even when the global default hides it.
## Configure Edit Mode Behavior
Control how editing works using two widget parameters:
* **`readonly`**: Set to `true` to disable all editing. The Edit button is hidden, and drag, resize, and add-task operations are blocked.
* **`alwaysedit`**: Set to `true` to keep the Gantt permanently in edit mode. The Edit/Close buttons are removed, and tasks are immediately draggable.
**Readonly and alwaysedit conflict**
If both `readonly` and `alwaysedit` are set to `true`, the Gantt operates in read-only mode. The `readonly` flag takes precedence.
## Configure the New Button
The ➕ **New** dropdown lists all work item types that have `enableCreate` set to `true` in the Work Item Types Configuration. Each type appears with its icon and name.
To hide the New button entirely, ensure no work item type has `enableCreate=true`, or set the `EnableCreateNew` flag to `false`.
## Use the Hamburger Menu
Click the ☰ hamburger icon in the first grid column header to access quick actions:
* **Refresh** -- Reloads Gantt data from the server
* **Drag children with parent** -- Toggles whether child tasks move with their parent
* **Go to today** -- Scrolls the timeline to today's date
* **Set scale** -- Submenu to change the zoom level (Day, Week, Month, Quarter, Year; **Hour** appears only when the widget is in High Precision (Hours) mode)
* **Column visibility** -- Submenu with checkboxes to show or hide individual grid columns
* **Help** -- Opens the Gantt documentation site
## Use Context Menus
Right-click on different areas of the Gantt chart for context-specific menus:
* **Column header** -- Right-click to show/hide columns via checkboxes
* **Timeline header** -- Right-click to change the zoom scale or navigate to today
**Browser context menu**
Hold **Shift** while right-clicking to bypass the Gantt context menu and access the browser's default context menu.
## Configure the Parameters Button
The ⚙️ **Parameters** button appears in the toolbar only when the Gantt is in maximized (fullscreen) view. It opens a scrollable modal dialog where you can modify all widget parameters without editing the wiki page source.
To force non-maximized mode via URL, append `?MaximizeGanttView=false`.
## Verification
You should now see only the toolbar buttons relevant to your configuration. If you set `hide_toolbar=true`, the toolbar area should be completely hidden. If you configured `alwaysedit=true`, task bars should be immediately draggable without clicking Edit.
## See Also
* [Use Fullscreen and Maximize Mode](/gantt/guides/layout/fullscreen-mode)
* [Configure Page Parameters](/gantt/guides/layout/page-parameters)
* [Manage Column Visibility](/gantt/guides/visualization/column-visibility)
* [Use Undo and Redo](/gantt/guides/editing/undo-redo)
# Plans Gantt
Source: https://learn.nextedy.com/gantt/guides/plans/index
The Nextedy GANTT Plans Gantt mode displays Polarion Plans as first-class entities on the Gantt chart, enabling portfolio-level scheduling with releases, iterations, and their associated work items.
Configure the Plans Gantt widget to display both Polarion Plans and their contained work items in a unified hierarchy.
Calculate and display plan completion progress using server-side scripts that count resolved versus total work items.
Automatically assign work items to Polarion Plans based on their schedule dates, keeping plan membership in sync with the Gantt hierarchy.
Set up multi-level plan hierarchies such as Release > Iteration > Work Package for cross-team and release planning views.
**Getting started with Plans Gantt**
If you are setting up a Plans Gantt for the first time, start with the [Set Up a Plans Gantt Chart](/gantt/getting-started/setup-plans-gantt) tutorial, then return to these guides for advanced configuration.
# Configure Multiple Plan Levels
Source: https://learn.nextedy.com/gantt/guides/plans/plan-level-configuration
This guide explains how to display a multi-level plan hierarchy in the Nextedy GANTT Plans Gantt widget, showing releases, iterations, and work items together.
## Understanding the Plan Hierarchy
A typical multi-level setup looks like this:
The Plans Gantt widget displays Polarion Plans as first-class task bars. By configuring the **Load Children** parameter and **Work Item Types Configuration**, you control how many levels of the hierarchy are visible.
Open **Widget Parameters > Plans Dataset** and set up a dataset filter to select the top-level plans. For example, filter by template to show only Release plans:
* Set the Plans dataset to show plans with **Template: Release**
This defines the first level of the hierarchy.
Navigate to **Widget Parameters > Load Children** and set the number of sub-plan levels to load:
| Load Children Value | Levels Displayed |
| ------------------- | --------------------------------------------------------------------------- |
| `0` | Top-level plans only (e.g., Releases) |
| `1` | Top-level + one child level (e.g., Releases + Iterations) |
| `2` | Top-level + two child levels (e.g., Releases + Iterations + Sub-iterations) |
| `3` | Three levels of nested plans plus work items |
For a typical Release > Iteration > Work Package structure, set **Load Children** to `2` or `3`.
In the **Plan Types Configurations** section of the widget parameters, define which plan template types you use and their hierarchy:
1. Add each plan type (e.g., Release, Iteration)
2. For each child type, specify which plan types are allowed as parents
3. Plans do not use dependency link roles -- only parent-child relationships apply
To show work items beneath their parent plans, scroll to the **Show Plan Work Item** section:
1. Set **Enable Show Items** to `Yes`
2. Configure the **Data Mapping** fields:
* **Start Field** -- the work item field used for task start dates
* **End Field** -- the work item field used for task end dates
* **Duration Field** -- the work item field for duration
* **Progress Field** -- the work item field for completion percentage
* **Parent Role** -- the link role defining parent-child relationships between work items
* **Dependency Role** -- the link role for dependency links between work items
In the **Work Item Types Configuration** section, add entries for each work item type that should appear under plans:
* Set the **Item Type** for each type (e.g., Work Package, Task)
* Configure the **Gantt Presentation Mode** (Item, Derived Schedule, Milestone, or Auto-Mode)
* Set **Parent Mode** to control hierarchy placement
**Dependency links apply to work items only**
Plans do not support direct dependency links. Dependency links only apply between work items. If you need scheduling dependencies at the plan level, manage them through work items within those plans.
**Work item creation is limited to the lowest plan level**
Currently, you can only create new work items at the lowest displayed plan level. If you need to add items at different plan levels, use separate Gantt widget instances configured for each level.
**Use page parameters for level toggling**
If you need to switch between viewing different plan levels, configure a page parameter that controls which plan template the dataset filter uses. This lets you toggle between Release-level and Iteration-level views without editing the widget configuration.
## Verify
After applying the configuration, reload the Gantt chart. You should now see your plan hierarchy displayed with the correct number of levels -- releases at the top, iterations nested beneath them, and work items under the iterations. Expand and collapse plan nodes to navigate the hierarchy.
## See also
* [Set Up a Plans Gantt Chart](/gantt/getting-started/setup-plans-gantt)
* [Show Plans and Work Items Together](/gantt/guides/plans/plans-and-work-items)
* [Sync Work Item Dates to Plans](/gantt/guides/plans/sync-to-plans)
* [Configure Page Parameters](/gantt/guides/layout/page-parameters)
# Compute Plan Progress
Source: https://learn.nextedy.com/gantt/guides/plans/plan-progress
Calculate and display plan completion progress in the Nextedy GANTT Plans Gantt view using a server-side item script that counts resolved versus total work items.
## How Plan Progress Works
In the Plans Gantt, plan bars do not have a built-in progress calculation. You use an **Item Script** to query work items assigned to each plan, compute a completion ratio, and display it on the Gantt chart.
The script runs server-side for each plan item, calculating progress as the ratio of resolved work items to total work items in the plan.
Open the Plans Gantt widget parameters and navigate to **Advanced > Gantt Config Script**. Add the following script to display progress as right-side text on each plan bar:
```javascript theme={null}
gantt.templates.rightside_text = function(start, end, task) {
return (task.progress > 0
? "Progress: " + Math.round(task.progress * 100) + " % (" + task.fields.progressString + ") "
: "");
};
```
This script renders progress text to the right of each plan bar, showing both the percentage and the resolved/total count.
Navigate to **Advanced > Item Script** and add the server-side computation:
```javascript theme={null}
var allitems = trackerService.queryWorkItems(
"PLAN:(" + plan.getProjectId() + "/" + plan.getId() + ")", "id"
).size();
var resolveditems = trackerService.queryWorkItems(
"PLAN:(" + plan.getProjectId() + "/" + plan.getId() + ") AND HAS_VALUE:resolution", "id"
).size();
if (allitems > 0) {
task.progress = resolveditems / allitems;
} else {
task.progress = 0;
}
task.getFields().put("progressString", resolveditems + " / " + allitems + " done");
```
This script:
1. Queries all work items assigned to the current plan
2. Queries work items with a resolution (resolved items)
3. Computes progress as the ratio of resolved to total
4. Stores a human-readable string for display
If work items under your plans are unplanned (no start/end dates), you can derive their schedule from the plan assignment. Add this to the **Item Script** section of your Work Items configuration:
```javascript theme={null}
if (typeof wi !== 'undefined') {
if (task.unplanned) {
task.deriveScheduleFromPlans(wi, "iteration");
}
}
```
**Null check required**
Always wrap work item script logic with a `typeof wi !== 'undefined'` check. If the script runs on a plan item that has no backing work item, `wi` is undefined and the script throws an error. See [Migrate Scripts for Polarion 2304+](/gantt/guides/scripting/script-migration-2304) for details.
**Progress syncs on schedule changes only**
The progress value is computed each time the Gantt loads or refreshes data. Editing work item resolution status outside the Gantt requires a Gantt refresh to update the progress display.
## Customizing the Progress Query
You can adjust the progress calculation by modifying the Lucene query in the item script. For example, to count only items with status "done" instead of any resolution:
```javascript theme={null}
var resolveditems = trackerService.queryWorkItems(
"PLAN:(" + plan.getProjectId() + "/" + plan.getId() + ") AND status:done", "id"
).size();
```
## Verification
You should now see progress percentages displayed to the right of each plan bar in the Plans Gantt, showing text like "Progress: **75% (3 / 4 done)**". Plans with no assigned work items show no progress text.
## See Also
* [Show Plans and Work Items Together](/gantt/guides/plans/plans-and-work-items)
* [Track and Calculate Progress](/gantt/guides/editing/progress-tracking)
* [Calculate Progress with Scripts](/gantt/guides/scripting/progress-calculation-scripts)
* [Write Item Scripts](/gantt/guides/scripting/item-script-basics)
* [Derive Schedule from Polarion Plans](/gantt/guides/scheduling/plan-derived-schedule)
# Show Plans and Work Items Together
Source: https://learn.nextedy.com/gantt/guides/plans/plans-and-work-items
Configure the Nextedy GANTT Plans Gantt widget to display Polarion Plans alongside their contained work items in a unified hierarchy on the Gantt chart.
## Overview
The standard Work Items Gantt shows only work items. The Plans Gantt mode lets you visualize multi-level structures such as:
* **Release** (Polarion Plan) > **Iteration** (Polarion Plan) > **Work Package** (work item) > **Task** (work item)
This guide walks you through configuring the Plans Gantt widget to show both plans and their associated work items.
1. Open a Polarion wiki page in edit mode.
2. Add a **Gantt (Plans)** widget to the page.
3. Configure the **Plans data set** parameter to select which plans appear. For example, filter by plan template `Release` to show only release-level plans at the top.
In the widget parameters, navigate to **Plan Types Configurations**:
1. Define which plan types you use (e.g., Release, Iteration).
2. For each plan type, specify which other plan types are allowed as parents. Unlike work items, plans do not use parent-child linking roles -- you only specify the allowed parent plan types.
Scroll down in the widget parameters to the **Show Plan Work Item** section:
1. Toggle **Enable Show Items** to display work items within plans.
2. Configure the **Data mapping** fields for work items: Start Field, End Field, Duration Field, and Progress Field.
**Optional section**
Showing work items under plans is optional. Some configurations only display the plan hierarchy without individual work items.
In the **Work Item Types Configuration** section within the Plans Gantt parameters, define which work item types appear under plans. This configuration is identical to the Work Items Gantt setup:
* Set the **Item Type** to display
* Choose the **Gantt Presentation Mode** (Item, Derived Schedule, Auto-Mode, or Milestone)
* Configure **Parent Mode** and **Parent Types** to control hierarchy placement
Set the **Load Children** parameter to control how many child levels of the hierarchy to display. The value counts child levels below the top-level plans, so `0` shows only the top-level plans. For example:
* `0` -- Shows only the top-level plans
* `1` -- Shows plans and their child plans
* `2` -- Shows plans, child plans, and one more level (e.g., work items)
* `3` -- Shows plans, child plans, and two further levels
If you need work items under iterations under releases (a four-level Release > Iteration > Work Package > Task hierarchy), set Load Children to at least `3` and configure the Parent Link Roles to load work item children.
**Dependency links apply to work items only**
Plans do not support dependency links between each other. Dependency links can only be created between work items. If you need to establish relationships between plans, use the parent-child plan hierarchy instead.
**Multiple parent relationships**
The Gantt processes items sequentially, not level-by-level. If a work item has multiple parent relationships, it displays under the first-found parent. Use a custom field (such as a dedicated `PlannedIn` custom field) to manage complex parent scenarios.
## Verification
You should now see your plan hierarchy displayed on the Gantt chart with releases at the top level, iterations nested beneath them, and work items shown as task bars under their respective iterations. Plan bars and work item bars are visually distinct.
## See Also
* [Set Up a Plans Gantt Chart](/gantt/getting-started/setup-plans-gantt)
* [Configure Multiple Plan Levels](/gantt/guides/plans/plan-level-configuration)
* [Compute Plan Progress](/gantt/guides/plans/plan-progress)
* [Sync Work Item Dates to Plans](/gantt/guides/plans/sync-to-plans)
* [Derive Schedule from Polarion Plans](/gantt/guides/scheduling/plan-derived-schedule)
# Sync Work Item Dates to Plans
Source: https://learn.nextedy.com/gantt/guides/plans/sync-to-plans
This guide shows you how to automatically synchronize work item dates with their assigned Polarion Plans using item scripts and the `syncToPlans` configuration.
## Prerequisites
* A working Nextedy GANTT widget with Plans configured
* Work items assigned to Polarion Plans (iterations, releases)
* Access to **Widget Parameters > Advanced > Item Script**
## Option 1: Derive Schedule from Plans Using Item Script
When you need a work item's dates to come from its plan assignment rather than from its own date fields, add the following to **Widget Parameters > Advanced > Item Script**:
```javascript theme={null}
var plans = wi.getPlannedIn().iterator();
while(plans.hasNext()){
var plan = plans.next();
if(plan.getTemplate().getId()==="Iteration"){
task.start_date=util.getDate(plan, "startDate");
task.end_date=util.getDate(plan, "dueDate");
task.duration=null;
task.readonly=true;
task.unplanned=false;
}
}
```
This script iterates through all plans the work item belongs to, finds the one matching the `Iteration` template, and copies the plan's start and due dates onto the task bar.
## Option 2: Use the Utility Method for Unplanned Items
For work items that have no dates set, use the built-in `deriveScheduleFromPlans` utility method in your item script:
```javascript theme={null}
if(task.unplanned){
task.deriveScheduleFromPlans(wi, "iteration");
}
```
This method automatically sets the task's start and end dates from the matching plan.
**Null check for work items**
If you encounter errors during script execution, the script may be processing a non-existent work item. Add a null check around your script:
```javascript theme={null}
if (wi != null){
if(task.unplanned){
task.deriveScheduleFromPlans(wi, "iteration");
}
}
```
## Option 3: Automatic Sync with syncToPlans
You can configure the Gantt to automatically keep work item plan membership in sync when dates are edited. In **Widget Parameters > Work Item Types Configuration**, enable **Sync to Plans** for the relevant work item type.
When `syncToPlans` is enabled, saving a task in the Gantt automatically adds or removes the work item from overlapping Polarion Plans that match the configured plan templates.
| Configuration | Location | Effect |
| --------------------------- | ------------------------------------------ | ------------------------------------------------- |
| Item Script (derive dates) | Widget Parameters > Advanced > Item Script | Copies plan dates onto work item display |
| `deriveScheduleFromPlans()` | Item Script utility method | Sets dates for unplanned items from matching plan |
| Sync to Plans | Work Item Types Configuration | Auto-updates plan membership on save |
**Filter plans with contextField**
When you have many plans (100+), use a `contextField` filter to limit which plans are considered for sync. This prevents performance issues and ensures only relevant plans are matched. A bug fix in v25.8.0 ensures the most recent plans are fetched by due date.
**Plan sync has a fetch limit**
The plan sync mechanism fetches up to 100 plans by default. If you have more than 100 plans, newer plans may not appear unless you upgrade to v25.8.0 or later, which fetches plans ordered by due date.
## Verify
After configuring one of the above methods, reload the Gantt chart. You should now see work items positioned on the timeline according to their assigned plan dates. Unplanned items should display at their plan's date range, and items with `syncToPlans` enabled should automatically update plan membership when you drag and save them.
## See also
* [Derive Schedule from Polarion Plans](/gantt/guides/scheduling/plan-derived-schedule)
* [Show Plans and Work Items Together](/gantt/guides/plans/plans-and-work-items)
* [Configure Multiple Plan Levels](/gantt/guides/plans/plan-level-configuration)
* [Write Item Scripts](/gantt/guides/scripting/item-script-basics)
# Set Up a Cross-Team Gantt Chart
Source: https://learn.nextedy.com/gantt/guides/resources/cross-team-gantt
Configure a Nextedy GANTT chart that shows work items grouped by team in the resource view, giving you a clear picture of each team's workload without drilling into individual assignments.
## Prerequisites
* Gantt version **23.4.0** or later
* A custom field of type **Enum > Nextedy Team** on your work item types
1. Open **Administration > Custom Fields** for your project.
2. Create a new custom field with ID `team` (or a similar name).
3. Set the field type to **Enumeration** and select **Nextedy Team** as the enumeration source.
The Nextedy Team enumeration automatically lists all work items of type "Team" in your project as selectable options.
4. Add this field to the relevant work item types (e.g., Work Package, Feature).
Open each work item and set the `team` field to the appropriate team. This tells the Gantt which team is responsible for each work item.
1. Open the Gantt page in **Edit mode**.
2. Open **Widget Parameters**.
3. Configure the following settings:
| Parameter | Value |
| ------------------------- | ------------------------------- |
| **Resource Field** | `team` (your custom team field) |
| **Show Resource View** | Yes |
| **Load Team Assignments** | Yes |
4. Click **Apply**.
**Load Team Assignments requires working calendars**
The **Load Team Assignments** parameter only becomes visible after you enable **Use Working Calendar** and **Load User Calendars** under the **Working Calendars** section. Enable those two options first if you do not see **Load Team Assignments**. See [Working Calendars Parameters](/gantt/reference/widget-parameters/working-calendars) for the full dependency chain.
For cross-team views, the most common calculation modes are:
* **Leaf Items Count** -- shows how many work items each team has in each time period
* **Estimate + Spent** -- shows the total effort (hours) distributed across the team's scheduled work
Select the appropriate mode in **Resource Load Calculation** within the Resource View parameters.
**Use Assignment Allocation for capacity percentage**
If your teams have assignment work items defining per-user allocation percentages, select **Assignment Allocation** mode to see capacity as percentages rather than hours.
You can pre-filter the Gantt to show only a specific team's work items by passing a `team` query parameter in the page URL. This limits both the task list and the resource allocation calculations to the selected team.
**Team members with less than 50% allocation appear greyed out**
In the resource view, users allocated below 50% to a team may appear with grey markers instead of colored ones. Verify team assignment percentages if resources appear unexpectedly greyed out.
**Multi-project team management**
If your teams span multiple Polarion projects, consider using an [external team management project](/gantt/guides/resources/external-team-management) to centralize team definitions and capacity data.
## Verification
You should now see:
* One row per team in the resource view below the Gantt chart
* Work item counts or effort hours displayed in each cell per team
* Color-coded cells indicating whether each team is within capacity (green) or overallocated (red)
* The team custom field values reflected in the resource column labels
## See Also
* [Set Up the Resource View](/gantt/guides/resources/resource-view)
* [Configure Resource Fields](/gantt/guides/resources/resource-field-configuration)
* [Set Up Team Assignments Gantt](/gantt/guides/resources/team-assignments-gantt)
* [Set Up a Release Gantt with Teams](/gantt/guides/resources/release-gantt-with-teams)
* [Configure External Team Management Project](/gantt/guides/resources/external-team-management)
# Configure External Team Management Project
Source: https://learn.nextedy.com/gantt/guides/resources/external-team-management
Set up a Nextedy GANTT chart that sources team and resource data from a separate Polarion project, enabling cross-project resource allocation views that reflect a centralized team structure.
## When to Use This
Use an external team management project when:
* Multiple Polarion projects share the same teams and team members
* You want a single source of truth for team assignments and capacity
* Resource allocation needs to be visible across project boundaries
Create a dedicated Polarion project to hold all team-related work items:
1. Create a new Polarion project (for example, `TeamManagement`)
2. Configure the Team and Team Assignment work item types in this project
3. Create Team work items representing each team
4. Create Team Assignment work items under each team, specifying the assignee, allocation percentage, and date range
In each Polarion project that needs to reference the external team data, add the following configuration property under **Administration > Configuration Properties**:
```
nextedy.gantt.teamManagementProjectId=TeamManagement
```
Replace `TeamManagement` with the actual project ID of your team management project.
**Property Location**
This property must be set in the project that contains the Gantt widget, not in the team management project itself. Each consuming project needs this property.
If your team management project uses custom work item type IDs instead of the defaults, set these context properties:
| Property | Default | Description |
| ------------------------------------------ | ---------------- | ------------------------------------------- |
| `nextedy.gantt.teamWorkItemType` | `team` | Work item type ID for Team items |
| `nextedy.gantt.teamAssignmentWorkItemType` | `teamAssignment` | Work item type ID for Team Assignment items |
**Verify in application**
If you are using the default work item type IDs (`team` and `teamAssignment`), you do not need to set these properties.
In the Gantt widget parameters of each consuming project:
1. Set **Show Resource View** to `Yes`
2. Under **Working Calendars**, enable **Use Working Calendar**
3. Enable **Load User Calendars**
4. Enable **Load Team Assignments**
The Gantt now pulls team structure and capacity data from the external project while displaying work items from the current project.
**Multi-Project Capacity Calculations**
When teams span multiple projects, capacity calculations in the resource view reflect the allocation defined in the team management project. Ensure that team assignments in the central project accurately represent each member's availability across all projects to avoid misleading overallocation indicators.
After setting the properties and widget parameters:
1. Open the Gantt chart in one of the consuming projects
2. Switch to the resource view
3. Verify that team names and member allocations match the data in the team management project
## Verification
You should now see:
* Resource view rows populated with teams and members from the external team management project
* Allocation percentages reflecting the assignments defined in the central project
* Work items from the current project distributed under the correct team members
## See Also
* [Set Up Team Assignments Gantt](/gantt/guides/resources/team-assignments-gantt)
* [Set Up a Cross-Team Gantt Chart](/gantt/guides/resources/cross-team-gantt)
* [Set Up a Release Gantt with Teams](/gantt/guides/resources/release-gantt-with-teams)
* [Configure Capacity Modifier Fields](/gantt/guides/calendars/capacity-modifier-fields)
# Resources
Source: https://learn.nextedy.com/gantt/guides/resources/index
Nextedy GANTT provides a resource view that displays workload allocation, team capacity, and assignment tracking below the Gantt chart.
## Guides
[**Set Up the Resource View**](/gantt/guides/resources/resource-view) — Enable the resource view panel and configure load calculation modes, view height, and unassigned task visibility.
[**Configure Resource Fields**](/gantt/guides/resources/resource-field-configuration) — Change which work item field drives the resource view, including custom enumeration and team fields.
[**Set Up a Cross-Team Gantt Chart**](/gantt/guides/resources/cross-team-gantt) — Display teams as resource rows using a custom team field, showing team-level capacity without individual assignments.
[**Set Up Team Assignments Gantt**](/gantt/guides/resources/team-assignments-gantt) — Visualize per-user allocation percentages within teams using the Assignment Allocation load mode.
[**Set Up a Release Gantt with Teams**](/gantt/guides/resources/release-gantt-with-teams) — Combine plan-based views with team resource allocation for release planning.
[**Configure External Team Management Project**](/gantt/guides/resources/external-team-management) — Source team and resource data from a separate Polarion project for cross-project capacity planning.
[**Hide Inactive Resources**](/gantt/guides/resources/resource-hiding) — Automatically hide resources that have no tasks assigned in the current view.
[**Mark Tasks Without Resource Allocation**](/gantt/guides/resources/no-allocation-marking) — Highlight unassigned tasks so unallocated work is visible during planning.
If you are new to resource management in the Gantt, begin with [Set Up the Resource View](/gantt/guides/resources/resource-view) to enable the panel, then explore team-based configurations as your needs grow.
## See Also
* [View Resource Allocation](/gantt/getting-started/first-resource-view) -- introductory tutorial
* [Calendars](/gantt/guides/calendars/index) -- configure working hours that affect capacity calculations
* [Filter by Resource and Allocation](/gantt/guides/filtering/filter-by-resource) -- filter tasks by assigned resource
# Mark Tasks Without Resource Allocation
Source: https://learn.nextedy.com/gantt/guides/resources/no-allocation-marking
Identify unassigned tasks at a glance in Nextedy GANTT by enabling visual indicators that highlight work items missing a resource allocation.
## How No-Allocation Marking Works
When a task has no assignee, the Gantt chart applies two visual indicators:
1. **Red task bar background** -- the task bar in the Gantt chart receives a red highlight, making it immediately distinguishable from assigned tasks
2. **Grey resource view cell** -- in the resource view, cells for unallocated tasks display with a grey background instead of the usual green or red allocation markers
These indicators help project managers quickly spot work items that need assignment during planning sessions.
| Task State | Task Bar | Resource View Cell |
| ------------------------- | ----------------------------- | ------------------ |
| Assigned, within capacity | Standard color | Green marker |
| Assigned, overallocated | Standard color | Red marker |
| No assignee (active) | Red highlight | Grey cell |
| No assignee, status Done | Standard color (no highlight) | No indicator |
**Done Tasks Are Excluded**
Tasks with a **Done** status are exempt from the no-allocation marking even if they have no resource assignment. This prevents completed items from cluttering the view with false warnings.
To see both the task bar and resource view indicators, enable the resource view in your Gantt widget parameters:
1. Open the Gantt widget parameters
2. Set **Show Resource View** to `Yes`
3. Configure the **Resource Field** (defaults to `assignee`)
To see unallocated tasks grouped in the resource view:
1. In the widget parameters, set **Show Unassigned** to `Yes`
2. This adds a dedicated row in the resource view for all work items that have no value in the resource field
**Combine with Resource Hiding**
If you use the [Hide Inactive Resources](/gantt/guides/resources/resource-hiding) feature, the Unassigned row remains visible as long as there are unassigned tasks, making it easy to spot items needing attention.
With the configuration in place:
1. Open the Gantt chart and look for task bars highlighted in red -- these are tasks without an assignee
2. Check the resource view for grey cells indicating unallocated time periods
3. Open any highlighted task in the lightbox to assign a resource
**Filtered Items and Resource Calculations**
Work items that are filtered from the task list but not hidden may still contribute to resource view markers. If you see unexpected grey cells, check your active filters to ensure items are not being filtered out of the task view while remaining in resource calculations.
**Orphaned Team Assignments**
If you use team assignments, ensure all team assignment work items are properly linked to their parent team. Unlinked team assignments can cause grey capacity indicators that appear similar to the no-allocation markers but indicate a configuration issue rather than a missing assignee.
## Verification
You should now see:
* Task bars with no assignee highlighted in red in the Gantt chart
* Grey cells in the resource view for unallocated time periods
* Completed (Done) tasks displaying normally without the red highlight, even if they have no assignee
## See Also
* [Set Up the Resource View](/gantt/guides/resources/resource-view)
* [Hide Inactive Resources](/gantt/guides/resources/resource-hiding)
* [Configure Resource Fields](/gantt/guides/resources/resource-field-configuration)
* [Configure Resource Allocation Marker Colors](/gantt/guides/visualization/resource-marker-colors)
* [Filter by Resource and Allocation](/gantt/guides/filtering/filter-by-resource)
# Set Up a Release Gantt with Teams
Source: https://learn.nextedy.com/gantt/guides/resources/release-gantt-with-teams
Configure a Nextedy GANTT chart that combines release planning with team assignments, allowing you to view work items filtered by both team and release using page parameters.
## Prerequisites
* Team and Team Assignment work item types are configured (version 23.4.0+)
* A custom field of type **Enum > Nextedy Team** exists on both your Plan and work item types
* Separate Iterations (Plans) exist for each team
If you have not already created a team custom field, add one to both your Plan type and your work item type (such as Work Package):
1. Navigate to **Administration > Work Items > Custom Fields**
2. Create a field with type **Enum > Nextedy Team**
3. Apply it to both the Plan and the relevant work item types
The Nextedy Team enumeration automatically populates with all work items of type Team, letting you assign plans and tasks to specific teams.
For each Iteration (Plan), set the team custom field to the appropriate team:
1. Open the Iteration in Polarion
2. Select the matching team from the team custom field dropdown
3. Ensure each team has its own set of Iterations for proper separation
Set up two page parameters on your LiveDoc page to enable interactive filtering:
| Page Parameter | Configuration |
| -------------- | -------------------------------------------------------------------------- |
| **Release** | Points to the Plan/Release field, allowing selection of a specific release |
| **Team** | Points to the team custom field, allowing selection of a specific team |
**Keep the Team Parameter ID as 'team'**
When creating the Team page parameter, use `team` as the parameter ID. This specific naming is required for proper integration with the Gantt query field.
Connect the page parameters to the Gantt widget by setting the **Query Type** to **Lucene + Velocity** and entering a query such as:
```
team.KEY:$pageParameters.team #if($pageParameters.Release.singleValue()) AND PLAN:($pageParameters.Release) #end
```
This query filters work items by the selected team and optionally by the selected release.
Add the **Page Parameter** widget to the same LiveDoc page alongside the Gantt widget. This provides dropdown selectors for switching between teams and releases without editing widget parameters.
To visually distinguish iteration boundaries on the Gantt chart, add a marker script in the **Markers Script** field of the widget parameters. The script queries plans matching the selected team and adds colored markers at each iteration due date.
**Update Project References in Scripts**
If you use marker or item scripts, update the project ID references to match your actual Polarion project. Scripts referencing incorrect project IDs will fail silently and no markers will appear.
If work items lack explicit start and end dates, you can use an item script to inherit the iteration dates. Add a script in the **Item Script** field that checks each work item for an assigned iteration and, if no dates are set, uses the iteration start and due dates as the task schedule.
## Understanding the Resource View
With this configuration, the resource view shows team members and their workload within the context of the selected team and release:
* **Team members** appear as resource rows with their assigned work items
* **Outside of Team** row appears when a work item is assigned to the selected team but the assignee is not a member of that team -- click to expand and see the specific user
## Verification
You should now see:
* Page parameter dropdowns for Team and Release on the LiveDoc page
* The Gantt chart filtering work items based on the selected team and release
* Resource view rows showing team member allocation for the filtered scope
* Iteration markers (if configured) highlighting plan boundaries
## See Also
* [Set Up Team Assignments Gantt](/gantt/guides/resources/team-assignments-gantt)
* [Set Up a Cross-Team Gantt Chart](/gantt/guides/resources/cross-team-gantt)
* [Configure Page Parameters](/gantt/guides/layout/page-parameters)
* [Use Dynamic Queries with Page Parameters](/gantt/guides/filtering/dynamic-queries)
* [Create Markers with Scripts](/gantt/guides/scripting/marker-scripts)
# Configure Resource Fields
Source: https://learn.nextedy.com/gantt/guides/resources/resource-field-configuration
Change which work item field the Nextedy GANTT resource view uses to identify resources, allowing you to display teams, departments, or custom groupings instead of individual assignees.
## Default Behavior
By default, the resource view uses the standard Polarion `assignee` field. Each row in the resource view represents one user, and workload is calculated based on work item assignments to that user.
## Step 1 -- Choose a Resource Field
The **Resource Field** widget parameter determines which work item field drives the resource view. You can point it to any field of the following types:
| Field Type | Example | Use Case |
| --------------------- | -------------------------- | ------------------------------------- |
| **User** | `assignee` | Standard per-user workload view |
| **Enumeration** | `primaryOwnership`, `team` | Team or department grouping |
| **Multi Enumeration** | `teams` | Work items assigned to multiple teams |
## Step 2 -- Set the Resource Field Parameter
1. Open the Gantt page in **Edit mode**.
2. Click the widget gear icon to open **Widget Parameters**.
3. In the **Resource View** section, locate the **Resource Field** parameter.
4. Enter the field ID of your chosen resource field (e.g., `primaryOwnership`).
5. Click **Apply**.
**Use team enumeration for cross-team views**
In Polarion SAFe templates, the "Feature" work item type often has a `primaryOwnership` custom field of type Enumeration pointing to teams. Set Resource Field to `primaryOwnership` to see team-based resource allocation instead of individual users.
## Step 3 -- Verify Field Type Compatibility
The resource field must be one of the supported types listed above. If you configure a field that is not a User, Enumeration, or Multi Enumeration type, the resource view may not display resources correctly.
**Custom fields must exist on displayed work item types**
If the resource field does not exist on a work item type shown in the Gantt, those work items will appear as unassigned in the resource view. Verify the field is defined on all relevant work item types.
## Example: Team-Based Resource View
To show teams instead of individual users:
1. Create a custom field `team` of type **Enum > Nextedy Team** on your work item type.
2. Assign work items to teams using this field.
3. Set **Resource Field** to `team` in the Gantt widget parameters.
4. Enable **Show Resource View**.
The resource view now shows one row per team with workload markers reflecting all work items assigned to that team.
## Example: Multi-Team Assignments
If a work item can belong to multiple teams, use a **Multi Enumeration** field:
1. Create a custom field `teams` of type Multi Enumeration.
2. A single work item assigned to both "Team Alpha" and "Team Beta" will contribute workload to both resource rows.
## Step 4 -- Customize the Resource Label
The **Resource Label** parameter controls the column header text in the resource view. Set it to a descriptive name such as "Team" or "Department" to match the field you selected.
**Combine with resource load modes**
The resource field configuration works with all four [resource load calculation modes](/gantt/guides/resources/resource-view). When using Assignment Allocation mode with a team field, you get team-level capacity percentages.
## Verification
You should now see:
* Resource view rows labeled with values from your chosen field (teams, departments, etc.) instead of individual user names
* Workload markers distributed correctly across the resource rows
* Work items without a value in the resource field appearing in the "Unassigned" row (if Show Unassigned is enabled)
## See Also
* [Set Up the Resource View](/gantt/guides/resources/resource-view)
* [Set Up a Cross-Team Gantt Chart](/gantt/guides/resources/cross-team-gantt)
* [Set Up Team Assignments Gantt](/gantt/guides/resources/team-assignments-gantt)
* [Filter by Resource and Allocation](/gantt/guides/filtering/filter-by-resource)
# Hide Inactive Resources
Source: https://learn.nextedy.com/gantt/guides/resources/resource-hiding
Reduce visual clutter in the Nextedy GANTT resource view by hiding resources that have no tasks assigned in the current view.
Navigate to the Polarion page containing your Gantt widget with the resource view enabled. If you have not yet enabled the resource view, set **Show Resource View** to `Yes` in the widget parameters.
Click the **Hide Empty Resources** button in the Gantt toolbar. This toggles the visibility of resource rows that have no tasks in the currently visible time range and filter scope.
When activated:
* Resources with **zero visible tasks** are hidden from the resource view
* Resources with **at least one visible task** remain displayed
* The toggle state is preserved while you interact with the chart
**Quick Toolbar Access**
The hide empty resources toggle is available in the Gantt toolbar alongside other view controls. Look for it in the resource view section of the toolbar buttons.
## How Resource Hiding Works
The resource hiding behavior evaluates each resource against the current view state:
| Condition | Resource Visible? |
| -------------------------------------------- | -------------------- |
| Resource has tasks in current filter | Yes |
| Resource has no tasks in current filter | Hidden |
| Filter changes to include resource tasks | Automatically shown |
| Filter changes to exclude all resource tasks | Automatically hidden |
Resource visibility is **re-evaluated automatically** when:
* You apply or change a filter
* Tasks are added or removed
* The visible time range changes
**Distinction from Show Unassigned**
Resource hiding and the **Show Unassigned** option serve different purposes. **Show Unassigned** controls whether work items without an assignee appear in a dedicated "Unassigned" row. **Hide Empty Resources** controls whether resource rows with no assigned tasks are shown. These are independent features that can be used together.
You can combine resource hiding with resource-specific filtering for targeted views:
1. Enable resource hiding via the toolbar toggle
2. Use the resource filter to narrow down to specific resources
3. When a resource filter is active, only the filtered resource is shown -- all other resources are hidden regardless of task assignments
**Filtered Items Still Appear in Resource Markers**
Items that are filtered from the task row list may still appear in the resource view markers. Only items that are explicitly *hidden* are excluded from marker calculations. This is by design to ensure resource load calculations remain accurate even when the task list is filtered.
After enabling the toggle:
1. Check that resources with no tasks in the current view are no longer displayed
2. Apply a filter that excludes some tasks -- verify that resources losing all visible tasks disappear
3. Remove the filter -- verify that previously hidden resources reappear
**Use with Large Teams**
Resource hiding is especially useful for charts with many team members. It keeps the resource view focused on active contributors for the current time period, making overallocation detection faster and clearer.
## Verification
You should now see:
* Only resources with active tasks displayed in the resource view
* Resource rows automatically appearing and disappearing as you change filters or the visible time range
* The hide empty resources toggle in the toolbar controlling the behavior
## See Also
* [Set Up the Resource View](/gantt/guides/resources/resource-view)
* [Filter by Resource and Allocation](/gantt/guides/filtering/filter-by-resource)
* [Configure Resource Fields](/gantt/guides/resources/resource-field-configuration)
* [Mark Tasks Without Resource Allocation](/gantt/guides/resources/no-allocation-marking)
# Set Up the Resource View
Source: https://learn.nextedy.com/gantt/guides/resources/resource-view
Enable and configure the Nextedy GANTT resource view to display workload allocation for each team member or team directly below the Gantt chart.
The Resource View adds a grid below the Gantt timeline with one row per resource. Cell values indicate the effort assigned to each user, and hovering over a load cell reveals a tooltip with work item IDs or capacity details.
1. Open the Gantt page in **Edit mode**.
2. Click the widget gear icon to open **Widget Parameters**.
3. In the **Resource View** section, set **Show Resource View** to **Yes**.
4. Click **Apply**.
Once enabled, additional parameters appear in the Resource View section.
Resource view sub-parameters such as View Height, Resource Field, and Resource Load Calculation only become visible after you set Show Resource View to Yes.
| Parameter | Description | Default |
| ----------------------------- | ---------------------------------------------------------------------------------------- | ---------------- |
| **Show Resource View** | Enables the resource view panel | No |
| **Items per Resource** | Maximum items per resource before overallocation is flagged (Leaf Items Count mode only) | 1 |
| **View Height** | Default pixel height of the resource view panel | 250 |
| **Resource Field** | Work item field used to identify resources | `assignee` |
| **Resource Label** | Column header text for the resource list | - |
| **Show Unassigned** | Display a row for work items with no assigned resource | No |
| **Resource Load Calculation** | How workload values are computed in each cell | Leaf Items Count |
The Gantt offers four calculation modes for the resource view cells:
| Mode | What It Shows | Best For |
| ------------------------- | ----------------------------------------------------------------------------- | -------------------------- |
| **Leaf Items Count** | Number of leaf-level work items assigned per time period | Simple task counting |
| **Estimate + Spent** | Remaining estimate plus time already spent, distributed across scheduled days | Full effort picture |
| **Remaining Estimate** | Only future remaining effort, distributed from today onward | Forecasting remaining work |
| **Assignment Allocation** | Percentage-based team allocation from team assignment work items | Team capacity planning |
**Leaf Items Count** counts each leaf-level item as one unit. In the example below, the two leaf items each contribute a green cell marked "1" for their scheduled timeframe.
**Estimate + Spent** combines remaining estimate with time already spent and distributes it across the scheduled days, making it easy to spot overloaded team members.
When 96 hours of combined effort are spread across 10 scheduled days, the Resource View shows a daily load of 9.6 hours for the assigned user.
**Remaining Estimate** distributes only the future remaining effort across scheduled days. A 6-day remaining estimate spread across 10 calendar days yields a workload of 4.8 hours per day.
**Assignment Allocation** shows percentage-based team allocation. A user assigned 35% in one team and 10% in another shows a combined 45% workload for that period; totals above 100% indicate overallocation.
If your project tracks time spent, the Remaining Estimate mode gives you the most actionable view of outstanding work without inflating numbers with already-completed effort.
**Resolution status affects calculation**
The resource load calculation considers work item resolution status, not just time fields. If a work item is resolved, it may be excluded from certain calculation modes. Use Remaining Estimate mode if resolved items appear to inflate numbers in Estimate + Spent mode.
**Split the effort between multiple assignees.** By default, a task’s effort is shown in full for every assignee — a 4-day estimate appears as 4 days for each one.
To divide the effort equally between assignees instead, add `nextedy.gantt.multiAssignmentSameEffortForAll=false` to **Administration > Configuration Properties**.
To see work items that have no resource assigned:
1. Set **Show Unassigned** to **Yes** in the Resource View parameters.
2. A dedicated row labeled "Unassigned" appears at the bottom of the resource view.
This helps you identify unallocated tasks during sprint or release planning.
**Show only users with tasks assigned.** Starting with version 24.1.1, the **Hide No Task Resources** button on the Gantt toolbar lets you collapse the list to resources that actually carry work. By default, all resources are shown.
Toggling the button hides every resource that has no tasks from the Gantt page.
You can set the initial panel height via the **View Height** parameter. After the Gantt loads, you can also resize the resource view by dragging the horizontal divider between the Gantt chart and the resource view.
Resource allocation markers use color coding to indicate capacity status:
* **Green** cells indicate the resource is within capacity
* **Red** cells indicate the resource is overallocated
The default scheme uses green for acceptable allocation and red for overallocation.
You can customize these bubbles for a clearer, more intuitive allocation overview.
With the dynamic approach, you define color thresholds via the Gantt Config Script or Configuration Properties — for example, lightgreen up to 50%, `#51c185` up to 100%, orange up to 150%, and `#ff8686` above 150%.
Team overallocation color schemes let you distinguish global overload from in-team overload. Since version 25.4.1, this also works when defined via Configuration Properties at project or global level.
With the static approach, a Script Block widget overrides the OK marker (default green bubble) and the overloaded marker (default red bubble) so you can apply any background-color and color combination.
The static CSS approach applies to **Leaf Items Count** and **Assignment Allocation** modes. For **Estimate + Spent** and **Remaining Estimate** modes, use the dynamic `resourceMarkersColorConfig` approach instead.
For full instructions, see [Configure Resource Allocation Marker Colors](/gantt/guides/visualization/resource-marker-colors).
When using Leaf Items Count mode, only leaf-level work items (those with no children) are counted. If you enable `onlyLeafTasks`, parent summary tasks are excluded from both the Gantt display and resource calculations.
Only Tasks and Work Packages that have no child items are counted as load for their assignees, so real, hands-on work is counted once per user and parent items are not double-counted.
To count higher-level items as well — useful when you intentionally track effort at multiple levels — set `nextedy.gantt.config.onlyLeafTasks=false` in **Widget Properties > Gantt Config Script**.
With that setting, all items are counted in the Resource View.
To skip specific tasks from the calculation — for example, keeping only Work Packages — add a rule to the Item Script such as `if(wi.getType().getId()==="task") { task.load=0; }`.
You can also calculate Resource Load globally while showing only the project timeline, so the load counts items from other projects too.
Achieve this by querying items from multiple projects.
## Verification
You should now see:
* A resource view panel below the Gantt chart with one row per assigned resource
* Workload values in each cell matching your chosen calculation mode
* Color-coded cells indicating within-capacity (green) and overallocation (red) states
## See Also
* [Configure Resource Fields](/gantt/guides/resources/resource-field-configuration)
* [Set Up a Cross-Team Gantt Chart](/gantt/guides/resources/cross-team-gantt)
* [Hide Inactive Resources](/gantt/guides/resources/resource-hiding)
* [Configure Resource Allocation Marker Colors](/gantt/guides/visualization/resource-marker-colors)
* [Filter by Resource and Allocation](/gantt/guides/filtering/filter-by-resource)
# Set Up Team Assignments Gantt
Source: https://learn.nextedy.com/gantt/guides/resources/team-assignments-gantt
Configure a Nextedy GANTT chart to visualize team member allocation percentages and track capacity across teams over defined time periods.
## Prerequisites
Before you begin, ensure that:
* You have Team and Team Assignment work item types configured in Polarion (version 23.4.0 or later)
* Team Assignment work items are linked to parent Team work items
* Custom date fields exist for team assignment start and end dates
Unlike Polarion's built-in **Time-split Assignments** (Administration > Users), which allocate a user's time to a *project* rather than to a *team*, this setup models allocation at the team level:
Create a new LiveDoc page that will host the Gantt widget. In the widget parameters:
1. Set the **Work Item Type** to `Team`
2. Set **Load Children** to `1` so the Gantt loads both Team and Team Assignment work items
In the widget parameters, specify the **Parent Role** that links Team Assignment work items to their parent Team work items -- the `assignment` link role (opposite role "is assigned to"). Fill in the **WI Type Configuration** section to define how each work item type appears in the chart.
In Polarion **Administration**, define the two work item types this guide relies on -- `team` (Team) and `teamAssignment` (Team Assignment):
Add the three custom fields that hold each assignment's period and capacity on the `teamAssignment` type -- `from` and `to` (Date) and `capacity` labeled % Assignment (Integer):
Create the `assignment` work item link role (opposite role "is assigned to") that connects each Team Assignment to its parent Team:
Optionally, add capacity-modifier custom fields to the `team` type -- `capModA` (Outstanding Buffer %) and `capModB` (Unclear Buffer %) -- to reserve a share of each member's time for unplanned work or future uncertainty:
Select the start and end date fields that correspond to your team assignment custom fields:
| Parameter | Value |
| --------------- | -------------------------------------------- |
| **Start Field** | Your custom team assignment start date field |
| **End Field** | Your custom team assignment end date field |
Set the **Resource Load Calculation** field to **Assignment Allocation**. This tells the Gantt to calculate resource load based on the percentage allocation specified in each team assignment rather than task estimates.
In the widget parameters under **Resource View**:
1. Set **Show Resource View** to `Yes`
2. Configure the **Resource Field** to point to the assignee field
The resource view displays each team member's allocation percentage. Cells turn green when allocation is within capacity (at or below 100%) and red when the resource is overallocated.
**Unlinked Team Assignments Are Ignored**
Each Team Assignment work item **must be linked to a parent Team work item**. Assignments not associated with a parent team are ignored during capacity calculations. Verify all team assignment links before relying on the resource view data.
**Required Fields Are Auto-Enforced**
Team Assignment work items are treated specially by the Gantt. The system automatically enforces the presence of fields required for team assignment handling, so you do not need to set those fields as required in Polarion.
## How Allocation Percentages Work
When you open a team assignment in the lightbox, you see two required fields:
* **Assignee** (marked with a red asterisk) -- select the team member from the dropdown
* **Assignment** -- specify the allocation percentage for that member
The lightbox title updates dynamically to show the selected user name and assignment percentage. The resource view then aggregates these percentages across all teams for each user, making overallocation immediately visible.
| Scenario | Resource View Display |
| ------------------------------------------- | -------------------------------------- |
| User at 50% in Team Alpha, 30% in Team Beta | 80% total -- green cell |
| User at 70% in Team Alpha, 50% in Team Beta | 120% total -- red cell (overallocated) |
| User at 100% in one team only | 100% -- green cell |
**Auto-Assignee Not Available for Team Assignments**
The resources dropdown in the team assignment lightbox only shows explicit users. The automatic assignee option is not available for team assignments, distinguishing them from regular work item assignments.
## Cross-Project Team Management
If your teams span multiple Polarion projects, you can centralize team management in a single project and reference it from other projects. See [Configure External Team Management Project](/gantt/guides/resources/external-team-management) for details on cross-project team setups.
## Verification
A working setup has each Team work item (Alpha, Beta, Gama) as a parent with its Team Assignment children carrying the assignees:
You should now see:
* Team work items displayed as parent rows in the Gantt chart
* Team Assignment work items nested under their respective teams
* The resource view showing allocation percentages per user, with green cells for normal allocation and red cells for overallocation
In the rendered Gantt, teams appear as bars with their assignments below, and the resource view aggregates each user's allocation per day -- here a red bubble flags Steve at a combined 120% (GT-561 at 40% plus GT-560 at 80%):
## See Also
* [Set Up a Cross-Team Gantt Chart](/gantt/guides/resources/cross-team-gantt)
* [Set Up a Release Gantt with Teams](/gantt/guides/resources/release-gantt-with-teams)
* [Configure External Team Management Project](/gantt/guides/resources/external-team-management)
* [Set Up the Resource View](/gantt/guides/resources/resource-view)
* [Configure Resource Fields](/gantt/guides/resources/resource-field-configuration)
# Configure Auto-Scheduling
Source: https://learn.nextedy.com/gantt/guides/scheduling/configure-auto-scheduling
Enable automatic rescheduling of dependent tasks in Nextedy GANTT so that when you move a predecessor, all successor tasks adjust their dates automatically based on dependency links.
## Prerequisites
* A working Gantt chart with dependency links configured (see [Create and Configure Dependency Links](/gantt/guides/dependencies/create-dependency-links))
* Access to Polarion **Administration > Configuration Properties** (for default settings) or the wiki page editor (for per-widget settings)
## Enable Auto-Scheduling by Default
To make auto-scheduling active on all Gantt widgets by default, set the following administration property:
1. Navigate to **Administration > Configuration Properties** (project or global level).
2. Add the property:
```
nextedy.gantt.default.auto_scheduling=true
```
This sets the default for new and existing Gantt widgets. The default value is `false`.
**Existing Widgets**
This property serves as the default toggle. Once auto-scheduling is set on a specific widget, the widget-level setting takes precedence.
## Toggle Auto-Scheduling at Runtime
Users can toggle auto-scheduling on and off using the toolbar button during an editing session. The auto-scheduling toggle is available in the Gantt toolbar when the chart is in edit mode.
When auto-scheduling is active:
* Moving a task automatically pushes successor tasks forward to maintain dependency constraints
* Shortening or extending a task adjusts the start dates of successors accordingly
* The rescheduling is triggered only when you change an item or modify a dependency link
## How Auto-Scheduling Works
Auto-scheduling enforces finish-to-start constraints between linked tasks. When you move Task A forward by 3 days, Task B (which depends on Task A) automatically shifts its start date forward by 3 days as well. This propagation continues through the entire dependency chain.
| Action | Result with Auto-Scheduling ON | Result with Auto-Scheduling OFF |
| -------------------------- | --------------------------------------- | -------------------------------------- |
| Move predecessor forward | Successors shift forward | Successors stay in place |
| Shorten predecessor | Successors may shift earlier | No change |
| Create new dependency link | Successor adjusts to satisfy constraint | Dependency arrow drawn, no date change |
| Delete dependency link | Successor dates unchanged | Dependency arrow removed |
**No Built-in Conflict Detection for Concurrent Edits**
Auto-scheduling operates on the client side during your editing session. If multiple users edit the same Gantt simultaneously, the last save wins. There is no built-in conflict detection for concurrent edits.
## Combine Auto-Scheduling with Manual Control
In complex project hierarchies, you may want auto-scheduling for lower-level tasks but manual control for top-level milestones. You can achieve this by:
* Using the `readonly` property on specific items via Item Script to prevent them from being moved by auto-scheduling
* Setting specific work item types to **Milestone** presentation mode, which treats them as fixed date markers
**Mixed Scheduling Strategy**
For waterfall projects where top-level phases have fixed dates but sub-tasks should auto-schedule within those phases, combine the parent bounds constraint with auto-scheduling. Enable auto-scheduling for task-level items and set parent items to Derived Schedule mode so they automatically span their children.
## Enable Critical Path Alongside Auto-Scheduling
Auto-scheduling pairs well with critical path analysis. To enable both:
```
nextedy.gantt.default.auto_scheduling=true
nextedy.gantt.default.critical_path=true
```
With both features active, the Gantt highlights the longest dependency chain in red while automatically maintaining schedule consistency when tasks are moved.
## Verification
After enabling auto-scheduling:
1. Open your Gantt chart in edit mode.
2. Verify the auto-scheduling toggle is active in the toolbar.
3. Drag a predecessor task to a new date.
4. You should now see all dependent successor tasks shift automatically to maintain the dependency constraint.
## See Also
* [Auto-Scheduling and Dependency Propagation](/gantt/concepts/auto-scheduling) -- conceptual background
* [Create and Configure Dependency Links](/gantt/guides/dependencies/create-dependency-links) -- set up the dependency links that auto-scheduling uses
* [Configure Advanced Dependency Types (FS, SS, FF, SF)](/gantt/guides/dependencies/advanced-dependency-types) -- use all four dependency types
* [Prevent Tasks from Moving Outside Parent Range](/gantt/guides/scheduling/prevent-moving-out-of-parent) -- combine with parent constraints
# Disable Date Rounding on Drag
Source: https://learn.nextedy.com/gantt/guides/scheduling/date-rounding
Configure Nextedy GANTT to stop rounding task dates to the nearest scale boundary when dragging task bars, giving you precise control over task positioning.
## Default Behavior
By default, when you drag a task bar on the Gantt chart, the start and end dates snap to the nearest scale marks. The rounding unit depends on your current time scale:
| Scale | Rounding Unit |
| ----------- | ------------- |
| Day (D, DD) | Full days |
| Week (W) | Full weeks |
| Month (M) | Full months |
| Year (Y) | Full years |
For example, if you set the scale to **Month**, dragging a task rounds its start date and duration to full months. This behavior simplifies scheduling at coarse granularity but prevents precise date placement when needed.
## Disable Date Rounding
To disable rounding, add the following line to **Widget Properties > Advanced > Gantt Config Script**:
```javascript theme={null}
gantt.config.round_dnd_dates = false;
```
After this change, dragging task bars places them at the exact position where you drop them, without snapping to scale boundaries.
**Combine with hour-precision scheduling**
If you are using [hour-precision scheduling](/gantt/guides/scheduling/hour-precision) with the scale set to hours (H), disabling date rounding lets you position tasks at specific times within the day rather than snapping to whole-hour boundaries.
## When to Keep Rounding Enabled
Date rounding is useful in scenarios where approximate scheduling is sufficient:
* **Long-term portfolio planning** at the month or year scale, where exact days do not matter
* **Sprint planning** at the week scale, where tasks should align to sprint boundaries
* **Release planning** where milestones align to month boundaries
**Rounding affects both drag and resize**
The `round_dnd_dates` setting controls rounding for both drag (move) and resize operations. Setting it to `false` disables rounding for all drag-and-drop interactions.
## Verification
You should now see:
* Task bars placed at the exact drop position when dragged, without snapping to scale boundaries
* Dates in the lightbox reflecting the precise position where the task was dropped
* Resized task bars ending at the exact cursor position rather than the nearest scale mark
## See Also
* [Schedule in Hours Instead of Days](/gantt/guides/scheduling/hour-precision)
* [Configure the Time Scale](/gantt/guides/visualization/timescale)
* [Configure Auto-Scheduling](/gantt/guides/scheduling/configure-auto-scheduling)
# Schedule in Hours Instead of Days
Source: https://learn.nextedy.com/gantt/guides/scheduling/hour-precision
Configure Nextedy GANTT to track task durations in hours rather than days, enabling fine-grained scheduling for short-duration activities.
## Prerequisites
* Gantt version 4.0.0 or newer
* Access to widget parameter editing on your Gantt page
1. Open the page containing your Gantt chart in edit mode.
2. Open **Widget Properties > Data Mapping > Duration Precision**.
3. Change the value from **Standard (Days)** to **High (Hours)**.
After this change, the Gantt manages durations as fractions of hours instead of whole days.
When working with high duration precision, you should set the default scale to display hours:
1. In **Widget Properties > Scale**, select **H** (hours).
2. Save the widget properties.
The Gantt chart header now displays individual hours, giving you visibility into sub-day task placement.
High-precision scheduling requires working time awareness so the Gantt correctly accounts for working hours in duration calculations:
1. In **Widget Properties > Advanced > Working Time**, set the value to **YES**.
This ensures the Gantt skips non-working hours when computing task durations.
Review your field configuration to ensure compatibility with hour-precision mode:
| Field | Recommended Type | Notes |
| --------------------- | ------------------------------------- | ------------------------------------ |
| Duration Field | Duration (`initialEstimate`) or Float | Value now represents hours, not days |
| Start/End Date Fields | **DateTime** (not Date) | Required for sub-day precision |
**Existing data interpretation changes**
If your duration field points to an Integer, Float, or String field, existing values are reinterpreted as hours after switching precision. For example, a stored value of `8` previously meant 8 days but now means 8 hours (1 working day).
**Use DateTime fields for start and end dates**
If your start/end date fields currently use a custom field of type **Date**, change them to **DateTime** to capture hour-level precision. Plain Date fields only store day-level values and cannot represent specific hours.
## Configuration Summary
| Widget Parameter | Value | Location |
| ------------------ | ------------ | -------------------------------- |
| Duration Precision | High (Hours) | Widget Properties > Data Mapping |
| Scale | H | Widget Properties > Scale |
| Working Time | YES | Widget Properties > Advanced |
## Impact on Resource View
When you enable high-precision scheduling, the resource view calculates load at the hour level. You can customize working hours per resource using the `workingHoursPerDay` property in **Administration > Configuration Properties** or via the Gantt Config Script:
```javascript theme={null}
gantt.config.workingHoursPerDay = 7;
```
For per-resource working hours, define a custom function in **Widget Properties > Advanced > Gantt Config Script**:
```javascript theme={null}
gantt.config.workingHoursPerDayFunction = (resource) => {
if (resource === "rProject") {
return 4;
}
return 8;
};
```
**Combine with working calendars**
For the most accurate resource load calculations in hour mode, enable working calendars under **Widget Properties > Working Calendars**. This ensures the Gantt respects per-user availability, time off, and schedule tweaks when computing hour-level capacity.
## Verification
You should now see:
* Task durations displayed in hours (e.g., `4h` instead of `1d`)
* The Gantt chart header showing hourly intervals
* Task bars snapping to hour-level positions when dragged
* Resource view displaying hourly capacity and load values
## See Also
* [Configure the Time Scale](/gantt/guides/visualization/timescale)
* [Customize Working Hours per Resource](/gantt/guides/calendars/working-hours-per-resource)
* [Set Up Work Item Calendars](/gantt/guides/calendars/work-item-calendar)
* [Set Up the Resource View](/gantt/guides/resources/resource-view)
# Scheduling
Source: https://learn.nextedy.com/gantt/guides/scheduling/index
The scheduling guides cover how to configure date management, auto-scheduling, duration precision, and timeline constraints in Nextedy GANTT.
Enable dependency-driven automatic date recalculation so successor tasks adjust when predecessors change.
Limit the visible timeline to a specific start and end date using scripts or page parameters.
Switch from day-level to hour-level duration precision for fine-grained scheduling.
Configure parent task bars to automatically span the extents of their child items.
Pull task start and end dates from Polarion plan assignments using item scripts.
Enforce constraints that keep child tasks within their parent's date boundaries.
**[Perform What-If Analysis Without Saving](/gantt/guides/scheduling/what-if-analysis)** -- Experiment with schedule changes before committing them to Polarion.
**[Disable Date Rounding on Drag](/gantt/guides/scheduling/date-rounding)** -- Allow precise date placement when dragging task bars.
**Related Concepts**
For background on how auto-scheduling and dependencies work, see [Auto-Scheduling and Dependency Propagation](/gantt/concepts/auto-scheduling) and [Critical Path Analysis](/gantt/concepts/critical-path).
# Derive Parent Schedule from Children
Source: https://learn.nextedy.com/gantt/guides/scheduling/parent-derived-schedule
Configure Nextedy GANTT so that parent work items automatically calculate their schedule from the date range of their children, instead of being scheduled manually.
Ensure your Gantt chart displays the correct hierarchy by configuring the parent link role:
1. Open the page in edit mode and access **Widget Properties**.
2. Under **Work Items > Parent Role**, select the link role that defines parent-child relationships (e.g., `has_parent`).
3. Verify that both parent and child work items appear in the Gantt chart with the correct nesting.
For each work item type that should derive its schedule from children, set the Gantt presentation mode:
1. In **Widget Properties > Work Item Types**, locate the configuration for the parent work item type (e.g., "Portfolio Epic" or "Feature").
2. Set the **Gantt Presentation Mode** to **Project**.
When a work item type uses the Project presentation mode, its task bar spans the full range of its child items. The parent's start date equals the earliest child start, and its end date equals the latest child end.
If your work breakdown structure has multiple levels, configure how many levels the Gantt loads:
1. In **Widget Properties**, set the **Load Children** depth to the number of levels you need (e.g., `3` for three levels of nesting).
**Parent dates are read-only in Project mode**
When a work item type uses Project presentation mode, its dates cannot be edited directly in the Gantt chart. The parent's schedule is always computed from its children. Attempting to drag or resize the parent bar will not change its dates.
**Mixed hierarchy with manual and derived scheduling**
If you need some parent types to derive their schedule from children while others remain manually scheduled, configure the presentation mode per work item type. Only types set to **Project** mode will derive dates automatically.
Parent items using the Project presentation mode are rendered with a distinct visual style (typically green summary bars) to distinguish them from manually scheduled items. This helps users quickly identify which work items are derived.
**Auto-scheduling interaction**
When auto-scheduling is enabled alongside derived parent schedules, be aware that moving child items triggers recalculation of the parent range. If you also have dependency links, the auto-scheduler recalculates successor dates first, then the parent bar adjusts. For complex hierarchies, consider using an Item Script to control which levels participate in auto-scheduling.
## Verification
You should now see:
* Parent work items displayed as summary bars that span the full range of their children
* Parent bars automatically updating when you move or resize child items
* Parent task dates being read-only (not draggable)
## See Also
* [Configure Auto-Scheduling](/gantt/guides/scheduling/configure-auto-scheduling)
* [Prevent Tasks from Moving Outside Parent Range](/gantt/guides/scheduling/prevent-moving-out-of-parent)
* [Derive Schedule from Polarion Plans](/gantt/guides/scheduling/plan-derived-schedule)
* [Configure Item Colors](/gantt/guides/visualization/configure-colors)
# Derive Schedule from Polarion Plans
Source: https://learn.nextedy.com/gantt/guides/scheduling/plan-derived-schedule
Configure Nextedy GANTT to derive work item schedules from their assignment to Polarion Plans, so that unplanned items inherit the plan's start and end dates automatically.
## When to Use This Approach
Use plan-derived scheduling when work items do not have their own start/end date fields populated but are assigned to Polarion Plans (iterations, releases) that have defined date ranges. This is common in agile workflows where sprints and iterations define the schedule.
Navigate to **Widget Properties > Advanced > Item Script** and add one of the following scripts depending on your scenario.
### Option A: Derive Schedule for All Unplanned Items
Use the built-in utility method to automatically assign plan dates to unplanned work items:
```javascript theme={null}
if (wi != null) {
if (task.unplanned) {
task.deriveScheduleFromPlans(wi, "iteration");
}
}
```
Replace `"iteration"` with the plan template ID that matches your project (e.g., `"release"`, `"sprint"`).
### Option B: Derive Schedule for a Specific Plan Type
For more control, iterate through the work item's plan assignments and match a specific template:
```javascript theme={null}
var plans = wi.getPlannedIn().iterator();
while (plans.hasNext()) {
var plan = plans.next();
if (plan.getTemplate().getId() === "Iteration") {
task.start_date = util.getDate(plan, "startDate");
task.end_date = util.getDate(plan, "dueDate");
task.duration = null;
task.readonly = true;
task.unplanned = false;
}
}
```
| Property | Effect |
| ------------------------ | ---------------------------------------------- |
| `task.start_date` | Sets the task start from the plan's start date |
| `task.end_date` | Sets the task end from the plan's due date |
| `task.duration = null` | Clears duration so it is computed from dates |
| `task.readonly = true` | Prevents manual editing of derived dates |
| `task.unplanned = false` | Marks the item as scheduled on the Gantt chart |
**Null check is required**
Always wrap your Item Script with `if (wi != null)` to prevent errors when the script processes synthetic or missing work items. Without this check, the script may fail silently.
**Use the property-assignment form for dates**
Set the derived dates with `task.start_date` and `task.end_date` (property assignment, as shown above) -- this is the documented form (see the [Item Script API](/gantt/reference/api/item-script-api)). Do **not** assign to `task.setStart_date` / `task.setEnd_date`: those are setter *methods*, not assignment targets, so assigning a value to them does not set the date. For the Polarion 2304+ scripting changes (getter methods and `typeof` checks), see [Migrate Scripts for Polarion 2304+](/gantt/guides/scripting/script-migration-2304).
If you want to display both plans and work items together on a single Gantt chart, use the Plans Gantt widget:
1. Set **Widget Properties > Show Plan Work Item > Enable Show Items** to **true**.
2. Configure the **Load Children** depth to control how many levels of sub-plans and work items are displayed.
3. Set the child link role to load work items under their parent plans.
**Combine with the Roadmap view**
For portfolio-level visibility, configure the Plans Gantt with Release as the top-level plan template, Iteration as the second level, and work items as the third level. Set **Load Children** to `3` to display the full hierarchy.
Save the widget properties and reload the page. The Gantt chart recalculates work item positions based on their plan assignments.
## Verification
You should now see:
* Previously unplanned work items now positioned on the Gantt chart at the dates of their assigned plans
* Derived items marked as read-only (not draggable) if you set `task.readonly = true`
* Plan date ranges reflected accurately on the work item task bars
## See Also
* [Derive Parent Schedule from Children](/gantt/guides/scheduling/parent-derived-schedule)
* [Show Plans and Work Items Together](/gantt/guides/plans/plans-and-work-items)
* [Write Item Scripts](/gantt/guides/scripting/item-script-basics)
* [Migrate Scripts for Polarion 2304+](/gantt/guides/scripting/script-migration-2304)
* [Sync Work Item Dates to Plans](/gantt/guides/plans/sync-to-plans)
# Prevent Tasks from Moving Outside Parent Range
Source: https://learn.nextedy.com/gantt/guides/scheduling/prevent-moving-out-of-parent
Configure Nextedy GANTT to enforce date containment constraints so that child tasks cannot be scheduled outside their parent's date range.
## How the Constraint Works
When enabled, the Gantt chart enforces that every child task must stay within the date boundaries of its parent task. This applies to three editing interactions:
* **Drag** -- moving a child task bar left or right on the chart
* **Resize** -- extending or shrinking a child task bar from either end
* **Lightbox editing** -- changing dates or duration in the lightbox
If a child task is dragged or resized beyond the parent's boundaries, the Gantt blocks the operation. When editing via the lightbox, validation prevents saving dates that fall outside the parent range.
Add the following to **Widget Properties > Advanced > Gantt Config Script** to enable conflict detection:
```javascript theme={null}
gantt.config.rangeConflict = {
enabled: true,
checkStart: true,
checkEnd: true,
highlightChild: true
};
```
| Property | Description |
| ---------------- | ---------------------------------------------------------------- |
| `enabled` | Activates parent-child date range conflict detection |
| `checkStart` | Validates that child start dates are not before the parent start |
| `checkEnd` | Validates that child end dates are not after the parent end |
| `highlightChild` | Highlights out-of-range child tasks with a visual warning style |
**Check only one boundary**
If you only need to enforce that children do not extend past the parent's end date (but allow earlier starts), set `checkStart: false` and `checkEnd: true`.
When range conflict detection is active, the Gantt provides several automatic behaviors:
**During drag operations:**
* Child tasks that are dragged outside the parent range are visually highlighted with a conflict indicator
* When you move the child back within range, the conflict indicator is removed automatically
* Parent tasks that have out-of-range children are also highlighted
**During lightbox editing:**
* If you set a duration or date that places the task outside its parent's bounds, an error message appears and the save button is disabled
* The error message identifies the parent's date range so you can correct the values
**Parent resize behavior:**
* When a parent task is resized and its boundary moves inward, children that would fall outside the new range are automatically adjusted to stay within bounds
**Conflict detection is hierarchical**
Range conflict checking operates across all ancestor levels, not just the immediate parent. A deeply nested task is validated against every ancestor in the hierarchy. If a grandchild task extends beyond a grandparent's range, both the parent and grandparent are flagged.
After enabling range conflict detection, the Gantt scans all tasks on load. Parent tasks with out-of-range children are highlighted immediately, so you can identify and fix scheduling inconsistencies in your existing data.
The conflict tooltip on affected parent tasks displays a message indicating that children have a range conflict.
**Removing the parent clears constraints**
If a task needs to move freely outside its current parent's range, you can change the parent field to "no parent" in the lightbox. This removes the containment constraint for that task.
The Gantt toolbar includes a toggle for dragging children together with their parent. When this toggle is active and you move a parent task, all children move with it, maintaining their relative positions and avoiding range conflicts.
Use this in combination with range conflict detection to ensure hierarchical consistency during bulk rescheduling.
## Verification
You should now see:
* Child tasks blocked from being dragged past their parent's start or end date
* A visual highlight on parent and child tasks when a range conflict exists
* Error messages in the lightbox when attempting to save dates outside the parent range
* Conflicts detected automatically when the Gantt chart loads
## See Also
* [Derive Parent Schedule from Children](/gantt/guides/scheduling/parent-derived-schedule)
* [Configure Auto-Scheduling](/gantt/guides/scheduling/configure-auto-scheduling)
* [Configure Drag Children Behavior](/gantt/guides/editing/drag-children)
* [Use the Lightbox Inline Editor](/gantt/guides/editing/lightbox-editor)
# Set the Gantt Time Range
Source: https://learn.nextedy.com/gantt/guides/scheduling/set-time-range
Control which date range is visible in your Nextedy GANTT chart by setting explicit start and end boundaries.
## Set a Fixed Time Range via Script
To define a static date range, add the following to **Widget Properties > Advanced > Gantt Config Script**:
```javascript theme={null}
gantt.config.start_date = new Date(2024, 11, 10);
gantt.config.end_date = new Date(2025, 7, 20);
```
**JavaScript Months Are Zero-Based**
In JavaScript, months are numbered starting from 0 (January = 0, December = 11). The example above sets the range from **December 10, 2024** to **August 20, 2025**, not November-to-July.
| Month | JavaScript Value | Month | JavaScript Value |
| -------- | ---------------- | --------- | ---------------- |
| January | 0 | July | 6 |
| February | 1 | August | 7 |
| March | 2 | September | 8 |
| April | 3 | October | 9 |
| May | 4 | November | 10 |
| June | 5 | December | 11 |
## Set a Dynamic Time Range via Page Parameters
For dashboards where users need to select the visible date range, use **Polarion Page Parameters** to make the range interactive.
1. Add two Date-type page parameters to your LiveDoc page, named `start` and `end`.
2. Add the following to **Widget Properties > Advanced > Gantt Config Script**:
```javascript theme={null}
gantt.config.start_date = new Date($widgetContext.pageParameters.start.value.time);
gantt.config.end_date = new Date($widgetContext.pageParameters.end.value.time);
```
If your page parameters have different IDs, replace `start` and `end` with the actual parameter names.
**Combining with Filters**
The time range filter works alongside other Gantt filters (text filter, resource filter, closed items filter). Tasks outside the configured date range are hidden from the chart even if they match other filter criteria.
## Footer Indicator for Filtered Items
Starting with version 25.3.1, when a time range filter is active and some items are hidden, the Gantt footer displays:
* The count of visible rows versus total rows
* A funnel icon with a tooltip describing the active time range
This indicator helps users understand that tasks may be hidden because they fall outside the configured date range, not because they are missing from the data set.
## Reset to Auto-Fit
To remove the time range constraint and return to the default behavior (auto-fit to loaded items), simply remove the `gantt.config.start_date` and `gantt.config.end_date` lines from the Gantt Config Script. The chart will automatically adjust its visible range to fit all loaded work items.
## Verification
After configuring the time range:
1. Open your Gantt chart and verify the timeline header shows dates within your specified range.
2. If tasks exist outside your range, confirm they are hidden from the chart.
3. Check the footer for the filtered items indicator showing how many rows are visible versus total.
## See Also
* [Configure the Time Scale](/gantt/guides/visualization/timescale) -- adjust zoom levels and header formats within your time range
* [Configure Page Parameters](/gantt/guides/layout/page-parameters) -- set up page parameters for dynamic filtering
* [Schedule in Hours Instead of Days](/gantt/guides/scheduling/hour-precision) -- combine time range with hour-precision scheduling
* [Manage Large Datasets with Max Items](/gantt/guides/filtering/max-items) -- another approach to limiting visible data
# Perform What-If Analysis Without Saving
Source: https://learn.nextedy.com/gantt/guides/scheduling/what-if-analysis
Use Nextedy GANTT edit mode to explore schedule changes interactively without committing them to Polarion, allowing you to evaluate different scheduling scenarios before deciding to save.
## How It Works
The Gantt chart operates in a two-phase editing model: you make changes in edit mode, and those changes only persist to Polarion when you explicitly click **Save**. Until you save, all modifications are local to your browser session. This makes the Gantt a natural tool for what-if analysis.
Click the **Edit** button in the Gantt toolbar. Task bars become draggable, and the lightbox becomes available for field editing.
**Always-edit mode**
If your Gantt is configured with `alwaysedit` mode, the chart is always editable and there is no Edit button. In this case, unsaved changes still behave the same way -- they are not persisted until you click Save.
With the Gantt in edit mode, you can perform any combination of the following:
* **Drag task bars** left or right to change start dates
* **Resize task bars** to change duration
* **Edit dates in the lightbox** for precise adjustments
* **Create or remove dependency links** to evaluate cascading effects
* **Move parent tasks** to shift entire work breakdown branches
If auto-scheduling is enabled, moving one task automatically recalculates the dates of dependent successors, giving you immediate feedback on the downstream impact of your change.
Review the schedule after your changes. Key indicators to watch:
| Indicator | What to Look For |
| ----------------- | --------------------------------------------------------------------------- |
| Task bar colors | Red or orange bars indicate overdue or delayed items |
| Dependency arrows | Red dotted lines indicate violated dependency constraints |
| Resource view | Overallocated resources appear highlighted in the resource view |
| Critical path | If enabled, critical path highlighting shows which tasks drive the end date |
| Range conflicts | Parent tasks with out-of-range children are visually flagged |
**To save your changes:** Click the **Save** button in the Gantt toolbar. All modifications are persisted to Polarion work items.
**To discard your changes:** Reload the page in your browser. The Gantt reloads the original data from Polarion, reverting all unsaved changes.
**No built-in conflict detection for concurrent editors**
The Gantt uses a last-save-wins model. If another user saves changes to the same work items while you are in edit mode, your save will overwrite their changes. Coordinate with your team when performing what-if analysis on shared schedules.
**Use baselines for comparison**
Before starting your what-if analysis, save a baseline snapshot. This lets you compare your experimental schedule against the original plan visually, even after saving changes. See [Compare Schedule with Baselines](/gantt/guides/visualization/baselines-comparison).
## Verification
You should now see:
* Task bars responding to drag and resize in edit mode without any server communication
* Dependency links recalculating successor dates in real-time when auto-scheduling is enabled
* All changes reverting cleanly when you reload the page without saving
## See Also
* [Configure Auto-Scheduling](/gantt/guides/scheduling/configure-auto-scheduling)
* [Compare Schedule with Baselines](/gantt/guides/visualization/baselines-comparison)
* [Handle Unsaved Changes and Session Timeout](/gantt/guides/editing/unsaved-changes)
* [Use Undo and Redo](/gantt/guides/editing/undo-redo)
# Color Logic Script Examples
Source: https://learn.nextedy.com/gantt/guides/scripting/color-logic-scripts
Apply custom color logic to task bars in Nextedy GANTT using Item Scripts and Gantt Config Scripts, from simple date-based highlighting to multi-condition color schemes.
## Understand Static vs. Dynamic Coloring
Before writing color scripts, choose between two coloring modes:
| Mode | Property | Behavior |
| ----------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| **Dynamic** | `task.taskColor` | Overrides the default blue color only. Progress-related colors (red for overdue, orange for delayed, gray for resolved) still apply. |
| **Static** | `task.color` | Overrides all coloring. No automatic progress-based colors. Requires `gantt.config.show_progress_colors = false` in the Gantt Config Script. |
## Default Color Legend
Out of the box, the Gantt chart uses these dynamic colors:
| Color | Meaning |
| ---------- | ----------------------------------------------------- |
| Red | Overdue -- end date in the past, still unresolved |
| Orange | Delayed -- progress behind schedule, still unresolved |
| Blue | On track -- unresolved, schedule looks optimistic |
| Gray | Resolved -- work item completed |
| Light blue | Unscheduled -- no start date, defaults to today |
| Green | Project item -- schedule derived from children |
## Case 1: Date-Based Dynamic Coloring
Highlight tasks starting after today in green while keeping progress colors for all other tasks.
In **Widget Parameters > Advanced > Item Script**:
```javascript theme={null}
var today = new Date();
if(task.start_date.getTime() > today.getTime()){
task.taskColor = "green";
}
```
This uses dynamic coloring (`task.taskColor`), so overdue and delayed tasks retain their red/orange indicators.
## Case 2: Type and Status Static Coloring
Color tasks based on their work item type and status, overriding all automatic colors.
In **Widget Parameters > Advanced > Gantt Config Script**:
```javascript theme={null}
gantt.config.show_progress_colors = false;
```
In **Widget Parameters > Advanced > Item Script**:
```javascript theme={null}
var today = new Date();
if(wi.getType().getId() === "workpackage" && wi.getStatus().getId() === "draft"){
if(task.start_date.getTime() < today.getTime()){
task.color = "green";
}
}
```
**Use static coloring when combining type and status conditions**
If you set `task.taskColor` for tasks that already changed color due to progress (overdue, delayed), the dynamic color takes precedence. Switch to `task.color` with `show_progress_colors = false` for full control.
## Case 3: Assignee-Based Coloring
Color tasks by their assigned user. This example uses dynamic coloring for a single-assignee scenario:
```javascript theme={null}
var assignee = null;
var aIterator = wi.getAssignees().iterator();
if(aIterator.hasNext()){
assignee = aIterator.next();
if(assignee && assignee.id === "yourAssigneeId"){
task.taskColor = "#a9d08e";
}
}
```
**Use HEX colors for precise control**
Both `task.color` and `task.taskColor` accept standard color names and HEX values like `"#bfbfbf"`. Use HEX for precise brand or team colors.
## Case 4: Overdue Highlighting Without Progress Colors
Show tasks with end dates in the past as red, with all other progress coloring disabled:
In **Gantt Config Script**:
```javascript theme={null}
gantt.config.show_progress_colors = false;
```
In **Item Script**:
```javascript theme={null}
var tdate = new Date();
var edate = task.end_date;
var interval = tdate.getTime() - edate.getTime();
if(interval > 0){
task.color = "red";
}
```
**Polarion 2304+ script syntax**
If your scripts use `wi.type.id` or `wi.status.id`, update them to `wi.getType().getId()` and `wi.getStatus().getId()` after upgrading to Polarion 2304+. See [Migrate Scripts for Polarion 2304+](/gantt/guides/scripting/script-migration-2304).
## Verify Your Changes
Save the page and reload the Gantt chart. You should now see task bars reflecting your custom color logic. Hover over individual tasks to confirm that the correct conditions trigger the expected colors.
## See Also
* [Configure Item Colors](/gantt/guides/visualization/configure-colors) for non-scripting color configuration
* [Customize Progress-Related Coloring](/gantt/guides/visualization/progress-coloring) for the `progress_color_resolved` property
* [Write Item Scripts](/gantt/guides/scripting/item-script-basics) for Item Script fundamentals
* [Write Gantt Config Scripts](/gantt/guides/scripting/gantt-config-script) for Gantt Config Script patterns
* [Migrate Scripts for Polarion 2304+](/gantt/guides/scripting/script-migration-2304) for syntax migration
# Debug Script Errors
Source: https://learn.nextedy.com/gantt/guides/scripting/debug-scripts
Identify and resolve errors in your Nextedy GANTT item scripts, configuration scripts, and marker scripts using the built-in error reporting and browser debugging tools.
## Locate Script Errors
Since version **25.4.2**, the Gantt provides a built-in error alert system that surfaces script problems directly in the interface.
### Edit Mode (Administrator View)
When a script contains an error, a warning indicator appears in the **Gantt footer**. Click the indicator to open a detailed message that identifies the error type and location:
* **Config Script Error** -- An error in the Gantt configuration script
* **Markers Script Error** -- An error in the markers script
* **Item Script Error** -- An error in the item script
The error count badge on the indicator shows how many distinct errors were detected.
### View Mode (User View)
In view mode (non-edit), a triangle warning icon appears in the Gantt footer when configuration or data-related issues are present. This informs end users that something requires administrator attention.
**Errors do not crash the Gantt**
Script errors are caught and logged. The Gantt continues to render with the remaining valid configuration. Tasks affected by a broken script may appear with default styling instead of custom colors or markers.
## Use the Browser Console
For detailed debugging, open the browser developer console:
1. Right-click anywhere on the Gantt page.
2. Select **Inspect**.
3. Navigate to the **Console** tab.
4. Look for error messages prefixed with the script type.
Script errors are logged with their full stack trace in the browser console, providing the exact line and expression that failed.
## Enable Debug Mode
Set the configuration property `nextedy.gantt.debug` to `true` to enable verbose client-side debug logging:
```
nextedy.gantt.debug=true
```
When debug mode is active, the Gantt logs detailed information about configuration values, data loading, and event processing to the browser console.
**Verify in application**
Debug mode can also be enabled via the hamburger menu's Debug submenu in development builds. This provides options to toggle the debug panel and inspect configuration state.
## Common Script Error Patterns
| Error Message | Likely Cause | Fix |
| --------------------------------------------------- | ----------------------------------------------- | ------------------------------------------------------------------ |
| `TypeError: Cannot read property 'id' of undefined` | Pre-2304 script syntax after Polarion upgrade | Use getter methods: `wi.getType().getId()` instead of `wi.type.id` |
| `ReferenceError: wi is not defined` | Script runs on a task with no backing work item | Add a `typeof wi !== 'undefined'` check |
| `SyntaxError: Unexpected token` | JavaScript syntax error in the script | Check for missing brackets, quotes, or semicolons |
**Polarion 2304+ script changes**
If you recently upgraded Polarion to version 2304 or later, your scripts may need migration. See [Migrate Scripts for Polarion 2304+](/gantt/guides/scripting/script-migration-2304) for a complete before/after reference.
## Debug Server-Side Scripts
Server-side item scripts execute on the Polarion server and log errors to the **server logs**. Contact your Polarion administrator to review the server log files for script evaluation errors.
Server-side scripts have access to context variables including the work item, project, and platform services. Errors in server-side scripts are logged but do not crash the Gantt data load -- affected tasks render with default values.
## Step-by-Step Debugging Workflow
## Verification
You should now see no error indicators in the Gantt footer after fixing your scripts. The browser console should be free of script-related error messages, and tasks should display with the expected custom colors, markers, and computed values.
## See Also
* [Migrate Scripts for Polarion 2304+](/gantt/guides/scripting/script-migration-2304)
* [Write Item Scripts](/gantt/guides/scripting/item-script-basics)
* [Write Gantt Config Scripts](/gantt/guides/scripting/gantt-config-script)
* [Color Logic Script Examples](/gantt/guides/scripting/color-logic-scripts)
* [Troubleshooting Script Errors](/gantt/guides/troubleshooting/script-errors)
# Write Gantt Config Scripts
Source: https://learn.nextedy.com/gantt/guides/scripting/gantt-config-script
Use the Gantt Config Script to customize global chart behavior, templates, and visual settings for a specific Nextedy GANTT widget instance.
## Prerequisites
* A Gantt widget added to a Polarion LiveDoc or Wiki page
* Access to the widget parameter editor (Edit mode on the page)
## Open the Config Script Editor
1. Open the page containing your Gantt widget in edit mode.
2. In the widget parameters panel, locate the **Advanced** section.
3. Find the **Gantt Config Script** parameter and click to expand the script editor.
This script runs once during chart initialization. Any `gantt.config.*` properties you set here override system defaults and administration-level Configuration Properties for this specific widget instance.
## Understand the Script Scope
The Gantt Config Script executes with access to these objects:
| Object | Purpose |
| --------- | ----------------------------------------------------------------------------- |
| `gantt` | The chart instance with `gantt.config`, `gantt.templates`, and event handlers |
| `config` | The Nextedy configuration object with widget parameters and context |
| `Nextedy` | The Nextedy singleton exposing markers, editors, and license info |
Configuration Properties set system-wide defaults. Widget parameters override those defaults per instance. The Gantt Config Script runs last and can override both.
## Common Configuration Patterns
### Disable Progress Drag
Prevent users from adjusting progress by dragging the task bar fill:
```javascript theme={null}
gantt.config.drag_progress = false;
```
### Set Custom Resolved Color
Override the default color for resolved work items while keeping progress-related coloring active:
```javascript theme={null}
gantt.config.progress_color_resolved = "#0AA33A";
```
You can also set this globally via the Configuration Property `nextedy.gantt.default.progress_color_resolved`.
### Enable Square Task Borders
Switch from rounded to square task bar borders:
```javascript theme={null}
gantt.config.squareTaskBorder = true;
```
**Global vs. per-widget configuration**
Set `nextedy.gantt.config.squareTaskBorder=true` in Administration > Configuration Properties to apply square borders globally. Use `gantt.config.squareTaskBorder = false` in the Gantt Config Script to override the global setting for a specific chart.
### Customize Right-Side Text
Display a custom label to the right of each task bar using the `rightside_text` template:
```javascript theme={null}
gantt.templates.rightside_text = function(start, end, task) {
return task.progressString || "";
};
```
### Disable Auto-Scheduling
Turn off automatic date propagation for this chart instance:
```javascript theme={null}
gantt.config.auto_scheduling = false;
```
The system default is controlled by `nextedy.gantt.default.auto_scheduling` (default: `false`).
## Configuration Properties Reference
These `nextedy.gantt.*` properties can be set in Administration > Configuration Properties as system-wide defaults:
| Property | Default | Purpose |
| ----------------------------------------- | --------- | ---------------------- |
| `nextedy.gantt.default.auto_scheduling` | `false` | Enable auto-scheduling |
| `nextedy.gantt.default.critical_path` | `false` | Show critical path |
| `nextedy.gantt.config.squareTaskBorder` | `false` | Square task borders |
| `nextedy.gantt.workitems.unplanned_color` | `#7D3C98` | Unplanned item color |
| `nextedy.gantt.today.color` | `gray` | Today marker color |
| `nextedy.gantt.debug` | `false` | Enable debug messages |
**Script execution order matters**
The Gantt Config Script runs during chart initialization. If you modify `gantt.config` properties after the chart renders, call `gantt.render()` to apply changes. Template functions (like `rightside_text`) take effect on the next render cycle automatically.
## Handle Script Errors
When the Gantt Config Script contains a syntax or runtime error, the chart displays a warning indicator in the footer. In edit mode, clicking the indicator shows the error details prefixed with **Config Script Error:**. In view mode, a triangle icon appears as a warning.
Check the browser console for detailed error messages. See [Debug Script Errors](/gantt/guides/scripting/debug-scripts) for a systematic debugging approach.
## Verify Your Changes
After saving the page, reload the Gantt chart. You should now see your configuration changes reflected:
* Modified task bar styles or colors appear immediately
* Template changes (right-side text, tooltips) render with each task bar
* Disabled features (drag progress, auto-scheduling) no longer respond to user interaction
## See Also
* [Write Item Scripts](/gantt/guides/scripting/item-script-basics) for per-task customization
* [Write Page Scripts with Velocity](/gantt/guides/scripting/page-script) for server-side pre-processing
* [Color Logic Script Examples](/gantt/guides/scripting/color-logic-scripts) for color customization patterns
* [Customize Progress-Related Coloring](/gantt/guides/visualization/progress-coloring) for progress color configuration
* [Debug Script Errors](/gantt/guides/scripting/debug-scripts) for troubleshooting script issues
# Scripting
Source: https://learn.nextedy.com/gantt/guides/scripting/index
Nextedy GANTT provides three scripting entry points that let you customize data preparation, chart behavior, and dynamic content.
## Guides in This Section
**[Write Item Scripts](/gantt/guides/scripting/item-script-basics)** --- Learn the basics of server-side item scripts, including the `task` and `wi` variables, reading work item fields, and passing custom data to the client.
**[Write Gantt Config Scripts](/gantt/guides/scripting/gantt-config-script)** --- Configure chart behavior at load time using JavaScript snippets in the Advanced > Gantt Config Script parameter.
**[Write Page Scripts with Velocity](/gantt/guides/scripting/page-script)** --- Use Apache Velocity templates to query Polarion data and inject dynamic content into the Gantt page.
**[Color Logic Script Examples](/gantt/guides/scripting/color-logic-scripts)** --- Apply custom color logic to task bars based on work item fields, status, or priority.
**[Calculate Progress with Scripts](/gantt/guides/scripting/progress-calculation-scripts)** --- Override the default progress calculation with custom formulas that aggregate child task data.
**[Create Markers with Scripts](/gantt/guides/scripting/marker-scripts)** --- Add custom vertical markers to the Gantt timeline using the markers scripting API.
**[Migrate Scripts for Polarion 2304+](/gantt/guides/scripting/script-migration-2304)** --- Update existing scripts to work with the breaking API changes introduced in Polarion 2304 and later.
**[Debug Script Errors](/gantt/guides/scripting/debug-scripts)** --- Diagnose and fix common script errors using the Gantt error indicator and browser developer tools.
**Start with item scripts**
If you are new to Gantt scripting, begin with [Write Item Scripts](/gantt/guides/scripting/item-script-basics) to understand the core `task` and `wi` variables. Most customizations build on this foundation.
# Write Item Scripts
Source: https://learn.nextedy.com/gantt/guides/scripting/item-script-basics
This guide shows you how to write server-side item scripts in Nextedy GANTT to read work item data and pass custom fields to the Gantt chart client.
## What Item Scripts Do
Item scripts run on the server for each work item loaded into the Gantt chart. They let you read data from the Polarion work item object (`wi`) and pass it to the client-side task object (`task`) using the `task.getFields().put(KEY, VALUE)` pattern.
Common use cases include extracting assignee names, computing custom labels, reading custom field values, and controlling task visibility.
## Access the Item Script Parameter
1. Open your Gantt page in **Edit** mode.
2. In the widget parameter sidebar, expand the **Advanced** section.
3. Locate the **Item Script** text area.
4. Enter your JavaScript snippet.
5. Click **Apply**.
## Available Variables
Item scripts have access to the following server-side variables:
| Variable | Type | Description |
| ------------------ | ----------------- | ----------------------------------------------- |
| `task` | Task | The Gantt task object being sent to the client |
| `wi` | IWorkItem | The Polarion work item (read data from here) |
| `item` | IWorkItem | Alias for `wi` |
| `plan` | IPlan | The Polarion plan (Plans Gantt only) |
| `config` | Config | The current Gantt configuration object |
| `ganttDataService` | IGanttDataService | Server-side data service for advanced queries |
| `util` | Utility | Helper methods (e.g., `getDate`, `getDuration`) |
Additionally, Velocity pre-processing runs before script execution, making `$project` and `$user` available as Velocity expressions within the script text.
## Task Object Properties
The `task` object contains the following fields that you can read or modify:
| Field | Type | Description |
| ------------ | ------- | ------------------------------------------- |
| `id` | String | Unique task identifier |
| `text` | String | Display label (work item ID + title) |
| `start_date` | Date | Task start date |
| `duration` | int | Task duration in days (default: 10) |
| `progress` | float | Completion percentage (0.0 to 1.0) |
| `parent` | String | Parent task ID |
| `type` | String | Task type (task, project, milestone) |
| `url` | String | Link to the Polarion work item |
| `itemId` | String | Polarion work item ID (e.g., "WI-123") |
| `projectId` | String | Polarion project ID |
| `readonly` | boolean | Whether the task is read-only |
| `unplanned` | boolean | Whether the task has no scheduled dates |
| `open` | boolean | Whether the task node is expanded |
| `color` | String | CSS color for the task bar |
| `fields` | Map | Custom key-value pairs passed to the client |
## Basic Example: Pass Assignee Names to the Client
```javascript theme={null}
if (wi.getType().getId() === 'task') {
var aIt = wi.getAssignees().iterator();
var assignees = "";
var separator = "";
while (aIt.hasNext()) {
var assignee = aIt.next();
assignees = assignees + separator + assignee.name;
separator = ", ";
}
if (assignees !== "") {
task.getFields().put("assignees", assignees);
}
}
```
This script reads all assignees from the work item and stores a comma-separated string in the `fields` map under the key `"assignees"`. You can then reference this value in Gantt Config Script templates (for example, to display it as right-side text on the task bar).
## Control Task Visibility
Use the `task.hide` property to hide specific work items from the chart:
```javascript theme={null}
if (wi.getType().getId() === 'changeRequest') {
task.hide = true;
}
```
**Combine with type filtering**
Use `task.hide` in item scripts when you need conditional logic beyond what the widget query provides. For simple type filtering, configure the query directly in the widget parameters instead.
## Error Handling
Script errors are logged on the server but do not crash the Gantt chart load. When an item script contains an error, a warning indicator appears in the Gantt toolbar showing the error count. Hover over it to see the error details.
**Polarion 2304+ breaking changes**
If you upgraded to Polarion 2304 or later, existing item scripts may stop working. Key changes:
* Use `typeof wi !== 'undefined'` instead of `wi != null` for null checks.
* Use getter methods instead of direct property access: `wi.getStatus().getId()` instead of `wi.status.id`.
* Use `wi.getType().getId()` instead of `wi.type.id`.
See [Migrate Scripts for Polarion 2304+](/gantt/guides/scripting/script-migration-2304) for a full migration guide.
## Verification
After adding an item script, you should now see:
* No error indicator in the Gantt toolbar (the script runs without errors).
* Custom field values available in the task data (verify by referencing them in a Gantt Config Script template or tooltip).
* Tasks hidden or modified according to your script logic.
## See Also
* [Write Gantt Config Scripts](/gantt/guides/scripting/gantt-config-script)
* [Write Page Scripts with Velocity](/gantt/guides/scripting/page-script)
* [Color Logic Script Examples](/gantt/guides/scripting/color-logic-scripts)
* [Migrate Scripts for Polarion 2304+](/gantt/guides/scripting/script-migration-2304)
* [Debug Script Errors](/gantt/guides/scripting/debug-scripts)
* [Compare Schedule with Baselines](/gantt/guides/visualization/baselines-comparison)
# Create Markers with Scripts
Source: https://learn.nextedy.com/gantt/guides/scripting/marker-scripts
Add milestone markers to the Nextedy GANTT timeline using the Markers Script, from manual date markers to dynamically generated markers from Polarion plans and work items.
## Where to Add Marker Scripts
Open your Gantt widget parameters, expand the **Advanced** section, and locate the **Markers Script** field. All marker scripts go here. The script has access to `markerFactory`, `trackerService`, and `config` objects.
## Marker Factory API
The `markerFactory` object provides these methods:
| Method | Purpose |
| ----------------------------------------------------------- | ------------------------------------------------------- |
| `markerFactory.addMarker()` | Create a new empty marker object |
| `markerFactory.addMarker(text, date)` | Create a marker with text and date string |
| `markerFactory.addPlanMarkers(query, color)` | Add markers from Polarion plans matching a Lucene query |
| `markerFactory.addWorkItemMarkers(query, dateField, color)` | Add markers from work items matching a Lucene query |
The **marker object** returned by `addMarker()` has these setter methods:
| Method | Purpose |
| ------------------------- | ----------------------------------------------- |
| `marker.setText(String)` | Set the marker label |
| `marker.setTitle(String)` | Set the tooltip text |
| `marker.setDate(Date)` | Set the date (java.util.Date) |
| `marker.setDate(String)` | Set the date as string (`"2025-08-04"` format) |
| `marker.setColor(String)` | Set the color (one of the 16 basic HTML colors) |
## Add a Manual Marker
Create a fixed marker at a specific date:
```javascript theme={null}
var marker = markerFactory.addMarker();
marker.setText("20.0");
marker.setDate("2025-08-04");
marker.setColor("green");
```
This adds a green vertical line labeled "20.0" at August 4, 2025.
## Add Markers from Plans
Automatically generate markers from Polarion plan boundaries (iterations, sprints):
```javascript theme={null}
markerFactory.addPlanMarkers(
"template.id:iteration AND project.id:gantt2",
"blue"
)
```
For the current project, use `config.getContextProjectId()` instead of a hardcoded project ID:
```javascript theme={null}
markerFactory.addPlanMarkers(
"template.id:iteration AND project.id:" + config.getContextProjectId(),
"blue"
)
```
## Add Markers from Work Items
Generate markers from work items of a specific type using a date field:
```javascript theme={null}
markerFactory.addWorkItemMarkers(
"type:release AND project.id:" + config.getContextProjectId(),
"publicLaunch",
"blue"
)
```
The second parameter (`"publicLaunch"`) specifies which date field on the work item provides the marker date.
## Use Polarion API for Dynamic Markers
For full scripting control, use `trackerService` to query work items and create markers programmatically. This example loads Polarion project time points:
```javascript theme={null}
var timePoints = trackerService.getTrackerProject("GANTT")
.getTimePoints().iterator();
while(timePoints.hasNext()){
var tp = timePoints.next();
var marker = markerFactory.addMarker();
marker.setText(tp.getName());
marker.setDate(tp.getTime().getDate());
marker.setColor("fuchsia");
var desc = tp.getDescription();
if(desc != null){
marker.setTitle(desc.getContent());
}
}
```
**Polarion 2304+ getter methods**
On Polarion 2304 and later, use `tp.getName()` and `tp.getTime().getDate()` instead of `tp.name` and `tp.time.date`. See [Migrate Scripts for Polarion 2304+](/gantt/guides/scripting/script-migration-2304).
## Filter Markers with Page Parameters
Use page parameters to let users control which markers appear. This example reads a `milestone` page parameter and renders matching work items as markers:
```javascript theme={null}
var milestoneIds = config.pageParameters.milestone;
if(milestoneIds === null){
milestoneIds = "";
} else {
milestoneIds = milestoneIds.replaceAll(',', ' ');
}
var milestones = trackerService.queryWorkItems(
"project.id:Gantt3 AND type:milestone AND id:(" + milestoneIds + ")",
"id").iterator();
while(milestones.hasNext()){
var tp = milestones.next();
var marker = markerFactory.addMarker();
marker.setText(tp.getTitle());
marker.setDate(tp.getValue('releaseDate').getDate());
marker.setColor("blue");
}
```
**Marker positioning convention**
Markers render at the end of the specified date. If you need a marker at the start of a day, subtract one day from the date value in your script.
## Marker Styling
Markers automatically receive CSS classes based on their source:
| Marker Type | CSS Class | Default Appearance |
| -------------- | ---------------------------- | ----------------------------------- |
| Today marker | `today` | Highlighted vertical line |
| Plan markers | `plan` | Styled as plan boundary lines |
| Custom markers | `gantt_marker` + color class | Default styling with optional color |
Hovering over a marker displays a tooltip showing the marker name and due date.
## Handle Script Errors
If the Markers Script contains errors, the Gantt chart displays a warning indicator in the footer with the prefix **Markers Script Error:**. Check the browser console for details. See [Debug Script Errors](/gantt/guides/scripting/debug-scripts) for systematic debugging.
## Verify Your Changes
Save the page and reload the Gantt chart. You should now see vertical marker lines on the timeline at the specified dates, with labels and colors matching your script configuration. Hover over markers to confirm tooltip text displays correctly.
## See Also
* [Create and Configure Markers](/gantt/guides/visualization/markers) for marker visualization options
* [Write Page Scripts with Velocity](/gantt/guides/scripting/page-script) for server-side Velocity scripting
* [Configure Page Parameters](/gantt/guides/layout/page-parameters) for dynamic parameter-based filtering
* [Debug Script Errors](/gantt/guides/scripting/debug-scripts) for troubleshooting marker script issues
# Write Page Scripts with Velocity
Source: https://learn.nextedy.com/gantt/guides/scripting/page-script
Use Velocity page scripts in Nextedy GANTT to pre-process widget parameters on the server before the Gantt chart renders, enabling dynamic baselines, markers, and data-driven configuration.
## How Page Scripts Work
Page scripts run on the Polarion server using the Apache Velocity template engine. The rendered output is then embedded into the Gantt widget as JavaScript. This means you can use Velocity expressions to access Polarion data (projects, users, plans, work items) and inject dynamic values into the Gantt configuration.
A common use is a page script that reads a page parameter (for example a `department` parameter) and injects it into the widget's query so the Gantt shows only the matching work items:
A page script can also walk up the parent hierarchy and add the parents of the selected items to the chart, using `$pageContext` to pass the assembled query back to the widget's Query field:
## Available Velocity Context Variables
The following objects are available inside page scripts:
| Variable | Type | Purpose |
| ----------------- | ---------------- | --------------------------- |
| `$project` | Polarion project | Current project reference |
| `$user` | Polarion user | Current logged-in user |
| `$trackerService` | Polarion service | Query work items and plans |
| `$page` | Wiki page | Current page reference |
| `config` | Gantt config | Widget configuration object |
| `markerFactory` | Marker factory | Create timeline markers |
## Create a Baseline Comparison Page
This example creates a portal page that lists project baselines and opens the Gantt chart with a comparison overlay.
1. Add a page parameter named `baselineRevision` of type **string** to your Gantt report page.
2. In **Widget Parameters > Advanced > Item Script**, add the baseline loading logic:
```javascript theme={null}
var revision = config.getPageParameters().get("baselineRevision");
if(revision && revision.length > 0){
var origWi = wi.getDataSvc().getVersionedInstance(wi.uri, revision);
task.planned_start_date = util.getDate(origWi, "start");
task.planned_duration = util.getDuration(origWi, "initialEstimate");
}
```
3. Create a separate Wiki page with this Velocity snippet to list baselines:
```velocity theme={null}
#set($projectId = $page.reference.projectId)
#set($ganttPagePath = "/project/$projectId/wiki/Planning/Gantt")
#set($project = $trackerService.getTrackerProject($projectId))
<ul>
#foreach($b in $project.baselinesManager.baselines)
<li>
<a target="_blank"
href="/gantt/polarion/#$ganttPagePath?baselineRevision=$b.getBaseRevision()">
$b.name - $b.getBaseRevision()
</a>
<br/>$b.baseRevisionObject.created
</li>
#end
</ul>
```
**Adjust field names to your mapping**
The field names in `util.getDate(origWi, "start")` and `util.getDuration(origWi, "initialEstimate")` must match the field names in your widget Data Mapping section. If you use `plannedStart` and `duration`, update the script accordingly.
## Add Dynamic Markers with Velocity
Use the `markerFactory` in the **Markers Script** to create timeline markers from Polarion data. For example, load iteration boundaries from plans:
```javascript theme={null}
markerFactory.addPlanMarkers(
"template.id:iteration AND project.id:" + config.getContextProjectId(),
"blue"
)
```
Or load project time points using the Polarion API:
```javascript theme={null}
var timePoints = trackerService.getTrackerProject("$projectId")
.getTimePoints().iterator();
while(timePoints.hasNext()){
var tp = timePoints.next();
var marker = markerFactory.addMarker();
marker.setText(tp.getName());
marker.setDate(tp.getTime().getDate());
marker.setColor("fuchsia");
}
```
**Polarion 2304+ getter syntax**
If you are on Polarion 2304 or later, use getter methods like `tp.getName()` and `tp.getTime().getDate()` instead of direct property access like `tp.name` and `tp.time.date`. See [Migrate Scripts for Polarion 2304+](/gantt/guides/scripting/script-migration-2304) for details.
## Verify Your Changes
After saving the page, reload the Gantt chart. You should now see:
* Baseline comparison bars rendered below current task bars (if a baseline revision is selected)
* Dynamic markers appearing as vertical lines on the Gantt timeline
* Velocity-generated values correctly resolved in the widget output
## See Also
* [Write Gantt Config Scripts](/gantt/guides/scripting/gantt-config-script) for client-side global configuration
* [Write Item Scripts](/gantt/guides/scripting/item-script-basics) for per-task customization
* [Create Markers with Scripts](/gantt/guides/scripting/marker-scripts) for detailed marker scripting
* [Compare Schedule with Baselines](/gantt/guides/visualization/baselines-comparison) for baseline features
* [Configure Page Parameters](/gantt/guides/layout/page-parameters) for page parameter setup
# Calculate Progress with Scripts
Source: https://learn.nextedy.com/gantt/guides/scripting/progress-calculation-scripts
Compute task progress automatically in Nextedy GANTT using Item Scripts, based on time estimates, resolved status, or plan completion ratios.
## Progress Data Model
The Gantt chart stores progress as a float value between `0.0` (no progress) and `1.0` (complete). The progress column in the grid displays this as a percentage (0-100). The default Progress Field widget parameter is `gantt_progress`.
## Calculate Progress from Time Estimates
This script computes progress as `timeSpent / (remainingEstimate + timeSpent)` and automatically sets resolved items to 100%.
In **Widget Parameters > Advanced > Item Script**:
```javascript theme={null}
if(wi.getType().getId() === 'workpackage'){
var all = (wi.getRemainingEstimate() != null
? wi.getRemainingEstimate().getHours() : 0)
+ (wi.getTimeSpent() != null
? wi.getTimeSpent().getHours() : 0);
var done = (wi.getTimeSpent() != null
? wi.getTimeSpent().getHours() : 0);
if(wi.getResolution() != null){
task.progress = 1;
} else if(all == 0){
task.progress = 0;
} else {
task.progress = done / all;
}
var progressString = (wi.getTimeSpent() != null ? wi.getTimeSpent() : "0h")
+ " | "
+ (wi.getRemainingEstimate() != null ? wi.getRemainingEstimate() : "0h")
+ " (" + Math.round(task.progress * 100) + " %)";
task.getFields().put("progressString", progressString);
}
```
**Adjust the work item type filter**
The script above filters for `workpackage` items. Change `'workpackage'` to your work item type ID, or remove the `if` statement entirely to apply the calculation to all items.
## Disable Progress Drag
When progress is computed automatically, disable manual progress adjustment. In **Widget Parameters > Advanced > Gantt Config Script**:
```javascript theme={null}
gantt.config.drag_progress = false;
```
This hides the progress drag handle on task bars and prevents users from overriding calculated values.
## Display Progress Text on Task Bars
Show the computed progress summary next to each task bar. In **Gantt Config Script**:
```javascript theme={null}
gantt.config.drag_progress = false;
gantt.templates.rightside_text = function(start, end, task){
return " "
+ task.fields.statusName + " "
+ (task.progress != null ? task.fields.progressString : "");
};
```
This renders the work item status icon, status name, time spent, remaining estimate, and completion percentage to the right of each task bar.
## Calculate Epic Progress from Children
For epic-level items where time estimates are derived from child stories:
```javascript theme={null}
if(wi.getType().getId() === 'epic'){
task.type = 'project';
var all = (wi.getRemainingEstimate() != null
? wi.getRemainingEstimate().getHours() : 0)
+ (wi.getTimeSpent() != null
? wi.getTimeSpent().getHours() : 0);
var done = (wi.getTimeSpent() != null
? wi.getTimeSpent().getHours() : 0);
if(wi.getResolution() != null){
task.progress = 1;
} else if(all == 0){
task.progress = 0;
} else {
task.progress = done / all;
}
var progressString = "Time Spent:"
+ (wi.getTimeSpent() != null ? wi.getTimeSpent() : "0h")
+ " Remaining: "
+ (wi.getRemainingEstimate() != null ? wi.getRemainingEstimate() : "0h")
+ " (" + Math.round(task.progress * 100) + "%)";
task.getFields().put("progressString", progressString);
}
```
Setting `task.type = 'project'` renders the epic as a summary bar with its schedule derived from children.
## Calculate Plan Progress from Resolved Items
For Plans Gantt, compute progress as the ratio of resolved to total work items in a plan. In **Item Script**:
```javascript theme={null}
var allitems = trackerService.queryWorkItems(
"PLAN:(" + plan.getProjectId() + "/" + plan.getId() + ")", "id").size();
var openitems = trackerService.queryWorkItems(
"PLAN:(" + plan.getProjectId() + "/" + plan.getId()
+ ") AND HAS_VALUE:resolution", "id").size();
if(allitems > 0){
task.progress = openitems / allitems;
} else {
task.progress = 0;
}
task.getFields().put("progressString", openitems + " / " + allitems + " done");
```
**Plans Gantt context**
The `plan` variable is only available in the Plans Gantt Item Script. In the Work Items Gantt, use `wi` to access work item data instead.
## Verify Your Changes
Save the page and reload the Gantt chart. You should now see:
* Task bars with progress fill matching the computed percentages
* Progress text displayed to the right of each task bar (if configured)
* The progress drag handle hidden (if `drag_progress` is disabled)
## See Also
* [Track and Calculate Progress](/gantt/guides/editing/progress-tracking) for manual progress tracking
* [Configure Right-Side Text on Task Bars](/gantt/guides/visualization/right-side-text) for template customization
* [Write Item Scripts](/gantt/guides/scripting/item-script-basics) for Item Script fundamentals
* [Compute Plan Progress](/gantt/guides/plans/plan-progress) for Plans Gantt progress
# Migrate Scripts for Polarion 2304+
Source: https://learn.nextedy.com/gantt/guides/scripting/script-migration-2304
Update your Nextedy GANTT item scripts and configuration scripts to work with the scripting engine changes introduced in Polarion 2304 and later versions.
## What Changed
Since Polarion version 2304, the scripting engine used by the Gantt widget has been updated. Scripts that use direct property access on Polarion objects (such as `wi.type.id` or `wi.status.id`) no longer work as expected. You must update these to use getter methods.
If your Gantt configuration uses item scripts or configuration scripts, you may encounter errors like:
```
TypeError: Cannot read property 'id' of undefined
```
## Migration Steps
### Step 1: Replace Direct Property Access with Getter Methods
The most common change is replacing direct property access patterns with their getter equivalents.
| Old Syntax (Pre-2304) | New Syntax (2304+) |
| --------------------- | ---------------------------- |
| `wi.type.id` | `wi.getType().getId()` |
| `wi.status.id` | `wi.getStatus().getId()` |
| `wi.resolution.id` | `wi.getResolution().getId()` |
| `wi.priority.id` | `wi.getPriority().getId()` |
### Step 2: Replace Null Checks with typeof Checks
In Polarion 2304+, variables that were previously `null` when undefined now require `typeof` checks.
| Old Syntax (Pre-2304) | New Syntax (2304+) |
| --------------------- | ---------------------------------- |
| `if (wi != null)` | `if (typeof wi !== 'undefined')` |
| `if (plan != null)` | `if (typeof plan !== 'undefined')` |
### Step 3: Update Comparison Operators
Use strict equality operators (`===`) instead of loose equality (`==`) for consistent behavior with the updated scripting engine.
```javascript theme={null}
// Before (pre-2304)
if (wi.type.id == "task") { ... }
// After (2304+)
if (wi.getType().getId() === "task") { ... }
```
### Step 4: Test Each Script
After updating your scripts, test each one:
1. Open the Gantt page in edit mode.
2. Check the browser console for errors (right-click the page, select **Inspect**, open the **Console** tab).
3. Verify that task bars render with the expected colors, markers, and labels.
**Test before production upgrade**
When upgrading Polarion to 2304 or later, always update your Gantt to the latest version and test all scripts in a staging environment first. Script errors do not crash the Gantt but may cause incorrect rendering or missing visual elements.
**Error indicator in the footer**
Since version 25.4.2, script errors display a warning indicator in the Gantt footer. Click the indicator to see a detailed error message identifying the script and error location.
## Common Migration Examples
**Color logic script:**
```javascript theme={null}
// Before
if (wi.type.id == "milestone") {
task.color = "#ff7043";
}
// After
if (typeof wi !== 'undefined' && wi.getType().getId() === "milestone") {
task.color = "#ff7043";
}
```
**Progress calculation script:**
```javascript theme={null}
// Before
if (wi != null && wi.status.id == "done") {
task.progress = 1;
}
// After
if (typeof wi !== 'undefined' && wi.getStatus().getId() === "done") {
task.progress = 1;
}
```
## Verification
You should now see your Gantt chart rendering correctly without `TypeError` messages in the browser console. Task bars should display the expected colors, progress, and markers as defined by your scripts.
## See Also
* [Debug Script Errors](/gantt/guides/scripting/debug-scripts)
* [Write Item Scripts](/gantt/guides/scripting/item-script-basics)
* [Write Gantt Config Scripts](/gantt/guides/scripting/gantt-config-script)
* [Troubleshooting Script Errors](/gantt/guides/troubleshooting/script-errors)
# Troubleshooting Blank or Non-Loading Gantt
Source: https://learn.nextedy.com/gantt/guides/troubleshooting/blank-gantt
This guide helps you diagnose and resolve situations where the Nextedy GANTT chart appears blank, shows a permanent loading spinner, or fails to display work items.
## Diagnostic Checklist
Work through the following checks in order to identify the root cause:
| Check | How to Verify | Common Fix |
| ---------------------- | ---------------------------------------- | ---------------------------------------- |
| Browser console errors | Right-click > Inspect > Console tab | Fix reported errors |
| Gantt footer messages | Look for triangle warning icon in footer | Address configuration warnings |
| Item count in footer | Check "Gantt Rows: N" display | Increase Max Items if items were skipped |
| Gantt version | Check version in footer | Update to latest version |
| Widget parameters | Open widget configuration | Verify dataset and field mappings |
## Check 1: Review Browser Console for Errors
Open the browser developer tools (right-click > Inspect > Console tab) and look for error messages. Common errors include:
* **Script execution errors** -- Item scripts or config scripts contain syntax errors
* **Network errors** -- API calls to the Gantt data endpoint are failing
* **Authentication errors** -- Session has expired or user lacks permissions
**Capture console output for support**
When contacting support, copy the full browser console output along with your widget parameter configuration. This significantly speeds up diagnosis.
## Check 2: Verify the Gantt Footer
The Gantt footer displays diagnostic information including:
* **Gantt Rows** -- The number of items loaded
* **Error indicator** -- A triangle icon with a count badge when errors are present
* **Skipped items warning** -- Appears when items exceed the Max Items limit
Click the error indicator to see detailed error messages.
## Check 3: Increase Max Items for Large Projects
If your project has more than the default item limit, the Gantt may appear blank because all items were skipped. Check the footer for a skipped items count.
To increase the limit, go to **Widget Parameters > Max Items** and set a higher value.
**Projects with 5000+ items may appear blank**
Very large projects can exceed the default item limit, causing the Gantt to appear empty. Increase the **Max Items** widget parameter incrementally (e.g., to 2000, then 5000) and monitor loading performance. Extremely high values may cause slow loading.
## Check 4: Update to the Latest Gantt Version
Intermittent blank display issues were fixed in several Gantt releases. If you are running an older version:
1. Check the current version in the Gantt footer
2. Update to the latest version following the [Update to the Latest Version](/gantt/getting-started/update-gantt) guide
**Version 24.5.2+ fixes intermittent blank display**
An issue where the Gantt chart intermittently failed to display, particularly related to script execution, was fixed in version 24.5.2. If you experience intermittent blank charts, updating is the recommended first step.
## Check 5: Review Custom Scripts
Custom item scripts, config scripts, or marker scripts can prevent the Gantt from rendering if they contain errors. The Gantt displays an error indicator in the footer when scripts fail.
To test whether a script is causing the issue:
1. Open the widget parameters in the page editor
2. Temporarily clear the **Item Script**, **Gantt Config Script**, and **Markers Script** fields
3. Save and reload the page
4. If the Gantt loads, re-add scripts one at a time to isolate the problem
## Check 6: Verify Configuration Properties
Ensure the widget parameters reference valid Polarion configuration values:
* **Data Mapping fields** (Start Field, End Field, Duration Field) must match actual work item custom field IDs
* **Dependency Role** must reference a valid link role configured in Polarion
* **Work Item Types** must match types defined in the project
The Gantt runs validation at startup and displays diagnostic messages for detected configuration issues.
## Verify
After addressing the identified issue, reload the Gantt chart page. You should now see work items displayed as task bars on the timeline, with the footer showing the correct item count and no error indicators.
## See also
* [Troubleshooting Installation Issues](/gantt/guides/troubleshooting/installation-issues)
* [Troubleshooting Script Errors](/gantt/guides/troubleshooting/script-errors)
* [Troubleshooting Performance Issues](/gantt/guides/troubleshooting/performance)
* [Manage Large Datasets with Max Items](/gantt/guides/filtering/max-items)
# Troubleshooting Calendar Integration Issues
Source: https://learn.nextedy.com/gantt/guides/troubleshooting/calendar-issues
Diagnose and resolve common problems with Nextedy GANTT working calendar integration, including user calendars not loading, capacity calculations appearing incorrect, and calendar project connectivity problems.
The working calendar parameters follow a strict dependency chain. Each level must be enabled before the next becomes available:
1. Open the Gantt widget parameters
2. Navigate to the **Working Calendars** section
3. Confirm the toggles are enabled in order:
* **Use Working Calendar** must be `Yes`
* **Load User Calendars** only appears when Use Working Calendar is `Yes`
* **Load Team Assignments** only appears when both above are `Yes`
**Progressive disclosure**
If you do not see the **Load User Calendars** option, check that **Use Working Calendar** is set to `Yes` first. The sub-options are hidden until their parent toggle is enabled.
If user calendars are not loading, verify that the required administration properties are set in **Administration > Configuration Properties** for both the calendar project and the consuming project:
```
nextedy.gantt.workitemCalendar.projectId=
nextedy.gantt.workitemCalendar.globalID=
```
* Replace `` with the project ID of the work item calendar project
* Replace `` with the work item ID of the calendar work item used as the global calendar
**Apply to both projects**
These properties must be configured in both the work item calendar project **and** every project that uses it. Missing either side causes silent failures where calendars appear empty.
Calendar work items must have the correct assignee set to link to a resource in the Gantt chart.
| Calendar Item Type | Required Fields | Purpose |
| ------------------ | --------------------------------------- | ----------------------------------- |
| Calendar | Assignee, From/To dates, Weekday hours | Defines regular working schedule |
| Time Off | Assignee, From/To dates | Marks non-working periods |
| Time On | Assignee, From/To dates | Overrides Time Off for a user |
| Tweak | Assignee, From/To dates, Work Start/End | Adjusts hours for a specific period |
**Assignee is mandatory**
Calendar items without an assignee will not be associated with any resource. Ensure every user-specific calendar work item has the correct Polarion user set as the assignee.
Calendar work items use the `inherits from` link role for parent-child inheritance and the `affects` link role for exceptions (Time Off, Time On, Tweak).
* User calendars should have a parent link to the global calendar via **inherits from**
* Exception items (Time Off, Time On, Tweak) must be linked to their target calendar via **affects**
**Missing link roles**
If exception items are not linked to a calendar via the `affects` link role, they will be silently ignored by the Gantt chart regardless of their date settings.
If user calendar changes stop reflecting in resource allocation bubbles after an upgrade:
* Versions **v25.7.0 through v25.8.0** contain a known regression where work items missing fields required by a workflow action can fail to load on the Gantt, which can leave resource rows and allocations incomplete
* Upgrade to **v25.9.0** or later to resolve this issue
* As a workaround, roll back to **v24.10.1** if upgrading is not immediately possible
If calendar changes are not reflected after editing calendar work items, the server-side calendar cache may be stale. Caching is enabled by the **Cache Working Calendars** widget parameter (or the `nextedy.gantt.workingCalendar.useCache` administration property).
When caching is active, clear the stale cache using either method:
* Click the **Clear Calendar Cache** toolbar button, which appears in the Gantt toolbar when caching is enabled
* Call the `api/clearCalendarCache` endpoint directly
## Verification
You should now see:
* The **Working Calendars** section in widget parameters shows all three toggles in sequence
* User-specific non-working days appear as gray areas on the resource view
* Resource allocation markers reflect correct capacity based on each user's calendar
* Time Off, Time On, and Tweak items correctly adjust the displayed availability
## See Also
* [Load User Calendars](/gantt/guides/calendars/user-calendars)
* [Set Up Work Item Calendars](/gantt/guides/calendars/work-item-calendar)
* [Use Calendars from Another Project](/gantt/guides/calendars/cross-project-calendar)
* [Customize Working Hours per Resource](/gantt/guides/calendars/working-hours-per-resource)
* [Set Up the Resource View](/gantt/guides/resources/resource-view)
# Troubleshooting
Source: https://learn.nextedy.com/gantt/guides/troubleshooting/index
This section provides solutions for common Nextedy GANTT issues.
Resolve problems after installing or upgrading Gantt, including missing widget errors.
Diagnose and fix situations where the Gantt chart fails to display or shows a loading screen.
Fix issues where changes made in the Gantt chart fail to persist to Polarion.
Identify and resolve errors in item scripts, config scripts, and marker scripts.
Fix permission problems when users have read-only access instead of edit access.
Understand and fix the today marker showing an incorrect date due to timezone differences.
**[Troubleshooting Performance Issues](/gantt/guides/troubleshooting/performance)** -- Diagnose slow loading and rendering issues with large datasets.
**[Troubleshooting Calendar Integration Issues](/gantt/guides/troubleshooting/calendar-issues)** -- Resolve problems with working calendars, holidays, and per-user schedules.
**General troubleshooting approach**
For any Gantt issue, start by checking the Gantt footer for error indicators (triangle icon) and item count statistics. Open the browser console (right-click > Inspect > Console) for detailed error messages. When contacting support, include the browser console output and your widget parameter configuration.
# Troubleshooting Installation Issues
Source: https://learn.nextedy.com/gantt/guides/troubleshooting/installation-issues
This guide helps you resolve common problems that occur after installing or upgrading Nextedy GANTT on your Polarion server.
## Symptom: Widget Not Found or Error Message After Installation
If you see an error message in the Polarion UI where the Gantt widget should appear, or the widget is not listed in the available widgets, the most common cause is that the configuration cache was not cleared after installation.
Shut down the Polarion server before making any file system changes. Use your standard server management process to stop the service.
Navigate to your Polarion installation directory and delete the `.config` folder:
```
[POLARION_INSTALL]/data/workspace/.config
```
This folder contains configuration caches that Polarion rebuilds automatically on startup. Deleting it forces Polarion to re-read all extension registrations, including the newly installed Gantt widget.
**This is a standard Polarion procedure**
Deleting the `.config` folder is prescribed by the Polarion team whenever a new extension with a web application component is installed. The caches are rebuilt automatically and no data is lost.
Restart the Polarion server. The first startup after clearing the cache may take slightly longer as Polarion rebuilds its configuration.
1. Navigate to a LiveDoc or Wiki page in Polarion
2. Enter edit mode and add a widget
3. Search for **Gantt** in the widget list
4. Verify that both **Gantt (Work Items)** and **Gantt (Plans)** appear
**Verify in application**
If the widget still does not appear after clearing the cache, verify that the Gantt extension files were placed in the correct directory as described in the `INSTALL.txt` file included in the distribution package.
## Additional Checks
| Check | Location | Expected Result |
| ----------------------- | ------------------------------------------- | --------------------------------- |
| Extension files present | `[POLARION_INSTALL]/polarion/extensions/` | Gantt extension folder exists |
| Cache cleared | `[POLARION_INSTALL]/data/workspace/.config` | Folder deleted (rebuilt on start) |
| Server restarted | Polarion service | Running without errors |
| Widget available | Page editor > Add Widget | Gantt widgets listed |
## Verify
After completing these steps, you should now see the Gantt widget available in the Polarion page editor widget picker. Adding it to a page should display the Gantt chart configuration panel without errors.
## See also
* [Install Gantt](/gantt/getting-started/installation)
* [Update to the Latest Version](/gantt/getting-started/update-gantt)
* [Troubleshooting Blank or Non-Loading Gantt](/gantt/guides/troubleshooting/blank-gantt)
# Troubleshooting Performance Issues
Source: https://learn.nextedy.com/gantt/guides/troubleshooting/performance
This guide helps you diagnose and resolve slow loading or rendering in the Nextedy GANTT chart.
## Diagnostic Steps
Start by checking the Gantt footer for load statistics. The footer shows key performance indicators:
| Footer Metric | Meaning | Action if High |
| ---------------- | ---------------------------------------- | ----------------------------------------- |
| Gantt Rows | Number of items loaded | Reduce with filters or lower Max Items |
| Skipped | Items beyond the Max Items limit | Increase limit or narrow query scope |
| Server load time | Time taken to prepare data on the server | Check server resources, reduce item count |
| Errors | Issues encountered during load | Address errors to avoid retry overhead |
The most impactful performance optimization is reducing the number of items the Gantt needs to load and render.
**Narrow the dataset query:**
Configure the widget's dataset to filter for only the relevant work items. Use Polarion Lucene queries to scope the data:
* Filter by status (e.g., exclude closed items)
* Filter by date range to show only current sprints
* Filter by work item type to show only relevant types
**Adjust Max Items:**
Navigate to **Widget Parameters > Max Items** and set a value appropriate for your project size. The default limit prevents excessive loading, but setting it too high causes slow performance.
**Avoid loading 5000+ items**
Projects with thousands of work items can cause the Gantt to load slowly or appear blank. Use dataset filters to reduce the scope before increasing Max Items. If you must display large datasets, consider splitting the view into multiple Gantt widgets, each focused on a subset.
Item scripts execute for every loaded work item, so complex scripts multiply their impact across the entire dataset.
* **Simplify item scripts** -- Remove unnecessary API calls or complex logic
* **Avoid heavy Polarion API calls in scripts** -- Each call adds server round-trip time
* **Check for script errors** -- Failing scripts may cause retry loops that slow loading
**Check for script errors in the footer**
A triangle icon with an error count badge in the Gantt footer indicates script errors. Fixing these errors can improve performance because the Gantt avoids processing broken scripts repeatedly.
Performance issues are sometimes caused by configuration mismatches with Polarion administration settings:
1. **Verify enumeration values** -- Ensure that work item type IDs, link role IDs, and field IDs in the widget parameters match the values defined in **Polarion Administration**
2. **Check field mappings** -- Invalid field references (Start Field, End Field, Duration Field) cause extra error handling during load
3. **Review dependency roles** -- Missing or incorrect dependency roles generate errors for each affected work item
If you use working calendars, calendar resolution adds processing time per work item. Consider:
* Using a shared calendar project rather than per-user calendars for simpler configurations
* Clearing the calendar cache after making calendar changes by calling the `clearCalendarCache` endpoint
Newer Gantt versions include performance improvements. Check the version displayed in the Gantt footer and update if you are running an older release.
## Performance Optimization Summary
## Verify
After applying optimizations, reload the Gantt chart. You should now see faster loading with the footer showing a reduced item count, zero skipped items, and no error indicators. Check the server load time in debug mode to confirm improvement.
## See also
* [Manage Large Datasets with Max Items](/gantt/guides/filtering/max-items)
* [Use Gantt Filters](/gantt/guides/filtering/gantt-filters)
* [Troubleshooting Blank or Non-Loading Gantt](/gantt/guides/troubleshooting/blank-gantt)
* [Troubleshooting Script Errors](/gantt/guides/troubleshooting/script-errors)
# Troubleshooting Reviewer Access Issues
Source: https://learn.nextedy.com/gantt/guides/troubleshooting/reviewer-access
This guide helps you resolve situations where users have read-only (reviewer) access to the Nextedy GANTT widget instead of full edit access.
## Symptom
Users see the Gantt chart but cannot edit items -- dragging, resizing, and the Edit button are disabled. The Gantt displays a reviewer-level interface without editing controls.
The Gantt determines edit access based on membership in a specific Polarion user group.
1. Navigate to **Global Administration > User Management > Users**
2. Verify that a group called `nextedy_gantt_users` exists
3. Add all users who need edit access to this group
| Group | Access Level | Capabilities |
| ---------------------------- | ------------- | --------------------------------------------------- |
| `nextedy_gantt_users` member | Full edit | Drag tasks, resize bars, create items, save changes |
| Not in group | Reviewer only | View-only access, no editing |
**Group membership determines edit access**
Even if a user has full Polarion project permissions, they need to be in the `nextedy_gantt_users` group to edit items in the Gantt widget. This is a Gantt-specific permission layer separate from Polarion's standard role-based access.
After updating the user group, you must reload the Gantt licenses for the changes to take effect:
1. Navigate to the **Gantt - License** page in Polarion administration
2. The page automatically reloads all active licenses and applies the updated user access rights
3. Ask affected users to refresh their browser page
**License reload is required after group changes**
Simply adding users to the `nextedy_gantt_users` group is not enough. You must visit the license page to trigger a license reload. Without this step, the permission change will not be applied.
Ask the affected user to:
1. Refresh the Gantt page in their browser
2. Check that the Edit button appears in the toolbar
3. Click Edit and verify that task bars become draggable
## Verify
After completing these steps, you should now see the Edit button in the Gantt toolbar. Clicking it should enable full editing mode, allowing you to drag task bars, resize durations, create dependency links, and save changes.
## See also
* [Licensing and User Access](/gantt/getting-started/licensing)
* [Troubleshooting Save Failures](/gantt/guides/troubleshooting/save-failures)
* [Troubleshooting Installation Issues](/gantt/guides/troubleshooting/installation-issues)
# Troubleshooting Save Failures
Source: https://learn.nextedy.com/gantt/guides/troubleshooting/save-failures
This guide helps you diagnose and fix situations where changes made in the Nextedy GANTT chart fail to save to Polarion.
## How Saving Works
When you click the Save button, the Gantt sends all pending task and link changes to the Polarion server. A progress spinner appears during the save operation. If there are no unsaved changes, the save button does nothing.
The Gantt tracks unsaved changes across all tasks. Modified tasks are visually marked to indicate they have pending changes. The Save button state reflects whether any unsaved changes exist.
## Common Causes and Solutions
### Hidden Dependency Items
The most common cause of save failures is when dependency source items are hidden from the Gantt view, either by item scripts or by exceeding the Max Items limit.
**Hidden items can cause data loss**
When a dependency source item is hidden by an item script or cut off by the Max Items limit, save operations may fail silently. This issue was fixed in v25.5.0. If you are on an older version, apply the workarounds below.
**Workaround:**
1. Increase the **Max Items** widget parameter to a higher value (e.g., `10000`) to ensure all dependency-related items are loaded
2. Review your item scripts and remove any logic that hides items that are dependency sources
3. Update to Gantt v25.5.0 or later, which resolves this issue
### Missing or Invalid Field Configuration
Save failures occur when the configured data mapping fields do not match valid Polarion work item fields:
| Field | Widget Parameter | Check |
| ---------- | ---------------- | ------------------------------------ |
| Start date | Start Field | Must be a valid date custom field |
| End date | End Field | Must be a valid date custom field |
| Duration | Duration Field | Must be a valid numeric custom field |
| Progress | Progress Field | Must be a valid float custom field |
| Resource | Resource Field | Must be a valid field or `assignee` |
### Workflow Validation Errors
Polarion workflow rules may reject changes if required fields are missing or if the current work item state does not allow modifications. Check the browser console for specific error messages from the Polarion server.
**Check browser console for details**
Open the browser developer tools (right-click > Inspect > Console tab) to see detailed error responses from the server. Save errors include the specific Polarion validation message explaining why the save was rejected.
### Permission Issues
Edit and save operations require the user to be a member of the `nextedy_gantt_users` group. If a user has reviewer-only access (is not in this group), the Gantt opens in read-only mode and save operations are unavailable. See [Troubleshooting Reviewer Access Issues](/gantt/guides/troubleshooting/reviewer-access) for resolution steps.
### Session Timeout
Long editing sessions can cause the Polarion session to expire. The Gantt includes a keep-alive mechanism to prevent this, but network interruptions may still cause session loss. If saves fail after a long session, refresh the page to re-establish the session.
**Save before leaving the page**
The Gantt warns you about unsaved changes when navigating away. Always save your changes before leaving the page or closing the browser tab. Unsaved changes cannot be recovered after a page refresh.
## Diagnostic Steps
1. **Check the Gantt footer** for error indicators (triangle icon with count badge)
2. **Open browser console** (right-click > Inspect > Console) and look for error messages after clicking Save
3. **Verify field mappings** in widget parameters match actual Polarion custom field IDs
4. **Check user permissions** -- ensure the user is in the `nextedy_gantt_users` group
5. **Test with a simple edit** -- try dragging a single task and saving to isolate the issue
## Verify
After addressing the identified issue, make a small change (drag a task bar to a new date) and click Save. You should now see the progress spinner complete without errors, and the task's modified indicator should clear. Refresh the page to confirm the change persisted.
## See also
* [Handle Unsaved Changes and Session Timeout](/gantt/guides/editing/unsaved-changes)
* [Troubleshooting Reviewer Access Issues](/gantt/guides/troubleshooting/reviewer-access)
* [Manage Large Datasets with Max Items](/gantt/guides/filtering/max-items)
* [Troubleshooting Blank or Non-Loading Gantt](/gantt/guides/troubleshooting/blank-gantt)
# Troubleshooting Script Errors
Source: https://learn.nextedy.com/gantt/guides/troubleshooting/script-errors
This guide helps you identify and resolve errors in Nextedy GANTT item scripts, config scripts, and marker scripts.
## How Script Errors Are Displayed
Since version 25.4.2, the Gantt provides an improved error alert system that makes it easier to identify and resolve script issues.
### In Edit Mode (Administrator View)
When a script contains an error, a footer indicator appears. Clicking it opens a detailed message that identifies the error location. Errors are also logged in the **browser console** and **server logs**.
To access the browser console, right-click on the page, select **Inspect**, and go to the **Console** tab.
### In View Mode (User View)
A visual indicator (triangle icon in the Gantt footer) informs end users when configuration or data-related issues occur. The indicator shows a count badge with the number of errors detected.
## Error Types
The Gantt distinguishes between three script error categories:
| Error Type | Prefix in Error Panel | Source |
| -------------------- | ----------------------- | ------------------------------------ |
| Config Script Error | `Config Script Error:` | Gantt Config Script widget parameter |
| Markers Script Error | `Markers Script Error:` | Markers Script widget parameter |
| Item Script Error | `Item Script Error:` | Item Script widget parameter |
1. Open the page in edit mode
2. Look for the error indicator in the Gantt footer
3. Click the indicator to see the detailed error list
4. Note the error type prefix to determine which script is failing
**Server-side script errors are logged but do not crash the Gantt**
Item scripts run on the server for each work item. If an item script contains an error, the error is logged but the Gantt continues to load. Items with script errors may display without the customizations the script was supposed to apply (e.g., missing colors).
If your scripts stopped working after a Polarion upgrade to version 2304 or later, you need to update the script syntax:
**Before (Polarion 2303 and earlier):**
```javascript theme={null}
if (wi.status != null) {
var statusId = wi.status.id;
}
```
**After (Polarion 2304+):**
```javascript theme={null}
if (typeof wi !== 'undefined') {
var statusId = wi.getStatus().getId();
}
```
Key changes:
* Replace `null` checks with `typeof` checks (e.g., `typeof wi !== 'undefined'`)
* Replace direct property access with getter methods (e.g., `wi.getStatus().getId()` instead of `wi.status.id`)
**Scripts break silently after Polarion 2304 upgrade**
After upgrading Polarion to 2304+, existing item and plan scripts may fail with `undefined` variable errors. Visual elements like colors may stop loading. Update all scripts to use the new API syntax.
1. **Isolate the error** -- Temporarily clear the script content, save, and confirm the Gantt loads without errors
2. **Re-add incrementally** -- Add the script back line by line to pinpoint the failing statement
3. **Check variable availability** -- Item scripts have access to `task`, `wi` (work item), `plan`, `config`, `util`, and other context variables. Verify you are using the correct variable names.
4. **Check browser console** -- Look for detailed JavaScript error messages including line numbers
**Update to version 24.5.3+ for script execution fixes**
If item scripts are not executing at all (causing colors or other visual elements to not load), update to Gantt version 24.5.3 or later, which includes a fix for script execution issues.
After correcting the script:
1. Save the page in the wiki editor
2. Switch to view mode
3. Verify the error indicator has disappeared from the Gantt footer
4. Check that the script's intended behavior (colors, markers, custom logic) is applied correctly
## Verify
You should now see the Gantt chart loading without the error indicator in the footer. If you had script-driven colors, markers, or other customizations, they should now render correctly on all task bars.
## See also
* [Write Item Scripts](/gantt/guides/scripting/item-script-basics)
* [Write Gantt Config Scripts](/gantt/guides/scripting/gantt-config-script)
* [Debug Script Errors](/gantt/guides/scripting/debug-scripts)
* [Migrate Scripts for Polarion 2304+](/gantt/guides/scripting/script-migration-2304)
# Troubleshooting Today Marker Position
Source: https://learn.nextedy.com/gantt/guides/troubleshooting/today-marker-position
This guide explains why the Nextedy GANTT today marker may show an incorrect date and how to resolve or hide it.
## Symptom
The today marker (a vertical line on the Gantt timeline) displays a date that does not match your current local date. For example, it may show January 24 when your local date is already January 25.
## Why This Happens
The today marker date is determined by the **Polarion server's timezone**, not the user's browser timezone. When the server is located in a different timezone than the user, the today marker may appear to be one day behind or ahead.
| Scenario | Server Time | Client Time | Today Marker Shows |
| -------------------------------- | ------------- | ------------- | ------------------ |
| Server in UTC, client in UTC+9 | Jan 24, 23:00 | Jan 25, 08:00 | Jan 24 |
| Server in UTC+1, client in UTC-5 | Jan 25, 01:00 | Jan 24, 19:00 | Jan 25 |
The today marker tooltip displays the exact date in `Today: YYYY-MM-DD` format. Hover over the marker to see the precise server date.
**This is expected behavior**
The timezone difference between server and client is the most common cause of the today marker appearing in the wrong position. In most environments where server and client are in the same timezone, the dates match.
## Option 1: Align Server Timezone
If your organization requires the today marker to match client time, coordinate with your Polarion server administrator to set the server timezone to match your primary user base.
**Verify in application**
The server timezone configuration is managed at the operating system level on the Polarion server host. Consult your Polarion administrator for changes.
## Option 2: Hide the Today Marker
If the timezone discrepancy is not critical and you prefer to remove the marker entirely:
1. Open the Gantt widget parameters in the page editor
2. Navigate to **Widget Parameters > Advanced > Show Today Marker**
3. Set the value to **No**
4. Save the page
## Option 3: Adjust Marker Position with Scripts
For milestone markers that you create via the Markers Script, the marker date follows an end-of-day rendering convention. If a marker appears one day off from where you expect it, you can apply a `-1` day offset in your script to shift it to a start-of-day position.
**Marker end-of-day convention**
All markers (including the today marker) render at the end of the specified date by convention. If you need a marker to appear at the start of a day, subtract one day from the date value in your markers script. This is particularly relevant for custom milestone markers created with `markerFactory`.
## Custom Marker Troubleshooting
If you use custom markers via the **Markers Script** (under **Widget Parameters > Advanced**), verify these common issues:
* **Markers not appearing** -- Ensure the markers script has no syntax errors (check the Gantt footer for a "Markers Script Error" indicator)
* **Wrong marker color** -- The `setColor` method accepts one of the 16 basic HTML color names (e.g., `"red"`, `"blue"`, `"green"`, `"fuchsia"`)
* **Markers from wrong project** -- When using `addPlanMarkers` or `addWorkItemMarkers`, verify the `project.id` in the Lucene query matches the intended source project
## Verify
After applying your chosen solution, reload the Gantt chart. You should now see either:
* The today marker correctly aligned with the expected date (Option 1)
* No today marker displayed on the timeline (Option 2)
* Custom markers positioned at the correct dates (Option 3)
Hover over the today marker (if visible) to confirm the tooltip shows `Today: YYYY-MM-DD` with the expected date.
## See also
* [Create and Configure Markers](/gantt/guides/visualization/markers)
* [Create Markers with Scripts](/gantt/guides/scripting/marker-scripts)
* [Scroll to Today on Load](/gantt/guides/layout/scroll-to-today)
* [Configure the Time Scale](/gantt/guides/visualization/timescale)
# Compare Schedule with Baselines
Source: https://learn.nextedy.com/gantt/guides/visualization/baselines-comparison
Display a visual overlay comparing the current Nextedy GANTT schedule against a historical snapshot, helping you identify schedule drift and newly added tasks.
## Option 1: One-Time Comparison from the Toolbar
Use the toolbar Compare button for an ad-hoc comparison against any historical point in time.
1. Open your Gantt chart page in Polarion.
2. Click the **Compare** button in the Gantt toolbar.
3. In the comparison dialog, select one of three modes:
| Mode | What You Enter | When to Use |
| ------------ | ------------------------------------------- | ------------------------------------------------- |
| **Date** | A specific calendar date | Compare against a known date (e.g., sprint start) |
| **Baseline** | A named Polarion baseline from the dropdown | Compare against a formal project baseline |
| **Revision** | A Polarion SVN revision number | Compare against a specific repository revision |
4. Click **Compare**. The Gantt reloads and displays baseline bars behind each task bar, showing where tasks were scheduled at the selected point in time.
**Save Before Comparing**
The Compare dialog does not open if you have unsaved changes. Save your work first, then initiate the comparison.
Since version **25.3.0**, the comparison dialog supports all three modes (date, baseline, and revision) in a single improved interface. Tasks created after the comparison point are marked with a **NEW** badge, making it easy to spot recently added work items.
## Option 2: Always-On Baseline Display
To show baseline bars every time the Gantt loads, configure the widget to display baselines automatically.
1. Open the page in edit mode and select the Gantt widget.
2. Navigate to **Widget Properties > Baselines**.
3. Set **Show Baselines** to **Yes**.
4. In **Compare to date**, choose one of:
* A **relative date** (T-minus, e.g., 30 days ago)
* A **specific date** in the past
* A **page parameter** to let users pick the date dynamically
5. Save the page. The Gantt now loads with baseline overlay bars visible by default.
**Combine with Page Parameters**
Create a page parameter called `baselineRevision` of type **string** on your Gantt report page. Users can then select different baselines without editing widget properties. See [Configure Page Parameters](/gantt/guides/layout/page-parameters) for setup details.
## Option 3: API Approach with Item Script
For item-specific baselines (where each work item stores its own approved schedule), use the Item Script to populate baseline fields from custom fields.
Add the following to **Widget Properties > Advanced > Item Script**:
```javascript theme={null}
task.planned_start_date = util.getDate(wi, "gantt_initial_start");
task.planned_duration = util.getDuration(wi, "gantt_initial_duration");
```
This reads the approved start date and duration from custom fields on each work item. The baseline bars reflect per-item approved schedules rather than a single historical snapshot.
**Field Names Must Match Data Mapping**
The field names passed to `util.getDate()` and `util.getDuration()` must match your Data Mapping configuration. If your mapping uses `start` and `initialEstimate`, use those exact names in the script.
## Browsing Baselines with a Portal Page
You can create a Polarion wiki page that lists all project baselines and links each one directly to your Gantt with the comparison pre-applied. This approach uses a Velocity script that iterates through `$project.baselinesManager.baselines` and constructs links with the `baselineRevision` page parameter.
**Verify in application**
The Velocity-based baseline portal page requires Polarion wiki scripting permissions. Consult your Polarion administrator for access.
## Exiting Compare Mode
To stop the baseline comparison and return to the normal view, click the **Compare** button again in the toolbar (it appears in a toggled/active state during comparison). The baseline overlay bars are removed and the Gantt returns to its current-schedule-only display.
## Verification
You should now see secondary bars behind each task bar in the Gantt chart. These baseline bars represent the historical schedule. If a task has moved since the comparison date, you will see the current task bar offset from the baseline bar. Tasks added after the comparison date display a **NEW** badge.
## See Also
* [Configure Page Parameters](/gantt/guides/layout/page-parameters)
* [Configure Item Colors](/gantt/guides/visualization/configure-colors)
* [Perform What-If Analysis Without Saving](/gantt/guides/scheduling/what-if-analysis)
* [Write Item Scripts](/gantt/guides/scripting/item-script-basics)
# Use Classic Project Brackets View
Source: https://learn.nextedy.com/gantt/guides/visualization/classic-project-brackets
Switch parent work items from the default task bar rendering to classic bracket notation in your Nextedy GANTT chart, providing a traditional project management visual for derived-schedule items.
## When to Use Brackets
In the Gantt chart, parent work items with a derived schedule (dates calculated from their children) can be displayed in two ways:
| Display Mode | Visual Style | Best For |
| -------------------- | ----------------------------------------------- | ------------------------------------------------------------------- |
| **Default (tasks)** | Standard task bars, similar to child work items | Modern, unified look |
| **Classic brackets** | Bracket shapes spanning the child date range | Traditional project management view, clear parent-child distinction |
The classic bracket view makes it immediately obvious which items are containers with derived schedules versus individual tasks with their own dates.
Navigate to **Administration > Configuration Properties** and add the following property:
```
nextedy.gantt.classic_project=true
```
This applies the bracket rendering to all Gantt widgets across the project. Parent work items with a derived schedule now appear as brackets instead of standard task bars.
If you prefer to enable brackets on a single Gantt widget rather than globally, add the following to **Widget Properties > Advanced > Gantt Config Script**:
```javascript theme={null}
gantt.config.classic_project = true;
```
**Override Global Setting Per Widget**
You can set `nextedy.gantt.classic_project=true` globally and then override it on specific widgets with `gantt.config.classic_project = false;` in the Gantt Config Script. The widget-level setting takes precedence.
After applying the configuration:
1. Reload the Gantt chart page.
2. Locate any parent work item whose schedule is derived from its children.
3. Confirm that it now renders as a bracket shape spanning the date range of its children, rather than as a standard task bar.
**Right-Side Text on Brackets**
In versions prior to **24.11.3**, right-side text configured via `rightside_text` templates was not displayed on bracket-style items. Upgrade to version 24.11.3 or later if you need right-side text on classic bracket items.
## Verification
You should now see parent work items rendered as bracket shapes in the Gantt chart. Child work items beneath them display as standard task bars. The bracket spans from the earliest child start date to the latest child end date.
## See Also
* [Derive Parent Schedule from Children](/gantt/guides/scheduling/parent-derived-schedule)
* [Configure Right-Side Text on Task Bars](/gantt/guides/visualization/right-side-text)
* [Configure Item Colors](/gantt/guides/visualization/configure-colors)
* [Configure Milestone Work Items](/gantt/guides/visualization/milestones)
# Manage Column Visibility
Source: https://learn.nextedy.com/gantt/guides/visualization/column-visibility
This guide shows you how to show and hide columns in the Nextedy GANTT grid panel using the context menu and hamburger menu, and how visibility preferences persist across sessions.
## Toggle Columns via the Context Menu
Right-click on any column header in the Gantt grid to open the column visibility context menu. The menu lists all configured columns with checkboxes indicating their current visibility state.
Click a column name to toggle it between visible and hidden. The change takes effect immediately -- the column appears or disappears from the grid without a page reload.
**First column cannot be hidden**
The first column (the task title column) is always visible. Its entry in the context menu is disabled and cannot be unchecked. This ensures you always have a reference column identifying each work item in the grid.
## Toggle Columns via the Hamburger Menu
Click the ☰ hamburger icon in the first column header to open the main menu, then select the **Column visibility** submenu. This provides the same checkbox list as the context menu, offering an alternative access point when you prefer not to right-click.
The hamburger menu also provides other options including **Refresh**, **Drag children** toggle, **Go to today**, **Set scale**, and a **Help** link to the documentation.
## How Visibility Preferences Are Saved
Column visibility settings are saved to browser local storage automatically. After you hide or show columns, the Gantt remembers your choices and restores them on the next page visit.
| Behavior | Details |
| :--------------- | :----------------------------------------------------------- |
| Storage location | Browser local storage (per-browser, per-user) |
| Persistence | Survives page reloads and browser restarts |
| Scope | Settings are tied to the specific Gantt widget instance |
| Reset | Use the hamburger menu to reset to widget parameter defaults |
**Visibility settings are browser-local**
Because column visibility is stored in the browser, your preferences do not follow you across different browsers or devices. If you switch to a new browser, you will see the default column layout until you adjust it again.
## Bypass the Custom Context Menu
If you need to access the browser's native context menu on a column header (for example, to inspect an element), hold **Shift** while right-clicking. This bypasses the Gantt column visibility menu and opens the standard browser context menu instead.
**Test column visibility in the sandbox**
The column visibility feature is available in the Nextedy sandbox environment. Use the [demo project](/gantt/getting-started/demo-project) to experiment with showing and hiding columns before applying changes to your production Gantt charts.
## Verification
You should now be able to right-click any column header and toggle its visibility. After hiding a column, reload the page and confirm the column remains hidden. The first column should always remain visible with its menu item disabled.
## See also
* [Configure Grid Columns](/gantt/guides/visualization/columns)
* [Use Inline Cell Editing](/gantt/guides/editing/inline-cell-editing)
* [Configure the Toolbar and Menus](/gantt/guides/layout/toolbar-configuration)
* [Configure the Time Scale](/gantt/guides/visualization/timescale)
* [Set Up a Basic Gantt Chart](/gantt/getting-started/setup-basic-gantt)
# Configure Grid Columns
Source: https://learn.nextedy.com/gantt/guides/visualization/columns
This guide shows you how to add, configure, and customize the columns displayed in the Nextedy GANTT grid panel (the left side of the Gantt chart).
## Default Column Layout
Out of the box, the Gantt grid displays the following columns:
| Column | Content | Editable |
| :---------------- | :---------------------------------------------------- | :----------------- |
| Task number (WBS) | Work breakdown structure number | No |
| Title | Work item ID, type icon, and title (with tree indent) | No |
| Start date | Task start date | Yes (date picker) |
| End date | Task end date | Yes (date picker) |
| Duration | Task duration in days | Yes (number input) |
| Assignee | Assigned resource | No |
## Configure the First Column
The first column always displays the task label and cannot be hidden. You can control what appears in it through the **Widget Properties > Table > First Column** settings:
| Parameter | Effect |
| :-------------------- | :------------------------------------------------------------------ |
| `FIRST_COL.showId` | Displays the work item ID prefix (e.g., "WI-123:") before the title |
| `FIRST_COL.showTitle` | Displays the work item title text |
| `FIRST_COL.showIcon` | Displays the work item type icon before the label |
Set `showId` to `true` when users need to quickly identify work items by their Polarion ID without opening the lightbox.
**Save space by hiding the title**
If you only need to see work item IDs in the grid, set `showTitle` to `false` and `showId` to `true`. This produces a compact first column showing only the ID.
## Add Custom Columns
Navigate to **Widget Properties > Table > Columns** to add additional columns beyond the defaults. Each column has these parameters:
| Parameter | Description | Default |
| :-------- | :------------------------------------------------------------------ | :--------------------- |
| `field` | Polarion work item field ID (e.g., `priority`, `status`, `dueDate`) | Required |
| `label` | Column header text | Field's Polarion label |
| `width` | Column width in pixels | 300 |
| `align` | Text alignment: `left`, `center`, or `right` | `left` |
| `render` | Template identifier controlling how cell values are displayed | Standard |
### Available Column Templates
The following template identifiers control how column values are rendered:
| Template ID | Rendering Behavior |
| :----------- | :---------------------------------------------------- |
| `deadline` | Shows dates in red when the task is overdue |
| `start_date` | Renders the start date with precision formatting |
| `end_date` | Renders the end date with precision formatting |
| `owner` | Shows assignees as initials in circles or full names |
| `standard` | Renders duration values |
| `progress` | Shows progress percentage rounded to 2 decimal places |
## Configure the Grid Width
Set the overall width of the grid panel through **Widget Properties > Table > WIDTH**. This controls how much horizontal space the column area occupies relative to the timeline.
**User preferences override widget settings**
When a user resizes the grid panel or individual columns by dragging, those widths are saved to browser local storage. On the next visit, the saved widths are restored instead of the widget parameter defaults. Users can reset to defaults via the hamburger menu.
## Configure Assignee Display Mode
The assignee column supports two display modes controlled by the configuration property:
```
nextedy.gantt.assignee_column_display_mode=initials
```
| Value | Display |
| :--------- | :---------------------------------------- |
| `initials` | User initials shown in a circle (compact) |
| `fullname` | Full user name displayed as text |
Set this property in **Administration > Configuration Properties**.
## Access the Hamburger Menu
The first column header contains a ☰ hamburger menu icon that provides quick access to:
* **Refresh** the Gantt data
* **Drag children** toggle
* **Go to today** navigation
* **Set scale** submenu
* **Column visibility** submenu
* **Help** link to the documentation
## Verification
You should now see the configured columns in the Gantt grid. Verify that custom field columns display the expected values and that column widths match your configuration. If a column shows empty values, confirm the field ID matches a valid Polarion work item field.
## See also
* [Manage Column Visibility](/gantt/guides/visualization/column-visibility)
* [Use Inline Cell Editing](/gantt/guides/editing/inline-cell-editing)
* [Show Deadlines and Due Dates](/gantt/guides/visualization/deadlines)
* [Configure the Toolbar and Menus](/gantt/guides/layout/toolbar-configuration)
* [Set Up a Basic Gantt Chart](/gantt/getting-started/setup-basic-gantt)
# Configure Item Colors
Source: https://learn.nextedy.com/gantt/guides/visualization/configure-colors
Control task bar colors in Nextedy GANTT using either static coloring (full manual control) or dynamic coloring (progress-based with customizable defaults).
## Choose a Coloring Mode
The Gantt supports two coloring modes that determine how task bar colors are applied:
| Mode | How It Works | Color Property | Use When |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------ | ---------------- | --------------------------------------------------------------- |
| **Static** | All progress-based coloring is disabled; you set every color manually via Item Script | `task.color` | You want complete control over every task bar color |
| **Dynamic** | Progress-based colors (overdue, delayed, on-track, resolved) are applied automatically; you can override only the default blue color | `task.taskColor` | You want schedule-status awareness with selective customization |
## Option 1: Static Coloring
Disable all progress-based colors and assign colors entirely through Item Scripts.
Add to **Widget Properties > Advanced > Gantt Config Script**:
```javascript theme={null}
gantt.config.show_progress_colors = false;
```
Then add to **Widget Properties > Advanced > Item Script**:
```javascript theme={null}
if (wi.getType().getId() === "workpackage" && wi.getStatus().getId() === "draft") {
task.color = "#bfbfbf";
}
```
In static mode, use `task.color` to set the task bar color. This property overrides all automatic coloring, giving you full control.
**Milestones and Static Coloring**
Milestone colors are hardcoded to yellow and red (for passed deadlines) unless static coloring is enabled. To apply custom colors to milestones, you must set `gantt.config.show_progress_colors = false` and then assign colors via `task.color` in the Item Script.
## Option 2: Dynamic Coloring
Keep progress-based status colors active while customizing specific aspects.
To change the default blue color for on-track items, add to **Widget Properties > Advanced > Item Script**:
```javascript theme={null}
if (wi.getType().getId() === "portfolioepic") {
task.taskColor = "#bfbfbf";
}
```
In dynamic mode, use `task.taskColor` to change only the default (blue) color. Items that are overdue, delayed, or resolved retain their progress-based colors regardless of `task.taskColor`.
**task.color vs. task.taskColor**
Using `task.color` in dynamic mode overrides all progress-based coloring for that item. Use `task.taskColor` instead if you want to change only the default color while keeping overdue/delayed/resolved status colors active. Using `task.color` when progress colors are enabled effectively forces that item into static coloring.
## Customize Progress Color Defaults
Override the default progress colors at the project or server level. Add the following under **Administration > Configuration Properties**:
```
nextedy.gantt.default.progress_color_overdue=red
nextedy.gantt.default.progress_color_progressdue=orange
nextedy.gantt.default.progress_color_resolved=gray
nextedy.gantt.workitems.unplanned_color=#c7cffb
nextedy.gantt.workitems.unplanned_color_fg=#001379
```
Alternatively, set these per-widget in the **Gantt Config Script**:
```javascript theme={null}
gantt.config.progress_color_overdue = "red";
gantt.config.progress_color_progressdue = "orange";
gantt.config.progress_color_resolved = "gray";
```
**HEX Color Format**
Both named colors (red, green, gray) and HEX color codes (#bfbfbf, #0AA33A) are supported in all color properties. Use HEX codes for precise color matching across your project.
## Verify
You should now see that task bars display colors according to your chosen mode. In static mode, all bars use the colors assigned in the Item Script. In dynamic mode, overdue items appear in your configured overdue color, delayed items in the progress-due color, and on-track items in either the default blue or your custom `task.taskColor` value.
## See Also
* [Customize Progress-Related Coloring](/gantt/guides/visualization/progress-coloring)
* [Color Logic Script Examples](/gantt/guides/scripting/color-logic-scripts)
* [Write Item Scripts](/gantt/guides/scripting/item-script-basics)
* [Write Gantt Config Scripts](/gantt/guides/scripting/gantt-config-script)
* [Configure Resource Allocation Marker Colors](/gantt/guides/visualization/resource-marker-colors)
# Show Deadlines and Due Dates
Source: https://learn.nextedy.com/gantt/guides/visualization/deadlines
This guide shows you how to enable deadline visualization in Nextedy GANTT so that work items with a due date display a deadline marker on the timeline, with overdue items highlighted in a configurable color.
## Enable Deadlines
Navigate to **Widget Properties > Deadlines** and configure the following parameters:
| Parameter | Description | Required |
| :---------------------- | :---------------------------------------------------------------------- | :--------------------------- |
| `ShowDeadlines` | Enable deadline marker display on the Gantt chart | Yes (set to `true`) |
| `Deadline Field` | The Polarion work item field that holds the deadline date | Yes |
| `Passed Deadline Color` | CSS color applied to items where the end date extends past the deadline | No (default styling applies) |
The `Deadline Field` and `Passed Deadline Color` parameters only appear after you set `ShowDeadlines` to `true`. This progressive disclosure keeps the parameter panel clean when deadlines are not in use.
Set `Deadline Field` to any date-type field on your work items, such as `dueDate` or a custom date field. The field must contain a date value for the deadline marker to appear.
## Understand Overdue Coloring
When `ShowDeadlines` is enabled, the Gantt compares each task's end date against its deadline field value. If the end date extends beyond the deadline, the task bar is styled with the `Passed Deadline Color` and receives an overdue visual indicator.
**Deadline coloring compares end date to due date, not current date**
The overdue color indicates that a task's scheduled end date extends past its deadline -- it does not compare against today's date. A task finishing on March 15 with a deadline of March 10 will appear overdue regardless of what today's date is. If you need current-date-relative coloring, use a custom [Item Script](/gantt/guides/scripting/item-script-basics) with date comparison logic.
## Add a Deadline Column to the Grid
You can display deadline dates in the grid panel by adding a column with the `deadline` template. Navigate to **Widget Properties > Table > Columns** and add a column with these settings:
| Parameter | Value |
| :-------- | :--------------------------------------- |
| `field` | Your deadline field ID (e.g., `dueDate`) |
| `render` | `deadline` |
The deadline column template displays dates in a compact format (e.g., "Sep-09", "Nov-30"). When the task is overdue, the date text turns red to provide a clear visual cue in the grid.
**Deadline column is read-only**
The deadline column in the grid does not support inline editing. To update a work item's deadline date, edit the field through the lightbox or directly in Polarion.
## Configure the Passed Deadline Color
Set `Passed Deadline Color` to any valid CSS color value. Common choices include:
* Named colors: `red`, `orange`, `darkred`
* Hex codes: `#e53935`, `#ff5722`
Leave this parameter empty to use the default overdue styling.
## Verification
You should now see deadline markers on the Gantt timeline for work items that have a value in the configured deadline field. Items whose end date extends past the deadline should appear in the configured color. If you added a deadline column, verify that overdue dates display in red text.
## See also
* [Configure Grid Columns](/gantt/guides/visualization/columns)
* [Configure Item Colors](/gantt/guides/visualization/configure-colors)
* [Write Item Scripts](/gantt/guides/scripting/item-script-basics)
* [Create and Configure Markers](/gantt/guides/visualization/markers)
* [Set Up a Basic Gantt Chart](/gantt/getting-started/setup-basic-gantt)
# Visualization
Source: https://learn.nextedy.com/gantt/guides/visualization/index
Control the appearance of task bars, colors, columns, markers, and timescales in your Nextedy GANTT chart.
## Colors and Styling
* **[Configure Item Colors](/gantt/guides/visualization/configure-colors)** — Set static or dynamic colors on task bars using Item Scripts and Gantt Config Scripts
* **[Customize Progress-Related Coloring](/gantt/guides/visualization/progress-coloring)** — Change the default colors for overdue, delayed, resolved, and unplanned items
* **[Configure Resource Allocation Marker Colors](/gantt/guides/visualization/resource-marker-colors)** — Customize the color thresholds for over-allocated and within-capacity resource markers
* **[Use Square Task Borders](/gantt/guides/visualization/square-task-borders)** — Switch from rounded to square task bar corners
## Text and Labels
* **[Configure Right-Side Text on Task Bars](/gantt/guides/visualization/right-side-text)** — Display status, progress, or custom fields next to each task bar
* **[Customize Text Inside Task Bars](/gantt/guides/visualization/text-inside-bars)** — Control the label shown inside the task bar itself
* **[Customize Gantt Tooltips](/gantt/guides/visualization/tooltips)** — Configure the hover tooltip content for task bars
## Grid and Columns
* **[Configure Grid Columns](/gantt/guides/visualization/columns)** — Add, remove, and reorder columns in the Gantt grid
* **[Manage Column Visibility](/gantt/guides/visualization/column-visibility)** — Let users toggle column visibility at runtime
## Timeline and Scale
* **[Configure the Time Scale](/gantt/guides/visualization/timescale)** — Set zoom levels, date formats, and scale units
* **[Adjust Gantt Row Height](/gantt/guides/visualization/row-height)** — Change the height of task rows in the chart
* **[Highlight Off-Days in the Timeline](/gantt/guides/visualization/off-day-highlighting)** — Shade weekends and holidays in the timeline background
## Milestones and Markers
* **[Configure Milestone Work Items](/gantt/guides/visualization/milestones)** — Display point-in-time events as diamond shapes on the chart
* **[Show Deadlines and Due Dates](/gantt/guides/visualization/deadlines)** — Overlay deadline indicators on task bars
* **[Create and Configure Markers](/gantt/guides/visualization/markers)** — Add vertical line markers for today, milestones, or custom dates
## Schedule Comparison
* **[Compare Schedule with Baselines](/gantt/guides/visualization/baselines-comparison)** — Show planned versus actual dates as dual task bars
* **[Use Classic Project Brackets View](/gantt/guides/visualization/classic-project-brackets)** — Display parent items as bracket-style summary bars
**Scripting for Advanced Customization**
Many visualization features can be further customized through [Item Scripts](/gantt/guides/scripting/item-script-basics) and [Gantt Config Scripts](/gantt/guides/scripting/gantt-config-script). See [Color Logic Script Examples](/gantt/guides/scripting/color-logic-scripts) for practical color customization patterns.
# Create and Configure Markers
Source: https://learn.nextedy.com/gantt/guides/visualization/markers
This guide shows you how to add vertical timeline markers in Nextedy GANTT to highlight key dates such as version releases, iteration boundaries, and project deadlines.
## Access the Markers Script
Markers are defined in the **Markers Script**, located under **Widget Properties > Advanced > Markers Script**. This server-side script runs each time the Gantt loads and produces the set of marker lines displayed on the timeline.
The script has access to the `markerFactory` object, which provides methods for creating markers manually and from Polarion data.
## Add a Marker Manually
To create a single marker at a specific date, use the `markerFactory.addMarker()` method:
```javascript theme={null}
var marker = markerFactory.addMarker();
marker.setText("20.0");
marker.setDate("2025-08-04");
marker.setColor("green");
```
This creates a green vertical line labeled "20.0" on August 4, 2025.
The marker object provides these methods:
| Method | Description |
| :----------------------------- | :---------------------------------------------------------- |
| `setText(String text)` | Set the marker label displayed on the timeline |
| `setTitle(String tooltip)` | Set the tooltip text shown on hover |
| `setDate(String dateStr)` | Set the marker date (format: `"YYYY-MM-DD"`) |
| `setDate(java.util.Date date)` | Set the marker date from a Java Date object |
| `setColor(String color)` | Set the marker color (one of the 16 basic HTML color names) |
**Marker position follows end-of-day convention**
Markers render at the end of the specified date. If you set a marker to "2025-08-04", the vertical line appears at the end of August 4th. To position a marker at the start of a date, subtract one day from the date value in your script.
## Add Markers from Plans
Use `addPlanMarkers` to automatically create markers from Polarion Plan items matching a Lucene query:
```javascript theme={null}
markerFactory.addPlanMarkers("template.id:iteration AND project.id:gantt2", "blue")
```
This creates a blue marker for each iteration plan in the project "gantt2". The marker date is taken from the plan's date range.
## Add Markers from Work Items
Use `addWorkItemMarkers` to create markers from work items, specifying which date field to use:
```javascript theme={null}
markerFactory.addWorkItemMarkers("type:release AND project.id:gantt2", "start", "red")
```
| Parameter | Description |
| :-------------- | :------------------------------------------------------------------------------ |
| First argument | Lucene query filtering which work items to include |
| Second argument | The date field to read the marker date from (e.g., `"start"`, `"publicLaunch"`) |
| Third argument | Marker color |
To reference the current project dynamically instead of hard-coding the project ID:
```javascript theme={null}
markerFactory.addWorkItemMarkers(
"type:release AND project.id:" + config.getContextProjectId(),
"publicLaunch",
"blue"
)
```
**Use custom date fields for release markers**
When marking version releases, point the date field parameter to a custom field like `publicLaunch` rather than the task's scheduling dates. This lets you track external release dates independently from the work item's planned schedule.
## Use the Polarion API for Dynamic Markers
For full scripting control, use the `trackerService` API to query Polarion data and build markers dynamically. This approach supports conditional logic, custom tooltips, and color-coding based on field values.
**Example: Load Time Points as markers:**
```javascript theme={null}
var timePoints = trackerService.getTrackerProject("GANTT")
.getTimePoints().iterator();
while(timePoints.hasNext()) {
var tp = timePoints.next();
var marker = markerFactory.addMarker();
marker.setText(tp.getName());
marker.setDate(tp.getTime().getDate());
marker.setColor("fuchsia");
var desc = tp.getDescription();
if(desc != null) {
marker.setTitle(desc.getContent());
}
}
```
**Example: Dynamic markers from page parameters:**
```javascript theme={null}
var milestoneIds = config.pageParameters.milestone;
if(milestoneIds === null) {
milestoneIds = "";
} else {
milestoneIds = milestoneIds.replaceAll(',', ' ');
}
var milestones = trackerService.queryWorkItems(
"project.id:Gantt3 AND type:milestone AND id:(" + milestoneIds + ")",
"id"
).iterator();
while(milestones.hasNext()) {
var tp = milestones.next();
var marker = markerFactory.addMarker();
marker.setText(tp.getTitle());
marker.setDate(tp.getValue('releaseDate').getDate());
marker.setColor("blue");
}
```
This example works with Milestone-type work items that carry two custom fields: `releaseDate` (a date) and `productType` (an enumeration with values such as typeA, typeB, and typeC).
Define the page parameter that drives the query as an Enumeration-type parameter so editors get a dropdown of milestone work items. Its ID must match the one referenced in the script — here, `milestone`.
This reads a comma-separated list of work item IDs from the `milestone` page parameter, queries them, and renders each as a marker. Changing the page parameter updates which markers appear without editing the script.
As a result, only the selected work items appear as markers, dated from their `releaseDate` field. Milestones 1 and 3 appear blue because their `productType` has a value, while Milestone 2 is pink because its `productType` is typeB.
To switch the displayed markers quickly, add a Page Parameters Block widget to the same page as the Gantt and expose the `milestone` parameter there.
## Marker CSS Classes
Markers receive CSS classes based on their type, which you can use for custom styling:
| CSS Class | Applied To |
| :------------- | :--------------------------------------------------- |
| `today` | The automatic today-date marker |
| `plan` | Markers created from Plan items via `addPlanMarkers` |
| `gantt_marker` | All custom markers (base class) |
To keep only the marker line and hide its header label, add a script-block widget above the Gantt that sets `.gantt_marker_content { display: none; }`. The result shows the marker line without its text header.
**Markers Script errors are displayed to users**
If the Markers Script contains a syntax or runtime error, the Gantt displays a warning indicator with the message prefix "Markers Script Error:". This warning is visible to all users viewing the page, not just to page editors. Test your scripts thoroughly before deploying.
## Marker Tooltips
Hovering over a marker line displays a tooltip showing the marker name and date. Set the tooltip content using `marker.setTitle()` for custom tooltip text, or let the Gantt generate a default tooltip from the marker text and date.
## Verification
You should now see vertical marker lines on the Gantt timeline at the configured dates. Hover over each marker to verify the tooltip displays the expected name and date. If markers do not appear, check the Markers Script for errors using the warning indicator in the Gantt toolbar area.
## See also
* [Configure Milestone Work Items](/gantt/guides/visualization/milestones)
* [Create Markers with Scripts](/gantt/guides/scripting/marker-scripts)
* [Configure Page Parameters](/gantt/guides/layout/page-parameters)
* [Customize Gantt Tooltips](/gantt/guides/visualization/tooltips)
* [Show Deadlines and Due Dates](/gantt/guides/visualization/deadlines)
# Configure Milestone Work Items
Source: https://learn.nextedy.com/gantt/guides/visualization/milestones
This guide shows you how to display work items as milestone diamonds in Nextedy GANTT using either type-based configuration or conditional scripting.
## Option 1: Type-Based Milestones
The simplest approach sets an entire work item type to render as milestones. Navigate to the work item type configuration in Polarion and set the **Gantt Presentation Mode** to **Milestone (Only date, zero duration)**.
All work items of that type will appear as diamond shapes on the timeline instead of task bars. Milestones represent a single point in time with zero duration.
| Presentation Mode | Visual Appearance | Behavior |
| :--------------------------- | :---------------------------- | :---------------------------------------------------------- |
| `TASK` (Item) | Standard task bar | Directly editable, shows duration |
| `PROJECT` (Derived Schedule) | Summary bar spanning children | Dates computed from child extents, not directly editable |
| `MILESTONE` (Milestone) | Diamond shape | Zero duration, shows only the start date |
| `AUTO` (Auto-Mode) | Automatic | Renders as `TASK` if no children, `PROJECT` if has children |
**Use AUTO mode for flexible rendering**
Set the presentation mode to `AUTO` when work items of the same type may or may not have children. Items with children will render as summary project bars, while leaf items will render as standard task bars.
## Option 2: Conditional Milestones via Item Script
Use an **Item Script** when you need to control which individual items appear as milestones based on conditions beyond the work item type. Navigate to **Widget Properties > Advanced > Item Script** and add a script that sets `task.type` to `"milestone"`:
```javascript theme={null}
if(wi.getType().getId() === "release" && wi.getStatus().getId() === "inprogress") {
task.type = "milestone";
}
```
In this example, only Release items with the status "In progress" render as milestones. When the status changes, the item reverts to its default presentation (a standard task bar with duration).
You can combine multiple conditions to match your project needs. For example, display all items of a specific type as milestones only when they are unresolved:
```javascript theme={null}
if(wi.getType().getId() === "goal" && wi.getResolution() === null) {
task.type = "milestone";
}
```
## Schedule Milestones from a Custom Date Field
By default, milestones use the date fields configured in the widget Data Mapping section. To pull the date from a different field (such as a "Public Launch" custom field), use an Item Script that overrides the schedule for unplanned items:
```javascript theme={null}
var typeId = wi.getType().getId();
if (typeId === "release") {
if (task.unplanned && wi.getValue("publicLaunch")) {
task.start_date = util.getDate(wi, "publicLaunch");
task.readonly = true;
task.unplanned = false;
}
}
```
**Set task.readonly to prevent schedule conflicts**
When overriding the schedule from a custom field, always set `task.readonly = true`. This prevents users from dragging the milestone on the timeline, which would trigger the default scheduling logic and overwrite the custom date field value.
## Render a Visual Milestone Marker from a Custom Field
To highlight an important date on a work item without changing its actual schedule, render a small diamond marker at the custom field date. This requires both an **Item Script** and a **Gantt Config Script**.
**Item Script** (passes the custom field value to the client):
```javascript theme={null}
function storeMS(field) {
var milestone_Field = wi.getValue(field);
if (milestone_Field) {
task.getFields().put(field, milestone_Field.toString());
}
}
if(wi.getType().getId() === "workpackage") {
storeMS("testDateField");
}
```
**Gantt Config Script** (attaches the milestone marker to the task bar):
```javascript theme={null}
var milestones = [];
milestones.push(["testDateField", "green"]);
gantt.attachEvent("onTaskLoading", function(task) {
milestones.forEach(m => {
parseDateHelper(task, m[0])
});
return true;
});
milestones.forEach(m => {
attachMilestoneMarker(m[0], m[1]);
});
```
The result is a small diamond shape at the custom field date, overlaid on the task bar without altering the task's start or end dates. This is useful for highlighting review dates, internal checkpoints, or delivery milestones.
By default the marker's label shows the field ID. To display a friendlier label, replace the `.deadline` element's title text in an `onGanttRender` event handler.
**Milestone colors require static coloring configuration**
By default, milestones inherit progress-based coloring. To apply custom colors to milestone diamonds, disable progress coloring in the Gantt Config Script with `gantt.config.show_progress_colors = false;` and use static coloring via the Item Script. See [Configure Item Colors](/gantt/guides/visualization/configure-colors) for details.
## Alternative: Use Milestone Markers
For dates that are not tied to a specific work item (such as version releases or phase deadlines), consider using **milestone markers** instead. Markers appear as vertical lines spanning the entire timeline. See [Create and Configure Markers](/gantt/guides/visualization/markers) for setup details.
## Verification
You should now see milestone diamonds on the Gantt timeline for the configured work item types or script conditions. Hover over a milestone to verify the tooltip shows the correct name and date. If you used a custom date field, confirm the diamond appears at the expected date position.
## See also
* [Create and Configure Markers](/gantt/guides/visualization/markers)
* [Configure Item Colors](/gantt/guides/visualization/configure-colors)
* [Write Item Scripts](/gantt/guides/scripting/item-script-basics)
* [Write Gantt Config Scripts](/gantt/guides/scripting/gantt-config-script)
* [Show Deadlines and Due Dates](/gantt/guides/visualization/deadlines)
# Highlight Off-Days in the Timeline
Source: https://learn.nextedy.com/gantt/guides/visualization/off-day-highlighting
Visually distinguish non-working days (weekends, holidays, and personal time off) in the Nextedy GANTT timeline by shading off-day cells with a different background color.
## How Off-Day Highlighting Works
When a working calendar is active, the Gantt chart automatically applies a visual background highlight to timeline cells that fall on non-working days. These cells receive a distinct styling that makes it easy to identify when resources are unavailable.
The highlighting applies to three layers of calendar data, each progressively more specific:
| Calendar Layer | Scope | Activation |
| ---------------------------- | ------------------------------------------- | ---------------------------------------------------- |
| **Global calendar off-days** | All resources, project-wide | Enable **Use Working Calendar** in widget properties |
| **User calendar off-days** | Per-resource (individual working calendars) | Enable **Load User Calendars** |
| **Team assignment off-days** | Per-resource (team-based availability) | Enable **Load Team Assignments** |
Open the page in edit mode and select the Gantt widget. Navigate to **Widget Properties > Working Calendars** and set **Use Working Calendar** to **Yes**.
With this setting alone, the Gantt highlights weekends and any global off-days defined in the project working calendar. These cells appear shaded in every task row and resource row.
To show per-user off-days (personal vacation, sick leave, part-time schedules), enable user calendars:
1. In **Widget Properties > Working Calendars**, set **Load User Calendars** to **Yes**.
2. Ensure each user has a Calendar work item in Polarion with their personal off-days configured.
When enabled, the Gantt applies per-resource highlighting: each resource row shows that user's specific off-days in addition to the global calendar. For example, if User A has Friday off but User B works Fridays, only User A's row highlights Fridays.
**Base Calendar Holder**
You can designate a specific user as the base calendar holder. That user's off-days serve as the baseline calendar, and other users' calendars overlay additional off-days on top. This is useful when a team shares a common schedule with individual exceptions.
For team-based resource management, you can also highlight days where a resource has zero team assignment hours:
1. In **Widget Properties > Working Calendars**, set **Load Team Assignments** to **Yes** (this option appears only when both Use Working Calendar and Load User Calendars are enabled).
2. Days where a resource has no assigned team hours are treated as unavailable and receive the off-day highlight.
**Progressive Disclosure**
The calendar widget parameters use progressive disclosure: **Load User Calendars** only appears when **Use Working Calendar** is enabled, and **Load Team Assignments** only appears when both previous options are enabled.
To change the visual style of off-day cells, add a **Script block** widget to the page with custom CSS:
```html theme={null}
```
Adjust the `background-color` value to match your project's visual standards. Lighter shades work well without obscuring task bars that span across off-days.
**Scale Level Matters**
Off-day cell highlighting is most visible at day-level (D) or two-day (DD) zoom scales. At weekly (W) or monthly (M) scales, individual off-days are aggregated into larger cells and the highlighting may not appear per-day. Use a day-level scale to verify your calendar setup.
## Working Calendar Sources
Off-days can come from several sources. The Gantt processes them in order of specificity:
## Verification
You should now see shaded cells in the Gantt timeline for non-working days. At the day-level zoom scale, weekends appear shaded by default. If you enabled user calendars, individual resource rows show that user's personal off-days as shaded cells. Grey markers in the resource view indicate days where a resource is unavailable.
## See Also
* [Load Holidays and Non-Working Days](/gantt/guides/calendars/load-holidays)
* [Load User Calendars](/gantt/guides/calendars/user-calendars)
* [Import Calendars from CSV](/gantt/guides/calendars/csv-calendar-import)
* [Configure the Time Scale](/gantt/guides/visualization/timescale)
* [Apply Custom CSS to the Gantt Widget](/gantt/guides/integration/custom-css-styling)
# Customize Progress-Related Coloring
Source: https://learn.nextedy.com/gantt/guides/visualization/progress-coloring
Adjust the default progress-based task bar colors in Nextedy GANTT to match your project's visual standards while retaining schedule-status awareness.
## Default Color Legend
Out of the box, the Gantt uses dynamic coloring to indicate schedule status:
| Color | Condition | Meaning |
| -------------- | ---------------------------------------------------------- | -------------------------------------------- |
| **Red** | End date is in the past, work item is unresolved | Overdue — should have been finished |
| **Orange** | End date is in the future, but progress is behind schedule | Delayed — progress is not keeping pace |
| **Blue** | End date is in the future, progress is on track | On track — schedule and progress are aligned |
| **Gray** | Work item is resolved | Completed |
| **Light Blue** | Start date defaults to today (no scheduled date) | Unplanned — not yet scheduled |
| **Green** | Item is set to project type via Item Script | Parent item — schedule derived from children |
Starting with version 25.10.2, the Gantt also flags tasks in red when the assigned user has no available working days during the scheduled period.
## Change Progress Colors per Widget
Override the default progress colors for a specific Gantt widget by adding the following to **Widget Properties > Advanced > Gantt Config Script**:
```javascript theme={null}
gantt.config.progress_color_overdue = "#e53935";
gantt.config.progress_color_progressdue = "#fb8c00";
gantt.config.progress_color_resolved = "#0AA33A";
```
These properties control the colors for the three progress states. The default (on-track) blue color is not configurable via a Gantt Config Script property; use `task.taskColor` in the Item Script to change it.
## Change Progress Colors Across Projects
Set default progress colors at the project or server level under **Administration > Configuration Properties**:
```
nextedy.gantt.default.progress_color_overdue=red
nextedy.gantt.default.progress_color_progressdue=orange
nextedy.gantt.default.progress_color_resolved=gray
```
These administration properties serve as the baseline that individual widgets can override via the Gantt Config Script.
## Configure Unplanned Item Colors
Unplanned items (those with no scheduled start date) have their own color properties:
```
nextedy.gantt.workitems.unplanned_color=#c7cffb
nextedy.gantt.workitems.unplanned_color_fg=#001379
```
The `unplanned_color` sets the task bar background and `unplanned_color_fg` sets the text color for unplanned items.
## Combine with Custom Item Script Colors
When using dynamic (progress-based) coloring, you can selectively override the default blue color for specific work item types using `task.taskColor` in the Item Script:
```javascript theme={null}
if (wi.getType().getId() === "portfolioepic") {
task.taskColor = "#bfbfbf";
}
```
**task.taskColor vs. task.color**
In dynamic mode, `task.taskColor` changes only the default on-track color. Overdue, delayed, and resolved items keep their progress colors. If you use `task.color` instead, it overrides all progress-based coloring for that specific item. See [Configure Item Colors](/gantt/guides/visualization/configure-colors) for the full comparison.
**Disable Progress Colors for Full Control**
If you want complete manual control over all task bar colors, disable progress coloring entirely with `gantt.config.show_progress_colors = false` in the Gantt Config Script. Then use `task.color` in the Item Script to assign colors based on any condition.
## Verify
You should now see that task bars use your customized progress colors. Overdue items appear in your configured overdue color, delayed items in your progress-due color, and resolved items in your resolved color. Unplanned items display with the configured unplanned background and foreground colors.
## See Also
* [Configure Item Colors](/gantt/guides/visualization/configure-colors)
* [Color Logic Script Examples](/gantt/guides/scripting/color-logic-scripts)
* [Write Item Scripts](/gantt/guides/scripting/item-script-basics)
* [Write Gantt Config Scripts](/gantt/guides/scripting/gantt-config-script)
* [Track and Calculate Progress](/gantt/guides/editing/progress-tracking)
# Configure Resource Allocation Marker Colors
Source: https://learn.nextedy.com/gantt/guides/visualization/resource-marker-colors
Customize the color coding of resource allocation markers in the Nextedy GANTT resource view to visually distinguish between within-capacity, over-allocated, and under-allocated states.
## Prerequisites
Before configuring marker colors, ensure the resource view is enabled on your Gantt widget. Navigate to **Widget Properties > Resource View** and set **Show Resource View** to **Yes**.
The Gantt resource view uses color-coded markers in each time cell to communicate allocation status at a glance. The default colors are:
| Allocation State | Default Color | Meaning |
| ---------------- | ------------- | ------------------------------------------------ |
| Within capacity | Green | Resource workload is at or below available hours |
| Over-allocated | Red/Orange | Resource workload exceeds available hours |
Markers are rendered with the `resource_marker resource_marker_variable_color` classes, and each cell's color is applied through an inline `--marker_color` custom property computed from the allocation value -- there are no separate `ok`/`over` element classes to target. See [Resource View CSS Classes](/gantt/reference/css-classes) for the marker DOM structure.
You can override the default marker colors by providing a custom `resourceMarkersColorConfig` object. This configuration accepts `ok` and `over` properties defining CSS color values.
Add the following to **Widget Properties > Advanced > Gantt Config Script**:
```javascript theme={null}
gantt.config.resourceMarkersColorConfig = {
ok: "#2196F3",
over: "#E53935"
};
```
This sets within-capacity markers to blue and over-allocated markers to red.
For more granular color coding, you can define multiple color thresholds using the `colors` and `percentages` arrays. The `percentages` array defines breakpoints (in ascending order), and the `colors` array defines the color for each range.
```javascript theme={null}
gantt.config.resourceMarkersColorConfig = {
percentages: [50, 100],
colors: ["#4CAF50", "#FB8C00", "#E53935"]
};
```
This configuration produces three zones:
* **0-50%** allocation: Green (`#4CAF50`)
* **50-100%** allocation: Orange (`#FB8C00`)
* **Over 100%** allocation: Red (`#E53935`)
**Array Length Constraint**
The `colors` array must contain exactly **one more element** than the `percentages` array. If the arrays are mismatched, the Gantt displays a validation error both in the wiki editor and in view mode.
**Ascending Order Required**
The `percentages` array must contain numbers in **ascending order**. Non-ascending values trigger a validation error.
To set default marker colors across all Gantt widgets in your project, navigate to **Administration > Configuration Properties** and define the color configuration there rather than in individual widget scripts.
**Per-Widget Override**
Colors set in the Gantt Config Script of a specific widget override global Configuration Properties values. Use global properties for organization-wide defaults and widget-level scripts for exceptions.
## How Resource Load Modes Affect Markers
The marker display varies depending on the configured `resourceLoadMode`:
| Load Mode | Marker Shows | Color Trigger |
| ------------ | ------------------------------- | ------------------------------- |
| `num` | Task count per resource per day | Exceeds item threshold |
| `time` | Allocated hours per day | Exceeds available working hours |
| `remaining` | Remaining capacity (hours) | Negative value (overallocation) |
| `allocation` | Percentage of capacity used | Exceeds 100% |
**Zoom Level Affects Marker Aggregation**
When you zoom out, time cells span wider date ranges. Allocation values are aggregated across the wider range, which can cause markers to appear red at lower zoom levels even if individual days are within capacity. Set your threshold values based on the zoom level your team typically uses.
## Verification
You should now see color-coded resource allocation markers in the resource view below the Gantt chart. Within-capacity cells display in your configured `ok` color, and over-allocated cells display in your configured `over` color. If you used multi-threshold colors, intermediate allocation levels display the corresponding middle color.
If you see a validation error instead of colored markers, verify that your `colors` array has exactly one more element than your `percentages` array and that percentages are in ascending order.
## See Also
* [Set Up the Resource View](/gantt/guides/resources/resource-view)
* [Configure Item Colors](/gantt/guides/visualization/configure-colors)
* [Customize Progress-Related Coloring](/gantt/guides/visualization/progress-coloring)
* [Mark Tasks Without Resource Allocation](/gantt/guides/resources/no-allocation-marking)
# Configure Right-Side Text on Task Bars
Source: https://learn.nextedy.com/gantt/guides/visualization/right-side-text
This guide shows you how to display custom text to the right of task bars in Nextedy GANTT and style it to match your project needs.
## Display a Work Item Field as Right-Side Text
To show a field value next to each task bar, you need two scripts: an **Item Script** to prepare the data and a **Gantt Config Script** to render it.
### Step 1: Prepare the data with Item Script
Navigate to **Widget Properties > Advanced > Item Script** and add a script that extracts the field you want to display. For example, to show the owner name next to Epic work items:
```javascript theme={null}
if(wi.getType().getId()==='epic'){
var o = wi.getValue("owner");
if(o!=null){
task.getFields().put("owner", o.getName());
}
}
```
You can pass any field using `task.getFields().put(KEY, VALUE)`. For example, to show multiple assignees:
```javascript theme={null}
if(wi.getType().getId()==='portfolioepic'){
var aIt = wi.getAssignees().iterator();
var assignees = "";
var separator = "";
while(aIt.hasNext()){
var assignee = aIt.next();
assignees = assignees + separator + assignee.name;
separator = ",";
}
if(assignees!=""){
task.getFields().put("assignees", assignees);
}
}
```
### Step 2: Configure the rendering template
Navigate to **Widget Properties > Advanced > Gantt Config Script** and define the `rightside_text` template:
```javascript theme={null}
gantt.templates.rightside_text = function(start, end, task){
return (task.fields.owner ? "Owner: " + task.fields.owner + " " : "");
};
```
## Show Progress as Right-Side Text
To display a progress percentage next to each task bar, combine the Item Script and Gantt Config Script:
**Item Script** (calculates progress from time tracking fields):
```javascript theme={null}
if(wi.getType().getId()==='epic'){
var all = (wi.getRemainingEstimate()!=null ? wi.getRemainingEstimate().getHours() : 0) +
(wi.getTimeSpent()!=null ? wi.getTimeSpent().getHours() : 0);
var done = (wi.getTimeSpent()!=null ? wi.getTimeSpent().getHours() : 0);
if(wi.getResolution()!=null){
task.progress = 1;
} else if(all==0){
task.progress = 0;
} else {
task.progress = done / all;
}
var progressString = "Time Spent:" + (wi.getTimeSpent()!=null ? wi.getTimeSpent() : "0h") +
" Remaining: " + (wi.getRemainingEstimate()!=null ? wi.getRemainingEstimate() : "0h") +
" completion: " + Math.round(task.progress*100) + "%";
task.getFields().put("progressString", progressString);
}
```
**Gantt Config Script**:
```javascript theme={null}
gantt.templates.rightside_text = function(start, end, task){
return (task.progress > 0 ? "Progress: " + Math.round(task.progress * 100) + " % (" +
task.fields.progressString + ") " : "");
};
gantt.config.drag_progress = false;
```
## Show Only Status Icon
To display just the work item status icon instead of text, use this Gantt Config Script:
```javascript theme={null}
gantt.templates.rightside_text = function(start, end, task){
return " ";
};
```
**Classic project view limitation**
In earlier versions, the classic project view (black summary bar) did not display right-side text even when the `rightside_text` template was set. This was fixed in version 24.11.3. Update to the latest version if right-side text is missing on project-type items.
**Prevent progress drag interference**
When displaying progress text, add `gantt.config.drag_progress = false;` to your Gantt Config Script. This disables the interactive progress drag handle so users do not accidentally change progress values while viewing the text.
## Style the Right-Side Text with CSS
To adjust the color, size, and positioning of right-side text, add a **Script - block** widget to the same page as your Gantt chart with CSS:
```html theme={null}
```
* **Positioning**: Modify `top` and `bottom` to adjust vertical alignment
* **Appearance**: Customize `color` and `font-size` to match your style
**Text clipping at end of timeline**
Right-side text on the last items in the timeline may be cut off if the text extends beyond the viewport. As a workaround, adjust the zoom level to provide more space. An improvement for automatic right-margin padding is planned for a future release.
## Verification
You should now see the configured field value displayed as text to the right of each task bar. If you styled the text with CSS, verify the color and positioning match your expectations.
## See also
* [Configure Item Colors](/gantt/guides/visualization/configure-colors)
* [Customize Text Inside Task Bars](/gantt/guides/visualization/text-inside-bars)
* [Write Gantt Config Scripts](/gantt/guides/scripting/gantt-config-script)
* [Write Item Scripts](/gantt/guides/scripting/item-script-basics)
* [Apply Custom CSS to the Gantt Widget](/gantt/guides/integration/custom-css-styling)
# Adjust Gantt Row Height
Source: https://learn.nextedy.com/gantt/guides/visualization/row-height
This guide shows you how to make Nextedy GANTT rows smaller or larger to fit more items on screen or improve readability.
## Set Row and Task Height
Navigate to **Widget Properties > Advanced > Gantt Config Script** and add the following properties:
```javascript theme={null}
gantt.config.task_height = 22;
gantt.config.row_height = 28;
```
| Property | Description | Default |
| :------------------------- | :-------------------------------------- | :------ |
| `gantt.config.task_height` | Height of the task bar in pixels | 32 |
| `gantt.config.row_height` | Height of the entire grid row in pixels | 38 |
**Task height must be smaller than row height**
Always set `task_height` to a value smaller than `row_height`. If the task bar is taller than the row, it will overlap adjacent rows and produce rendering artifacts.
## Compact Mode for Large Charts
When working with charts containing many items, reduce both values to show more rows on screen. For example, a compact configuration:
```javascript theme={null}
gantt.config.task_height = 20;
gantt.config.row_height = 22;
```
This produces a dense layout where task bars are closely packed, maximizing the number of visible items without scrolling.
For comparison, the default configuration with `task_height = 32` and `row_height = 38` provides more padding between rows and larger task bars, which improves readability when you have fewer items.
## Pair with Right-Side Text
If you are using [right-side text](/gantt/guides/visualization/right-side-text) on task bars, adjust the row height to accommodate both the task bar and the text label. A tight row height may cause text to overlap adjacent rows. Start with a configuration like:
```javascript theme={null}
gantt.config.task_height = 20;
gantt.config.row_height = 22;
```
Then increase `row_height` if the right-side text appears clipped or overlaps.
**Use fullscreen mode for large charts**
When working with compact row heights and many items, enable **Widget Properties > Advanced > Maximize** to expand the Gantt chart to fill the browser window. This maximizes the number of visible rows. See [Use Fullscreen and Maximize Mode](/gantt/guides/layout/fullscreen-mode).
## Verification
You should now see the Gantt chart rows rendered at your configured height. Compare the row spacing before and after the change to confirm the values took effect. If rows appear too cramped, increase `row_height` by a few pixels.
## See also
* [Configure Right-Side Text on Task Bars](/gantt/guides/visualization/right-side-text)
* [Configure the Time Scale](/gantt/guides/visualization/timescale)
* [Use Fullscreen and Maximize Mode](/gantt/guides/layout/fullscreen-mode)
* [Write Gantt Config Scripts](/gantt/guides/scripting/gantt-config-script)
* [Apply Custom CSS to the Gantt Widget](/gantt/guides/integration/custom-css-styling)
# Use Square Task Borders
Source: https://learn.nextedy.com/gantt/guides/visualization/square-task-borders
Switch task bar corners from rounded to square in the Nextedy GANTT chart for a more compact, traditional visual style.
## Overview
By default, task bars in the Gantt chart have slightly rounded corners. The `squareTaskBorder` configuration option removes the rounded corners (sets `border-radius` to `0px`) on both the task bar itself and the progress fill bar inside it.
To apply square borders to all Gantt widgets across the project, navigate to **Administration > Configuration Properties** and add:
```
nextedy.gantt.config.squareTaskBorder=true
```
This sets the default for all Gantt instances. The default value is `false` (rounded corners).
To enable square borders on a single Gantt widget, add the following to **Widget Properties > Advanced > Gantt Config Script**:
```javascript theme={null}
gantt.config.squareTaskBorder = true;
```
**Override Global Setting**
If square borders are enabled globally via Configuration Properties, you can override the setting for a specific widget by adding `gantt.config.squareTaskBorder = false;` to that widget's Gantt Config Script.
## What Changes
When `squareTaskBorder` is enabled, the following elements lose their rounded corners:
| Element | Rounded (default) | Square |
| ----------------- | -------------------- | -------------------- |
| Task bar | `border-radius: 2px` | `border-radius: 0px` |
| Progress fill bar | `border-radius: 2px` | `border-radius: 0px` |
**Verify in application**
The exact default border-radius value may vary by version. Enable the setting and visually confirm the change in your Gantt chart.
## When to Use Square Borders
Square borders are particularly useful in the following scenarios:
* **Dense schedules**: When many task bars are packed closely together, square corners reduce visual clutter and make row boundaries clearer.
* **Print and export**: Square borders render more consistently when exporting the Gantt chart to PNG or printing to PDF, since rounded corners can appear slightly different across renderers.
* **Corporate style guides**: Some organizations prefer a flat, angular visual style that aligns with their design standards. Square task borders provide a more traditional project management appearance.
* **Combining with other visual customizations**: When you use custom progress coloring or item color scripts, square borders create a cleaner canvas that lets the color coding stand out without the distraction of rounded edges.
**Milestone and Project Bars**
The `squareTaskBorder` setting applies specifically to standard task bars and their progress fill. Milestone items (diamond shapes) and project-type summary bars are not affected by this setting, as they use different rendering shapes.
## Verification
You should now see task bars with sharp, square corners instead of the default rounded edges. Both the outer task bar and the inner progress fill bar should have straight corners. If you enabled the setting globally, check multiple Gantt pages to confirm consistent rendering.
## See Also
* [Configure Item Colors](/gantt/guides/visualization/configure-colors)
* [Customize Text Inside Task Bars](/gantt/guides/visualization/text-inside-bars)
* [Adjust Gantt Row Height](/gantt/guides/visualization/row-height)
* [Apply Custom CSS to the Gantt Widget](/gantt/guides/integration/custom-css-styling)
# Customize Text Inside Task Bars
Source: https://learn.nextedy.com/gantt/guides/visualization/text-inside-bars
Control what text and labels appear inside and alongside task bars in the Nextedy GANTT chart, including the task label, right-side status text, and progress indicator.
## Default Text Rendering
By default, each task bar displays the work item ID and title as its label (the `text` property). The task bar also renders a progress fill bar showing the completion percentage. Optionally, a right-side text label can display additional information such as status or remaining estimate.
| Text Element | Position | Default Content |
| --------------- | ------------------------------------ | --------------------------------------------- |
| Task label | Inside the task bar | Work item ID + title |
| Progress bar | Inside the task bar (filled portion) | Percentage of completion |
| Right-side text | To the right of the task bar | Configurable (status, estimate, custom field) |
The right-side text displays a label to the right of each task bar. Configure it using the `rightside_text` template in the **Gantt Config Script**:
```javascript theme={null}
gantt.templates.rightside_text = function(start, end, task) {
return task.fields.status || "";
};
```
This displays the work item status next to each task bar. You can display any field that you populate in the Item Script.
**Show Status Icons Instead of Text**
To display only a status icon without the full status text, use the `statusIcon` field in your `rightside_text` template:
```javascript theme={null}
gantt.templates.rightside_text = function(start, end, task) {
if (task.fields && task.fields.statusIcon) {
return ' ';
}
return "";
};
```
Populate the `statusIcon` field in the **Item Script** by reading the icon URL from the work item.
To customize the appearance (color, font size, position) of the right-side text, add a **Script block** widget to the page containing your Gantt chart with the following CSS:
```html theme={null}
```
* **Positioning**: Adjust the `top` and `bottom` values to control vertical alignment relative to the task bar.
* **Appearance**: Set `color` and `font-size` to match your visual preferences.
If text appears crowded inside task bars, increase the row and task heights. Add the following to the **Gantt Config Script**:
```javascript theme={null}
gantt.config.task_height = 20;
gantt.config.row_height = 22;
```
**Task Height Must Be Smaller Than Row Height**
Always set `task_height` slightly smaller than `row_height` for proper rendering. If they are equal or task height is larger, visual artifacts may occur.
To show custom work item fields in the task bar text or right-side labels, first extract them in the **Item Script**:
```javascript theme={null}
// Extract remaining estimate for display
var remaining = wi.getValue("remainingEstimate");
if (remaining) {
task.getFields().put("remainingEstimate", remaining.toString());
}
// Extract a custom field
var priority = wi.getValue("priority");
if (priority) {
task.getFields().put("priorityLabel", priority.getName());
}
```
Then reference those fields in the Gantt Config Script templates as `task.fields.remainingEstimate` or `task.fields.priorityLabel`.
**Item Script Populates Data, Config Script Renders It**
These are two separate scripting contexts. The Item Script runs server-side for each work item and populates `task.fields`. The Gantt Config Script runs client-side and defines how those fields are rendered. Both scripts must be configured for custom text to appear.
## Verification
You should now see your customized text labels inside and alongside task bars in the Gantt chart. Right-side text displays the fields you configured, styled with your CSS customizations. Task bars show the work item label and a proportional progress fill.
## See Also
* [Configure Right-Side Text on Task Bars](/gantt/guides/visualization/right-side-text)
* [Write Item Scripts](/gantt/guides/scripting/item-script-basics)
* [Write Gantt Config Scripts](/gantt/guides/scripting/gantt-config-script)
* [Use Square Task Borders](/gantt/guides/visualization/square-task-borders)
* [Adjust Gantt Row Height](/gantt/guides/visualization/row-height)
# Configure the Time Scale
Source: https://learn.nextedy.com/gantt/guides/visualization/timescale
This guide shows you how to set the time scale (zoom level) in Nextedy GANTT to match your project planning horizon, from hour-level detail to multi-year roadmaps.
## Set the Default Scale via Widget Parameter
Navigate to **Widget Properties > Advanced > Scale** and select one of the available values:
| Scale Code | Label | Best For |
| :--------: | :------------- | :---------------------------------------- |
| `H` | Hours | Hour-precision scheduling, daily standups |
| `DD` | 2-Day | Short-term detailed planning |
| `D` | Day | Sprint-level task tracking |
| `W` | Week (default) | Sprint and iteration planning |
| `M` | Month | Release planning, quarterly views |
| `Q` | Quarter | Program-level roadmaps |
| `Y` | Year | Annual portfolio views |
| `YY` | 2-Year | Multi-year executive roadmaps |
The default scale is `W` (Week). Users see a weekly timeline header showing months over weeks when first loading the Gantt chart.
**Scale saved per user**
When a user changes the zoom level via the toolbar or menu, their preference is saved to browser local storage. On the next visit, the Gantt restores their last-used scale instead of the widget parameter default.
## Change the Scale at Runtime
Users can change the time scale without editing widget parameters using three methods:
1. **Toolbar zoom buttons** -- Click the zoom in/out buttons in the Gantt toolbar to step through available scales
2. **Hamburger menu** -- Click the ☰ icon in the first column header, then select **Set scale** and choose a level
3. **Right-click the timeline header** -- Right-click on the time scale area to open a context menu with scale options and a "Go to today" shortcut
**Bypass the custom context menu**
Press **Shift + right-click** on the timeline header to open the browser default context menu instead of the Gantt scale menu.
## Configure Scale Column Widths
You can adjust the width of timeline columns for each scale level through **Administration > Configuration Properties**:
```
nextedy.gantt.zoom.D.min_column_width=60
nextedy.gantt.zoom.W.min_column_width=30
nextedy.gantt.zoom.M.min_column_width=70
nextedy.gantt.zoom.Q.min_column_width=90
nextedy.gantt.zoom.Y.min_column_width=40
nextedy.gantt.zoom.YY.min_column_width=190
nextedy.gantt.zoom.DD.min_column_width=120
```
Increase the value to give more space to each time unit column; decrease it to fit more time periods on screen.
## Override Scale with Gantt Config Script
For advanced customization, use the **Gantt Config Script** to define custom scale rows with subscales. For example, to show a month header with week and day sub-rows:
```javascript theme={null}
gantt.config.scale_unit = "month";
gantt.config.step = 1;
gantt.config.date_scale = "%F, %Y";
gantt.config.min_column_width = 50;
gantt.config.scale_height = 90;
var weekScaleTemplate = function (date) {
var dateToStr = gantt.date.date_to_str("%d %M");
var endDate = gantt.date.add(gantt.date.add(date, 1, "week"), -1, "day");
return dateToStr(date) + " - " + dateToStr(endDate);
};
var daysStyle = function(date){
var dateToStr = gantt.date.date_to_str("%D");
if (dateToStr(date) == "Sun" || dateToStr(date) == "Sat") return "weekend";
return "";
};
gantt.config.subscales = [
{unit: "week", step: 1, template: weekScaleTemplate},
{unit: "day", step: 1, date: "%D", css: daysStyle}
];
```
**Display calendar week numbers**
To show calendar week numbers (CW format) on the time scale, use a custom `zoomConfig` script that formats the week label as `"CW" + weekNumber`. This is a common request for teams using ISO week numbering.
**Date rounding follows scale**
By default, dragging a task rounds its start and end dates to the nearest scale unit. For example, on month scale, dates round to full months. To disable this behavior, see [Disable Date Rounding on Drag](/gantt/guides/scheduling/date-rounding).
## Plans Gantt Scale
The Plans Gantt supports the same scale values as the Work Items Gantt. Plans typically use longer scales (`W`, `M`, `Y`) because plan bars span weeks or months. Set the scale in the Plans Gantt widget parameters the same way, under **Advanced > Scale**.
## Verification
You should now see the Gantt chart timeline header reflecting your configured scale. If you set `W`, the header shows months on the top row and weeks on the bottom row. Changing the zoom via toolbar buttons should cycle through the available levels.
## See also
* [Adjust Gantt Row Height](/gantt/guides/visualization/row-height)
* [Schedule in Hours Instead of Days](/gantt/guides/scheduling/hour-precision)
* [Disable Date Rounding on Drag](/gantt/guides/scheduling/date-rounding)
* [Configure the Toolbar and Menus](/gantt/guides/layout/toolbar-configuration)
* [Scroll to Today on Load](/gantt/guides/layout/scroll-to-today)
# Customize Gantt Tooltips
Source: https://learn.nextedy.com/gantt/guides/visualization/tooltips
Modify the content and behavior of hover tooltips on task bars, toolbar buttons, markers, and footer elements in the Nextedy GANTT chart.
## Default Tooltip Behavior
The Gantt chart provides several types of tooltips out of the box:
| Element | Tooltip Content | Trigger |
| ----------------------- | ------------------------------------------------------------------------------ | ---------------------------------------- |
| Task bars | Task title, dates, assignee, duration | Hover over a task bar |
| Toolbar buttons | Action description | Hover over a toolbar button |
| Milestone markers | Marker name and due date (format: `Milestone: `, `Due Date: YYYY-MM-DD`) | Hover over a milestone marker line |
| Today marker | Current date (format: `Today: YYYY-MM-DD`) | Hover over the today marker line |
| Grid column headers | Full column name | Hover over a truncated column header |
| Footer filter indicator | Active filter description (resource, date range, text) | Hover over the filter icon in the footer |
Customizing task bar tooltips requires two scripts working together: an **Item Script** to populate the data and a **Gantt Config Script** to render it.
First, add the data fields in **Widget Properties > Advanced > Item Script**:
```javascript theme={null}
// Extract fields from the Polarion work item
task.getFields().put("description", wi.getDescription() ? wi.getDescription().getContent() : "");
task.getFields().put("remainingEstimate", wi.getValue("remainingEstimate") ? wi.getValue("remainingEstimate").toString() : "N/A");
```
Then, override the tooltip template in **Widget Properties > Advanced > Gantt Config Script**:
```javascript theme={null}
gantt.templates.tooltip_text = function(start, end, task) {
return "" + task.text + " " +
" Start: " + gantt.templates.tooltip_date_format(start) +
" End: " + gantt.templates.tooltip_date_format(end) +
" Remaining: " + task.fields.remainingEstimate;
};
```
**Both Scripts Required**
The Item Script runs on the server and populates task field data. The Gantt Config Script runs on the client and renders the tooltip template. If you only configure the template without populating the fields, the tooltip displays empty or undefined values.
Milestone marker tooltips display automatically when you hover over a marker line on the timeline. The tooltip shows the marker name and due date in the following format:
```
Milestone: Release v2.0
Due Date: 2025-06-15
```
The marker tooltip content is derived from the `title` and `date` properties of each marker. To customize marker content, configure your markers with descriptive titles. See [Create and Configure Markers](/gantt/guides/visualization/markers) for details.
The Gantt footer displays a row count indicator (e.g., `Gantt Rows: 4 of 10`). When filters are active, a filter icon appears. Hovering over this icon shows a tooltip summarizing all active filters:
* **Closed items filter**: How many tasks are hidden because they are resolved
* **Date range filter**: The active start/end date range limiting visible tasks
* **Text filter**: The current search string and how many tasks it hides
* **Resource filter**: The active resource name and hidden task count
* **Marker filter**: Which marker is scoping the visible date range
These tooltips update dynamically as you apply or remove filters.
**Version Compatibility**
Tooltip script customization works best when your Gantt version matches your Polarion version. If tooltip scripts produce unexpected results after an upgrade, verify that both components are on compatible versions.
## Disabling Tooltips
To disable task bar tooltips entirely, add the following to the **Gantt Config Script**:
```javascript theme={null}
gantt.config.show_quick_info = false;
```
**Verify in application**
The exact property name to disable tooltips may vary by version. Test in your environment after applying the change.
## Verification
You should now see customized tooltip content when hovering over task bars in the Gantt chart. The tooltip displays the fields you configured in the Item Script, formatted according to your Gantt Config Script template. Milestone markers show their name and due date, and the footer tooltip describes any active filters.
## See Also
* [Write Item Scripts](/gantt/guides/scripting/item-script-basics)
* [Write Gantt Config Scripts](/gantt/guides/scripting/gantt-config-script)
* [Create and Configure Markers](/gantt/guides/visualization/markers)
* [Use Gantt Filters](/gantt/guides/filtering/gantt-filters)
* [Filter by Resource and Allocation](/gantt/guides/filtering/filter-by-resource)
# Gantt
Source: https://learn.nextedy.com/gantt/index
Project scheduling with dependencies, versioning, and resource allocation.
Welcome to the Nextedy GANTT documentation. Gantt is a project scheduling app for Siemens Polarion ALM that brings interactive project scheduling, resource management, dependency tracking, and visual timeline planning directly into your Polarion environment.
## Quick Navigation
Install Gantt, set up your first chart, and explore the demo project.
Understand architecture, scheduling modes, resource load calculations, and configuration hierarchy.
Step-by-step how-to guides for scheduling, dependencies, resources, calendars, visualization, and scripting.
Complete widget parameter lists, configuration properties, scripting API, and compatibility details.
Answers to common questions about scheduling, resources, licensing, scripting, and configuration.
## Key Features
* **Work Items Gantt** -- display Polarion work items as task bars on an interactive timeline with drag-and-drop scheduling
* **Plans Gantt** -- schedule and track Polarion Plans with cross-team and release planning views
* **Resource view** with capacity planning, multiple load calculation modes, and cross-project resource allocation
* **Working calendars** with holidays, custom working hours, and per-user calendar overrides
* **Auto-scheduling** with dependency-driven date calculation and conflict detection
* **Critical path analysis** highlighting the longest dependency chain in your project
* **Baselines** for comparing your current schedule against saved historical snapshots
* **Scripting API** for custom color logic, markers, and dynamic behavior
## Documentation Structure
| Section | Purpose | Start Here |
| ----------------------------------------------- | ------------------------------------------------------------ | ----------------------------------------------------------------------------------------- |
| [Getting Started](/gantt/getting-started/index) | Install, configure, and explore your first Gantt chart | [Install Gantt](/gantt/getting-started/installation) |
| [Concepts](/gantt/concepts/index) | Understand how scheduling, resources, and configuration work | [Product Overview](/gantt/concepts/overview) |
| [Guides](/gantt/guides/index) | Task-oriented instructions for specific features | [Configure Auto-Scheduling](/gantt/guides/scheduling/configure-auto-scheduling) |
| [Reference](/gantt/reference/index) | Look up widget parameters, properties, and API details | [Work Items Gantt Widget Parameters](/gantt/reference/widget-parameters/work-items-gantt) |
| [FAQ](/gantt/faq/index) | Quick answers to common questions | [General Questions](/gantt/faq/general) |
## Common Tasks
* [Set Up a Basic Gantt Chart](/gantt/getting-started/setup-basic-gantt) -- create your first Work Items Gantt widget
* [Create Your First Dependency Link](/gantt/getting-started/first-dependency) -- connect tasks with finish-to-start dependencies
* [View Resource Allocation](/gantt/getting-started/first-resource-view) -- enable the resource view to monitor team workload
* [Configure Item Colors](/gantt/guides/visualization/configure-colors) -- customize task bar colors based on type or status
* [Compare Schedule with Baselines](/gantt/guides/visualization/baselines-comparison) -- track schedule drift over time
* [Write Item Scripts](/gantt/guides/scripting/item-script-basics) -- add custom logic to task rendering
* [Troubleshooting Blank or Non-Loading Gantt](/gantt/guides/troubleshooting/blank-gantt) -- resolve common display issues
## Need help?
Can't find the answer here? Open a ticket and the Nextedy support team will help you out.
# Gantt Config Script API
Source: https://learn.nextedy.com/gantt/reference/api/config-script-api
The Gantt Config Script in Nextedy GANTT executes client-side JavaScript when the Gantt chart initializes.
Configure the Gantt Config Script in **Widget Parameters > Advanced > Gantt Config Script**.
## Execution Context
The Gantt Config Script runs once during chart initialization on the client side. It has access to the `gantt` object and its configuration properties.
**Execution Timing**
The Gantt Config Script executes **before** the chart renders data. Modifications to `gantt.config` and `gantt.templates` take effect on the initial render. To apply changes after initialization, call `gantt.render()`.
## Configuration Properties (gantt.config)
Control Gantt behavior by setting `gantt.config.*` properties:
### Interaction Properties
| Property | Type | Default | Description |
| ----------------------------------- | --------- | ------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `gantt.config.drag_links` | `Boolean` | `true` | Enable or disable creating dependency links by dragging between task bars. Set to `false` to prevent users from creating links. |
| `gantt.config.drag_progress` | `Boolean` | `true` | Enable or disable dragging the progress indicator on task bars. Set to `false` when progress is calculated automatically. |
| `gantt.config.show_progress_colors` | `Boolean` | `true` | Enable dynamic progress-based coloring (red, orange, blue, gray). Set to `false` for fully static coloring via `task.color`. |
### Display Properties
| Property | Type | Default | Description |
| --------------------------------- | --------- | ------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `gantt.config.workingHoursPerDay` | `Integer` | `8` | Default working hours per day for all resources. Overrides the server-side administration property for this widget instance. |
### Custom Working Hours Function
Define per-resource working hours:
```javascript theme={null}
gantt.config.workingHoursPerDayFunction = (resource) => {
if (resource === "rProject") {
return 4;
}
return 8;
};
```
**Velocity Pre-processing**
The Gantt Config Script supports Velocity expressions (`$project`, `$user`, `$trackerService`). Velocity runs on the server before the script reaches the client. Use this to dynamically build script content based on Polarion data.
## Template Functions (gantt.templates)
Override rendering templates to customize how task elements display:
### Right-Side Text
Display custom text to the right of each task bar:
```javascript theme={null}
gantt.templates.rightside_text = function(start, end, task) {
return (task.progress > 0
? "Progress: " + Math.round(task.progress * 100) + " % "
: "");
};
```
### Right-Side Text with Status Icon
```javascript theme={null}
gantt.templates.rightside_text = function(start, end, task) {
return " "
+ task.fields.statusName + " "
+ (task.progress != null ? task.fields.progressString : "");
};
```
### Status Icon Only
```javascript theme={null}
gantt.templates.rightside_text = function(start, end, task) {
return " ";
};
```
**Data Preparation**
Template functions access data prepared by the Item Script via `task.fields.*`. Prepare your data in the Item Script using `task.getFields().put(KEY, VALUE)`, then reference it in templates as `task.fields.KEY`.
## Common Configuration Patterns
### Disable Dependency Link Creation
```javascript theme={null}
gantt.config.drag_links = false;
```
### Disable Progress Dragging
```javascript theme={null}
gantt.config.drag_progress = false;
```
### Enable Static Coloring
Disable dynamic progress-based colors to use only `task.color` values set in the Item Script:
```javascript theme={null}
gantt.config.show_progress_colors = false;
```
### Combined Example
```javascript theme={null}
gantt.config.drag_progress = false;
gantt.config.show_progress_colors = false;
gantt.templates.rightside_text = function(start, end, task) {
return (task.fields.owner
? "Owner: " + task.fields.owner + " "
: "");
};
```
## REST API Endpoints
The Gantt chart communicates with the server via these REST API endpoints:
| Endpoint | Method | Description |
| ------------------------ | ------ | ---------------------------------------------------------------------------------------------------------------- |
| `gantt/api/data` | GET | Serves Gantt data (tasks, links, resources). Requires `config` query parameter. |
| `gantt/api/conf` | GET | Serves Gantt configuration data. |
| `gantt/api/fields` | GET | Returns custom field metadata for the lightbox form. |
| `api/clearCalendarCache` | GET | Clears the server-side working calendar cache. Call after modifying calendar work items when caching is enabled. |
**Authentication Required**
All Gantt API endpoints require Polarion user authentication. Anonymous access is not supported.
## Error Handling
* Script errors display as a warning indicator with a count badge in the Gantt toolbar
* **Config Script Error:** prefix identifies errors from this script
* **Markers Script Error:** prefix identifies errors from the markers script
* **Item Script Error:** prefix identifies errors from the Item Script
* Errors appear in both view mode and wiki editor mode with different messages
## Configuration Example
A complete Gantt Config Script for a project tracking view:
```javascript theme={null}
// Disable progress drag (calculated in Item Script)
gantt.config.drag_progress = false;
// Set custom working hours
gantt.config.workingHoursPerDay = 7;
// Custom right-side text showing progress info
gantt.templates.rightside_text = function(start, end, task) {
return " "
+ task.fields.statusName + " "
+ (task.progress != null ? task.fields.progressString : "");
};
```
## Related Pages
* [Item Script API](/gantt/reference/api/item-script-api) -- server-side script for data preparation
* [Velocity Context Variables](/gantt/reference/api/velocity-context) -- server-side variables for dynamic script generation
* [Item Color Legend](/gantt/reference/item-color-legend) -- how `show_progress_colors` affects task colors
* [Default Configuration Values](/gantt/reference/configuration/default-values) -- server-level property defaults
* [Dependency Types Reference](/gantt/reference/dependency-types) -- advanced dependency link types
# Scripting API
Source: https://learn.nextedy.com/gantt/reference/api/index
Nextedy GANTT provides a scripting API that enables you to customize Gantt chart behavior, appearance, and data processing.
Access and modify task properties and Polarion work item data during server-side data loading. Control colors, labels, progress, and field values per work item.
Configure client-side Gantt behavior including templates, event handlers, drag settings, and visual properties. Runs once when the chart initializes.
Add vertical milestone markers to the Gantt timeline. Create markers from Polarion plans, work items, or custom dates with configurable labels and colors.
Define user-input parameters accessible in the maximized Gantt view toolbar. Use parameter values in Item Scripts for dynamic filtering and behavior.
Access Polarion server-side variables in script pre-processing. Use project, user, and service objects to generate dynamic script content.
**Script Execution Order**
Velocity context variables are resolved first (server-side), then Item Scripts execute per work item during data loading, and finally the Gantt Config Script runs once on the client when the chart initializes. The Marker Factory executes alongside Item Scripts on the server.
## Related Pages
* [Widget Parameters](/gantt/reference/widget-parameters/index) -- configure scripts via widget parameter fields
* [Configuration Properties](/gantt/reference/configuration/index) -- global administration properties
* [Item Color Legend](/gantt/reference/item-color-legend) -- default color behavior that scripts can override
# Item Script API (Task and Work Item Objects)
Source: https://learn.nextedy.com/gantt/reference/api/item-script-api
The Item Script in Nextedy GANTT executes server-side JavaScript for each work item during data loading.
Configure the Item Script in **Widget Parameters > Advanced > Item Script**.
## Script Variables
The following variables are available in the Item Script scope:
| Variable | Type | Description |
| ------------------ | -------------------- | ------------------------------------------------------------------------------------------------------------ |
| `task` | Task object | The Gantt task being prepared for client rendering. Modify its properties to change appearance and behavior. |
| `wi` | IWorkItem | The source Polarion work item. Read work item fields, status, type, assignees, and linked items. |
| `item` | IWorkItem | Alias for `wi` -- the same source work item object. |
| `plan` | IPlan | The source Polarion plan (Plans Gantt only). Access plan dates, template ID, and contained work items. |
| `trackerService` | ITrackerService | Polarion tracker service for querying work items via Lucene queries. |
| `ganttDataService` | IGanttDataService | Gantt data service for accessing Gantt-specific data and helpers. |
| `config` | Configuration object | The current Gantt configuration, including page parameters. |
| `util` | Utility helper | Helper methods for date conversion and plan schedule derivation. |
**Polarion 2304+ Scripting Changes**
Since Polarion version 2304, the scripting engine requires getter methods instead of direct property access. Use `wi.getType().getId()` instead of `wi.type.id`. Use `typeof wi !== 'undefined'` instead of `wi != null` for existence checks.
## Task Object Properties
The `task` object represents a Gantt chart task. You can read and modify these properties:
| Property | Type | Default | Description |
| ----------------- | --------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `task.id` | `String` | *from work item* | Unique task identifier derived from the Polarion work item ID. |
| `task.text` | `String` | *from work item* | Display label combining the work item ID and title. |
| `task.start_date` | `Date` | *from configured field* | Task start date. Set to override the configured start field value. |
| `task.duration` | `Integer` | `10` | Task duration in days (or hours in high-precision mode). |
| `task.progress` | `Float` | *from configured field* | Completion percentage as a decimal (0.0 to 1.0). |
| `task.parent` | `String` | *from parent link* | ID of the parent task in the hierarchy. |
| `task.type` | `String` | *from configuration* | Gantt task type: `task` (normal bar), `project` (summary bar derived from children), or `milestone` (diamond shape, zero duration). |
| `task.color` | `String` | `null` | Static CSS color for the task bar. Overrides all dynamic coloring including progress-based colors. |
| `task.taskColor` | `String` | `null` | Dynamic CSS color for the task bar. Only overrides the default blue color; does not affect progress-based colors (red, orange, gray). |
| `task.itemId` | `String` | *from work item* | Polarion work item ID (e.g., `WI-123`). |
| `task.projectId` | `String` | *from work item* | Polarion project ID containing the work item. |
| `task.readonly` | `Boolean` | `false` | When `true`, prevents the task from being dragged or resized. |
| `task.unplanned` | `Boolean` | `false` | When `true`, marks the task as unplanned (no scheduled dates). |
| `task.open` | `Boolean` | `true` | Controls whether a parent (summary) task is expanded. Set to `false` to render the item collapsed when the Gantt chart loads. |
| `task.hide` | `Boolean` | `false` | When `true`, hides the task from the chart. Use for conditional filtering beyond what the widget query provides. |
| `task.url` | `String` | *generated* | URL to the Polarion work item. |
### Custom Fields Map
Pass additional data to the client using `task.getFields()`:
```javascript theme={null}
task.getFields().put("myField", "myValue");
```
Access the value on the client side (e.g., in Gantt Config Script templates):
```javascript theme={null}
task.fields.myField
```
## Color Logic
There are two color properties with different behavior:
| Property | Behavior | Use Case |
| ---------------- | --------------------------------------------------------------------- | ----------------------------------------------------------------- |
| `task.color` | **Static** -- overrides ALL colors, including progress-based coloring | Force a specific color regardless of task status |
| `task.taskColor` | **Dynamic** -- only overrides the default blue color | Change color while preserving red/orange/gray progress indicators |
**Static vs. Dynamic Coloring**
Use `task.taskColor` when you want to keep progress-based color indicators (red for overdue, orange for delayed, gray for resolved). Use `task.color` only when you want to force a specific color regardless of progress status. To use fully static coloring, also set `gantt.config.show_progress_colors=false` in the Gantt Config Script.
### Color by Assignee Example
```javascript theme={null}
var assignee = null;
var aIterator = wi.getAssignees().iterator();
if (aIterator.hasNext()) {
assignee = aIterator.next();
if (assignee && assignee.id === "yourAssigneeId") {
task.taskColor = "#a9d08e";
}
}
```
### Color by Type and Status Example
```javascript theme={null}
// Requires gantt.config.show_progress_colors=false in Config Script
if (wi.getType().getId() === "workpackage" && wi.getStatus().getId() === "draft") {
var today = new Date();
if (task.start_date.getTime() < today.getTime()) {
task.color = "green";
}
}
```
## Progress Calculation
Compute progress from time estimates:
```javascript theme={null}
if (wi.getType().getId() === 'workpackage') {
var all = (wi.getRemainingEstimate() != null ? wi.getRemainingEstimate().getHours() : 0)
+ (wi.getTimeSpent() != null ? wi.getTimeSpent().getHours() : 0);
var done = (wi.getTimeSpent() != null ? wi.getTimeSpent().getHours() : 0);
if (wi.getResolution() != null) {
task.progress = 1;
} else if (all == 0) {
task.progress = 0;
} else {
task.progress = done / all;
}
var progressString = (wi.getTimeSpent() != null ? wi.getTimeSpent() : "0h")
+ " | " + (wi.getRemainingEstimate() != null ? wi.getRemainingEstimate() : "0h")
+ " (" + Math.round(task.progress * 100) + " %)";
task.getFields().put("progressString", progressString);
}
```
## Milestone Configuration
Set a task to render as a milestone diamond:
```javascript theme={null}
if (wi.getType().getId() === "release" && wi.getStatus().getId() === "inprogress") {
task.type = "milestone";
}
```
## Schedule Derivation from Plans
Derive a task's schedule from its Polarion plan assignment:
```javascript theme={null}
if (task.unplanned) {
task.deriveScheduleFromPlans(wi, "iteration");
}
```
Manual plan schedule derivation:
```javascript theme={null}
var plans = wi.getPlannedIn().iterator();
while (plans.hasNext()) {
var plan = plans.next();
if (plan.getTemplate().getId() === "Iteration") {
task.start_date = util.getDate(plan, "startDate");
task.end_date = util.getDate(plan, "dueDate");
task.duration = null;
task.readonly = true;
task.unplanned = false;
}
}
```
## Baseline Comparison
Set custom baseline values for schedule comparison:
```javascript theme={null}
task.planned_start_date = util.getDate(wi, "gantt_initial_start");
task.planned_duration = util.getDuration(wi, "gantt_initial_duration");
```
## Passing Data to Right-Side Text
Prepare data in the Item Script, then render it in the Gantt Config Script:
**Item Script:**
```javascript theme={null}
if (wi.getType().getId() === 'epic') {
var o = wi.getValue("owner");
if (o != null) {
task.getFields().put("owner", o.getName());
}
}
```
**Gantt Config Script:**
```javascript theme={null}
gantt.templates.rightside_text = function(start, end, task) {
return (task.fields.owner ? "Owner: " + task.fields.owner + " " : "");
};
```
## Script Execution Flow
## Error Handling
* Script errors display as a warning indicator in the Gantt chart toolbar
* The error message includes the prefix **Item Script Error:**
* Add null checks before accessing work item properties: `if (wi != null) { ... }`
* On Polarion 2304+, use `typeof wi !== 'undefined'` for existence checks
## Configuration Example
A complete Item Script combining progress calculation, color logic, and right-side text:
```javascript theme={null}
// Guard against null work items
if (wi != null) {
// Calculate progress from time estimates
var all = (wi.getRemainingEstimate() != null ? wi.getRemainingEstimate().getHours() : 0)
+ (wi.getTimeSpent() != null ? wi.getTimeSpent().getHours() : 0);
var done = (wi.getTimeSpent() != null ? wi.getTimeSpent().getHours() : 0);
if (wi.getResolution() != null) {
task.progress = 1;
} else if (all == 0) {
task.progress = 0;
} else {
task.progress = done / all;
}
// Set epics as project items
if (wi.getType().getId() === 'epic') {
task.type = 'project';
}
// Derive unplanned items from iteration plan
if (task.unplanned) {
task.deriveScheduleFromPlans(wi, "iteration");
}
}
```
## Related Pages
* [Gantt Config Script API](/gantt/reference/api/config-script-api) -- client-side script for templates and events
* [Velocity Context Variables](/gantt/reference/api/velocity-context) -- server-side variables available in script pre-processing
* [Item Color Legend](/gantt/reference/item-color-legend) -- default color behavior and how scripts override it
* [Page Parameters API](/gantt/reference/api/page-parameters-api) -- access user-input parameters in scripts
* [Marker Factory API](/gantt/reference/api/markers-api) -- add milestone markers from scripts
# Marker Factory API
Source: https://learn.nextedy.com/gantt/reference/api/markers-api
The Marker Factory API in Nextedy GANTT provides server-side methods for adding vertical milestone markers to the Gantt chart timeline.
Configure the Markers Script in **Widget Parameters > Advanced > Markers Script**.
## Script Variables
The following variables are available in the Markers Script scope:
| Variable | Type | Description |
| ---------------- | -------------------- | ---------------------------------------------------------------------------------- |
| `markerFactory` | MarkerFactory | Factory object for creating and registering timeline markers. |
| `trackerService` | ITrackerService | Polarion tracker service for querying work items and projects via Lucene queries. |
| `config` | Configuration object | The current Gantt configuration, including page parameters and context project ID. |
## MarkerFactory Methods
| Method | Return Type | Description |
| -------------------------------------------------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------- |
| `markerFactory.addMarker()` | Marker | Create and register a new empty marker object. Set its properties using the marker methods below. |
| `markerFactory.addMarker(text, date)` | Marker | Utility method that creates a marker with the specified text label and date string. Date format: `"YYYY-MM-DD"`. |
| `markerFactory.addPlanMarkers(query, color)` | void | Query Polarion plans matching the Lucene query and add a marker for each plan's start or end date. |
| `markerFactory.addWorkItemMarkers(query, dateProperty, color)` | void | Query Polarion work items matching the Lucene query and add a marker for each work item using the specified date property. |
## Marker Object Methods
The marker object returned by `addMarker()` provides these methods:
| Method | Parameter Type | Description |
| -------------------------- | ---------------- | --------------------------------------------------------------------------------------------------------------------- |
| `marker.setText(text)` | `String` | Set the text label displayed on the marker line. |
| `marker.setTitle(tooltip)` | `String` | Set the tooltip text displayed when hovering over the marker. |
| `marker.setDate(date)` | `java.util.Date` | Set the marker date using a Java Date object. |
| `marker.setDate(dateStr)` | `String` | Set the marker date using a date string. Format: `"YYYY-MM-DD"`. |
| `marker.setColor(color)` | `String` | Set the marker color. Must be one of the 16 basic HTML color names (e.g., `"red"`, `"blue"`, `"green"`, `"fuchsia"`). |
**Marker Tooltip Format**
Hovering over a milestone marker displays a tooltip in the format:
`Milestone: ` followed by `Due Date: `.
## Marker Positioning
Markers render at the **end of the specified date** by convention. If you need a marker to appear at the start of a date, subtract one day from the date value.
**End-of-Day Rendering**
By design, a marker set to `"2025-08-04"` renders at the end of August 4th. To position it at the start of August 4th, set the date to `"2025-08-03"` instead.
## Manually Adding a Marker
Create a marker with explicit values:
```javascript theme={null}
var marker = markerFactory.addMarker();
marker.setText("20.0");
marker.setDate("2025-08-04");
marker.setColor("green");
```
Using the shorthand method:
```javascript theme={null}
markerFactory.addMarker("test", "2019-01-30");
```
## Adding Markers from Plans
Pull markers automatically from Polarion plans matching a Lucene query:
```javascript theme={null}
markerFactory.addPlanMarkers("template.id:iteration AND project.id:gantt2", "blue");
```
* `template.id:iteration` -- filters plans by template ID
* `project.id:gantt2` -- restricts to a specific project
Plan-based markers receive the CSS class `plan`, enabling distinct visual styling.
## Adding Markers from Work Items
Pull markers from Polarion work items matching a Lucene query:
```javascript theme={null}
markerFactory.addWorkItemMarkers("type:release AND project.id:gantt2", "publicLaunch", "blue");
```
* `type:release` -- filters work items by type
* `"publicLaunch"` -- the date field on the work item used to position the marker
* `"blue"` -- the marker color
### Dynamic Project ID
Use `config.getContextProjectId()` to reference the current project instead of hardcoding:
```javascript theme={null}
markerFactory.addWorkItemMarkers(
"type:release AND project.id:" + config.getContextProjectId(),
"publicLaunch",
"blue"
);
```
## Dynamic Markers with Polarion API
Use `trackerService` for full scripting control over marker creation. This approach supports filtering, conditional coloring, and custom tooltip content.
### Loading Time Points
```javascript theme={null}
var timePoints = trackerService.getTrackerProject("GANTT").getTimePoints().iterator();
while (timePoints.hasNext()) {
var tp = timePoints.next();
var marker = markerFactory.addMarker();
marker.setText(tp.getName());
marker.setDate(tp.getTime().getDate());
marker.setColor("fuchsia");
var desc = tp.getDescription();
if (desc != null) {
marker.setTitle(desc.getContent());
}
}
```
**Polarion 2304+ Scripting Changes**
Since Polarion version 2304, use getter methods instead of direct property access. Use `tp.getName()` instead of `tp.name`. Use `tp.getTime().getDate()` instead of `tp.time.date`.
### Polarion 22 R2 and Older
For older Polarion versions, use direct property access:
```javascript theme={null}
var timePoints = trackerService.getTrackerProject("GANTT").getTimePoints().iterator();
while (timePoints.hasNext()) {
var tp = timePoints.next();
var marker = markerFactory.addMarker();
marker.setText(tp.name);
marker.setDate(tp.time.date);
marker.setColor("fuchsia");
var desc = tp.description;
if (desc != null) {
marker.setTitle(desc.content);
}
}
```
## Dynamic Marker Customization with Page Parameters
Combine `trackerService` with page parameters to let users control which markers appear:
```javascript theme={null}
var milestoneIds = config.pageParameters.milestone;
if (milestoneIds === null) {
milestoneIds = "";
} else {
milestoneIds = milestoneIds.replaceAll(',', ' ');
}
var milestones = trackerService.queryWorkItems(
"project.id:Gantt3 AND type:milestone AND id:(" + milestoneIds + ")", "id"
).iterator();
while (milestones.hasNext()) {
var tp = milestones.next();
var marker = markerFactory.addMarker();
marker.setText(tp.getTitle());
marker.setDate(tp.getValue('releaseDate').getDate());
var productType = tp.getValue('productType');
marker.setColor("blue");
if (productType !== null && productType.getId() === 'typeB') {
marker.setColor("fuchsia");
}
}
```
## Marker CSS Classes
| CSS Class | Applied To | Description |
| -------------------------------- | -------------- | --------------------------------------------------- |
| `gantt_marker` | All markers | Base class applied to every marker element. |
| `today` | Today marker | Applied to the automatic today-date marker line. |
| `plan` | Plan markers | Applied to markers created by `addPlanMarkers()`. |
| Named color class (e.g., `blue`) | Custom markers | Applied when a color is specified via `setColor()`. |
## Error Handling
* Script errors display as a warning indicator with a count badge in the Gantt toolbar
* The error message includes the prefix **Markers Script Error:**
* Errors appear in both view mode and wiki editor mode
## Configuration Example
A complete Markers Script combining plan markers, work item markers, and a manual milestone:
```javascript theme={null}
// Add iteration boundary markers
markerFactory.addPlanMarkers(
"template.id:iteration AND project.id:" + config.getContextProjectId(),
"blue"
);
// Add release markers from work items
markerFactory.addWorkItemMarkers(
"type:release AND project.id:" + config.getContextProjectId(),
"start",
"red"
);
// Add a manual milestone
var marker = markerFactory.addMarker();
marker.setText("Go-Live");
marker.setDate("2025-12-01");
marker.setColor("green");
```
## Related Pages
* [Item Script API](/gantt/reference/api/item-script-api) -- server-side script for data preparation
* [Gantt Config Script API](/gantt/reference/api/config-script-api) -- client-side script for templates and events
* [Velocity Context Variables](/gantt/reference/api/velocity-context) -- server-side variables for dynamic script generation
* [Page Parameters API](/gantt/reference/api/page-parameters-api) -- user-input parameters for dynamic marker filtering
* [Item Color Legend](/gantt/reference/item-color-legend) -- default color behavior for task bars
# Page Parameters API
Source: https://learn.nextedy.com/gantt/reference/api/page-parameters-api
The Page Parameters API in Nextedy GANTT enables user-input parameters accessible from the maximized Gantt view toolbar.
**Since version 4.6.0.**
## How Page Parameters Work
Page parameters are standard Polarion Rich Page parameters placed on the same wiki page as the Gantt widget. When the Gantt runs in maximized mode, a **Settings** button appears in the toolbar that opens the Page Parameters panel, allowing users to modify parameter values without editing the wiki page.
**Query Type Requirement**
Page Parameters only work with the **Lucene + Velocity** query type. They do not work with pure Lucene queries. Set your Gantt query type to "Lucene + Velocity" when using page parameters.
## Setup Steps
1. Add a **Page Parameters** widget to the top of your wiki page
2. Add the **Gantt widget** below it (keep Maximized turned **OFF** initially)
3. Define your page parameters in the Page Parameters widget
4. Reference the page parameters in your Gantt widget parameters using Velocity syntax
5. Test that the page works correctly with the parameters
6. Turn the **Maximized** option **ON** in the Gantt widget parameters
Once maximized, the **Settings** action appears in the Gantt toolbar, allowing users to modify page parameters directly from the Gantt view.
## Accessing Page Parameters in Item Script
Read page parameter values in the Item Script using the `config` object:
```javascript theme={null}
config.getPageParameters().get("pageParamId");
```
Replace `"pageParamId"` with the ID of the page parameter you defined in the Page Parameters widget.
**Two equivalent accessor forms**
`config` exposes page parameters two equivalent ways: the method form `config.getPageParameters().get("id")` (used here) and the shorthand property form `config.pageParameters.` (used in the Markers Script examples below). Both read the same values -- use whichever reads better.
### Example: Filter by Version
```javascript theme={null}
var versionParam = config.getPageParameters().get("version");
if (versionParam != null && wi.getType().getId() === "feature") {
var targetVersion = wi.getValue("targetVersion");
if (targetVersion != null && targetVersion.getId() !== versionParam) {
task.hide = true;
}
}
```
## Accessing Page Parameters in Markers Script
Page parameters are also available in the Markers Script for dynamic marker filtering:
```javascript theme={null}
var milestoneIds = config.pageParameters.milestone;
if (milestoneIds === null) {
milestoneIds = "";
} else {
milestoneIds = milestoneIds.replaceAll(',', ' ');
}
var milestones = trackerService.queryWorkItems(
"project.id:" + config.getContextProjectId()
+ " AND type:milestone AND id:(" + milestoneIds + ")", "id"
).iterator();
while (milestones.hasNext()) {
var tp = milestones.next();
var marker = markerFactory.addMarker();
marker.setText(tp.getTitle());
marker.setDate(tp.getValue('releaseDate').getDate());
marker.setColor("blue");
}
```
## Page Parameters Panel API
The Page Parameters panel provides methods for programmatic control:
| Method | Return Type | Description |
| -------------------------------------- | ----------- | ----------------------------------------------------------------------- |
| `NextedyPageParamsApi.show()` | void | Open the widget parameter editor panel. |
| `NextedyPageParamsApi.close()` | void | Close the widget parameter editor panel. |
| `NextedyPageParamsApi.load(params)` | void | Load specific parameter values into the editor panel. |
| `NextedyPageParamsApi.anyParams()` | `Boolean` | Return `true` if the Gantt widget has any configurable page parameters. |
| `NextedyPageParamsApi.isVisible()` | `Boolean` | Return `true` if the parameter editor panel is currently open. |
| `NextedyPageParamsApi.setHeader(text)` | void | Set the header text of the parameter editor panel. |
**Verify in application**
The `NextedyPageParamsApi` methods are available on the client side for advanced customization. Typical usage relies on the built-in toolbar button rather than direct API calls.
## Toolbar Button Behavior
| Condition | Toolbar Button |
| ---------------------------------------------------- | ------------------------------------------ |
| Gantt is in maximized mode AND page parameters exist | **Settings** button (gear icon) is visible |
| Gantt is not maximized | Settings button is hidden |
| `MaximizeGanttView=false` URL parameter is set | Settings button is hidden |
| No page parameters defined on the wiki page | Settings button is hidden |
The Page Parameters panel opens as a scrollable dialog overlay (maximum height 80% of viewport). Close it by clicking the X button or pressing **Escape**.
## Configuration Example
A wiki page setup with a page parameter for version filtering:
**Page Parameters Widget:** Define a parameter with ID `version` and type `String`.
**Gantt Widget Parameters:**
* **Query:** `type:feature AND version:$version` (Lucene + Velocity query type)
* **Maximized:** ON
**Item Script** (optional additional filtering):
```javascript theme={null}
var versionParam = config.getPageParameters().get("version");
if (versionParam != null) {
task.getFields().put("targetVersion", versionParam);
}
```
**Gantt Config Script** (display version in right-side text):
```javascript theme={null}
gantt.templates.rightside_text = function(start, end, task) {
return (task.fields.targetVersion
? "Version: " + task.fields.targetVersion + " "
: "");
};
```
## Related Pages
* [Item Script API](/gantt/reference/api/item-script-api) -- `config.getPageParameters()` usage in server-side scripts
* [Marker Factory API](/gantt/reference/api/markers-api) -- using page parameters for dynamic marker filtering
* [Velocity Context Variables](/gantt/reference/api/velocity-context) -- server-side variables available alongside page parameters
* [Gantt Config Script API](/gantt/reference/api/config-script-api) -- client-side templates that display parameter-based data
* [Work Items Gantt Widget Parameters](/gantt/reference/widget-parameters/work-items-gantt) -- Maximize and query type settings
* [URL Parameters Reference](/gantt/reference/url-parameters) -- `MaximizeGanttView` URL parameter
# Velocity Context Variables
Source: https://learn.nextedy.com/gantt/reference/api/velocity-context
Nextedy GANTT supports Apache Velocity pre-processing for all script parameters (Item Script, Gantt Config Script, and Markers Script).
**Verify in application**
This page has limited source coverage. Variable availability and behavior should be verified against your Polarion version.
## Velocity Pre-processing Flow
Velocity expressions use the `$variable` syntax. The Velocity engine replaces these with actual values from the Polarion server context before any script logic runs.
## Available Context Variables
| Variable | Type | Description |
| ----------------- | --------------- | -------------------------------------------------------------------------------------------------- |
| `$project` | IProject | The current Polarion project context. Access project metadata, configuration, and related objects. |
| `$user` | IUser | The currently authenticated Polarion user. Access user ID, name, roles, and preferences. |
| `$trackerService` | ITrackerService | Polarion tracker service for querying work items, projects, and time points via Lucene queries. |
**Verify in application**
Additional Velocity context variables may be registered by Polarion extensions. The variables listed above are confirmed from the Gantt configuration. Check your Polarion instance for the complete set of available Velocity context objects.
## Usage in Item Script
Velocity expressions in the Item Script are resolved on the server before the script executes per work item. Use Velocity to inject server-side data into your script logic:
```javascript theme={null}
// Velocity resolves $project.id before script execution
var currentProject = "$project.id";
if (wi.getType().getId() === "feature") {
task.getFields().put("projectName", "$project.name");
}
```
## Usage in Gantt Config Script
Velocity expressions in the Gantt Config Script are resolved on the server before the script is sent to the client browser:
```javascript theme={null}
// Server resolves $user.id, client receives the actual user ID string
var currentUser = "$user.id";
gantt.templates.rightside_text = function(start, end, task) {
if (task.fields.owner === currentUser) {
return "Assigned to you ";
}
return "";
};
```
## Usage in Markers Script
Velocity expressions in the Markers Script are resolved before marker creation logic runs:
```javascript theme={null}
// Dynamic project reference via Velocity
var timePoints = trackerService.getTrackerProject("$project.id").getTimePoints().iterator();
while (timePoints.hasNext()) {
var tp = timePoints.next();
var marker = markerFactory.addMarker();
marker.setText(tp.getName());
marker.setDate(tp.getTime().getDate());
marker.setColor("blue");
}
```
## Common Patterns
### Dynamic Project ID
Avoid hardcoding project IDs by using Velocity:
```javascript theme={null}
// Instead of: "project.id:MyProject"
var query = "project.id:$project.id AND type:release";
var releases = trackerService.queryWorkItems(query, "id").iterator();
```
### User-Specific Behavior
Customize Gantt behavior based on the current user:
```javascript theme={null}
var userId = "$user.id";
if (wi.getAssignees() != null) {
var aIterator = wi.getAssignees().iterator();
while (aIterator.hasNext()) {
var assignee = aIterator.next();
if (assignee.getId() === userId) {
task.taskColor = "#a9d08e";
}
}
}
```
### Conditional Script Sections
Use Velocity directives to include or exclude entire script blocks:
```velocity theme={null}
#if($project.id == "CriticalProject")
gantt.config.drag_links = false;
gantt.config.drag_progress = false;
#end
```
**Velocity vs. JavaScript**
Velocity expressions (`$variable`, `#if`, `#foreach`) are processed on the server and produce plain text output. JavaScript logic (`if`, `for`, `var`) executes afterward. Do not confuse the two -- Velocity runs first and generates the JavaScript that will run.
## Escaping
The Velocity-resolved script output is escaped for safe embedding in the page. Backslashes, single quotes, and newlines are automatically handled. You do not need to manually escape these characters in your Velocity expressions.
## Configuration Example
A complete Item Script combining Velocity context with JavaScript logic:
```javascript theme={null}
// Velocity injects the current project and user
var projectId = "$project.id";
var currentUser = "$user.id";
if (wi != null) {
// Highlight tasks assigned to the current user
var aIterator = wi.getAssignees().iterator();
while (aIterator.hasNext()) {
var assignee = aIterator.next();
if (assignee.getId() === currentUser) {
task.taskColor = "#a9d08e";
task.getFields().put("myTask", "true");
}
}
// Set project-specific defaults
task.getFields().put("sourceProject", projectId);
}
```
## Related Pages
* [Item Script API](/gantt/reference/api/item-script-api) -- server-side script where Velocity variables are most commonly used
* [Gantt Config Script API](/gantt/reference/api/config-script-api) -- client-side script with Velocity pre-processing
* [Marker Factory API](/gantt/reference/api/markers-api) -- Markers Script with Velocity support
* [Page Parameters API](/gantt/reference/api/page-parameters-api) -- user-input parameters accessible alongside Velocity variables
# Polarion Version Compatibility Matrix
Source: https://learn.nextedy.com/gantt/reference/compatibility-matrix
Nextedy GANTT is an app for Siemens Polarion ALM. This page documents version compatibility between Gantt releases and Polarion versions, including known migration requirements.
**Verify in application**
Always verify compatibility with your specific Polarion and Gantt versions before upgrading in production. Contact Nextedy support for the latest compatibility information.
## Compatibility Overview
| Polarion Version | Minimum Gantt Version | Notes |
| ---------------- | --------------------- | ------------------------------------------------ |
| Polarion 2310 | 24.6.0 | Fully compatible; update Gantt to latest version |
| Polarion 2404 | See application | Compatible with latest Gantt versions |
| Polarion 2506 | 25.9.0 | Compatibility issues fixed in v25.9.0 |
**Upgrade Requirement**
When upgrading Polarion, always update to the latest Gantt version to ensure full compatibility. Older Gantt versions may not function correctly with newer Polarion releases.
## Scripting API Changes (Polarion 2304+)
Starting with Polarion 2304, changes to the Polarion scripting environment require script migration for Gantt page scripts and config scripts.
| Change | Impact | Action Required |
| ------------------------ | --------------------------------------------------------- | ------------------------------------------------------------------- |
| Scripting API changes | Existing page scripts and config scripts may stop working | Review and update custom scripts after Polarion upgrade |
| Script execution context | Modified execution environment for Velocity scripts | Test all scripts in a staging environment before production upgrade |
**Test Before Upgrading**
Use a test license to validate your Gantt configuration and scripts against the new Polarion version before applying the upgrade to production. See [License Types and Evaluation Periods](/gantt/reference/license-types) for test license information.
## Upgrade Workflow
## Known Compatibility Issues
### Polarion 2506
| Issue | Symptom | Resolution |
| ------------------------- | --------------------------------------- | -------------------------------- |
| Workflow field regression | Log file errors after upgrade | Fixed in Gantt v25.9.0 |
| Log errors | Server log errors after Polarion update | Update Gantt to v25.9.0 or later |
### Polarion 2310
| Issue | Symptom | Resolution |
| --------------------- | ---------------------------------- | ------------------------------------------------------- |
| Older Gantt versions | Scripts stop working after upgrade | Update Gantt to v24.6.0 or later |
| Scripting API changes | Custom scripts fail to execute | Migrate scripts to updated API (Polarion 2304+ changes) |
## Version Identification
You can identify the installed Gantt version from the Gantt footer. The version number is displayed in the bottom-right corner of the Gantt chart widget.
| Location | Description |
| ------------ | ------------------------------------------------------------------------------------ |
| Gantt footer | Version string (e.g. `25.9.0`) displayed at the bottom of the widget |
| Admin page | Navigate to `/polarion/#/administration/gantt/setup` for version and license details |
## Pre-Upgrade Checklist
| Step | Action |
| ---- | ------------------------------------------------------------------------------------ |
| 1 | Verify target Polarion version compatibility with current Gantt version |
| 2 | Download the latest Gantt version from Nextedy |
| 3 | Install Gantt update in a staging environment |
| 4 | Test all custom scripts (config scripts, item scripts, page scripts, marker scripts) |
| 5 | Verify working calendar calculations |
| 6 | Validate dependency link behavior |
| 7 | Confirm resource view accuracy |
| 8 | Apply to production |
## Workflow Condition Compatibility
The Gantt provides a workflow condition that integrates with Polarion workflow enforcement. This condition is dependency-type-aware:
| Feature | Description |
| ---------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| Status gate enforcement | Prevents work item transitions unless linked predecessors are in allowed states |
| Dependency-type filtering | Only Finish-to-Start dependencies are enforced in forward checks; Start-to-Start and Start-to-Finish are excluded |
| Cross-permission enforcement | Dependency gates are enforced even when linked items are not visible to the current user |
**Workflow Condition Parameters**
Configure the workflow condition in Polarion's workflow XML with these parameters: `link.roles` (forward link roles), `back.link.roles` (reverse link roles), and `valid.states` (allowed status IDs). See [General Administration Properties](/gantt/reference/configuration/general-properties).
## Configuration Example
Verify the installed Gantt version by checking the footer or navigating to the admin page:
```
https://your-polarion.example.com/polarion/#/administration/gantt/setup
```
## Related Pages
* [Install Gantt](/gantt/getting-started/installation) -- installation and update instructions
* [Update to the Latest Version](/gantt/getting-started/update-gantt) -- step-by-step update tutorial
* [License Types and Evaluation Periods](/gantt/reference/license-types) -- test license for upgrade validation
* [Error Messages and Diagnostics](/gantt/reference/error-messages) -- diagnosing post-upgrade issues
# Calendar and Working Hours Properties
Source: https://learn.nextedy.com/gantt/reference/configuration/calendar-properties
Nextedy GANTT uses working calendars to define resource availability, working hours, and schedule exceptions.
Set these properties in **Administration > Configuration Properties**.
## Calendar Project Properties
| Name | Type | Default | Description |
| ------------------------------------------ | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `nextedy.gantt.workitemCalendar.projectId` | `String` | *empty* | Polarion project ID where work item calendars (per-user and global) are stored. Must be set on both the calendar project and any projects that reference it. |
| `nextedy.gantt.workitemCalendar.globalID` | `String` | *empty* | Work item ID of a `calendar` type work item used as the global calendar. If you prefer not to create a dedicated calendar, you can use a placeholder empty calendar. |
| `nextedy.gantt.calendarHolder` | `String` | *empty* | Polarion user ID whose calendar work item is used as the global working calendar. Use this when the global calendar is assigned to a specific user account rather than being project-level. |
**Apply to Both Projects**
The `nextedy.gantt.workitemCalendar.projectId` and `nextedy.gantt.workitemCalendar.globalID` properties must be configured on **both** the calendar project and any consuming projects.
## Working Hours Properties
| Name | Type | Default | Description |
| ---------------------------------- | --------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `nextedy.gantt.workingHoursPerDay` | `Integer` | `8` | Default number of working hours per day for all resources. Set in **Administration > Configuration Properties** to apply globally, or override per widget via Gantt Config Script. |
### Custom Working Hours Function
For different working hours per resource, define a custom function in the Gantt Config Script widget parameter:
```javascript theme={null}
gantt.config.workingHoursPerDayFunction = (resource) => {
if (resource === "rProject") {
return 4;
}
return 8;
};
```
**Velocity-Powered Functions**
The Gantt Config Script supports Velocity expressions. You can use `$trackerService` to dynamically build the working hours function based on work item data. The function definition is produced by Velocity on the server, then executed on the client.
## Calendar Work Item Types
The working calendar system uses four dedicated work item types:
| Work Item Type | ID | Purpose |
| -------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| Calendar | `calendar` | Defines regular working hours per weekday and the validity date range. All exceptions and inheritance chains connect to this type. |
| Time Off | `timeoff` | Marks specific date ranges as non-working days in a linked calendar. Used for holidays and vacations. |
| Time On | `timeon` | Activates additional working days, overriding Time Off exceptions. Used when a specific user must work during a global holiday. |
| Tweak | `scheduletweak` | Adjusts working hours for a date range without changing working/non-working status. Used for half-days or reduced schedules. |
## Calendar Custom Fields
Each `calendar` work item uses the following custom fields to define the weekly schedule:
| Field | Type | Format | Description |
| ------------------ | -------- | ------------- | ---------------------------------------------------------------------------------------------------------- |
| `from` | Date | `YYYY-MM-DD` | Date when the calendar becomes active. If empty, no start boundary. |
| `to` | Date | `YYYY-MM-DD` | Date when the calendar expires. If empty, no end boundary. |
| `regularMonday` | `String` | `HH:mm,HH:mm` | Working hours for Monday. Use `-` for explicitly non-working. Leave empty to inherit from parent calendar. |
| `regularTuesday` | `String` | `HH:mm,HH:mm` | Working hours for Tuesday. Same format as Monday. |
| `regularWednesday` | `String` | `HH:mm,HH:mm` | Working hours for Wednesday. Same format as Monday. |
| `regularThursday` | `String` | `HH:mm,HH:mm` | Working hours for Thursday. Same format as Monday. |
| `regularFriday` | `String` | `HH:mm,HH:mm` | Working hours for Friday. Same format as Monday. |
| `regularSaturday` | `String` | `HH:mm,HH:mm` | Working hours for Saturday. Typically `-` for standard work week. |
| `regularSunday` | `String` | `HH:mm,HH:mm` | Working hours for Sunday. Typically `-` for standard work week. |
**Weekday Hour Format**
Use the format `HH:mm,HH:mm` (e.g., `09:00,17:00` for a standard 8-hour day). Use `-` to mark a day as explicitly non-working. Leave the field empty to inherit hours from the parent calendar.
## Calendar Inheritance
Calendars support inheritance via the `inherits from` work item link role:
* A child calendar inherits base hours from its parent calendar
* Weekday fields left empty in the child calendar use the parent's hours
* Weekday fields set explicitly in the child override the parent's hours
* The `-` value means explicitly non-working (does not inherit)
### Resolution Order
When the Gantt chart calculates effective working hours for a specific date, it applies the following resolution order:
## Calendar Modes in Resource View
The resource view supports three calendar resolution modes that affect capacity calculation:
| Mode | Description |
| -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Global Calendar** | Default mode. Uses the project-wide working calendar for all resources. Off-days apply to all task and resource rows equally. |
| **User Calendars** | When **Load User Calendars** is enabled, per-user working calendars are applied per resource row. Each user's off-days are based on their individual calendar. |
| **Team Assignments** | When **Load Team Assignments** is enabled, cells where a resource has zero team assignment hours are marked as unavailable. |
**Base Calendar Overlay**
A designated user can act as a base calendar holder (via `nextedy.gantt.calendarHolder`). Their off-days are applied as the baseline, and other users' calendars overlay additional off-days on top.
## Configuration Example
To connect a project to a central working calendar project:
```properties theme={null}
nextedy.gantt.workitemCalendar.projectId=WICalendars
nextedy.gantt.workitemCalendar.globalID=WI-001
```
To set a global calendar via a placeholder user:
```properties theme={null}
nextedy.gantt.calendarHolder=calendarUser
```
To change the default working hours globally:
```properties theme={null}
nextedy.gantt.workingHoursPerDay=7
```
## Related Pages
* [Working Calendars Parameters](/gantt/reference/widget-parameters/working-calendars) -- widget-level calendar settings
* [Team and Resource Properties](/gantt/reference/configuration/team-properties) -- team capacity and resource configuration
* [Resource View Parameters](/gantt/reference/widget-parameters/resource-view) -- resource load modes and display options
* [Item Script API](/gantt/reference/api/item-script-api) -- access calendar data in scripts
# Color and Styling Properties
Source: https://learn.nextedy.com/gantt/reference/configuration/color-properties
Nextedy GANTT uses a color system that supports both static (server-defined) and dynamic (progress-based) task bar coloring.
## Static vs. Dynamic Coloring
The Gantt supports two coloring modes that determine how task bar colors are applied:
**Dynamic coloring** (default): Task bars display progress-based colors (overdue, progress-due, resolved) that override the default color. Use `task.taskColor` in the Item Script to change the base color while keeping progress color overrides active.
**Static coloring**: Set `gantt.config.show_progress_colors=false` in the Gantt Config Script to disable progress-based color overrides. Use `task.color` in the Item Script to set the final task bar color directly.
**task.color vs. task.taskColor**
In dynamic mode, `task.taskColor` changes only the default (blue) base color -- progress-related colors still override it for overdue or resolved tasks. In static mode, `task.color` sets the absolute color with no overrides. Mixing them incorrectly produces unexpected results.
## Progress Color Properties
These administration properties control the colors applied to task bars based on their scheduling status when dynamic coloring is active:
| Name | Type | Default | Description |
| -------------------------------------------------- | ------ | -------- | ------------------------------------------------------------------------------------------------ |
| `nextedy.gantt.default.progress_color_overdue` | String | `red` | Color applied to task bars where the end date is in the past (task is overdue). |
| `nextedy.gantt.default.progress_color_progressdue` | String | `orange` | Color applied to task bars where the progress date is in the past (progress is behind schedule). |
| `nextedy.gantt.default.progress_color_resolved` | String | `gray` | Color applied to task bars that are in a resolved status. |
Set these properties in **Administration > Configuration Properties** to apply globally:
```
nextedy.gantt.default.progress_color_overdue=red
nextedy.gantt.default.progress_color_progressdue=orange
nextedy.gantt.default.progress_color_resolved=gray
```
Alternatively, set them per Gantt instance in the **Gantt Config Script**:
```javascript theme={null}
gantt.config.progress_color_overdue = "#e53935";
gantt.config.progress_color_progressdue = "#fb8c00";
gantt.config.progress_color_resolved = "#0AA33A";
```
## Unplanned Item Colors
| Name | Type | Default | Description |
| -------------------------------------------- | ------ | --------------- | --------------------------------------------------------------------- |
| `nextedy.gantt.workitems.unplanned_color` | String | `#7D3C98` | Background color of unplanned task bars (items without a start date). |
| `nextedy.gantt.workitems.unplanned_color_fg` | String | See application | Foreground (text) color of unplanned task bars. |
## Today Marker Color
| Name | Type | Default | Description |
| --------------------------- | ------ | ------- | ------------------------------------------------------------- |
| `nextedy.gantt.today.color` | String | `gray` | Color of the vertical "today" marker line on the Gantt chart. |
## Resource Marker Colors
The resource view uses color-coded markers to indicate resource allocation levels. The `resourceMarkersColorConfig` object defines the color scheme:
| Property | Type | Default | Description |
| ------------- | ---------------- | ------------------- | ------------------------------------------------------------------------------------------------ |
| `ok` color | String | `#4CAF50` (green) | Color for resource markers within capacity. Applied via the `marker_ok` CSS class. |
| `over` color | String | Red/orange gradient | Color for resource markers that exceed capacity. Applied via the `marker_over` CSS class. |
| `percentages` | Array of numbers | See application | Ascending threshold values defining breakpoints for marker color changes. |
| `colors` | Array of strings | See application | Color values for each allocation level. Must be one element longer than the `percentages` array. |
**Array Length Constraint**
The `colors` array must have exactly one more element than the `percentages` array. The `percentages` array must contain numeric values in ascending order. Invalid configurations produce error messages in both view mode and the wiki editor.
## Marker CSS Classes
The Gantt applies CSS classes to timeline markers based on their type:
| CSS Class | Applied To | Description |
| ------------- | ---------------- | ------------------------------------------------------- |
| `today` | Today marker | The vertical line marking today's date on the timeline. |
| `plan` | Plan markers | Markers synced from plan (iteration) boundaries. |
| `marker_ok` | Resource markers | Resource allocation cells within capacity. |
| `marker_over` | Resource markers | Resource allocation cells exceeding capacity. |
Custom markers defined without a specific color class receive the base marker styling. You can assign a named CSS color class (e.g., `blue`) to custom markers to override the default appearance.
## Disabling Dynamic Coloring
To use purely static colors without progress-based overrides, add the following to the **Gantt Config Script**:
```javascript theme={null}
gantt.config.show_progress_colors = false;
```
Then use `task.color` in the **Item Script** to set colors based on your custom logic:
```javascript theme={null}
if (wi.getType().getId() === "workpackage" && wi.getStatus().getId() === "draft") {
task.color = "#bfbfbf";
}
```
## CSS-Based Styling
You can apply custom CSS styles to Gantt elements through the **Parameters Script** section. For example, to change the font color of task labels:
```css theme={null}
```
**Verify in application**
CSS class names and DOM structure may vary between Gantt versions. Verify the available CSS classes in your specific version. See [CSS Classes and DOM Structure](/gantt/reference/css-classes) for a reference.
## Configuration Example
To set up custom progress colors and disable dynamic coloring for a specific Gantt:
1. In **Administration > Configuration Properties**, add:
```
nextedy.gantt.default.progress_color_overdue=#e53935
nextedy.gantt.default.progress_color_resolved=#43a047
nextedy.gantt.workitems.unplanned_color=#c7cffb
nextedy.gantt.workitems.unplanned_color_fg=#001379
```
2. For a specific Gantt page that needs static coloring, add to the **Gantt Config Script**:
```javascript theme={null}
gantt.config.show_progress_colors = false;
```
3. In the **Item Script**, define the color logic:
```javascript theme={null}
if (wi.getType().getId() === "feature") {
task.color = "#42a5f5";
}
```
## Related Pages
* [General Administration Properties](/gantt/reference/configuration/general-properties) -- core behavior and scheduling properties
* [Item Script API](/gantt/reference/api/item-script-api) -- `task.color` and `task.taskColor` scripting reference
* [Gantt Config Script API](/gantt/reference/api/config-script-api) -- `gantt.config.show_progress_colors` and color overrides
* [Item Color Legend](/gantt/reference/item-color-legend) -- visual reference for default color meanings
* [Resource View Parameters](/gantt/reference/widget-parameters/resource-view) -- resource marker configuration
* [CSS Classes and DOM Structure](/gantt/reference/css-classes) -- Gantt CSS class reference
# Default Configuration Values
Source: https://learn.nextedy.com/gantt/reference/configuration/default-values
Nextedy GANTT provides administration properties that set default values for widget parameters. These defaults apply when you add a new Gantt widget to a page.
Set these properties in **Administration > Configuration Properties**.
**Override Hierarchy**
Administration defaults apply system-wide. Once a widget is placed on a page, its own parameter values override these defaults. User preferences (zoom level, column widths) are saved in the browser and override both.
## General Properties
| Name | Type | Default | Description |
| ------------------------------------------------- | --------- | ---------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `nextedy.gantt.workitems.unplanned_color` | `String` | `#7D3C98` | Color of unplanned task bars. |
| `nextedy.gantt.today.color` | `String` | `gray` | Color of the today marker line. |
| `nextedy.gantt.classic_project` | `Boolean` | `false` | Use the classic look for project item types. |
| `nextedy.gantt.zoom.DD.min_column_width` | `Integer` | `120` | Timeline column width in DD (2-Day) scale mode. |
| `nextedy.gantt.zoom.D.min_column_width` | `Integer` | `60` | Timeline column width in D (Day) scale mode. |
| `nextedy.gantt.zoom.W.min_column_width` | `Integer` | `30` | Timeline column width in W (Week) scale mode. |
| `nextedy.gantt.zoom.M.min_column_width` | `Integer` | `70` | Timeline column width in M (Month) scale mode. |
| `nextedy.gantt.zoom.Q.min_column_width` | `Integer` | `90` | Timeline column width in Q (Quarter) scale mode. |
| `nextedy.gantt.zoom.Y.min_column_width` | `Integer` | `40` | Timeline column width in Y (Year) scale mode. |
| `nextedy.gantt.zoom.YY.min_column_width` | `Integer` | `190` | Timeline column width in YY (2-Year) scale mode. |
| `nextedy.gantt.debug` | `Boolean` | `false` | Enable client-side debug messages in the browser console. |
| `nextedy.gantt.default.auto_scheduling` | `Boolean` | `false` | Toggle auto-scheduling by default for new widgets. |
| `nextedy.gantt.default.critical_path` | `Boolean` | `false` | Toggle critical path visualization by default for new widgets. |
| `nextedy.gantt.config.squareTaskBorder` | `Boolean` | `false` | Switch task bar borders to square instead of rounded. Set `true` in Configuration Properties for global effect. Can be overridden per widget in Gantt Config Script. |
| `nextedy.gantt.config.scheduleUnplannedTasksMode` | `String` | `parent` | Defines behavior for scheduling unplanned children. `parent` -- unscheduled children align with parent start date. `today` -- unscheduled children are scheduled to today's date. |
| `nextedy.gantt.sort_children_by_id` | `Boolean` | `false` | Sort child work items by ID instead of the default sorting based on the Sort By parameter. |
| `nextedy.gantt.assignee_column_display_mode` | `String` | `initials` | Presentation mode for the assignee column. Values: `initials` or `fullname`. |
## Work Items Gantt Widget Defaults
These defaults apply to new Work Items Gantt widgets. Once a widget is added, its own parameter values are used.
| Name | Type | Default | Description |
| ------------------------------------------------------- | --------- | ---------------- | ------------------------------------------------------------------------------- |
| `nextedy.gantt.workitems.default.sort_by` | `String` | `id` | Default value for the Sort By parameter. |
| `nextedy.gantt.workitems.default.expand_level` | `Integer` | `0` | Default value for Load Children. Specifies how many hierarchy levels to expand. |
| `nextedy.gantt.workitems.default.show_unplanned` | `Boolean` | `true` | Default value for Show Unplanned. |
| `nextedy.gantt.workitems.default.scale` | `String` | `W` | Default zoom scale. Values: `H`, `DD`, `D`, `W`, `M`, `Q`, `Y`, `YY`. |
| `nextedy.gantt.workitems.default.parent_link_roles` | `String` | *empty* | Default parent link roles. Semicolon-separated list of link role IDs. |
| `nextedy.gantt.workitems.default.dependency_link_roles` | `String` | *empty* | Default dependency link roles. Semicolon-separated list of link role IDs. |
| `nextedy.gantt.workitems.default.start_field` | `String` | `gantt_start` | Default Start Field mapping. |
| `nextedy.gantt.workitems.default.end_field` | `String` | *none* | Default End Field mapping. |
| `nextedy.gantt.workitems.default.duration_field` | `String` | `gantt_duration` | Default Duration Field mapping. |
| `nextedy.gantt.workitems.default.progress_field` | `String` | `gantt_progress` | Default Progress Field mapping. |
| `nextedy.gantt.workitems.default.maximize_view` | `Boolean` | `false` | Default value for Maximize view. |
| `nextedy.gantt.workitems.default.hide_toolbar` | `Boolean` | `false` | Default value for Hide Toolbar. |
| `nextedy.gantt.workitems.default.progress_coloring` | `Boolean` | `true` | Default value for Progress Coloring. |
| `nextedy.gantt.workitems.default.drag_children` | `Boolean` | `true` | Default value for Drag Children. |
| `nextedy.gantt.workitems.default.max_items` | `Integer` | `100` | Default maximum number of items loaded into the chart. |
| `nextedy.gantt.workitems.default.show_today_marker` | `Boolean` | `true` | Default value for Show Today Marker. |
| `nextedy.gantt.workitems.default.working_time` | `Boolean` | `true` | Default value for working time mode. |
| `nextedy.gantt.workitems.resolved_readonly` | `Boolean` | `true` | When `true`, resolved work items cannot be moved on the Gantt chart. |
### Additional Defaults (Not Configurable Per Widget)
These properties control behavior at the server level and cannot be overridden on a specific widget instance.
| Name | Type | Default | Description |
| ---------------------------------------------------- | --------- | ------- | --------------------------------------------------------------------------------------------------------------------------- |
| `nextedy.gantt.workitems.default.forward_dependency` | `Boolean` | `false` | Reverse dependency link direction. Set to `true` if you link tasks from B to A instead of A to B. |
| `nextedy.gantt.workitems.default_duration` | `Integer` | `10` | Default duration in days for items without a specified duration. |
| `nextedy.gantt.workitems.default.link_lag` | `Integer` | `0` | Default lead/lag time for dependency links. |
| `nextedy.gantt.multiAssignmentSameEffortForAll` | `Boolean` | `true` | When `true`, effort is the same for each assignee in multi-assignment mode. When `false`, effort is shared among assignees. |
## Plans Gantt Widget Defaults
These defaults apply to new Plans Gantt widgets.
| Name | Type | Default | Description |
| ----------------------------------------------- | --------- | --------------- | -------------------------------------- |
| `nextedy.gantt.plans.default.sort_by` | `String` | `id` | Default Sort By value. |
| `nextedy.gantt.plans.default.expand_level` | `Integer` | `0` | Default Load Children level. |
| `nextedy.gantt.plans.default.show_unplanned` | `Boolean` | `true` | Default Show Unplanned value. |
| `nextedy.gantt.default.plans.scale` | `String` | `W` | Default zoom scale for Plans Gantt. |
| `nextedy.gantt.plans.default.maximize_view` | `Boolean` | `false` | Default Maximize view value. |
| `nextedy.gantt.plans.default.hide_toolbar` | `Boolean` | `false` | Default Hide Toolbar value. |
| `nextedy.gantt.plans.default.progress_coloring` | `Boolean` | `true` | Default Progress Coloring value. |
| `nextedy.gantt.plans.default.drag_children` | `Boolean` | `true` | Default Drag Children value. |
| `nextedy.gantt.plans.default.max_items` | `Integer` | See application | Default maximum items for Plans Gantt. |
## Default Client-Side Values
The Gantt widget ships with these built-in client-side defaults:
| Setting | Default | Description |
| ------------------------------ | --------------------------------------- | ------------------------------------------------------------------------------------ |
| Default zoom scale | `W` (Week) | Users see a weekly timeline when first loading the chart without a saved preference. |
| Default undo steps | `10` | Maximum undo/redo operations in a single edit session. |
| Default work item types | `feature`, `workpackage`, `release` | Three built-in work item types with preset display modes. |
| Default working calendar | Mon-Fri, 8 hours/day | Standard 5-day work week. |
| Default resource marker colors | Green `#4CAF50` (ok), Red/Orange (over) | Color-coding for resource allocation markers. |
| Range conflict detection | `false` | Must be explicitly enabled. |
## Configuration Example
To customize defaults for a Work Items Gantt deployment:
```properties theme={null}
nextedy.gantt.workitems.default.scale=M
nextedy.gantt.workitems.default.max_items=200
nextedy.gantt.workitems.default.progress_coloring=true
nextedy.gantt.workitems.default.start_field=plannedStart
nextedy.gantt.workitems.default.end_field=plannedEnd
nextedy.gantt.workitems.default.duration_field=
nextedy.gantt.default.auto_scheduling=true
nextedy.gantt.assignee_column_display_mode=fullname
```
## Related Pages
* [General Administration Properties](/gantt/reference/configuration/general-properties) -- global non-default properties
* [Color and Styling Properties](/gantt/reference/configuration/color-properties) -- color configuration
* [Work Items Gantt Widget Parameters](/gantt/reference/widget-parameters/work-items-gantt) -- per-widget parameter reference
* [Plans Gantt Widget Parameters](/gantt/reference/widget-parameters/plans-gantt) -- per-widget Plans Gantt parameters
* [Zoom and Scale Levels Reference](/gantt/reference/zoom-scale-levels) -- zoom level codes and column widths
# General Administration Properties
Source: https://learn.nextedy.com/gantt/reference/configuration/general-properties
Nextedy GANTT provides global administration properties that control core behavior, scheduling defaults, and display options across all Gantt chart instances.
## General Behavior Properties
| Name | Type | Default | Description |
| ------------------------------------------------- | ------- | ---------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `nextedy.gantt.debug` | Boolean | `false` | Enables client-side debug messages in the browser console. |
| `nextedy.gantt.default.auto_scheduling` | Boolean | `false` | Toggles auto-scheduling by default. When enabled, dependent tasks are automatically rescheduled when a predecessor changes. |
| `nextedy.gantt.default.critical_path` | Boolean | `false` | Toggles visualization of the critical path by default. |
| `nextedy.gantt.config.squareTaskBorder` | Boolean | `false` | Switches task bar borders from rounded to square. Set `true` in Configuration Properties to apply globally, or in the Gantt Config Script for a specific page. A `false` in Gantt Config Script overrides a global `true`. |
| `nextedy.gantt.config.scheduleUnplannedTasksMode` | Enum | `parent` | Defines behavior for scheduling unplanned children. `parent` -- unscheduled children align with the parent start date. `today` -- unscheduled children are scheduled to today's date. |
| `nextedy.gantt.sort_children_by_id` | Boolean | `false` | When `true`, child work items are sorted by ID instead of the default sorting based on the `Sort by` widget parameter. |
| `nextedy.gantt.assignee_column_display_mode` | Enum | `initials` | Controls the presentation of the assignee column: `initials` (circle with user initials) or `fullname` (full display name). |
| `nextedy.gantt.classic_project` | Boolean | `false` | Uses the classic visual style for project (summary) item types. |
## Zoom Column Width Properties
These properties control the pixel width of timeline columns at each zoom scale level:
| Name | Type | Default | Description |
| ---------------------------------------- | ------- | ------- | ----------------------------------------------- |
| `nextedy.gantt.zoom.DD.min_column_width` | Integer | `120` | Column width in the DD (bi-daily) scale mode. |
| `nextedy.gantt.zoom.D.min_column_width` | Integer | `60` | Column width in the D (daily) scale mode. |
| `nextedy.gantt.zoom.W.min_column_width` | Integer | `30` | Column width in the W (weekly) scale mode. |
| `nextedy.gantt.zoom.M.min_column_width` | Integer | `70` | Column width in the M (monthly) scale mode. |
| `nextedy.gantt.zoom.Q.min_column_width` | Integer | `90` | Column width in the Q (quarterly) scale mode. |
| `nextedy.gantt.zoom.Y.min_column_width` | Integer | `40` | Column width in the Y (yearly) scale mode. |
| `nextedy.gantt.zoom.YY.min_column_width` | Integer | `190` | Column width in the YY (multi-year) scale mode. |
For a complete list of zoom levels and their behaviors, see [Zoom and Scale Levels Reference](/gantt/reference/zoom-scale-levels).
## Work Items Gantt Default Properties
These properties define default values for Work Items Gantt widget parameters. They apply when a new widget is added to a page. **Once the widget is saved, the widget's own parameter values take precedence.**
| Name | Type | Default | Description |
| ------------------------------------------------------- | ------- | ---------------- | ----------------------------------------------------------------------------------------- |
| `nextedy.gantt.workitems.default.sort_by` | String | `id` | Default value for the **Sort By** widget parameter. |
| `nextedy.gantt.workitems.default.expand_level` | Integer | `0` | Default value for **Load Children** -- number of child levels to add to the dataset. |
| `nextedy.gantt.workitems.default.show_unplanned` | Boolean | `true` | Default value for **Show Unplanned**. |
| `nextedy.gantt.workitems.default.scale` | String | `W` | Default value for **Scale** (timeline zoom level). |
| `nextedy.gantt.workitems.default.parent_link_roles` | String | *empty* | Default value for **Parent Link Roles**. A semicolon-separated list of link role IDs. |
| `nextedy.gantt.workitems.default.dependency_link_roles` | String | *empty* | Default value for **Dependency Link Roles**. A semicolon-separated list of link role IDs. |
| `nextedy.gantt.workitems.default.start_field` | String | `gantt_start` | Default value for **Start Field**. |
| `nextedy.gantt.workitems.default.end_field` | String | *none* | Default value for **End Field**. |
| `nextedy.gantt.workitems.default.duration_field` | String | `gantt_duration` | Default value for **Duration Field**. |
| `nextedy.gantt.workitems.default.progress_field` | String | `gantt_progress` | Default value for **Progress Field**. |
| `nextedy.gantt.workitems.default.maximize_view` | Boolean | `false` | Default value for **Maximize Gantt View**. |
| `nextedy.gantt.workitems.default.hide_toolbar` | Boolean | `false` | Default value for **Hide Toolbar**. |
| `nextedy.gantt.workitems.default.progress_coloring` | Boolean | `true` | Default value for **Progress Coloring**. |
| `nextedy.gantt.workitems.default.drag_children` | Boolean | `true` | Default value for **Drag Children**. |
| `nextedy.gantt.workitems.default.max_items` | Integer | `100` | Default value for **Max Items** -- limits the number of work items loaded. |
| `nextedy.gantt.workitems.default.show_today_marker` | Boolean | `true` | Default value for **Show Today Marker**. |
| `nextedy.gantt.workitems.default.working_time` | Boolean | `true` | Default value for legacy working time mode. |
| `nextedy.gantt.workitems.resolved_readonly` | Boolean | `true` | When `true`, prevents moving resolved items on the Gantt chart. |
## Global-Only Work Items Properties
These properties can only be set globally and are not configurable per widget instance:
| Name | Type | Default | Description |
| ---------------------------------------------------- | ------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `nextedy.gantt.workitems.default.forward_dependency` | Boolean | `false` | Reverses the dependency link direction. Set to `true` if you link tasks from B to A instead of the default A to B (where A depends on B). |
| `nextedy.gantt.workitems.default_duration` | Integer | `10` | Default task duration in days when no duration is specified on the work item. |
| `nextedy.gantt.workitems.default.link_lag` | Integer | `0` | Default lead/lag time for dependency links. |
| `nextedy.gantt.multiAssignmentSameEffortForAll` | Boolean | `true` | When `true`, the effort is the same for all assignees in a multi-assignment. When `false`, the effort is shared across assignees. |
## Plans Gantt Default Properties
These properties define default values for Plans Gantt widget parameters:
| Name | Type | Default | Description |
| ----------------------------------------------- | ------- | ------- | --------------------------------------------------- |
| `nextedy.gantt.plans.default.sort_by` | String | `id` | Default value for the **Sort By** widget parameter. |
| `nextedy.gantt.plans.default.expand_level` | Integer | `0` | Default value for **Load Children**. |
| `nextedy.gantt.plans.default.show_unplanned` | Boolean | `true` | Default value for **Show Unplanned**. |
| `nextedy.gantt.default.plans.scale` | String | `W` | Default value for **Scale**. |
| `nextedy.gantt.plans.default.maximize_view` | Boolean | `false` | Default value for **Maximize View**. |
| `nextedy.gantt.plans.default.hide_toolbar` | Boolean | `false` | Default value for **Hide Toolbar**. |
| `nextedy.gantt.plans.default.progress_coloring` | Boolean | `true` | Default value for **Progress Coloring**. |
| `nextedy.gantt.plans.default.drag_children` | Boolean | `true` | Default value for **Drag Children**. |
**Verify in application**
Additional Plans Gantt default properties (such as `max_items`) may be available. Verify the complete list of Plans Gantt defaults in your Gantt version.
## Calendar and Resource Properties
The following properties configure working calendar and resource resolution. For the full calendar property reference, see [Calendar and Working Hours Properties](/gantt/reference/configuration/calendar-properties). For team configuration, see [Team and Resource Properties](/gantt/reference/configuration/team-properties).
| Name | Type | Default | Description |
| ------------------------------------------ | ------- | --------------- | -------------------------------------------------------------------------------------- |
| `nextedy.gantt.workitemCalendar.projectId` | String | See application | The Polarion project ID where working calendar work items are stored. |
| `nextedy.gantt.workitemCalendar.globalID` | String | See application | The work item ID of the global working calendar used as the default for all resources. |
| `nextedy.gantt.calendarHolder` | String | See application | The Polarion user ID whose calendar work item is used as the global working calendar. |
| `nextedy.gantt.workingCalendar.useCache` | Boolean | See application | Enables server-side caching of working calendar data for performance. |
| `nextedy.gantt.loadResourcesFromCsv` | Boolean | See application | Enables loading resource definitions from a CSV file instead of Polarion users. |
| `nextedy.gantt.useTeamCapacityModifiers` | Boolean | See application | Enables team-level capacity modifiers for resource allocation. |
| `nextedy.gantt.phantomResourceHoursPerDay` | Integer | See application | Default working hours per day for unresolvable (phantom) resources. |
## Configuration Example
To enable auto-scheduling and critical path visualization globally:
1. Navigate to **Administration > Configuration Properties**.
2. Add the following properties:
```
nextedy.gantt.default.auto_scheduling=true
nextedy.gantt.default.critical_path=true
```
3. Save the configuration.
All new Gantt widgets added to pages will have auto-scheduling and critical path enabled by default. Existing widgets retain their saved parameter values.
## Related Pages
* [Color and Styling Properties](/gantt/reference/configuration/color-properties) -- progress colors and resource marker colors
* [Calendar and Working Hours Properties](/gantt/reference/configuration/calendar-properties) -- working calendar configuration
* [Team and Resource Properties](/gantt/reference/configuration/team-properties) -- team assignment and capacity modifiers
* [Default Configuration Values](/gantt/reference/configuration/default-values) -- complete default value reference
* [Widget Parameters](/gantt/reference/widget-parameters/index) -- per-instance widget parameters
# Configuration Properties
Source: https://learn.nextedy.com/gantt/reference/configuration/index
Nextedy GANTT provides global administration properties that control default behavior, appearance, and scheduling settings across all Gantt chart instances.
Core behavior settings including auto-scheduling, critical path, task borders, unplanned task scheduling mode, and debug options.
Progress colors, unplanned item colors, resource marker colors, and static vs. dynamic coloring configuration.
Working calendar project and global calendar references, cache settings, and phantom resource hours.
Team capacity modifiers, resource CSV loading, and team-based assignment configuration.
Default widget parameter values for Work Items Gantt and Plans Gantt instances, including sort order, scale, field mappings, and item limits.
**Widget Parameters vs. Configuration Properties**
**Widget parameters** are set per Gantt instance in the widget editor and control that specific chart. **Configuration properties** are set in Administration and define system-wide defaults. When a widget is first added to a page, it inherits the configuration property defaults. Once saved, the widget's own parameter values take precedence.
## Related Pages
* [Widget Parameters](/gantt/reference/widget-parameters/index) -- per-instance widget parameter reference
* [Scripting API](/gantt/reference/api/index) -- programmatic configuration via scripts
# Team and Resource Properties
Source: https://learn.nextedy.com/gantt/reference/configuration/team-properties
Nextedy GANTT supports dynamic team management through dedicated work item types.
Set these properties in **Administration > Configuration Properties**.
## Team Work Item Type Properties
| Name | Type | Default | Description |
| ------------------------------------------ | -------- | ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `nextedy.gantt.teamWorkItemType` | `String` | `team` | Polarion work item type ID treated as a Team. Teams appear as resource groups in the resource view. Since version **25.5.0**. |
| `nextedy.gantt.teamAssignmentWorkItemType` | `String` | `teamAssignment` | Polarion work item type ID treated as a Team Assignment. Team assignments define per-user allocation periods under a team. Since version **25.5.0**. |
| `nextedy.gantt.teamManagementProjectId` | `String` | *current project* | Polarion project ID where team and team assignment work items are stored. Falls back to the current project if not set. Enables cross-project team management. |
**Custom Type IDs**
Starting with version **25.5.0**, you can use custom work item type IDs for teams and assignments. Set `nextedy.gantt.teamWorkItemType` and `nextedy.gantt.teamAssignmentWorkItemType` to match your project's work item type configuration.
## Team Assignment Structure
Teams are defined using two work item types linked by the `assignment` link role:
| Work Item Type | Purpose | Required Fields |
| ------------------- | --------------------------------------------------------------------------------------------------- | -------------------------------------------- |
| **Team** | Container representing a team or organizational unit. Shown as a resource group in the Gantt chart. | Name |
| **Team Assignment** | Child item specifying a user's allocation to a team for a defined period. | Assignee, Start Date, End Date, Allocation % |
**Link Requirement**
Each Team Assignment work item **must be linked** to a parent Team work item using the `assignment` link role. Assignments not associated with a parent team are **ignored** during capacity calculations.
## Team Capacity Modifier Properties
Capacity modifiers represent the percentage of time resources spend on unplanned work or account for future uncertainty.
| Name | Type | Default | Description |
| ---------------------------------------------- | --------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `nextedy.gantt.useTeamCapacityModifiers` | `Boolean` | `false` | Enable team-level capacity modifiers. When `true`, modifier A and B fields reduce effective resource capacity. |
| `nextedy.gantt.capacityModifierAField` | `String` | *empty* | Name of the custom field on the Team work item containing capacity modifier A. This modifier represents **unplanned work** (meetings, emails, etc.) and is applied to all tasks. |
| `nextedy.gantt.capacityModifierBField` | `String` | *empty* | Name of the custom field on the Team work item containing capacity modifier B. This modifier represents **future uncertainty** and is applied only to tasks beyond the day limit threshold. |
| `nextedy.gantt.capacityModifierBFieldDayLimit` | `Integer` | See application | Number of days in the future after which capacity modifier B is applied. Set to `-1` to always apply modifier B. |
### Capacity Modifier Behavior
* **Modifier A** -- Applied to all tasks regardless of timing. Represents the percentage of time spent on unplanned activities.
* **Modifier B** -- Applied only to tasks that are `capacityModifierBFieldDayLimit` days or more in the future. Represents planning uncertainty.
## Resource Configuration Properties
| Name | Type | Default | Description |
| ------------------------------------------ | --------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `nextedy.gantt.phantomResourceHoursPerDay` | `Integer` | See application | Default working hours per day for phantom (unresolvable) resources when no calendar is available. Phantom resources appear when an assigned user cannot be resolved in Polarion. |
| `nextedy.gantt.loadResourcesFromCsv` | `Boolean` | `false` | Load resource definitions from a CSV file instead of from Polarion users. Use for large installations where Polarion user loading is too slow. |
## Resource View Behavior
The resource view supports multiple resource source modes:
| Source Mode | Description |
| --------------------- | ------------------------------------------------------------------------------------------------------------- |
| **Assignee** | Default. Resources are derived from the `assignee` field on work items. Shows individual users. |
| **Team Custom Field** | Set the Resource Field to a team enumeration field (e.g., `primaryOwnership`) to show team-level assignments. |
| **Multi Enumeration** | Resource Field can point to a multi-enum field, allowing a work item to be assigned to multiple teams. |
| **Categories** | Resource Field can point to a Polarion categories field for category-based grouping. |
**Resource Field Types**
The Resource Field widget parameter must point to a field of type **User**, **Enumeration** (including synthetic enumerations like `@user`), or **Multi Enumeration**.
## Configuration Example
To set up team assignments with custom type IDs and capacity modifiers:
```properties theme={null}
nextedy.gantt.teamWorkItemType=group
nextedy.gantt.teamAssignmentWorkItemType=groupAssignment
nextedy.gantt.teamManagementProjectId=TeamManagement
nextedy.gantt.useTeamCapacityModifiers=true
nextedy.gantt.capacityModifierAField=capaModA
nextedy.gantt.capacityModifierBField=capaModB
nextedy.gantt.capacityModifierBFieldDayLimit=10
```
To use a global calendar holder:
```properties theme={null}
nextedy.gantt.calendarHolder=calendarUser
```
## Related Pages
* [Calendar and Working Hours Properties](/gantt/reference/configuration/calendar-properties) -- working calendar configuration
* [Resource View Parameters](/gantt/reference/widget-parameters/resource-view) -- widget-level resource view settings
* [General Administration Properties](/gantt/reference/configuration/general-properties) -- global Gantt properties
* [Default Configuration Values](/gantt/reference/configuration/default-values) -- default widget property values
# CSS Classes and DOM Structure
Source: https://learn.nextedy.com/gantt/reference/css-classes
Nextedy GANTT applies CSS classes to DOM elements for task bars, markers, resource allocation indicators, and structural components.
**Verify in application**
This page documents CSS classes derived from source code constants. Class names are stable across versions, but inspect the DOM in your browser developer tools to confirm availability in your specific Gantt version.
## Task Bar CSS Classes
Task bars in the Gantt chart receive CSS classes based on their type and state:
Every task bar carries the base class `gantt_task_line`; type and state add further classes:
| CSS Class | Applied To | Description |
| ----------------------------------------- | --------------------------------------- | ----------------------------------------------------------------------------------------------- |
| `gantt_bar_task` | Task bars of type `task` | Applied to standard leaf-level task bars. |
| `gantt_bar_project` / `gantt_project` | Task bars of type `project` | Applied to summary/parent task bars with expandable children. |
| `gantt_bar_milestone` / `gantt_milestone` | Task bars of type `milestone` | Applied to diamond-shaped milestone markers. |
| `gantt_dependent_task` | Task bars participating in dependencies | Applied to tasks that have dependency links. |
| `gantt_task_inline_color` | Task bars with a per-item color | Applied when an item or status color overrides the default bar color (the color is set inline). |
| `gantt_task_progress` | Progress fill element inside a bar | The inner element representing the completed portion of the task. |
| `rangeConflict` | Task bars and parent bars | Applied when a child task's dates extend beyond its parent's date range. |
| `overdue` | Task bars at risk | Applied when the task end date is in the past. |
**Custom Task Styling**
Use the task bar CSS classes to visually distinguish milestones from summary tasks and leaf tasks. For example, apply a different background color to milestone elements.
## Marker CSS Classes
Timeline markers (vertical lines on the Gantt chart) receive type-specific CSS classes:
| CSS Class | Applied To | Description |
| ------------------ | -------------- | -------------------------------------------------------------------------------------------- |
| `today` | Today marker | Applied to the vertical line marking the current date |
| `plan` | Plan markers | Applied to markers synced from Polarion plan boundaries (iteration start/end dates) |
| `gantt_marker` | All markers | Base class applied to all custom markers |
| Custom color class | Custom markers | Named CSS class (e.g. `blue`, `red`) assigned via marker configuration for custom appearance |
### Marker Styling Example
```css theme={null}
/* Style the today marker line */
.gantt_marker.today {
background-color: #e53935;
opacity: 0.8;
}
/* Style plan iteration markers */
.gantt_marker.plan {
background-color: #3f51b5;
border-left: 2px dashed #3f51b5;
}
/* Custom color class for a named marker */
.gantt_marker.blue {
background-color: #039be5;
}
```
## Resource View CSS Classes
Each resource allocation cell in the resource view is a marker element carrying the base classes `gantt_resource_marker resource_marker`:
| CSS Class | Applied To | Description |
| -------------------------------- | --------------------- | ---------------------------------------------------------------------------------------------- |
| `gantt_resource_marker` | Resource marker cells | Base class on every resource allocation marker. |
| `resource_marker` | Resource marker cells | Base class on every resource allocation marker. |
| `resource_marker_variable_color` | Resource marker cells | Added when the marker color is computed from the allocation value (the default coloring mode). |
### How Marker Colors Are Applied
The marker color is **not** carried by discrete state classes. Instead, each marker is assigned an inline `--marker_color` CSS custom property whose value is computed from the resource's allocation relative to its capacity -- shading from a within-capacity color toward an over-allocation color. For example, a live marker renders as:
```html theme={null}
5.8
```
The color scale itself is configured through the `resourceMarkersColorConfig` object (its `ok`/`over` colors or its `colors`/`percentages` thresholds), not by editing the marker classes. See [Configure Resource Allocation Marker Colors](/gantt/guides/visualization/resource-marker-colors).
### Resource Marker Styling Example
```css theme={null}
/* Override the text color on resource markers */
.resource_marker {
color: #ffffff;
}
/* Force a fixed color, ignoring the computed --marker_color */
.resource_marker_variable_color {
background-color: #e53935 !important;
}
```
See [Color and Styling Properties](/gantt/reference/configuration/color-properties) for configuring marker colors via widget parameters.
## Timeline Cell CSS Classes
Cells in the chart's timeline area carry classes used for the grid background and for highlighting non-working time:
| CSS Class | Applied To | Description |
| ----------------- | ---------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `gantt_task_cell` | Each timeline background cell | Base class on every timeline grid cell. |
| `weekend` | Timeline cells on non-working days | Added (alongside `gantt_task_cell`) to cells that fall on a non-working day -- weekends, and holidays/time-off when a [working calendar](/gantt/guides/calendars/load-holidays) is loaded. Target it to restyle the off-day highlight. |
```css theme={null}
/* Customize the non-working-day shading */
.gantt_task_cell.weekend {
background-color: #f5f5f5;
}
```
## DOM Structure Overview
## Structural Element IDs
The Gantt widget uses the following stable DOM element IDs for CSS targeting:
| Element | Purpose |
| ------------------- | ------------------------------------------------------------------------- |
| Main container | Root element containing the entire Gantt widget |
| Toolbar container | Contains all toolbar buttons and controls |
| Footer container | Contains version display, item count, filter indicators, and error badges |
| Resource view panel | Container for the resource allocation view below the Gantt chart |
| Export panel | Container for the PNG export and print UI |
## Conflict and State Indicators
| CSS Class | Trigger | Visual Effect |
| -------------------- | ----------------------------------------------------- | --------------------------------- |
| Range conflict class | Child task dates exceed parent date range during drag | Red/highlighted task bar border |
| Edit mode class | Gantt is in edit mode | Edit-specific UI elements visible |
## Lightbox Form Classes
The lightbox (inline task editor) uses dedicated CSS classes for form layout:
| Class Category | Description |
| ---------------------- | ---------------------------------------------------- |
| Form container classes | Applied to the lightbox dialog wrapper |
| Work item form type | Applied when editing a work item |
| Plan form type | Applied when editing a plan item in Plans Gantt mode |
## Configuration Example
Add custom CSS to a Polarion wiki page to override Gantt styles:
```html theme={null}
```
## Related Pages
* [Color and Styling Properties](/gantt/reference/configuration/color-properties) -- color configuration via administration properties
* [Item Color Legend](/gantt/reference/item-color-legend) -- task bar color coding reference
* [Resource View Parameters](/gantt/reference/widget-parameters/resource-view) -- resource marker configuration
* [Error Messages and Diagnostics](/gantt/reference/error-messages) -- error indicator CSS classes
# Dependency Types Reference
Source: https://learn.nextedy.com/gantt/reference/dependency-types
Nextedy GANTT supports four dependency link types that control how task scheduling relationships are enforced between work items.
**Version Requirement**
Mapping advanced dependency types (SS, FF, SF) to Polarion link roles requires Gantt version **4.4.0** or later. (Advanced dependency link types were first introduced in 3.0.0.) Earlier versions only support Finish-to-Start.
## Dependency Type Codes
| Code | Type | Name | Constraint |
| ---- | ------------------ | --------------------- | ------------------------------------------------------------------- |
| `0` | `finish_to_start` | Finish-to-Start (FS) | Target task cannot start before source task ends (may start later) |
| `1` | `start_to_start` | Start-to-Start (SS) | Target task cannot start until source task starts (may start later) |
| `2` | `finish_to_finish` | Finish-to-Finish (FF) | Target task cannot end before source task ends (may end later) |
| `3` | `start_to_finish` | Start-to-Finish (SF) | Target task cannot end before source task starts (may end later) |
## Dependency Link Properties
Each dependency link in the Gantt chart carries the following properties:
| Property | Type | Default | Description |
| ---------- | ------- | --------------- | --------------------------------------------------------------------------------- |
| `id` | String | Generated | Unique identifier derived from the Polarion link role and connected work item IDs |
| `source` | String | Required | ID of the predecessor (source) task in the dependency |
| `target` | String | Required | ID of the successor (target) task in the dependency |
| `type` | String | `0` (FS) | Dependency type code: `0`=FS, `1`=SS, `2`=FF, `3`=SF |
| `roleId` | String | See application | The Polarion link role ID used for this dependency link (e.g. `dependson`) |
| `roleName` | String | See application | Human-readable name of the Polarion link role (e.g. "depends on") |
| `lag` | Integer | `0` | Lag time in days (positive) or lead time (negative) applied to the dependency |
## Dependency Type Visual Reference
## Enabling Advanced Dependency Types
By default, only Finish-to-Start (`0`) dependency links are supported. To enable all four types, set the following configuration property:
```properties theme={null}
nextedy.gantt.default.advanced_dependencies=true
```
Set this property in **Project / Repository Administration > Configuration Properties**.
**Hidden Custom Field Required**
When using advanced dependency types, the Gantt stores metadata in a custom field called `gantt_dependency_metadata`. Hide this field from end users in the Polarion Form Configuration.
## Dependency Role Widget Parameter
The **Dependency Role** widget parameter controls which Polarion work item link roles represent dependency relationships. Configure this under **Widget Properties > Work Items > Dependency Roles**.
| Setting | Description |
| ----------------------- | ------------------------------------------------------------------ |
| Empty | No dependency links are shown |
| Single role selected | All dependency links use this role |
| Multiple roles selected | The first role is used when creating new dependency links via drag |
## Link Role Mapping per Dependency Type
You can optionally map each dependency type to a different Polarion link role by adding these configuration properties:
```properties theme={null}
nextedy.gantt.workitems.linkRoles.finish_to_start=your_FS_role_id
nextedy.gantt.workitems.linkRoles.start_to_start=your_SS_role_id
nextedy.gantt.workitems.linkRoles.finish_to_finish=your_FF_role_id
nextedy.gantt.workitems.linkRoles.start_to_finish=your_SF_role_id
```
Multiple link roles per dependency type are supported as comma-separated values:
```properties theme={null}
nextedy.gantt.workitems.linkRoles.finish_to_finish=dependency_feature_ff,dependency_task_ff
```
## Link Direction
By default, the Gantt reverses the arrow direction to match standard Gantt chart conventions (source points to dependent item). If your Polarion link role already points from source to dependent, set the forward dependency property:
```properties theme={null}
nextedy.gantt.workitems.default.forward_dependency=true
```
## Disabling Dependency Link Creation
To prevent users from creating dependency links by dragging, add this to the **Gantt Config Script** widget parameter:
```javascript theme={null}
gantt.config.drag_links = false;
```
## Constraint Violation Indicators
When a dependency constraint is violated (for example, a target task is scheduled before its source finishes in a Finish-to-Start relationship), the Gantt displays a red dotted line under the incorrectly positioned task bar. Move the task to comply with the dependency rules to resolve the violation.
**Dependencies and Auto-Scheduling**
When [auto-scheduling](/gantt/reference/widget-parameters/work-items-gantt) is enabled, the Gantt automatically recalculates task dates based on dependency constraints. Dependency links that are hidden or not loaded due to limits are ignored by the scheduling engine.
## Lag and Lead Time
Each dependency link supports a `lag` property:
| Value | Effect |
| ---------------------------- | ------------------------------------------------------------------------------------ |
| Positive integer (e.g. `2`) | Delays the successor by the specified number of days after the dependency constraint |
| `0` | No lag (default) |
| Negative integer (e.g. `-1`) | Creates lead time, allowing the successor to begin before the dependency constraint |
## Related Pages
* [Create Your First Dependency Link](/gantt/getting-started/first-dependency) -- step-by-step tutorial
* [Work Items Gantt Widget Parameters](/gantt/reference/widget-parameters/work-items-gantt) -- Dependency Role parameter
* [General Administration Properties](/gantt/reference/configuration/general-properties) -- advanced dependency properties
* [Gantt Config Script API](/gantt/reference/api/config-script-api) -- `drag_links` and other config overrides
# Error Messages and Diagnostics
Source: https://learn.nextedy.com/gantt/reference/error-messages
Nextedy GANTT provides diagnostic information through error indicators, footer messages, and browser console output.
**Version 25.4.2+**
Starting with version 25.4.2, the error alert system was improved with clearer error location identification and distinct behavior between edit mode and view mode.
## Error Display Modes
### Edit Mode (Administrator View)
When a script contains an error in edit mode:
| Element | Description |
| ---------------- | --------------------------------------------------------------------------------- |
| Footer indicator | An error footer appears at the bottom of the Gantt chart |
| Click to expand | Clicking the footer opens a detailed error message identifying the error location |
| Browser console | Errors are also logged to the browser console for further debugging |
| Server logs | Errors are logged to Polarion server logs (contact your Polarion administrator) |
### View Mode (User View)
| Element | Description |
| ------------- | ----------------------------------------------------------------------------------- |
| Triangle icon | A visual indicator (triangle icon) appears in the Gantt footer |
| Purpose | Informs end users that configuration or data-related issues exist |
| Detail level | Less detailed than edit mode to avoid exposing configuration internals to end users |
## Script Error Categories
The Gantt displays categorized error messages with a bold prefix identifying the error source:
| Error Category | Prefix | Source |
| -------------------- | ------------------------- | ------------------------------------------------- |
| Config Script Error | **Config Script Error:** | Error in the Gantt Config Script widget parameter |
| Markers Script Error | **Markers Script Error:** | Error in the Markers Script widget parameter |
| Item Script Error | **Item Script Error:** | Error in the Item Script widget parameter |
### Error Count Badge
When configuration scripts contain errors, the Gantt displays an error indicator with a count badge:
| Element | Class | Description |
| --------------- | -------------------- | -------------------------------------------------- |
| Error indicator | `.gantt-errors-info` | Warning icon with error count badge |
| Count badge | Numeric | Total number of errors detected across all scripts |
| Visibility | Both modes | Appears in both view mode and wiki editor mode |
## Data Loading Statistics
The Gantt footer displays load statistics that help diagnose data issues:
| Metric | Description | Diagnostic Significance |
| ---------------- | ---------------------------------------------------------- | -------------------------------------------------------------------------- |
| `items` | Total work items loaded successfully | Expected total task count |
| `skipped` | Items skipped due to `maxItems` limit | Non-zero value triggers a footer warning; increase `maxItems` to load more |
| `filtered` | Items excluded by query or type filter | Indicates how many items the query returned versus how many are visible |
| `hidden` | Items hidden by client-side filter | Explains why visible count is lower than total items |
| `unresolvable` | Items that could not be resolved (permissions or deletion) | May appear as phantom tasks; check work item permissions |
| `errorsCount` | Total errors during data loading | Non-zero value triggers an error indicator in the footer |
| `serverLoadTime` | Server data preparation time (ms) | Useful for performance monitoring |
## Configuration Validation Errors
### Resource Marker Color Validation
The Gantt validates the resource marker color configuration at startup:
| Validation | Error Condition | Resolution |
| --------------------- | ------------------------------------------------------- | --------------------------------------------------------------- |
| `percentages` array | Empty, non-numeric, or not in ascending order | Provide a non-empty array of ascending numbers |
| `colors` array | Empty or wrong length | Provide an array with length = `percentages` length + 1 |
| Array length mismatch | `colors` length does not equal `percentages` length + 1 | Ensure `colors` has exactly one more element than `percentages` |
See [Color and Styling Properties](/gantt/reference/configuration/color-properties) for the correct format.
## Schedule Constraint Errors
The lightbox displays specific error messages when task scheduling violates constraints:
| Error Message | Trigger | Resolution |
| ----------------------------------- | --------------------------------------------------------------- | -------------------------------------------------------------------- |
| Task's schedule cannot be shortened | Duration edit would make task shorter than required by children | Adjust child task durations first |
| Cannot be scheduled outside | Task dates would exceed parent task date boundaries | Move the task within parent bounds or remove the parent relationship |
**Removing Parent Constraints**
Setting a task's parent to "no parent" in the lightbox removes the parent-bounds constraint. A previously invalid duration becomes valid after detaching from the parent.
## Diagnostic Message Flow
## Warning Messages
| Warning Type | Trigger | Description |
| ---------------------------- | -------------------------------------------------------------------------- | ------------------------------------------------ |
| Read-only mode warning | User attempts an edit action in view-only mode | Displayed as an overlay message |
| Editor configuration warning | Gantt detects a configuration or data error that prevents editing | Shown as an inline warning overlay |
| Required fields warning | Required workflow fields are missing from the Additional Dialog Fields | Shown in the server log as an admin warning |
| Invalid field reference | Field added to `fieldFilter` that is already bound as a data mapping field | Logged as a warning during configuration parsing |
## Debugging Steps
| Step | Action | Tool |
| ---- | ---------------------------------------------------------------------- | ---------------------------------------- |
| 1 | Check the Gantt footer for error indicators and load statistics | Gantt UI |
| 2 | Open browser developer tools (right-click > Inspect > Console tab) | Browser console |
| 3 | Review Polarion server logs for detailed error messages | Server log files |
| 4 | In edit mode, click the error footer to see the detailed error message | Gantt error panel |
| 5 | Verify script syntax in Config Script, Item Script, and Markers Script | Widget parameters |
| 6 | Check the admin settings page for configuration status | `/polarion/#/administration/gantt/setup` |
## Configuration Example
Enable diagnostic logging in the Gantt Config Script:
```javascript theme={null}
// Check for configuration errors in the browser console
console.log("Gantt config loaded:", gantt.config);
```
## Related Pages
* [Gantt Config Script API](/gantt/reference/api/config-script-api) -- configuration scripting reference
* [Marker Factory API](/gantt/reference/api/markers-api) -- marker script debugging
* [Item Script API](/gantt/reference/api/item-script-api) -- item script debugging
* [Color and Styling Properties](/gantt/reference/configuration/color-properties) -- marker color configuration format
* [License Types and Evaluation Periods](/gantt/reference/license-types) -- license-related error states
# Reference
Source: https://learn.nextedy.com/gantt/reference/index
The Nextedy GANTT reference section provides detailed technical specifications for every configurable parameter, property, and API surface.
## Widget Parameters
Per-instance configuration applied through the Polarion widget editor.
* **[Widget Parameters](/gantt/reference/widget-parameters/index)** -- Overview of all widget parameter categories
* **[Work Items Gantt Widget Parameters](/gantt/reference/widget-parameters/work-items-gantt)** -- Dataset, hierarchy, and display parameters for the Work Items Gantt
* **[Plans Gantt Widget Parameters](/gantt/reference/widget-parameters/plans-gantt)** -- Dataset, hierarchy, and display parameters for the Plans Gantt
* **[Data Mapping Parameters](/gantt/reference/widget-parameters/data-mapping)** -- Start, end, duration, and progress field mappings
* **[Work Item Types Configuration](/gantt/reference/widget-parameters/work-item-types)** -- Project type, milestone type, and per-type settings
* **[Resource View Parameters](/gantt/reference/widget-parameters/resource-view)** -- Resource view toggle, load mode, and display options
* **[Working Calendars Parameters](/gantt/reference/widget-parameters/working-calendars)** -- Calendar toggles, year range, and cache settings
* **[Baselines Parameters](/gantt/reference/widget-parameters/baselines)** -- Baseline comparison and history settings
* **[Deadlines Parameters](/gantt/reference/widget-parameters/deadlines)** -- Deadline display, field mapping, and color
* **[Column Configuration Parameters](/gantt/reference/widget-parameters/columns)** -- Grid column type, field, and editor settings
* **[Table and Grid Configuration](/gantt/reference/widget-parameters/table-configuration)** -- Grid width, first column, and layout settings
## Configuration Properties
System-wide administration properties set in **Administration > Configuration Properties**.
* **[Configuration Properties](/gantt/reference/configuration/index)** -- Overview of all administration properties
* **[General Administration Properties](/gantt/reference/configuration/general-properties)** -- Debug, auto-scheduling, critical path, zoom widths
* **[Color and Styling Properties](/gantt/reference/configuration/color-properties)** -- Unplanned color, today marker color, progress colors
* **[Calendar and Working Hours Properties](/gantt/reference/configuration/calendar-properties)** -- Calendar project, global calendar, cache settings
* **[Team and Resource Properties](/gantt/reference/configuration/team-properties)** -- Team capacity modifiers and resource defaults
* **[Default Configuration Values](/gantt/reference/configuration/default-values)** -- Default widget parameter values for new instances
## Scripting API
JavaScript and Velocity APIs for customizing Gantt behavior.
* **[Scripting API](/gantt/reference/api/index)** -- Overview of all scripting surfaces
* **[Item Script API (Task and Work Item Objects)](/gantt/reference/api/item-script-api)** -- Server-side task decoration objects
* **[Gantt Config Script API](/gantt/reference/api/config-script-api)** -- Client-side configuration object
* **[Marker Factory API](/gantt/reference/api/markers-api)** -- Server-side marker creation
* **[Page Parameters API](/gantt/reference/api/page-parameters-api)** -- Runtime parameter access
* **[Velocity Context Variables](/gantt/reference/api/velocity-context)** -- Velocity objects available in page scripts
## Quick Lookup
Standalone reference tables for common lookups.
* **[Item Color Legend](/gantt/reference/item-color-legend)** -- Task bar color mapping by status and type
* **[Dependency Types Reference](/gantt/reference/dependency-types)** -- FS, SS, FF, SF dependency types
* **[Zoom and Scale Levels Reference](/gantt/reference/zoom-scale-levels)** -- Available timeline scale levels
* **[Toolbar Actions and Keyboard Shortcuts](/gantt/reference/keyboard-shortcuts)** -- Toolbar buttons and keyboard navigation
* **[URL Parameters Reference](/gantt/reference/url-parameters)** -- URL query parameters for Gantt control
* **[Supported Field Types](/gantt/reference/supported-field-types)** -- Polarion field types compatible with Gantt mapping
* **[Polarion Version Compatibility Matrix](/gantt/reference/compatibility-matrix)** -- Supported Polarion versions
* **[License Types and Evaluation Periods](/gantt/reference/license-types)** -- License models and evaluation terms
* **[Error Messages and Diagnostics](/gantt/reference/error-messages)** -- Error codes and resolution steps
* **[CSS Classes and DOM Structure](/gantt/reference/css-classes)** -- Stable CSS selectors for custom styling
**Widget parameters vs. configuration properties**
Widget parameters are set per Gantt instance on each wiki page. Configuration properties are set globally in Polarion Administration and serve as defaults for all new widget instances. Widget-level values override administration defaults.
# Item Color Legend
Source: https://learn.nextedy.com/gantt/reference/item-color-legend
Nextedy GANTT uses dynamic color-coding to indicate task status at a glance. Each task bar color reflects the relationship between the task's schedule, progress, and resolution state.
## Default Dynamic Colors
The following colors are applied automatically when progress coloring is enabled (the default):
| Color | Condition | Meaning |
| -------------- | ------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
| **Red** | Work item is unresolved AND the end date is in the past | Task is **overdue** -- it should have been completed already |
| **Orange** | Work item is unresolved AND the end date is in the future AND current progress is behind schedule | Task is **delayed** -- progress does not match the expected completion rate |
| **Blue** | Work item is unresolved AND schedule and progress are on track | Task is **on track** -- optimistic schedule and progress alignment |
| **Gray** | Work item is resolved (completed in Polarion) | Task is **resolved** -- no further action required |
| **Light Blue** | Work item has no scheduled start date | Task is **unplanned** -- start date defaults to today |
| **Green** | Work item is configured as a `project` type via Item Script | Task is a **project item** -- schedule derived from children |
Each color case is shown below.
**Red Flagging for No Available Working Days**
Starting with version **25.10.2**, the Gantt chart visually flags tasks in red when the assigned user has no available working days during the scheduled period. This helps planners immediately identify unrealistic schedules caused by calendar conflicts.
## Color Decision Flow
## Static vs. Dynamic Coloring
There are two task color properties with different behavior:
| Property | Type | Behavior | Use Case |
| ---------------- | -------- | --------------------------------------------------------------------- | ----------------------------------------------------------------- |
| `task.color` | `String` | **Static** -- overrides ALL colors, including progress-based coloring | Force a specific color regardless of task status |
| `task.taskColor` | `String` | **Dynamic** -- only overrides the default blue color | Change color while preserving red/orange/gray progress indicators |
**Choosing the Right Property**
Use `task.taskColor` when you want to keep progress-based color indicators (red for overdue, orange for delayed, gray for resolved). Use `task.color` only when you want to force a specific color regardless of progress status.
### Disabling Dynamic Colors
To use fully static coloring where only `task.color` values from the Item Script determine task bar colors, add the following to the Gantt Config Script:
```javascript theme={null}
gantt.config.show_progress_colors = false;
```
When `show_progress_colors` is set to `false`, the Gantt chart does not apply the automatic red/orange/blue/gray coloring. Only colors explicitly set via `task.color` in the Item Script are used.
## Script-Based Color Overrides
### Color by Type and Status
Use `task.color` for fully static coloring (requires `gantt.config.show_progress_colors=false` in the Gantt Config Script):
**Item Script:**
```javascript theme={null}
if (wi.getType().getId() === "workpackage" && wi.getStatus().getId() === "draft") {
var today = new Date();
if (task.start_date.getTime() < today.getTime()) {
task.color = "green";
}
}
```
### Color by Assignee
Use `task.taskColor` to change the base color while keeping progress indicators:
**Item Script:**
```javascript theme={null}
var assignee = null;
var aIterator = wi.getAssignees().iterator();
if (aIterator.hasNext()) {
assignee = aIterator.next();
if (assignee && assignee.id === "yourAssigneeId") {
task.taskColor = "#a9d08e";
}
}
```
### Highlight Overdue Unresolved Items (Static Mode)
When dynamic colors are off, manually flag overdue items:
**Gantt Config Script:**
```javascript theme={null}
gantt.config.show_progress_colors = false;
```
**Item Script:**
```javascript theme={null}
var tdate = new Date();
var edate = task.end_date;
var interval = tdate.getTime() - edate.getTime();
if (interval > 0) {
task.color = "red";
}
```
## Resource View Marker Colors
The resource view uses separate color assignments for allocation markers:
| CSS Class | Default Color | Condition |
| ------------- | ----------------- | -------------------------------------------------- |
| `marker_ok` | Green (`#4CAF50`) | Resource utilization is within capacity |
| `marker_over` | Red/Orange | Resource is over-allocated (load exceeds capacity) |
Resource marker colors are configurable through the `resourceMarkersColorConfig` with `colors` and `percentages` arrays that define threshold breakpoints and corresponding color values.
**Color Configuration Validation**
The `percentages` array must contain numeric values in ascending order. The `colors` array must be exactly one element longer than the `percentages` array. Invalid configurations display error messages in both view mode and wiki editor mode.
## Marker CSS Classes
Timeline milestone markers receive CSS classes based on their type:
| CSS Class | Applied To | Description |
| -------------------------- | -------------- | ------------------------------------------------- |
| `gantt_marker` | All markers | Base class for all marker elements |
| `today` | Today marker | Applied to the automatic today-date vertical line |
| `plan` | Plan markers | Applied to markers synced from plan boundaries |
| Named color (e.g., `blue`) | Custom markers | Applied when a color is set via `setColor()` |
## Configuration Example
A complete setup combining static coloring with custom color logic:
**Gantt Config Script:**
```javascript theme={null}
gantt.config.show_progress_colors = false;
```
**Item Script:**
```javascript theme={null}
if (wi != null) {
// Color by type
if (wi.getType().getId() === "workpackage") {
task.color = "#4472C4";
} else if (wi.getType().getId() === "feature") {
task.color = "#70AD47";
}
// Override: flag overdue items
var today = new Date();
if (task.end_date.getTime() < today.getTime() && wi.getResolution() == null) {
task.color = "red";
}
}
```
## Related Pages
* [Item Script API](/gantt/reference/api/item-script-api) -- `task.color` and `task.taskColor` property reference
* [Gantt Config Script API](/gantt/reference/api/config-script-api) -- `gantt.config.show_progress_colors` setting
* [Color and Styling Properties](/gantt/reference/configuration/color-properties) -- global color administration properties
* [Default Configuration Values](/gantt/reference/configuration/default-values) -- default `progress_coloring` value
* [CSS Classes and DOM Structure](/gantt/reference/css-classes) -- marker CSS classes for custom styling
# Toolbar Actions and Keyboard Shortcuts
Source: https://learn.nextedy.com/gantt/reference/keyboard-shortcuts
Nextedy GANTT provides a toolbar with actions for editing, navigation, visualization, and data management.
**Verify in application**
This page documents toolbar actions derived from source code. Some actions may vary depending on your Gantt version and configuration.
## Edit Mode Actions
| Action | Icon | Visibility | Description |
| ------------- | ---- | --------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| Edit | | `readonly=false` and `alwaysedit=false` | Enters Gantt edit mode, enabling task drag, resize, and creation |
| Close Editing | ❌ | In edit mode, `alwaysedit=false` | Exits edit mode and returns to view-only display |
| Save | 💾 | Edit mode with unsaved changes | Saves all pending task and dependency link changes to Polarion. Shows a progress indicator during save |
| Undo | | Edit mode | Reverses the last change (up to `undo_steps` operations, default 10) |
| Redo | | Edit mode | Reapplies the last undone change |
**Always Edit Mode**
When `alwaysedit` is `true`, the Gantt opens directly in edit mode. No Edit/Close buttons appear. When `hideToolbar` is `true`, a floating save button appears instead of the full toolbar.
## Task Creation
| Action | Icon | Visibility | Description |
| ------------- | ---- | ---------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| New work item | ➕ | Edit mode, at least one type has `enableCreate=true` | Opens a dropdown to select the work item type, then creates a new task and opens the lightbox |
The new task dropdown lists all configured work item types that have `enableCreate` set to `true`. Each entry shows the type icon and name.
## Navigation Actions
| Action | Icon | Location | Description |
| ------------ | ---- | -------------------------- | ------------------------------------------------------------- |
| Go to today | | Toolbar and hamburger menu | Scrolls the Gantt chart horizontally to show the current date |
| Expand all | | Toolbar | Expands all task groups in the Gantt grid |
| Collapse all | | Toolbar | Collapses all task groups in the Gantt grid |
| Search | | Toolbar | Text input field for filtering work items by ID or title |
## Visualization Toggles
| Action | Icon | Toolbar Label | Description |
| ----------------------- | ---- | -------------------- | --------------------------------------------------------------- |
| Toggle critical path | | Critical Path | Highlights the longest dependency chain in red when enabled |
| Toggle dependency links | | Show Links | Shows or hides dependency link arrows between tasks |
| Toggle drag children | | Drag Children | When enabled, child tasks move with their parent during drag |
| Toggle auto-scheduling | | Auto Schedule | Enables automatic date recalculation based on dependency links |
| Toggle resource hiding | | Hide Empty Resources | Hides resource rows with no assigned tasks in the resource view |
## Data Actions
| Action | Icon | Description |
| ----------------------- | ---- | ---------------------------------------------------------------------------------------------------- |
| Refresh | 🔄 | Reloads Gantt data from the server. Preserves scroll position and selected task |
| Mark Differences | | Marks work items with unsynchronised derived dates as modified |
| Clear Calendar Cache | | Clears the server-side working calendar cache and reloads. Only visible when `useCalendarCache=true` |
| Print / Export to Image | | Opens the export panel for PNG export or printing |
## Page Parameters
| Action | Icon | Visibility | Description |
| --------------- | ---- | ------------------- | --------------------------------------------------------------------- |
| Page Parameters | ⚙️ | Maximized view only | Opens the widget parameter editor panel for runtime parameter changes |
**Maximize Requirement**
The Page Parameters button only appears when the Gantt is in maximized/fullscreen view. Use the `MaximizeGanttView` URL parameter to control this behavior. See [URL Parameters Reference](/gantt/reference/url-parameters).
## Hamburger Menu
The hamburger menu (☰) in the first grid column header provides quick access to common actions:
| Menu Item | Description |
| ----------------- | ------------------------------------------------------------------------ |
| Refresh | Reloads Gantt data from the server |
| Drag children | Toggle for moving children with parent |
| Go to today | Scrolls the timeline to the current date |
| Set scale | Submenu for selecting zoom level (Hour, Day, Week, Month, Quarter, Year) |
| Column visibility | Submenu with checkboxes to show/hide individual grid columns |
| Help | Opens the Gantt documentation site |
## Context Menu Actions
| Trigger | Location | Actions |
| ------------------------------- | ------------------ | -------------------------------------------------------------- |
| Right-click on column header | Grid column header | Column visibility checkboxes for all configured columns |
| Right-click on timescale header | Timeline header | Scale selector and Go to today |
| Shift + right-click | Anywhere | Bypasses the custom context menu and shows the browser default |
## Mouse Interactions
| Interaction | Edit Mode Required | Description |
| --------------------- | ------------------ | ---------------------------------------------------------------------- |
| Drag task bar | Yes | Moves the task to a new date range |
| Drag task bar edge | Yes | Resizes the task duration |
| Drag link handle | Yes | Creates a dependency link between two tasks by connecting link circles |
| Click task bar | No | Selects the task and shows details in the sidebar panel |
| Double-click task bar | Yes | Opens the lightbox for inline field editing |
## Footer Information
| Element | Description |
| ------------------- | ------------------------------------------------------------ |
| Version number | Displays the installed Gantt version in the footer |
| Items info | Shows the count of visible versus total task rows |
| Filter icon | Appears when items are hidden, with a tooltip explaining why |
| Error indicator | Appears when configuration or data errors are detected |
| Admin settings link | Gear icon linking to Gantt administration settings |
## Configuration Example
Disable dependency link creation via the Gantt Config Script:
```javascript theme={null}
gantt.config.drag_links = false;
```
Set the undo depth via the Gantt Config Script:
```javascript theme={null}
gantt.config.undo_steps = 20;
```
## Related Pages
* [Zoom and Scale Levels Reference](/gantt/reference/zoom-scale-levels) -- zoom level details and persistence
* [URL Parameters Reference](/gantt/reference/url-parameters) -- `MaximizeGanttView` and other URL parameters
* [Work Items Gantt Widget Parameters](/gantt/reference/widget-parameters/work-items-gantt) -- `readonly`, `alwaysedit`, and toolbar configuration
* [Gantt Config Script API](/gantt/reference/api/config-script-api) -- scripting overrides for toolbar behavior
# License Types and Evaluation Periods
Source: https://learn.nextedy.com/gantt/reference/license-types
Nextedy GANTT requires a valid license to operate. This page documents the license types, evaluation periods, and the behavior of the Gantt chart under different license states.
## License Types
| License Type | Duration | Description |
| ---------------------- | ----------------------------- | ----------------------------------------------------------------- |
| Evaluation (Primary) | 30 days from installation | Full-featured evaluation for determining product fit |
| Evaluation (Secondary) | 10 days from qualified update | Extended evaluation after a qualified software update |
| Standard | Per agreement | Full license for production use, obtained via License Certificate |
## Evaluation Period Rules
### Primary Evaluation Period
| Property | Value |
| ------------------- | ------------------------------------------------------------------- |
| Duration | 30 days from date of installation |
| Functionality | Full product capabilities |
| Purpose | Internal evaluation to determine if the software meets requirements |
| Expiration behavior | Software is automatically disabled |
### Secondary Evaluation Period
| Property | Value |
| -------- | ---------------------------------------------- |
| Duration | 10 days from date of qualified software update |
| Trigger | Qualified update of the software |
| Purpose | Re-evaluation after a significant update |
Upon expiration of the evaluation period, the Gantt software is automatically disabled. You must obtain a License Certificate for perpetual use or cease using the software. Attempting to disable or remove the automatic disabling feature violates the license agreement.
## License State Indicators
The Gantt displays a license panel with status information based on the current license state:
| License State | Panel Variant | Behavior |
| ------------- | ------------- | -------------------------------------------------------------------------------- |
| Valid | `ok` | License panel is hidden; Gantt operates normally |
| Warning | `warning` | License panel appears with a warning message (approaching expiry) |
| Expired | `expired` | License panel appears with expiration message; Gantt functionality is restricted |
| Invalid | Error | Inline warning banner appears with contact information |
## Maintenance Expiration
Separate from license validity, the Gantt tracks maintenance status:
| State | Description |
| ------------------- | ------------------------------------------------------------------------------------------------------------ |
| Maintenance active | Software updates and support are available |
| Maintenance expired | Software continues to work but updates are not available; a maintenance renewal is required for new versions |
An expired maintenance period does not disable the Gantt. The software continues to operate, but you cannot install newer versions without renewing maintenance.
## License Check Endpoint
The Gantt checks license status at startup by calling a server API endpoint:
| Property | Value |
| -------- | ------------------------------------------------------------------- |
| Endpoint | `GET /polarion/gantt/admin/api/license` |
| Timing | Called once at Gantt startup |
| Response | Returns license validity, expiry date, and a human-readable message |
## Multi-Node Deployment
Licenses can be used across multiple Polarion cluster nodes:
| Scenario | Supported |
| ------------------------ | ------------------------------ |
| Single server deployment | Yes |
| Multi-node cluster | Yes, same license on all nodes |
## Extended Evaluation
If you need more than 30 days for evaluation, contact Nextedy to request an extended time-limited license.
## Configuration Example
Check the license status from the admin page:
```text theme={null}
https://your-polarion.example.com/polarion/#/administration/gantt/setup
```
The license panel appears at the top of the Gantt widget when the license is approaching expiry or has expired. If you see the license panel, contact your administrator or visit the Nextedy support portal.
## Related Pages
* [Licensing and User Access](/gantt/getting-started/licensing) -- license setup tutorial
* [Install Gantt](/gantt/getting-started/installation) -- initial installation
* [Polarion Version Compatibility Matrix](/gantt/reference/compatibility-matrix) -- version compatibility reference
* [Error Messages and Diagnostics](/gantt/reference/error-messages) -- license-related error messages
# Supported Field Types
Source: https://learn.nextedy.com/gantt/reference/supported-field-types
Nextedy GANTT integrates with Polarion work item fields for scheduling, progress tracking, and inline editing via the lightbox.
## Lightbox Field Types
The following field types are supported in the Gantt lightbox editor:
| Field Type | Lightbox Control | Description |
| ----------------- | --------------------- | --------------------------------------------------------------- |
| `TEXT` | Text input | Standard single-line text entry |
| `INTEGER` | Numeric input | Integer value entry |
| `FLOAT` | Numeric input | Floating-point value entry |
| `DATE` | Date picker | Date-only field with calendar widget |
| `DATETIME` | Date-time picker | Date and time field with calendar widget |
| `DURATION` | Duration input | Duration entry with increment/decrement controls |
| `SELECT` | Dropdown | Single-value selection from enumeration options |
| `MULTISELECT` | Multi-select dropdown | Multiple-value selection from enumeration options |
| `SINGLE_CHECKBOX` | Checkbox | Boolean true/false toggle |
| `RICH_TEXT` | Read-only display | Rich text fields are displayed but not editable in the lightbox |
## Data Mapping Field Requirements
The Gantt uses specific Polarion work item fields for core scheduling data. Each mapping has field type requirements:
| Mapping | Widget Parameter | Supported Types | Default Field | Recommended Type |
| ---------- | ---------------- | ---------------------- | ---------------- | ---------------- |
| Start date | `startField` | Date, DateTime, String | `gantt_start` | Date |
| End date | `endField` | Date, DateTime, String | Not set | Date |
| Duration | `durationField` | Integer, String | `gantt_duration` | Integer |
| Progress | `progressField` | Float, String | `gantt_progress` | Float |
| Resource | `resourceField` | User enum, String | See application | User enum |
**String Type Limitations**
String-type fields work for start/end/duration/progress but have precision limitations. Use native Date, Integer, or Float field types for production deployments.
### Valid Field Mapping Combinations
You must configure exactly two of the three date/duration fields. Valid combinations:
| Combination | Fields Required | Description |
| ---------------- | ------------------------------ | -------------------------------------- |
| Start + End | `startField` + `endField` | Duration is calculated automatically |
| Start + Duration | `startField` + `durationField` | End date is calculated automatically |
| End + Duration | `endField` + `durationField` | Start date is calculated automatically |
## Duration Precision
| Mode | Value | Duration Unit | Date Format |
| -------- | ----------------- | ------------- | ------------- |
| Standard | `Standard (Days)` | Days | Date only |
| High | `High (Hours)` | Hours | Date and time |
**Verify in application**
High-precision mode changes the Gantt date format globally and requires hour-capable date fields. See [Data Mapping Parameters](/gantt/reference/widget-parameters/data-mapping).
## Progress Field Format
The progress field stores completion as a float value:
| Progress | Float Value | Task Bar Fill |
| -------- | ----------- | ------------- |
| 0% | `0.0` | Empty |
| 50% | `0.5` | Half filled |
| 100% | `1.0` | Fully filled |
## Enumeration Field Handling
Polarion enumeration fields are supported in the lightbox as follows:
| Polarion Field Type | Lightbox Behavior |
| --------------------- | --------------------------------------------------------------- |
| Single enum | Rendered as a `SELECT` dropdown with all enumeration options |
| Multi-enum / List | Rendered as a `MULTISELECT` dropdown with enhanced selection UI |
| User enum (@user) | Rendered as a `SELECT` dropdown with user list |
| User list (@userList) | Rendered as a `MULTISELECT` dropdown with user list |
| Category | Rendered as a `SELECT` dropdown with category options |
## Field Metadata Properties
Each field in the lightbox carries the following metadata:
| Property | Type | Description |
| -------------- | ------- | ------------------------------------------------------------------------------- |
| `id` | String | Internal Polarion field identifier used for reading/writing values |
| `referenceId` | String | Optional remapping identifier that overrides the field ID for data storage |
| `label` | String | Human-readable display label shown as the section heading in the lightbox |
| `fieldType` | String | The lightbox control type (TEXT, SELECT, DATE, etc.) |
| `valueType` | String | Primitive value type for type-safe conversion (INTEGER, FLOAT, STRING, etc.) |
| `defaultValue` | Varies | Default value applied when creating a new task |
| `required` | Boolean | When `true`, the field must have a value before saving. Marked with an asterisk |
| `readonly` | Boolean | When `true`, the field is displayed but not editable |
| `options` | Array | List of selectable values for SELECT and MULTISELECT fields |
## Excluded Field Types
The following field types are **not supported** for Gantt editing:
| Field Type | Reason |
| ----------------- | ---------------------------------------------------- |
| HTML Rich Text | Complex rendering not compatible with inline editing |
| TimeOnly | Not applicable to Gantt scheduling |
| `status` | System field managed by Polarion workflows |
| `resolution` | System field managed by Polarion workflows |
| `linkedWorkItems` | Managed through dependency link configuration |
## Additional Dialog Fields
You can add extra fields to the lightbox beyond the core date/duration/resource fields using the **Additional Dialog Fields** (`fieldFilter`) configuration per work item type.
**Field Exclusion Rule**
Fields already bound as `startField`, `endField`, `resourceField`, `durationField`, or `progressField` cannot be added to Additional Dialog Fields. The Gantt validates this and logs a warning for invalid field references.
## Role-Based Field Access
The Gantt enforces Polarion role-based field permissions in the lightbox:
| Permission | Lightbox Behavior |
| ----------------------- | --------------------------------- |
| User can read and write | Field is fully editable |
| User can read only | Field is displayed as read-only |
| User cannot read | Field is hidden from the lightbox |
**Current Limitation**
Date field mapping (`startField`, `endField`) is currently global across all work item types. Per-work-item-type date field mapping is a planned improvement.
## Configuration Example
Configure data mapping fields in the Work Items Gantt widget parameters:
| Parameter | Example Value |
| -------------- | ---------------- |
| Start Field | `plannedStart` |
| End Field | `plannedEnd` |
| Duration Field | `gantt_duration` |
| Progress Field | `gantt_progress` |
| Resource Field | `assignee` |
## Related Pages
* [Data Mapping Parameters](/gantt/reference/widget-parameters/data-mapping) -- field mapping widget parameters
* [Work Item Types Configuration](/gantt/reference/widget-parameters/work-item-types) -- per-type fieldFilter configuration
* [Work Items Gantt Widget Parameters](/gantt/reference/widget-parameters/work-items-gantt) -- core widget parameter reference
* [Error Messages and Diagnostics](/gantt/reference/error-messages) -- field validation error messages
# URL Parameters Reference
Source: https://learn.nextedy.com/gantt/reference/url-parameters
Nextedy GANTT supports URL query parameters that override widget behavior at page load time.
**Verify in application**
This page documents URL parameters derived from source code. Some parameters may vary depending on your Gantt version.
## View and Layout Parameters
| Parameter | Type | Default | Description |
| ------------------- | ------- | --------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `MaximizeGanttView` | Boolean | `true` (when maximize is enabled) | Controls whether the Gantt opens in maximized/fullscreen mode. Set to `false` to force non-maximized mode, which also hides the Page Parameters toolbar button |
## Resource View Parameters
| Parameter | Type | Default | Description |
| ----------------------- | ------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `loadTeamAssignments` | Boolean | See application | Controls whether team-level assignment capacity records are used in resource view calculations instead of individual user calendars |
| `Load_Team_Assignments` | Boolean | See application | Alternative spelling for `loadTeamAssignments`. Both parameter forms are supported |
| `LoadUserCalendars` | Boolean | See application | Enables per-user working calendars for effective hours calculation in the resource view. When `false`, the global project calendar is used |
**Parameter Spelling**
Both `loadTeamAssignments` and `Load_Team_Assignments` are accepted. Use consistent spelling across your deployment to avoid confusion.
## URL Parameter Format
Append parameters to the Polarion page URL using standard query string syntax:
```
https://your-polarion.example.com/polarion/#/project/MyProject/wiki/GanttPage?MaximizeGanttView=false
```
Multiple parameters are separated by `&`:
```
https://your-polarion.example.com/polarion/#/project/MyProject/wiki/GanttPage?MaximizeGanttView=false&loadTeamAssignments=true
```
## Resource Calendar Resolution
The resource view URL parameters control a three-level calendar resolution cascade:
| Configuration | Calendar Source | URL Parameters |
| -------------------- | --------------------------------------------- | --------------------------- |
| Global calendar only | Project-wide working calendar | Default (no URL parameters) |
| Per-user calendars | Individual user working calendars | `LoadUserCalendars=true` |
| Team assignments | Team capacity multipliers over user calendars | `loadTeamAssignments=true` |
## MaximizeGanttView Effects
The `MaximizeGanttView` parameter controls several related behaviors:
| When `MaximizeGanttView=false` | Effect |
| ------------------------------ | --------------------------------------------------------- |
| Page Parameters button | Hidden from the toolbar |
| Gantt layout | Embedded within the Polarion page layout (not fullscreen) |
| Toolbar | Standard toolbar display |
| When `MaximizeGanttView=true` (or not set) | Effect |
| ------------------------------------------ | --------------------------------- |
| Page Parameters button | Visible in the toolbar |
| Gantt layout | Fills the browser viewport |
| Toolbar | Full toolbar with settings button |
## Configuration Example
Open a Gantt chart with team assignments enabled and non-maximized view:
```
?MaximizeGanttView=false&loadTeamAssignments=true
```
Open a Gantt chart with per-user calendars for accurate resource capacity:
```
?LoadUserCalendars=true
```
## Related Pages
* [Toolbar Actions and Keyboard Shortcuts](/gantt/reference/keyboard-shortcuts) -- Page Parameters button visibility
* [Resource View Parameters](/gantt/reference/widget-parameters/resource-view) -- resource view widget configuration
* [Working Calendars Parameters](/gantt/reference/widget-parameters/working-calendars) -- calendar widget parameters
* [Team and Resource Properties](/gantt/reference/configuration/team-properties) -- team assignment configuration
# Baselines Parameters
Source: https://learn.nextedy.com/gantt/reference/widget-parameters/baselines
Nextedy GANTT supports baseline comparison to visualize the difference between the current schedule and a historical schedule snapshot.
## Baselines Widget Parameters
| Name | Type | Default | Description |
| ----------------- | ------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `Show Baselines` | Boolean | `false` | When enabled, the Gantt automatically loads and displays baseline data on every page load using the configured `Compare to date` value. |
| `Compare to date` | String | Empty | The default comparison reference point. Accepts a relative date (T-minus), a specific date, or a page parameter reference. Only visible when `Show Baselines` is `true`. |
**Parameter Dependency**
The `Compare to date` parameter only appears in the widget parameter editor after you set **Show Baselines** to `Yes`.
## Comparison Modes
The Gantt supports three methods for comparing the current schedule against a historical snapshot:
| Mode | Description | Available Since |
| -------------- | --------------------------------------------------------------------------------------------------------- | --------------- |
| Specific date | Select a calendar date to compare against. The Gantt loads task positions as of that date. | Version 1.5 |
| Named baseline | Select a named Polarion baseline from a dropdown. The baseline revision provides the historical snapshot. | Version 2.4.0 |
| SVN revision | Enter a specific SVN revision number. The system validates the revision exists before applying. | Version 25.3.0 |
## Automatic vs. One-Time Comparison
**Automatic comparison** (`Show Baselines` = `Yes`): The Gantt loads baseline data on every page render using the `Compare to date` value. Baseline bars are always visible.
**One-time comparison** (toolbar button): Click the **Compare with History** toolbar button to open a dialog where you select the comparison mode and reference point. The comparison persists until you close it or navigate away.
**One-Time Overrides Automatic**
When `Show Baselines` is configured but the user triggers a one-time comparison with a different date, the one-time comparison takes precedence and refreshes the baseline display.
## Compare to Date Formats
The `Compare to date` widget parameter accepts the following formats:
| Format | Example | Description |
| ------------------ | ------------ | --------------------------------------------------------------------------------- |
| Relative (T-minus) | `T-30` | Compare against the schedule 30 days ago. |
| Specific date | `2024-01-15` | Compare against a fixed historical date. |
| Page parameter | `$pageParam` | Use a Polarion page parameter value, allowing users to pick the date dynamically. |
## NEW Badge for Added Tasks
Since version **25.3.0**, tasks created after the selected comparison point are marked with a **NEW** badge. This helps you identify work items that were added to the schedule after the baseline was taken.
## Baseline Data Fields
When baseline comparison is active, the Gantt data response includes two additional fields per task:
| Field | Type | Description |
| -------------------- | ------ | --------------------------------------------------------------------- |
| `planned_start_date` | Date | The start date of the task as of the comparison date. |
| `planned_duration` | Number | The duration (in working days) of the task as of the comparison date. |
These fields drive the secondary baseline bar rendered below each current task bar.
## Baseline API
Named baselines are fetched from the Polarion server via the baselines API endpoint. Each baseline record contains:
| Field | Type | Description |
| ------------ | ------ | ----------------------------------------------------- |
| `revisionId` | String | The SVN revision number associated with the baseline. |
| `name` | String | The user-defined name of the baseline. |
| `created` | Date | The creation timestamp of the baseline. |
## Pre-Conditions
* **Unsaved changes:** The Compare with History dialog cannot be opened when the Gantt has unsaved edits. Save or discard changes before comparing.
* **Read-only mode:** Baseline comparison is fully available in read-only mode.
## Item Script Approach
For item-specific baselines (instead of a single historical date), use the [Item Script API](/gantt/reference/api/item-script-api) to set planned dates per item:
```javascript theme={null}
task.planned_start_date = util.getDate(wi, "gantt_initial_start");
task.planned_duration = util.getDuration(wi, "gantt_initial_duration");
```
This compares each item against its own saved initial schedule rather than a single global date.
## Configuration Example
To show automatic baseline comparison against a date 30 days ago:
1. Open **Widget Properties** for the Gantt widget.
2. In the **Baselines** section:
* Set **Show Baselines** to `Yes`.
* Set **Compare to date** to `T-30`.
3. Save the widget parameters.
The Gantt chart now displays baseline bars on every load, comparing the current schedule against the state 30 days prior.
## Related Pages
* [Work Items Gantt Widget Parameters](/gantt/reference/widget-parameters/work-items-gantt) -- main widget parameters
* [Item Script API](/gantt/reference/api/item-script-api) -- per-item baseline scripting
* [Toolbar Actions and Keyboard Shortcuts](/gantt/reference/keyboard-shortcuts) -- Compare with History toolbar button
# Column Configuration Parameters
Source: https://learn.nextedy.com/gantt/reference/widget-parameters/columns
Nextedy GANTT provides configurable grid columns that display work item field values alongside the Gantt chart.
## Column Properties
Each column added to the **Columns** configuration block exposes the following sub-parameters:
| Name | Type | Default | Description |
| ------------- | ------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `Field` | String | See application | The Polarion work item field ID that this column reads its value from (e.g., `priority`, `status`, `dueDate`). Custom fields are supported. |
| `Other Field` | String | See application | An additional field reference used when the column type is set to custom field. Only visible when the column type is `CUSTOM_FIELD`. |
| `ID` | String | See application | Unique column identifier used internally and for saving/restoring column widths per user. Must be stable across sessions. |
| `Label` | String | See application | Human-readable column header label. If not set, the field's Polarion display label is used as a fallback. |
| `Width` | Integer | `300` | Column width in pixels. Can be overridden by user settings when a user resizes the column. |
| `Align` | Enum | `left` | Text alignment for column cell content: `left`, `center`, or `right`. Numeric fields are typically right-aligned. |
| `Render` | String | See application | Template identifier or function name defining how the cell value is rendered. Only visible when the column type is `CUSTOM_FIELD`. |
**Parameter Dependency**
The `Other Field` and `Render` sub-parameters only appear in the widget parameter editor when the column type is set to `CUSTOM_FIELD`. This progressive disclosure keeps the column configuration clean for standard field columns.
## Column Template IDs
The `Render` parameter accepts the following built-in template identifiers, each providing a specialized rendering for the column cell:
| Template ID | Description |
| ------------ | ---------------------------------------------------------------------------------------------------------- |
| `deadline` | Renders deadline dates in **red text** when the task is overdue. Uses the configured deadline time format. |
| `start_date` | Renders the task's start date using the configured date format. |
| `end_date` | Renders the task end date. Applies the same high-precision correction as `start_date`. |
| `owner` | Renders the list of assigned resources as circles (initials mode) or full names (fullname mode). |
| `user` | Renders a user field value using the same display logic as the owner column. |
| `standard` | Renders a standard duration value in the column cell. |
| `null` | Renders an empty cell. Use this when a column is reserved for layout purposes. |
| `other` | Renders the raw field value as a string with no special formatting. |
## Assignee Column Display Mode
The assignee (owner) column supports two display modes, controlled by the `nextedy.gantt.assignee_column_display_mode` administration property:
| Mode | Value | Description |
| --------- | ---------- | --------------------------------------------------------------------------------- |
| Initials | `initials` | Displays each assigned user as a circle with their initials. This is the default. |
| Full name | `fullname` | Displays the full display name of each assigned user. |
Set this property in **Administration > Configuration Properties**:
```
nextedy.gantt.assignee_column_display_mode=fullname
```
## Selected Workload Column
The Gantt provides a special workload column that displays the planned effort hours for the currently selected resource within the active time range. This column:
* Only appears when a resource is selected in the [resource view](/gantt/reference/widget-parameters/resource-view).
* Shows per-task effort hours based on the active `Resource Load Calculation` mode (`time` or `remaining`).
* Disappears when no resource is selected.
**Verify in application**
The exact rendering of the workload column values depends on the `resourceLoadMode` configuration. Verify the column behavior with your specific Gantt version.
## Progress Column
The progress column template renders numeric progress values rounded to two decimal places. The progress value corresponds to the field configured in the [Data Mapping Parameters](/gantt/reference/widget-parameters/data-mapping) as the `Progress Field`.
## Column Width Persistence
When a user resizes a column by dragging the column border, the new width is saved to the browser's local storage. On subsequent page loads, the Gantt restores the saved column widths automatically. This persistence is keyed by the column ID, the document URL, and the widget version.
To reset all column widths to their defaults, use the **Reset View** toolbar action.
## Default Column Set
The Gantt ships with the following default columns:
| Column | Description |
| ----------------- | --------------------------- |
| WBS (task number) | Hierarchical task numbering |
| Title | Task label with tree indent |
| Start date | Task start date |
| End date | Task end date |
| Duration | Task duration value |
| Assignee | Assigned resource(s) |
## First Column Menu
The first grid column header contains a menu icon that opens the Gantt menu. This menu provides access to column visibility toggles, scale options, and navigation actions.
## Configuration Example
To add a custom `priority` column to the Gantt grid:
1. Open **Widget Properties** for the Gantt widget.
2. In the **Columns** section, add a new column entry:
* Set **Field** to `priority`.
* Set **Label** to `Priority`.
* Set **Width** to `100`.
* Set **Align** to `center`.
3. Save the widget parameters.
The priority field value now appears as a centered column in the Gantt grid.
## Related Pages
* [Table and Grid Configuration](/gantt/reference/widget-parameters/table-configuration) -- grid width and first column settings
* [Data Mapping Parameters](/gantt/reference/widget-parameters/data-mapping) -- field binding for start, end, duration, progress
* [Resource View Parameters](/gantt/reference/widget-parameters/resource-view) -- resource allocation display
* [Color and Styling Properties](/gantt/reference/configuration/color-properties) -- resource marker color customization
* [Zoom and Scale Levels Reference](/gantt/reference/zoom-scale-levels) -- timeline scale configuration
# Data Mapping Parameters
Source: https://learn.nextedy.com/gantt/reference/widget-parameters/data-mapping
Nextedy GANTT data mapping parameters define how Polarion work item fields are mapped to Gantt scheduling properties.
## Field Mapping Parameters
| Parameter | Type | Default | Supported Field Types | Description |
| -------------------- | ------ | ----------------- | ---------------------- | --------------------------------------------------------------------------------------------------- |
| `Start Field` | String | `gantt_start` | Date, DateTime, String | Work item field storing the task start date. |
| `End Field` | String | None | Date, DateTime, String | Work item field storing the task end date. |
| `Duration Field` | String | `gantt_duration` | Integer, String | Work item field storing the task duration in days (or hours in high-precision mode). |
| `Progress Field` | String | `gantt_progress` | Float, String | Work item field storing the task progress as a float value from 0.0 (0%) to 1.0 (100%). |
| `Duration Precision` | Enum | `Standard (Days)` | N/A | Controls whether durations are tracked in days or hours. Values: `Standard (Days)`, `High (Hours)`. |
## Valid Field Combinations
You must configure at least two of the three date-related fields. The Gantt calculates the missing field from the other two.
| Combination | Start Field | End Field | Duration Field | Behavior |
| ---------------- | ----------- | --------- | -------------- | ----------------------------------------- |
| Start + Duration | Required | Not set | Required | End date calculated from start + duration |
| Start + End | Required | Required | Not set | Duration calculated from date range |
| End + Duration | Not set | Required | Required | Start date calculated from end - duration |
If only one date field is mapped, the Gantt cannot calculate task scheduling. Tasks will appear at default positions without correct date representation.
## Recommended Field Types
For production use, configure proper Polarion custom fields with the recommended types:
| Field | Recommended Type | Ad-Hoc Fallback | Notes |
| -------------- | ---------------- | --------------- | -------------------------------------------------- |
| Start Field | Date (Only) | String | Date fields provide native date picker in Polarion |
| End Field | Date (Only) | String | Date fields ensure proper date validation |
| Duration Field | Integer | String | Integer provides numeric validation |
| Progress Field | Float | String | Float supports decimal precision (0.0 - 1.0) |
If a mapped custom field does not exist in Polarion, the Gantt automatically creates and uses a String ad-hoc custom field. While functional for testing, ad-hoc fields lack type validation and are not recommended for production use.
## Duration Precision
The `Duration Precision` parameter switches the entire Gantt between day-based and hour-based scheduling:
| Mode | Duration Unit | Date Format | Use Case |
| ----------------- | ------------- | ----------- | -------------------------------------------- |
| `Standard (Days)` | Days | Date only | Sprint planning, release scheduling |
| `High (Hours)` | Hours | Date + Time | Fine-grained task scheduling, shift planning |
Switching to `High (Hours)` precision changes the date format across the entire Gantt instance. All date fields display time components, and durations are stored in hours. See [Schedule in Hours Instead of Days](/gantt/guides/scheduling/hour-precision).
## Administration Defaults
Default data mapping values for new Work Items Gantt widget instances:
| Property | Default | Description |
| ------------------------------------------------ | ---------------- | --------------------------- |
| `nextedy.gantt.workitems.default.start_field` | `gantt_start` | Default start field name |
| `nextedy.gantt.workitems.default.end_field` | None | Default end field name |
| `nextedy.gantt.workitems.default.duration_field` | `gantt_duration` | Default duration field name |
| `nextedy.gantt.workitems.default.progress_field` | `gantt_progress` | Default progress field name |
## Configuration Example
A typical data mapping for a project using custom Polarion Date fields:
* **Start Field**: `plannedStart` (Date field)
* **End Field**: `plannedEnd` (Date field)
* **Duration Field**: `gantt_duration` (Integer field)
* **Progress Field**: `gantt_progress` (Float field)
* **Duration Precision**: `Standard (Days)`
With this mapping, the Gantt reads start and end dates from the plan fields, calculates duration automatically, and tracks progress via the float field.
## Plans Gantt Data Mapping
When **Show Plan Work Item** is enabled in the Plans Gantt, an equivalent set of data mapping fields appears for the work items displayed under each plan:
| Parameter | Description |
| ------------------------ | -------------------------------------------- |
| `Start Field` (Plans) | Start date field for work items within plans |
| `End Field` (Plans) | End date field for work items within plans |
| `Duration Field` (Plans) | Duration field for work items within plans |
| `Progress Field` (Plans) | Progress field for work items within plans |
These follow the same rules and field type requirements as the Work Items Gantt data mapping.
## See Also
* [Work Items Gantt Widget Parameters](/gantt/reference/widget-parameters/work-items-gantt)
* [Plans Gantt Widget Parameters](/gantt/reference/widget-parameters/plans-gantt)
* [Schedule in Hours Instead of Days](/gantt/guides/scheduling/hour-precision)
* [Supported Field Types](/gantt/reference/supported-field-types)
* [Default Configuration Values](/gantt/reference/configuration/default-values)
# Deadlines Parameters
Source: https://learn.nextedy.com/gantt/reference/widget-parameters/deadlines
Nextedy GANTT can display deadline markers on the Gantt chart to differentiate between a task's planned end date and its hard deadline (due date).
## Deadlines Widget Parameters
| Name | Type | Default | Description |
| ----------------------- | ------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `Show Deadlines` | Boolean | `false` | Master toggle that enables deadline marker display on the Gantt chart. All parameters below require this to be `true`. |
| `Deadline Field` | String | Empty | The Polarion work item field name that holds the deadline date. Must be a Date-Only or String type field. Only visible when `Show Deadlines` is `true`. |
| `Passed Deadline Color` | String | See application | The CSS color applied to task bars where the end date extends past the deadline date. Accepts named colors (e.g., `red`) or hex codes (e.g., `#e53935`). Only visible when `Show Deadlines` is `true`. |
**Parameter Dependency**
The `Deadline Field` and `Passed Deadline Color` parameters only appear in the widget parameter editor after you set **Show Deadlines** to `Yes`.
## How Deadline Coloring Works
The deadline coloring logic compares the task's **end date** against the **deadline field value**:
**End Date Comparison, Not Current Date**
The passed deadline color indicates a **schedule violation** -- the task's planned end date extends beyond its due date. It does **not** compare the deadline against today's date. To implement date-relative deadline coloring based on the current date, use a custom [Item Script](/gantt/reference/api/item-script-api).
## Deadline Column
When deadlines are enabled, you can add a dedicated deadline column to the Gantt grid using the [Column Configuration Parameters](/gantt/reference/widget-parameters/columns). The deadline column:
* Displays the deadline date in a compact format (e.g., `Sep-09`, `Nov-30`).
* Shows the date in **red text** when the task is overdue (end date past deadline).
* Uses the `deadline` template ID in the column configuration.
## Supported Field Types
The `Deadline Field` parameter accepts the following Polarion custom field types:
| Field Type | Notes |
| ---------- | ------------------------------------------------------------------------ |
| Date-Only | Recommended. Stores a calendar date without time component. |
| String | Stores the date as a string value. For production use, prefer Date-Only. |
For a full list of supported field types, see [Supported Field Types](/gantt/reference/supported-field-types).
## Configuration Example
To enable deadline tracking using a custom field called `dueDate`:
1. Open **Widget Properties** for the Gantt widget.
2. In the **Deadlines** section:
* Set **Show Deadlines** to `Yes`.
* Set **Deadline Field** to `dueDate`.
* Set **Passed Deadline Color** to `#e53935` (red).
3. Save the widget parameters.
Tasks with a `dueDate` value now display a deadline marker on the chart. If a task's end date extends past the `dueDate`, the task bar turns red.
## Dynamic Deadline Coloring via Item Script
For more advanced deadline logic (e.g., coloring based on proximity to the deadline or current date comparison), use the [Item Script API](/gantt/reference/api/item-script-api):
```javascript theme={null}
// Color task yellow if within 7 days of deadline, red if past
var deadline = util.getDate(wi, "dueDate");
var today = new java.util.Date();
if (deadline != null) {
var daysLeft = (deadline.getTime() - today.getTime()) / (1000 * 60 * 60 * 24);
if (daysLeft < 0) {
task.color = "#e53935"; // Past deadline
} else if (daysLeft < 7) {
task.color = "#fb8c00"; // Approaching deadline
}
}
```
**Verify in application**
The Item Script approach provides more control than the built-in `Passed Deadline Color` parameter. Verify the exact `util.getDate()` API in your Gantt version.
## Related Pages
* [Column Configuration Parameters](/gantt/reference/widget-parameters/columns) -- adding a deadline column to the grid
* [Item Script API](/gantt/reference/api/item-script-api) -- custom deadline coloring logic
* [Color and Styling Properties](/gantt/reference/configuration/color-properties) -- global color configuration
* [Data Mapping Parameters](/gantt/reference/widget-parameters/data-mapping) -- mapping work item fields for scheduling
# Widget Parameters
Source: https://learn.nextedy.com/gantt/reference/widget-parameters/index
Nextedy GANTT widget parameters control the behavior and appearance of each Gantt chart instance.
Dataset selection, hierarchy roles, dependency roles, and display settings for the Work Items Gantt.
Plan dataset, child levels, sort order, and plan-specific display settings for the Plans Gantt.
Field mappings for start date, end date, duration, progress, and duration precision.
Project type, milestone type, and per-type presentation and field filter settings.
Resource view toggle, load mode, resource field, and display options.
Calendar toggles, user calendar loading, team assignments, and year range.
## Additional Parameter Categories
* **[Baselines Parameters](/gantt/reference/widget-parameters/baselines)** -- Baseline comparison toggle and date selection
* **[Deadlines Parameters](/gantt/reference/widget-parameters/deadlines)** -- Deadline marker display and color settings
* **[Column Configuration Parameters](/gantt/reference/widget-parameters/columns)** -- Grid column definitions and editors
* **[Table and Grid Configuration](/gantt/reference/widget-parameters/table-configuration)** -- Grid width, first column display, and layout
**One widget per page**
Only one Gantt widget (Work Items or Plans) is supported per Polarion wiki page. To display multiple views, use separate wiki pages or dynamic page parameters to switch queries.
# Plans Gantt Widget Parameters
Source: https://learn.nextedy.com/gantt/reference/widget-parameters/plans-gantt
Complete reference for all Nextedy GANTT Plans Gantt widget parameters.
**One widget per page**
Only one Gantt widget (Work Items or Plans) is supported per Polarion wiki page.
## Core Parameters
| Parameter | Type | Default | Description |
| ---------------- | ------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `Plans` | Dataset | See application | Standard Polarion dataset parameter. Select which plans to display using query, collection, or scope. |
| `Sort by` | String | `id` | Sort criteria for top-level plan items. |
| `Load Children` | Integer | `0` | Number of child plan levels to traverse and add. `0` means only top-level plans are shown. |
| `Show Unplanned` | Boolean | `true` | When `yes`, plans without start dates are shown at today's date in gray. When `no`, they are hidden. |
| `Scale` | Enum | `W` | Timeline scale unit. Values: `H` (hour), `DD` (bi-daily), `D` (day), `W` (week), `M` (month), `Q` (quarter), `Y` (year), `YY` (multi-year). |
Plans typically span longer time ranges than individual work items. Use `W` (week), `M` (month), or `Y` (year) scale for better readability of plan-level scheduling.
## Show Plan Work Item Section
When enabled, work items belonging to each plan are displayed beneath the plan bar in the Gantt hierarchy.
| Parameter | Type | Default | Description |
| ------------------- | ------------------------- | --------------- | --------------------------------------------------------------------------- |
| `Enable Show Items` | Boolean | `false` | Enables displaying work items within plans on the Gantt chart. |
| `Start Field` | String | See application | Work item field storing the task start date (when showing plan work items). |
| `End Field` | String | See application | Work item field storing the task end date. |
| `Duration Field` | String | See application | Work item field storing the task duration. |
| `Progress Field` | String | See application | Work item field storing the task progress (0.0 to 1.0). |
| `Parent Role` | Multi-select (link roles) | Empty | Link roles for parent-child hierarchy among work items within a plan. |
| `Dependency Role` | Multi-select (link roles) | Empty | Link roles for dependency arrows among work items within a plan. |
## Advanced Parameters
| Parameter | Type | Default | Description |
| ----------------------- | --------------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `Maximize View` | Boolean | `false` | Expands the Gantt widget to fill the full working area. |
| `Height` | Integer | See application | Fixed pixel height of the Plans Gantt panel. |
| `Hide Toolbar` | Boolean | `false` | Hides the toolbar. Implicitly enables always-edit mode. |
| `Drag Children` | Boolean | `true` | Rescheduling a parent plan also moves child plans by the same offset. |
| `Max Items` | Integer | `100` | Maximum number of plans loaded into the Gantt view. |
| `Progress Coloring` | Boolean | `true` | Color-codes plan bars based on progress percentage. |
| `Read-only` | Boolean | `false` | Prevents edits to the Plans Gantt. |
| `Show Today Marker` | Boolean | `true` | Displays a vertical line on today's date. |
| `Override Today's Date` | String (`YYYY-MM-DD`) | Empty | Overrides the date treated as "today" on the chart. |
| `Working Time` | Boolean | See application | Enables legacy working time mode (weekends as non-working). For advanced calendar features, use the Working Calendars section instead. |
## Scripting Parameters
| Parameter | Type | Default | Description |
| --------------------- | ------ | ------- | ------------------------------------------------------------------------------------------------------------------------- |
| `Gantt Config Script` | Script | Empty | Client-side JavaScript for advanced configuration. See [Gantt Config Script API](/gantt/reference/api/config-script-api). |
| `Item Script` | Script | Empty | Server-side JavaScript per plan item for custom decoration. See [Item Script API](/gantt/reference/api/item-script-api). |
| `Markers Script` | Script | Empty | Server-side JavaScript for creating timeline markers. See [Marker Factory API](/gantt/reference/api/markers-api). |
The `Sort by` parameter controls the order of top-level plan items, but custom sorting options for plans are more limited than for work items. Plans cannot be sorted via the same parameter-based mechanisms available in the Work Items Gantt.
## Configuration Example
A typical Plans Gantt configuration for release and iteration planning:
* **Plans**: Query selecting all plans with template `Release`
* **Load Children**: `2` (to show iterations under releases and work items under iterations)
* **Enable Show Items**: `true`
* **Start Field**: `gantt_start`
* **Duration Field**: `gantt_duration`
* **Parent Role**: `parent`
* **Dependency Role**: `depends_on`
* **Scale**: `M`
* **Maximize View**: `true`
## Administration Defaults
Plans Gantt widget parameter defaults can be set in **Administration > Configuration Properties**:
| Property | Default | Description |
| ----------------------------------------------- | ------- | ------------------------- |
| `nextedy.gantt.plans.default.sort_by` | `id` | Default sort field |
| `nextedy.gantt.plans.default.expand_level` | `0` | Default child levels |
| `nextedy.gantt.plans.default.show_unplanned` | `true` | Default show unplanned |
| `nextedy.gantt.default.plans.scale` | `W` | Default scale |
| `nextedy.gantt.plans.default.maximize_view` | `false` | Default maximize |
| `nextedy.gantt.plans.default.hide_toolbar` | `false` | Default hide toolbar |
| `nextedy.gantt.plans.default.progress_coloring` | `true` | Default progress coloring |
| `nextedy.gantt.plans.default.drag_children` | `true` | Default drag children |
## See Also
* [Work Items Gantt Widget Parameters](/gantt/reference/widget-parameters/work-items-gantt)
* [Data Mapping Parameters](/gantt/reference/widget-parameters/data-mapping)
* [Set Up a Plans Gantt Chart](/gantt/getting-started/setup-plans-gantt)
* [Show Plans and Work Items Together](/gantt/guides/plans/plans-and-work-items)
* [Configure Multiple Plan Levels](/gantt/guides/plans/plan-level-configuration)
# Resource View Parameters
Source: https://learn.nextedy.com/gantt/reference/widget-parameters/resource-view
Nextedy GANTT provides a resource view panel below the Gantt chart that displays per-resource workload allocation with color-coded capacity markers.
## Resource View Widget Parameters
| Name | Type | Default | Description |
| ------------------------------- | ------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `Show Resource View` | Boolean | `false` | Master toggle that enables the resource view panel below the Gantt chart. All parameters below require this to be `true`. |
| `Resource Load Calculation` | Enum | See application | Controls how resource utilization is calculated and displayed. See [Load Modes](#load-modes) below. |
| `Resource Field` | String | See application | The Polarion work item field used to determine the assigned resource (user ID). Drives the resource view rows and the resource filter. |
| `Resource Label` | String | See application | Controls the display label for each resource row in the resource view. |
| `Show Unassigned` | Boolean | See application | When enabled, displays an "Unassigned" row for tasks that have no resource assignment. |
| `Items per resource - OK limit` | Integer | `1` | The threshold number of items or hours below which the resource marker displays in the "OK" (green) color. |
| `View Height` | Integer | `250` | The pixel height of the resource view panel. |
**Parameter Visibility**
The `Resource Load Calculation`, `Resource Field`, `Resource Label`, `Show Unassigned`, `Items per resource - OK limit`, and `View Height` parameters only appear in the widget parameter editor after you set **Show Resource View** to `Yes`. This progressive disclosure avoids clutter when the resource view is not in use.
## Load Modes
The `Resource Load Calculation` parameter determines how workload is computed for each resource:
| Mode | Value | Description |
| --------------------- | ------------ | --------------------------------------------------------------------------------------------------------- |
| Leaf Items Count | `num` | Counts the number of (leaf) items assigned to the resource in each time period. |
| Estimate + Spent | `time` | Sums each resource's time estimate plus time spent, based on task duration and the working calendar. |
| Remaining Estimate | `remaining` | Sums the remaining estimated hours for each resource in the visible time range. |
| Assignment Allocation | `allocation` | Calculates the allocation percentage against the resource's available capacity from the working calendar. |
## Resource Marker Colors
The resource view displays color-coded markers for each time cell:
| Marker State | Default Color | Description |
| -------------------- | ------------------- | ----------------------------------------------------------------------- |
| Within capacity (OK) | `#4CAF50` (green) | The resource is at or below the configured capacity threshold. |
| Over capacity | Red/orange gradient | The resource exceeds the capacity threshold, indicating overallocation. |
You can customize these colors using the `resourceMarkersColorConfig` property in [Color and Styling Properties](/gantt/reference/configuration/color-properties).
## Leaf Task Filtering
The `onlyLeafTasks` configuration property affects resource view calculations:
* When `onlyLeafTasks` is `true`, only leaf tasks (tasks with no children) are counted in resource allocation.
* Parent or summary tasks (presentation mode `Derived Schedule`) are excluded from workload calculations.
* Work items that have a parent presentation mode but no visible children due to filtering are treated as leaf items and included in calculations.
**Verify in application**
The exact behavior of filtered workpackages without visible children in resource calculations may vary by version. Verify the resource count behavior in your specific Gantt version.
## Unassigned Resource Row
Tasks with no value in the configured `Resource Field` are grouped under a synthetic "Unassigned" resource row. This row uses the internal constant `UNASSIGNED_ID` and appears at the bottom of the resource view when `Show Unassigned` is enabled.
## Team-Based Resource View
When team assignments are enabled (via [Team and Resource Properties](/gantt/reference/configuration/team-properties)), the resource view displays team rows instead of individual user rows. In team mode:
* Each team appears as a resource row with aggregated workload from all assigned tasks.
* The lightbox shows a team picker instead of a user picker for the resource field.
* Capacity is derived from team assignment records rather than individual working calendars.
## Configuration Example
To enable a resource view showing estimate-and-spent allocation:
1. Open **Widget Properties** for the Gantt widget.
2. In the **Resource View** section, set **Show Resource View** to `Yes`.
3. Set **Resource Load Calculation** to `Estimate + Spent`.
4. Set **Resource Field** to the Polarion field holding the assignee (e.g., `assignee`).
5. Optionally enable **Show Unassigned** to see unassigned tasks.
6. Save the widget parameters.
**Working Calendars for Accurate Load**
For accurate resource load calculations, enable [Working Calendars](/gantt/reference/widget-parameters/working-calendars) so that non-working days, holidays, and per-user schedule exceptions are reflected in the capacity values.
## Related Pages
* [Working Calendars Parameters](/gantt/reference/widget-parameters/working-calendars) -- calendar settings affecting capacity calculations
* [Color and Styling Properties](/gantt/reference/configuration/color-properties) -- resource marker color customization
* [Team and Resource Properties](/gantt/reference/configuration/team-properties) -- team-based assignment configuration
* [View Resource Allocation](/gantt/getting-started/first-resource-view) -- tutorial for first-time setup
# Table and Grid Configuration
Source: https://learn.nextedy.com/gantt/reference/widget-parameters/table-configuration
Nextedy GANTT displays a grid panel on the left side of the Gantt chart containing task data columns.
## Table Widget Parameters
| Name | Type | Default | Description |
| ------- | ------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `WIDTH` | Integer | See application | The total width of the grid panel (left side of the Gantt chart) in pixels. This controls the split point between the grid and the timeline area. |
## First Column Configuration
The first column always appears in the grid and displays the task label. The `FIRST_COL` configuration block controls what information is shown in this column:
| Name | Type | Default | Description |
| --------------------- | ------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `FIRST_COL.showId` | Boolean | See application | When `true`, the first column displays the work item ID prefix (e.g., `WI-123:`) before the title. |
| `FIRST_COL.showTitle` | Boolean | See application | When `true`, the first column displays the work item title text. Set to `false` if only the ID is needed. |
| `FIRST_COL.showIcon` | Boolean | See application | When `true`, the first column displays the work item type icon before the label. Type icons help visually distinguish work item types (task, milestone, work package) in the grid. |
**Compact First Column**
Set `FIRST_COL.showId` to `true` and `FIRST_COL.showTitle` to `false` to create a compact first column that shows only work item IDs. This is useful for dense schedules where screen space is limited.
## Columns List
The `COLUMNS` list parameter defines additional data columns that appear after the first column. Each column entry is configured with field mapping, label, width, alignment, and render template properties. For detailed column sub-parameters, see [Column Configuration Parameters](/gantt/reference/widget-parameters/columns).
The default columns list includes:
| Column | Field | Description |
| ---------- | -------------- | ----------------------------------------------- |
| WBS | Task number | Hierarchical work breakdown structure numbering |
| Title | Task label | Task label with tree indent |
| Start date | Start field | Task start date |
| End date | End field | Task end date |
| Duration | Duration field | Task duration value |
| Assignee | Resource field | Assigned resource(s) |
## Column Custom Field Dependency
When you add a column and set its type to `CUSTOM_FIELD`, the widget parameter editor reveals two additional sub-parameters:
* **Other Field** -- specifies an alternate field reference for the custom column.
* **Render** -- specifies the rendering template for the custom field column.
These parameters are hidden for standard field columns to reduce clutter in the configuration panel.
## User Settings Persistence
The Gantt saves user-specific grid preferences to the browser's local storage. The following settings are persisted per user:
| Setting | Description |
| ------------- | ------------------------------------------------------------------------- |
| Zoom scale | The current timeline zoom level (e.g., `W` for week, `M` for month). |
| Column widths | Individual column widths after user resizing. |
| Grid width | The overall grid panel width (the split point between grid and timeline). |
These preferences are keyed by the document URL and widget version. When a user returns to the same Gantt page, the saved zoom level, column widths, and grid width are restored automatically.
**Reset to Defaults**
Use the **Reset View** toolbar action to clear all saved user settings and restore the Gantt to its default zoom level and column layout.
## Grid Width Behavior
The grid width (`WIDTH` parameter) sets the initial width of the left panel. Users can adjust the grid width by dragging the splitter between the grid and the timeline. The adjusted width is saved to local storage and restored on subsequent visits.
If no `WIDTH` parameter is set, the Gantt uses a default width determined by the sum of configured column widths.
## Configuration Example
To configure a compact grid with work item IDs and a priority column:
1. Open **Widget Properties** for the Gantt widget.
2. In the **Table** section:
* Set **WIDTH** to `400`.
* Set **FIRST\_COL.showId** to `Yes`.
* Set **FIRST\_COL.showTitle** to `Yes`.
* Set **FIRST\_COL.showIcon** to `Yes`.
3. In the **Columns** section, add a column entry:
* Set **Field** to `priority`.
* Set **Label** to `Priority`.
* Set **Width** to `80`.
4. Save the widget parameters.
The Gantt grid now displays a 400px-wide panel with the task label (including icon and ID) in the first column, followed by the default columns and the added priority column.
## Related Pages
* [Column Configuration Parameters](/gantt/reference/widget-parameters/columns) -- per-column field mapping, templates, and rendering
* [Work Items Gantt Widget Parameters](/gantt/reference/widget-parameters/work-items-gantt) -- main widget parameters
* [Zoom and Scale Levels Reference](/gantt/reference/zoom-scale-levels) -- timeline scale options
* [Toolbar Actions and Keyboard Shortcuts](/gantt/reference/keyboard-shortcuts) -- Reset View and other toolbar actions
# Work Item Types Configuration
Source: https://learn.nextedy.com/gantt/reference/widget-parameters/work-item-types
Nextedy GANTT uses per-type configuration to control how each Polarion work item type is displayed and behaves on the Gantt chart.
## Per-Type Configuration Parameters
Each work item type added to the **Work Item Types** configuration block exposes the following sub-parameters:
| Name | Type | Default | Description |
| -------------------------- | ---------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Gantt Presentation Mode` | Enum | See application | Controls how the type renders on the chart: `Item` (a regular task bar), `Derived Schedule` (a summary bar whose schedule comes from children), `Auto-Mode` (`Derived` if the item has children, else `Item`), or `Milestone` (a single-date diamond with zero duration). |
| `Parent Mode` | Enum | See application | Determines how parent-child hierarchy is resolved for this type. Options include link-role-based or enumeration-based parent resolution. |
| `Parent Enum` | String | See application | When `Parent Mode` uses enumeration-based resolution, specifies the enum field to determine the parent work item. |
| `Additional Dialog Fields` | Field list | Empty | Extra work item fields displayed in the lightbox editor for this type, beyond the standard start/end/duration/progress fields. |
| `Sync to Plans` | Boolean | `false` | When enabled, links work items of this type to a Polarion Plan and adds plan due date markers to the chart. |
| `Enable Create` | Boolean | `false` | When enabled, this type appears in the **New** toolbar dropdown, allowing users to create work items of this type directly from the Gantt chart. |
| `Extra Child Query` | String | Empty | A Lucene query that loads additional child items for this type beyond the standard parent-child link traversal. |
The dynamic "presentation depends on whether the item has children" behaviour is provided by the **`Auto-Mode`** value of `Gantt Presentation Mode` (it is not a separate boolean parameter).
Fields already bound as `Start Field`, `End Field`, `Duration Field`, or `Progress Field` in the [Data Mapping Parameters](/gantt/reference/widget-parameters/data-mapping) cannot be added to **Additional Dialog Fields**. The system validates this at load time and logs a warning for invalid field references.
## Default Work Item Types
The Gantt chart ships with three built-in work item type configurations:
| Type ID | Gantt Presentation Mode | Description |
| ------------- | ----------------------- | --------------------------------------------------------------------------------------- |
| `feature` | Item | Standard task bars displayed as individual bars on the chart. |
| `workpackage` | Derived Schedule | Parent containers displayed as summary bars whose schedule is derived from child items. |
| `release` | Milestone | Milestone-style containers rendered as diamond shapes with no duration. |
The default types serve as a starting reference. Override them in the widget parameter editor to match your project's work item type IDs (e.g., `epic`, `story`, `task`).
## Presentation Modes
**Item** -- Rendered as a standard task bar with start date, end date, and duration. The bar is directly editable by dragging.
**Derived Schedule** -- Rendered as a summary bar whose schedule is derived from its child items. You cannot directly drag the start or end date of a derived-schedule item; it auto-calculates from children.
**Auto-Mode** -- Renders as **Derived Schedule** when the item has children, otherwise as **Item**. Use it for a type that can be either a parent or a leaf.
**Milestone** -- Rendered as a diamond shape at a single point in time. Milestones have no duration.
## Collapse Behavior via Item Script
You can control the initial collapsed state of parent work items per type using the [Item Script API](/gantt/reference/api/item-script-api):
```javascript theme={null}
// Collapse all workpackage-type items by default
if (wi.getType().getId() === "workPackage") {
task.open = false;
}
```
This sets the `task.open` property to `false`, causing the item to appear collapsed when the Gantt chart loads.
## Work Items Gantt vs. Plans Gantt
The per-type configuration applies differently depending on the Gantt mode:
| Aspect | Work Items Gantt | Plans Gantt |
| ------------------------ | -------------------------------------------- | ---------------------------------- |
| Type source | Polarion work item type ID | Plan template type |
| Presentation modes | Item, Derived Schedule, Auto-Mode, Milestone | Derived Schedule, Milestone |
| Enable Create | Creates a new work item | Creates a new plan from a template |
| Parent resolution | Link roles or enumeration | Plan hierarchy |
| Additional Dialog Fields | Work item custom fields | Plan-level fields |
For Plans Gantt configuration, see [Plans Gantt Widget Parameters](/gantt/reference/widget-parameters/plans-gantt).
## Configuration Example
To configure an `epic` type as a project container and a `release` type as a milestone:
1. Open **Widget Properties** for the Gantt widget.
2. In the **Work Item Types** section, add an entry for `epic`:
* Set **Gantt Presentation Mode** to `Derived Schedule`
* Set **Enable Create** to `Yes` if you want users to create epics from the toolbar
3. Add another entry for `release`:
* Set **Gantt Presentation Mode** to `Milestone`
4. Save the widget parameters.
Setting a type as `Project` or `Milestone` does not add or remove items from the Gantt view. It only changes how items of that type are rendered. The visible items are determined by the **Work Items** data set parameter in [Work Items Gantt Widget Parameters](/gantt/reference/widget-parameters/work-items-gantt).
## Related Pages
* [Work Items Gantt Widget Parameters](/gantt/reference/widget-parameters/work-items-gantt) -- main widget parameter reference
* [Plans Gantt Widget Parameters](/gantt/reference/widget-parameters/plans-gantt) -- plan-type configuration
* [Data Mapping Parameters](/gantt/reference/widget-parameters/data-mapping) -- field binding for start, end, duration, progress
* [Item Script API](/gantt/reference/api/item-script-api) -- scripting for per-item behavior customization
# Work Items Gantt Widget Parameters
Source: https://learn.nextedy.com/gantt/reference/widget-parameters/work-items-gantt
Complete reference for all Nextedy GANTT Work Items Gantt widget parameters.
Only one Work Items Gantt widget is supported per Polarion wiki page.
In the Polarion page editor, the Work Items Gantt widget is listed under the **Work Items** tag of the widget picker..
## Core Parameters
| Parameter | Default | Description |
| ------------------ | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Scope` | `current project` | Scope of displayed work items |
| `Sort by` | `start id` | Sort criteria for top-level work items in the Gantt grid. |
| `Load Children` | `1` | Number of child levels to traverse and add to the list. `0` means no additional items beyond the dataset. |
| `Show Unplanned` | `true` | When `yes`, work items without a Start Field value are shown at today's date in gray. When `no`, they are hidden. |
| `Scale` | `W` | Timeline scale unit. Values: `H` (hour), `DD` (bi-daily), `D` (day), `W` (week), `M` (month), `Q` (quarter), `Y` (year), `YY` (multi-year). |
| `Parent Role` | `implements` | Work item link roles used to detect parent-child relationships. If empty, no hierarchy is shown. |
| `Dependency Roles` | `depends_on` | Work item link roles used to detect dependency relationships. If empty, no dependency arrows are shown. The first selected role is used when creating new dependency links by dragging. |
## Type Configuration
Each work item type listed in the widget can be individually configured beyond just its presentation mode. These per-type settings control creation behavior and hierarchy placement.
| Parameter | Default | Description |
| ---------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Presentation Mode` | `task` | How the type renders on the chart. Values: `task`, `project` (summary bar derived from children), `milestone` (diamond shape). |
| `Allow Create` | `true` | Whether new items of this type can be created directly from the Gantt chart. |
| `Create Field Filter` | Empty | Limits which fields are shown in the inline create form for this type. |
| `Parent Mode` | `root` | Where in the hierarchy items of this type may be placed. Values: `root` (top level only), `child` (nested under a parent), `any`. |
| `Allowed Parent Types` | Empty | When `Parent Mode` is `child`, restricts which types may serve as a parent. |
| `Sync to Plans` | Empty | Polarion plan template(s) to automatically assign work items of this type to, based on matching time range. When set, items are planned into all Polarion plans whose date range overlaps with the item's schedule. |
| `Extra Child Query` | Empty | Additional Lucene query fragment appended when loading children of this type. |
## Data Mapping
These parameters map Polarion work item fields to Gantt scheduling data. See [Data Mapping Parameters](/gantt/reference/widget-parameters/data-mapping) for details.
| Parameter | Default | Description |
| -------------------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `Start Field` | `gantt_start` | Work item field storing the task start date. Supports Date, DateTime, or String field types. |
| `End Field` | None | Work item field storing the task end date. Supports Date, DateTime, or String field types. |
| `Duration Field` | `gantt_duration` | Work item field storing the task duration in days. Supports Integer or String field types. |
| `Progress Field` | `gantt_progress` | Work item field storing the task progress as a float (0.0 to 1.0). Supports Float or String field types. |
| `Duration Precision` | `Standard (Days)` | Precision mode. `Standard (Days)` uses day-based durations. `High (Hours)` stores durations in hours and displays times. |
Configure at least two of the three date fields: **Start Field + Duration Field**, **End Field + Duration Field**, or **Start Field + End Field**. For production use, define proper custom fields with the recommended types (Date, Integer, Float) rather than relying on ad-hoc string fields.
## Grid Columns
These parameters control the left-hand grid panel of the Gantt chart.
| Parameter | Default | Description |
| -------------------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Grid Width` | `400` | Width of the grid panel in pixels. |
| `First Column Label` | `Item` | Label for the combined ID + title column. |
| `Show ID` | `true` | Display the work item ID in the first column. |
| `Show Title` | `true` | Display the work item title in the first column. |
| `Show Type Icon` | `true` | Display the type icon in the first column. |
| `Columns` | `duration` column | Additional grid columns. Each column entry has a `Field`, `Label`, `Width` (px), `Alignment` (`left`, `center`, `right`), and `Render` mode (`default` or a custom renderer). |
## Deadlines
| Parameter | Default | Description |
| ---------------- | --------- | -------------------------------------------------------------------------------------------------- |
| `Show Deadlines` | `true` | Displays a deadline marker on the chart for each work item that has a value in the Deadline Field. |
| `Deadline Field` | `dueDate` | Work item field used as the deadline date. Supports Date or DateTime field types. |
| `Deadline Color` | `red` | Color of the deadline marker. Accepts CSS color names or hex values. |
## Baseline
| Parameter | Default | Description |
| --------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `Show Baseline` | `true` | Overlays a baseline bar behind each task bar to compare the current schedule against a historical snapshot. |
| `Baseline Date` | `-1` | Reference point for the baseline snapshot. A relative value of `-1` means one year ago; `0` means today. Can also be set to a specific Polarion revision ID. |
| `Revision ID` | Empty | Explicit Polarion revision to use as the baseline instead of a relative date. When set, takes precedence over `Baseline Date`. |
## Resource View
| Parameter | Default | Description |
| ----------------------- | ---------- | -------------------------------------------------------------------------------------------------------------- |
| `Show Resource View` | `true` | Displays a resource allocation panel below the Gantt chart. |
| `Resource Field` | `assignee` | Work item field used to identify the resource (person or team) for each task. |
| `Resource Label` | Empty | Display label shown in the resource panel header. |
| `Resource View Height` | `250` | Height of the resource view panel in pixels. |
| `Max Assignments OK` | `1` | Number of simultaneous assignments considered acceptable before flagging overallocation. |
| `Show Unassigned` | `false` | When `true`, includes an "Unassigned" row in the resource panel for tasks with no value in the Resource Field. |
| `Resource Load Display` | `time` | How resource load is shown. `num` displays a count of assigned tasks; `time` displays total estimated time. |
## Working Calendars
These parameters configure which working calendars are applied when calculating task durations and scheduling. Use these instead of the deprecated `Working Time` parameter.
| Parameter | Default | Description |
| -------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------- |
| `Use Global Calendar` | `true` | Apply the project-level global working calendar (excludes weekends and public holidays as defined globally). |
| `Use User Calendars` | `false` | Apply per-user working calendars when calculating resource availability. |
| `Use Assignment Calendars` | `false` | Apply calendars based on work item assignments. |
| `Load Future Years` | `0` | Number of future years of calendar data to pre-load. Increase if the chart spans beyond the current year. |
| `Load Past Years` | `0` | Number of past years of calendar data to pre-load. Increase when using baselines that reference historical dates. |
| `Use Cache` | `false` | Cache resolved working calendar data for faster rendering on large datasets. |
## Advanced Parameters
| Parameter | Default | Description |
| ----------------------- | --------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Maximize Gantt View` | `true` | Expands the Gantt widget to fill the full working area of the Polarion page. |
| `Gantt Height` | `600` | Fixed pixel height of the Gantt panel (label: *Gantt Height (0 for auto-height)*); `0` lets it auto-size to content. |
| `Hide Toolbar` | `false` | Hides the Gantt toolbar. Implicitly sets `Always Edit` to `true`. A floating save button appears instead. |
| `Always Edit` | `false` | Opens the Gantt directly in edit mode without the sidebar detail panel. |
| `Drag Children` | `true` | When dragging a parent task, child tasks are rescheduled by the same offset. |
| `Max Items` | `1000` | Maximum number of work items loaded into the Gantt view. |
| `Show Today Marker` | `true` | Displays a vertical line on today's date in the Gantt chart. |
| `Progress Coloring` | `true` | Color-codes task bars based on their progress percentage. |
| `Read Only` | `false` | Prevents all edits. Also automatically set when the user has no license or a Polarion baseline is active. |
| `Override Today's Date` | Empty | Overrides the date treated as "today" on the chart (useful for snapshots/testing). |
| `Working Time` | `true` | **Deprecated** (label: *Working Time (DEPRECATED - Use Working Calendars)*) — legacy working-time mode (weekends as non-working). Use the **Working Calendars** section instead. |
| `Sidebar Fields` | `title`, `status`, `initialEstimate`, `remainingEstimate`, `timeSpent`, `dueDate`, `assignee` | Work item fields displayed in the detail sidebar panel when a task is clicked. |
## Scripting Parameters
| Parameter | Default | Description |
| --------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `Gantt Config Script` | Empty | Client-side JavaScript snippet for advanced configuration. Runs once when the chart initializes, before data is rendered. See [Gantt Config Script API](/gantt/reference/api/config-script-api). |
| `Item Script` | Empty | Server-side JavaScript snippet executed per task to customize appearance. See [Item Script API](/gantt/reference/api/item-script-api). |
| `Markers Script` | Empty | Server-side JavaScript snippet for creating timeline markers. See [Marker Factory API](/gantt/reference/api/markers-api). |
## Configuration Example
A typical Work Items Gantt configuration for a project using parent-child hierarchy and finish-to-start dependencies:
* **Work Items**: Query selecting all `release` and `feature` items in the current project (`type:(release feature)`)
* **Sort by**: `start id`
* **Load Children**: `1`
* **Show Unplanned**: `true`
* **Scale**: `W`
* **Parent Role**: `implements`
* **Dependency Role**: `depends_on`
* **Project Types**: `feature`
* **Milestone Types**: `release`
* **Start Field**: `gantt_start`
* **Duration Field**: `gantt_duration`
* **Progress Field**: `gantt_progress`
* **Duration Precision**: `Standard (Days)`
* **Grid Width**: `400`
* **Grid Columns**: `duration` (label: `Durat.`, width: `80px`, aligned center)
* **Show Deadlines**: `true`, field: `dueDate`, color: `red`
* **Show Baseline**: `true`, relative date: `-1` (one year ago)
* **Show Resource View**: `true`, field: `assignee`, height: `250px`, load display: `time`
* **Use Global Calendar**: `true`
* **Maximize Gantt View**: `true`
* **Gantt Height**: `600`
* **Max Items**: `1000`
* **Drag Children**: `true`
* **Progress Coloring**: `true`
* **Show Today Marker**: `true`
* **Sidebar Fields**: `title`, `status`, `initialEstimate`, `remainingEstimate`, `timeSpent`, `dueDate`, `assignee`
## See Also
* [Plans Gantt Widget Parameters](/gantt/reference/widget-parameters/plans-gantt)
* [Data Mapping Parameters](/gantt/reference/widget-parameters/data-mapping)
* [Set Up a Basic Gantt Chart](/gantt/getting-started/setup-basic-gantt)
* [General Administration Properties](/gantt/reference/configuration/general-properties)
# Working Calendars Parameters
Source: https://learn.nextedy.com/gantt/reference/widget-parameters/working-calendars
Nextedy GANTT supports a three-level working calendar cascade that determines working days, hours, and capacity for scheduling and resource load calculations.
## Working Calendar Widget Parameters
| Name | Type | Default | Description |
| ------------------------- | ------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Use Working Calendar` | Boolean | `false` | Master toggle that enables calendar-aware scheduling. When enabled, the Gantt respects non-working days and hours when calculating task durations. When disabled, all days count equally. |
| `Load User Calendars` | Boolean | `false` | Loads personal calendar work items assigned to each resource. Each assignee must have a Calendar work item with their user ID. Only visible when `Use Working Calendar` is `true`. |
| `Load Team Assignments` | Boolean | `false` | Loads team assignment capacity records to apply partial availability multipliers. Only visible when both `Use Working Calendar` and `Load User Calendars` are `true`. |
| `Next Years to Load` | Integer | See application | Number of future years to pre-compute working calendar data for. Higher values ensure calendar data is available for long-range views but increase startup time. |
| `Previous Years to Load` | Integer | See application | Number of past years to pre-compute working calendar data for. Useful for tracking long-running or past tasks. |
| `Cache Working Calendars` | Boolean | `false` | Enables server-side caching of computed working calendar data to speed up repeated Gantt loads. |
## Three-Level Calendar Cascade
The working calendar system resolves capacity through three levels, each overriding the previous:
**Level 1 -- Global Calendar:** Defines the base working week (default: Monday--Friday, 8 hours/day). All resources inherit this calendar unless overridden.
**Level 2 -- User Calendars:** Personal calendars defined as Calendar-type work items in Polarion. Each calendar can include schedule exceptions (time off, holidays) and custom working hours per user.
**Level 3 -- Team Assignments:** Team assignment records that apply partial availability multipliers (e.g., a team member at 50% allocation on a project).
## Progressive Disclosure
The working calendar parameters are interdependent. The widget parameter editor reveals options progressively:
1. Enable **Use Working Calendar** -- unlocks `Load User Calendars`, `Next Years to Load`, `Previous Years to Load`, and `Cache Working Calendars`.
2. Enable **Load User Calendars** -- unlocks `Load Team Assignments`.
3. Enable **Load Team Assignments** -- loads team capacity data.
**Performance Recommendation**
Set **Next Years to Load** and **Previous Years to Load** to `1` or `2` for typical use. Higher values increase memory usage and Gantt startup time.
## Administration Properties
To use work item calendars from another Polarion project, configure these properties under **Administration > Configuration Properties**:
| Property | Type | Description |
| ------------------------------------------ | ------ | ---------------------------------------------------------------------------- |
| `nextedy.gantt.workitemCalendar.projectId` | String | The Polarion project ID of the project containing the Calendar work items. |
| `nextedy.gantt.workitemCalendar.globalID` | String | The work item ID of the calendar-type work item used as the global calendar. |
**Cross-Project Calendar Setup**
Both properties must be set in the calendar source project **and** in any projects that consume the calendar data.
For detailed administration property reference, see [Calendar and Working Hours Properties](/gantt/reference/configuration/calendar-properties).
## Calendar Cache
When `Cache Working Calendars` is enabled:
* The server caches computed calendar data between page loads.
* Repeated Gantt loads reuse cached calendar data, reducing load time.
* After calendar changes (new holidays, modified working hours), you must clear the cache. Use the **Clear Calendar Cache** toolbar button, which appears when caching is active.
## Resource Load and Calendars
Working calendars directly affect resource load calculations in the [resource view](/gantt/reference/widget-parameters/resource-view):
* **Without calendars:** All days are working days with equal capacity. Resource load is a simple task count or duration sum.
* **With global calendar:** Non-working days (weekends, holidays) are excluded from capacity. Resource markers reflect actual working days.
* **With user calendars:** Each user's personal schedule exceptions (vacation, part-time hours) reduce their available capacity individually.
* **With team assignments:** Team allocation percentages further adjust each user's effective hours.
## Configuration Example
To enable calendar-aware scheduling with user calendars:
1. Open **Widget Properties** for the Gantt widget.
2. In the **Working Calendars** section:
* Set **Use Working Calendar** to `Yes`.
* Set **Load User Calendars** to `Yes`.
* Set **Next Years to Load** to `1`.
* Set **Previous Years to Load** to `1`.
3. Optionally enable **Cache Working Calendars** for faster repeated loads.
4. In **Administration > Configuration Properties**, add:
```
nextedy.gantt.workitemCalendar.projectId=CalendarProject
nextedy.gantt.workitemCalendar.globalID=CAL-001
```
5. Save the widget parameters.
## Related Pages
* [Resource View Parameters](/gantt/reference/widget-parameters/resource-view) -- resource allocation display configuration
* [Calendar and Working Hours Properties](/gantt/reference/configuration/calendar-properties) -- server-side calendar administration
* [Team and Resource Properties](/gantt/reference/configuration/team-properties) -- team assignment configuration
# Zoom and Scale Levels Reference
Source: https://learn.nextedy.com/gantt/reference/zoom-scale-levels
Nextedy GANTT provides eight zoom levels that control the timescale granularity of the Gantt chart.
## Zoom Level Summary
| Code | Label | Timescale Header | Description |
| ---- | ------- | ----------------------------- | ------------------------------------------ |
| `H` | Hours | Day over hours | Finest zoom level showing individual hours |
| `DD` | 2-Day | Week over 2-day groups | Intermediate day-level detail |
| `D` | Day | Week over days | Individual day columns |
| `W` | Week | Month over weeks | **Default zoom level** |
| `M` | Month | Year over months | Monthly planning view |
| `Q` | Quarter | Year over quarters | Quarterly roadmap view |
| `Y` | Year | Multi-year over years | Annual planning view |
| `YY` | 2-Year | Multi-year over 2-year groups | Coarsest zoom for long-range roadmaps |
**Default Zoom Level**
The default scale is `W` (Week). Users see a weekly timeline when first loading the Gantt chart without a saved preference.
## Zoom Level Details
### Hour-Level Zoom (`H`)
| Property | Value |
| ---------------- | ---------------------------------------------------------- |
| Code | `H` |
| Upper header row | Day |
| Lower header row | Hour |
| Use case | Hour-precision scheduling with high-precision mode enabled |
**Verify in application**
Hour-level zoom requires `Duration Precision` set to `High (Hours)` for accurate hour-level task display. See [Data Mapping Parameters](/gantt/reference/widget-parameters/data-mapping).
### Day-Level Zoom (`D` and `DD`)
| Property | `D` | `DD` |
| ---------------- | ------------------- | ------------------ |
| Code | `D` | `DD` |
| Upper header row | Week | Week |
| Lower header row | Day | 2-Day |
| Use case | Daily task tracking | Day-level overview |
### Week-Level Zoom (`W`)
| Property | Value |
| ---------------- | --------------------------------- |
| Code | `W` |
| Upper header row | Month |
| Lower header row | Week |
| Use case | Sprint and release planning views |
### Month, Quarter, and Year Zoom (`M`, `Q`, `Y`, `YY`)
| Property | `M` | `Q` | `Y` | `YY` |
| ---------------- | ---------------- | ----------------- | -------------- | ------------------ |
| Code | `M` | `Q` | `Y` | `YY` |
| Upper header row | Year | Year | Multi-year | Multi-year |
| Lower header row | Month | Quarter | Year | 2-Year |
| Use case | Release planning | Quarterly roadmap | Annual roadmap | Executive overview |
## Timescale Header Structure
Each zoom level renders a two-row timescale header at the top of the Gantt chart:
## Accessing Zoom Controls
You can change the zoom level using any of the following methods:
| Method | Location | Description |
| -------------------- | ----------------- | --------------------------------------------------------------------------------- |
| Toolbar zoom buttons | Gantt toolbar | Zoom in (+) and zoom out (-) buttons |
| Set scale submenu | Hamburger menu | Radio-button list of all available scales (Hour, Day, Week, Month, Quarter, Year) |
| Timeline right-click | Time scale header | Context menu with scale selection and Go to today |
| Keyboard shortcut | Gantt chart | See [Toolbar Actions and Keyboard Shortcuts](/gantt/reference/keyboard-shortcuts) |
## Zoom Level Persistence
The current zoom level is automatically saved to browser local storage and restored on the next page load. This persistence is scoped per document URL and widget instance.
| Behavior | Description |
| --------------- | ------------------------------------------------------------------------ |
| Save trigger | Zoom level is saved each time you change the scale |
| Restore trigger | Zoom is restored from local storage during Gantt initialization |
| Reset | Use the **Reset view** action to clear saved zoom and column preferences |
| Scope | Per-user, per-document URL, per-widget instance |
## Zoom and Resource View Interaction
When the resource view is enabled, zoom level changes affect resource marker aggregation:
* **Zooming out** aggregates daily/weekly resource allocation values into larger time buckets
* **Red overallocation flags** may appear or disappear depending on how time cells aggregate at different zoom levels
* Resource load thresholds are evaluated per-cell, so wider cells at lower zoom levels accumulate more work items
**Resource View at Low Zoom**
At coarse zoom levels (Month, Quarter, Year), resource allocation cells cover longer time periods. Overallocation flags may trigger more frequently because each cell aggregates more work items. Set your threshold based on your typical zoom level.
## Custom Timescale Configuration
You can customize zoom level scales using the Gantt Config Script to render week numbers or other custom date formats:
```javascript theme={null}
// Example: Show calendar week numbers (CW format) in the Week zoom level
gantt.config.zoomConfig.levels[3].scales[1].format = function(date) {
var weekNum = gantt.date.getISOWeek(date);
return "CW" + weekNum;
};
```
See [Gantt Config Script API](/gantt/reference/api/config-script-api) for the full scripting reference.
## Configuration Example
Set the default zoom level using the Gantt Config Script widget parameter:
```javascript theme={null}
// Set default zoom to Month view
gantt.ext.zoom.setLevel("M");
```
## Related Pages
* [Toolbar Actions and Keyboard Shortcuts](/gantt/reference/keyboard-shortcuts) -- zoom keyboard controls
* [Gantt Config Script API](/gantt/reference/api/config-script-api) -- custom timescale scripting
* [Resource View Parameters](/gantt/reference/widget-parameters/resource-view) -- resource view zoom behavior
* [Default Configuration Values](/gantt/reference/configuration/default-values) -- default zoom and column settings
# Documentation Terms of Use & Intellectual Property Notice
Source: https://learn.nextedy.com/legal/terms
Legal terms governing use of the Nextedy product documentation, including restrictions on building competing products.
**Effective date:** 7 July 2026 · **Version 1.0**
## 1. Ownership
All content published on `learn.nextedy.com` — including the text, specifications,
descriptions of features and workflows, data models, schemas, configuration examples,
code and script samples, screenshots, diagrams, and the underlying product designs and
functionality they describe — is the intellectual property of **Nextedy Systems s.r.o.**
("Nextedy") and is protected by copyright and other laws. It is **licensed for reference,
not sold**, and all rights not expressly granted below are reserved.
## 2. Purpose of this documentation
This documentation is provided for one purpose: to help you **evaluate, purchase, deploy,
configure, and operate licensed Nextedy products**. It is not a grant of any right to the
product designs, functionality, or intellectual property that it describes.
## 3. What you may do
Subject to these terms, you may:
* View and read the documentation for the purpose described in Section 2.
* Copy the configuration examples and code samples **into your own licensed Polarion
environment**, to configure and operate a Nextedy product you are licensed to use.
* Share links to these pages internally.
## 4. What you may not do
You may **not**, in whole or in part, directly or through any third party or automated system:
1. **Build or specify a competing product.** Use the documentation — or any specification,
data model, workflow, algorithm, formula, configuration, or design described in it — to
design, develop, specify, commission, procure, or train a product, service, template, or
configuration that **replicates, reimplements, or competes with** any Nextedy product or
Nextedy Solution.
2. **Use AI to reconstruct the product.** Provide the documentation (in whole or in part) to
any large language model, coding assistant, autonomous agent, retrieval pipeline, or MCP
integration for the purpose of **reconstructing, reimplementing, approximating, or
generating a specification of** Nextedy product functionality. Reading the documentation
with AI assistance to *operate a licensed product* is permitted; using AI to *rebuild the
product* is not.
3. **Redistribute.** Republish, resell, sublicense, or otherwise distribute the documentation
or substantial extracts from it outside your organization.
4. **Reverse engineer via the documentation.** Use the documentation to reverse engineer,
derive the source of, or circumvent the licensing of any Nextedy product.
5. **Strip notices.** Remove, obscure, or alter any copyright, ownership, or license notice.
## 5. No license, no rights
The functionality described in this documentation is available **only under a valid Nextedy
commercial license or subscription**. Absent such a license, no right to that functionality —
however implemented — is granted. If you want the capability, **license the product**:
[contact Nextedy](https://www.nextedy.com) or see the
[Nextedy Solution License](https://www.nextedy.com/nextedy-solution-license).
## 6. Consequences of misuse
Using these materials in breach of Section 4 infringes Nextedy's copyright and other
intellectual-property rights and breaches these terms. Nextedy actively protects its
intellectual property and may pursue all available remedies, including **claims for damages,
account of profits, and injunctive relief**, against the infringing party and any entity
that commissions or benefits from the infringement.
## 7. Relationship to product and solution licenses
These terms govern the *documentation*. Use of the products themselves is governed by the
applicable Nextedy product license and, for Nextedy Solutions, by the
[Nextedy Solution License](https://www.nextedy.com/nextedy-solution-license). In the event of
a conflict, the product or solution license controls for the product; these terms control for
the documentation.
## 8. Governing law and contact
These terms are governed by the laws of the **Czech Republic**. Questions and license
enquiries:
**Nextedy Systems s.r.o.**, Pernerova 697/35, 186 00 Prague, Czech Republic ·
[info@nextedy.com](mailto:info@nextedy.com) · [nextedy.com](https://www.nextedy.com)
***
**These proprietary materials may be used solely under a valid Nextedy product license. Any
direct or indirect use, including AI-assisted use, to analyze, derive, specify, procure,
develop, duplicate, or support any competing or functionally similar product or service is
strictly prohibited and constitutes an unauthorized use.**
© Nextedy Systems s.r.o. All rights reserved.
# Welcome
Source: https://learn.nextedy.com/overview/index
Excel-like traceability matrices with unlimited depth and cross-domain linking.
Excel-like risk analysis with reusable components and actionable FMEA mitigations.
Project scheduling with dependencies, versioning, and resource allocation.
Capacity-aware sprint and release planning on a board of swimlanes and cards.
Actionable checklists for structured workflow execution in Polarion.
Automated scheduling for Polarion work items and plans.
Generate documents and media exports from Polarion data.
## Get Help
Nextedy provides dedicated support for all licensed products through our support portal.
Report an issue or request assistance from the Nextedy support team.
Pricing, licensing, or custom deployments.
## Contact Information
| Channel | Details |
| ------------------- | ------------------------------------------------------ |
| **Support portal** | Open a support ticket |
| **Email** | [support@nextedy.com](mailto:support@nextedy.com) |
| **Sales inquiries** | [info@nextedy.com](mailto:info@nextedy.com) |
| **Website** | [www.nextedy.com](https://www.nextedy.com) |
## What to Include in a Ticket
For the fastest resolution, include the following when submitting a support ticket:
1. **Product and version** — Which Nextedy product and version number
2. **Polarion version** — Your Polarion ALM version (e.g., 2404)
3. **Description** — What you expected vs. what happened
4. **Steps to reproduce** — Numbered steps to reproduce the issue
5. **Screenshots or logs** — Browser console output, server logs, or screenshots
Licensed customers receive priority support with guaranteed response times. Evaluation users also have access to support during the trial period.
## Product-Specific Help
Each product has built-in troubleshooting guides and FAQ sections:
Common Powersheet questions.
Common Risksheet questions.
Common Gantt questions.
**Trusted by enterprise teams worldwide** — Samsung, Siemens, J\&J MedTech, Rolls-Royce, Hyundai, Valeo, ABB, Infineon, Scania, LG, Kuka, Phoenix Contact, Viessmann, Doosan
# Installing a License
Source: https://learn.nextedy.com/overview/resources/installing-the-license
Install and reload a Nextedy product license in Polarion — via the admin UI or the filesystem — and configure named and concurrent users.
Once you receive your license file by email, you can install it for the relevant Nextedy product. There are two ways to do this — through the Polarion administration UI (recommended) or directly on the filesystem — followed by configuring which users the license applies to.
Throughout this guide, replace `PRODUCTNAME` with the product you are licensing (for example, `powersheet`, `risksheet`, `gantt`, `planningboard`, or `checklist`).
## Install the license from the Polarion UI
Most Nextedy products — currently Powersheet, Risksheet, Gantt, Planningboard, and Checklist — let you install the license directly from the Polarion administration interface.
Go to **Polarion Administration → Nextedy `PRODUCTNAME` → License**.
Drag and drop the license file onto the upload dialog, or select it from your file system. It is uploaded automatically and added under the correct repository.
If the license file is invalid, a pop-up message explains what went wrong during the upload.
Once the license is uploaded, follow the on-page instructions to configure the named or concurrent user list. See [Configure named (active) users](#configure-named-active-users) and [Configure concurrent users](#configure-concurrent-users) below.
## Install the license via the filesystem
Older versions of Nextedy products use the following filesystem-based deployment.
Ensure the license file name ends with `PRODUCTNAME_lic.json` — for example, `YOURCOMPANY-gantt_lic.json` or `YOURCOMPANY-risksheet_lic.json`.
Move the license file to the following folder on your Polarion server:
```
[POLARION_INSTALL]/polarion/license
```
This is the same directory where the main Polarion license is stored.
You do not need to restart the Polarion server. Simply navigate to **Polarion Administration → Nextedy `PRODUCT_NAME` → License** to reload the license file.
Some Nextedy products require a selection of active users. In that case, open the **Polarion Administration → Nextedy `PRODUCT_NAME` → License** page and follow the instructions there, or refer to [Configure named (active) users](#configure-named-active-users) below.
## Polarion cluster setup
If you run a **Polarion cluster** (with multiple Polarion nodes), you must place the license file on **each node** in the same location:
```
[POLARION_INSTALL]/polarion/license
```
## Configure named (active) users
To configure the named users:
Create a **user group** (**Polarion Administration → User Management → Groups**) or a **global user role** (**Polarion Administration → User Management → Roles**) with the ID `nextedy_PRODUCTNAME_users`.
Add the users who should be assigned an active user license to this group or role.
To reload the updated configuration, reopen the License page: **Polarion Administration → Nextedy `PRODUCT_NAME` → License**.
If you don't perform this reload action, the newly added users will not receive an active license.
## Configure concurrent users
To configure the concurrent users:
Create a **user group** (**Polarion Administration → User Management → Groups**) or a **global user role** (**Polarion Administration → User Management → Roles**) with the ID `nextedy_PRODUCTNAME_users_concurrent`.
Add the users who should be assigned a concurrent user license to this group or role.
To reload the updated configuration, reopen the License page: **Polarion Administration → Nextedy `PRODUCT_NAME` → License**.
You can add more users to the concurrent users group than the number of licenses you purchased. The concurrent license is assigned to the users from that list who log in to the system first.
## When both Risksheet and Powersheet are installed
If your server has a production license for both Risksheet and Powersheet, you only need to configure **one** Powersheet users group (named or concurrent, depending on your license). There is no need to create a separate group for Risksheet — it is ignored.
This is because the Risksheet active user license is provided free of charge: it is bundled with Powersheet active user licenses.
As a result, both Risksheet and Powersheet check the `nextedy_powersheet_users` or `nextedy_powersheet_users_concurrent` groups.
## Behavior without a license
If you don't have a production or evaluation license for a specific Nextedy product, the product is shown in a **read-only** view. You can see all the content, but you cannot actively manipulate the data.
The License page signals that there is no active license.
On the product page itself, a similar pop-up appears. You can request an evaluation license by following the **Contact us** link.
The license upload procedure is the same for both production and evaluation licenses. However, once an evaluation license expires, the product switches back to the read-only view. You'll see the pop-up notification when the license expires.
## Need help?
For any assistance, [submit a ticket](https://support.nextedy.com/support/tickets/new) and the Nextedy support team will help you out.
# Nextedy AI
Source: https://learn.nextedy.com/overview/resources/nextedy-ai
The Nextedy AI package adds AI Assistant to Nextedy POWERSHEET and Nextedy RISKSHEET — where to find it in each product, and what its license covers.
**Nextedy AI** is an AI capability you can add to Powersheet and Risksheet. It is not included with either product: it arrives as a separately installed Nextedy AI package and is licensed on its own.
Two conditions govern what you get, and they are independent of one another:
* **Installing the package** enables the **Admin AI Assistant**, the assistant in a product's configuration editor. It needs no license.
* **A valid Nextedy AI license** additionally enables the in-sheet assistants: the **Risksheet AI Assistant** and the **Powersheet AI Assistant**.
Each assistant is documented with the product it appears in. For what you get in which combination, see [What is available when](#what-is-available-when).
**The AI Assistant proposes, you decide.** Everything it produces is presented as a suggestion for you to review, adjust, or reject. It does not change work items, sheet data, or configuration on your behalf.
## Where to find it
**In the configuration editor — the Admin AI Assistant.** A sparkle button in the editor toolbar opens a documentation-grounded chat, so an administrator can ask configuration questions without leaving the YAML they are editing. The window is titled after the product you are configuring -- **✦ Powersheet AI** in Powersheet, **✦ Risksheet AI** in Risksheet -- and answers are drawn from that product's documentation, with links to the pages used.
**In the sheet — the Risksheet AI Assistant and the Powersheet AI Assistant.** Configured actions let the assistant propose content against your Polarion data -- for example, suggesting work items you can then apply into a Risksheet sheet. Which actions are offered is up to you: they are defined per project, or globally, under **Administration → Nextedy AI → AI Assistant Actions**.
Powersheet: open the Admin AI Assistant in the configuration editor, ask questions, and attach the file you are editing as context.
Powersheet: documentation grounding, availability states, and what the Admin AI Assistant can and cannot do.
Risksheet: open the Admin AI Assistant in the configuration editor, ask questions, and attach the configuration you are editing.
Risksheet: documentation grounding, availability states, and the browser authentication flow behind it.
## What is available when
| Situation | Admin AI Assistant | In-sheet AI Assistant (Risksheet, Powersheet) |
| ---------------------------------------- | ------------------------------------ | --------------------------------------------- |
| Nextedy AI package not installed | Not available | Not available |
| Package installed, no or invalid license | **Available** -- no license required | Denied, with a tooltip about the license |
| Package installed, valid license | Available | Available |
**Before the package is installed you will still see the button.** By default the AI Assistant appears in the toolbars even when the Nextedy AI package is not installed. That is deliberate: it tells you what to do to get the full capability -- install the package, or contact Nextedy for a license. An administrator can switch it off; see [Turning AI features off](#turning-ai-features-off).
**In the sheet, an invalid license denies use rather than degrading it.** The entry point stays visible, but using the Risksheet or Powersheet AI Assistant is refused, and the tooltip tells you the license is invalid and to contact your administrator. Administrators find the details on the Polarion license page. This is stricter than most Nextedy features, where an invalid license limits what you can do instead of blocking it.
**A button that does not respond is not always a license problem.** Three states look alike. The Nextedy AI package may not be installed, in which case the button is there to point you at Nextedy AI and its tooltip says so. In the sheet, the license may be missing or invalid, in which case use is refused and your administrator can resolve it. In the configuration editor, the button is disabled when the package cannot be reached or your Polarion session cannot be identified, and its tooltip reads *"AI Assistant is currently unavailable"* -- none of the editor's tooltips mentions a license, because the Admin AI Assistant is never license-gated. See [How the Admin AI Assistant works](/powersheet/concepts/admin-ai-assistant) for the full set of availability states.
## Licensing
The **Risksheet AI Assistant** and the **Powersheet AI Assistant** need a valid Nextedy AI license, separate from the license for the product they appear in. The **Admin AI Assistant** does not -- it works as soon as the package is installed, so every installation can use it, including one whose license has expired.
The license is a **server-side license**, installed once per Polarion server and managed at **Administration → Nextedy AI → License**. One license covers the in-sheet assistants across every Nextedy product that offers them -- there is no separate license per product.
It is installed the same way as any other Nextedy license: drag the license file onto the **License** page, or place it on the server filesystem. See [Installing a License](/overview/resources/installing-the-license) for both routes, including Polarion cluster setups.
What each assistant needs from an AI provider differs:
* The **Admin AI Assistant** needs nothing. You do not need your own account with an AI provider and you do not supply an API key -- it talks to the Nextedy AI service, which Nextedy operates.
* The **in-sheet assistants** send their requests from your own Polarion server, so that server needs a model endpoint and an API key of your own. Until one is configured, the assistant reports itself unavailable and its entry points stay disabled. See [Configure the AI Assistant](/risksheet/guides/administration/configure-the-ai-assistant) for the properties and the key-resolution order.
### Evaluation
Until a production license is installed, the **License** page offers an evaluation of the licensed features for **30 days**. The upload procedure is identical for evaluation and production licenses. When an evaluation expires, the in-sheet assistants stay visible but their use is refused; the Admin AI Assistant and the rest of the product are unaffected.
For current pricing, a quote, or a custom licensing arrangement, contact [info@nextedy.com](mailto:info@nextedy.com). For a product-level overview of what Nextedy builds with AI, see [nextedy.com](https://www.nextedy.com).
## Turning AI features off
Three switches are available as Polarion context properties, so an administrator can set each one globally or for a single project:
* Turn the **in-sheet AI Assistant** off in a project, while keeping the package installed.
* Turn the **Admin AI Assistant** off.
* Turn off the **promotion** shown when the package is not installed.
## Your data
Nothing about your instance is sent by default. The Admin AI Assistant sends your question only, and receives no configuration or work-item data unless you explicitly attach the file you are editing -- attachments are opt-in, apply to the questions you ask after attaching them, and can be dismissed at any time. Your content is not used to train shared models.
See [Security and Privacy](/overview/security-and-privacy/index) for how Nextedy handles product security and customer data generally.
## Related pages
* [Use the Admin AI Assistant](/powersheet/guides/administration/use-admin-ai-assistant) -- Powersheet: open the Admin AI Assistant in the configuration editor and ask questions
* [How the Admin AI Assistant works](/powersheet/concepts/admin-ai-assistant) -- Powersheet: grounding, availability, and graceful degradation
* [Use the Admin AI Assistant](/risksheet/guides/configuration/use-admin-ai-assistant) -- Risksheet: open the Admin AI Assistant in the configuration editor and ask questions
* [Admin AI Assistant](/risksheet/concepts/admin-ai-assistant) -- Risksheet: grounding, availability, and the authentication flow
* [Installing a License](/overview/resources/installing-the-license) -- install and reload a Nextedy license
* [Polarion Version Support](/overview/resources/polarion-version-support) -- which Polarion versions Nextedy supports
* [Security and Privacy](/overview/security-and-privacy/index) -- how Nextedy handles product security and customer data
## Need help?
For any assistance, [submit a ticket](https://support.nextedy.com/support/tickets/new) and the Nextedy support team will help you out.
# Polarion Version Support
Source: https://learn.nextedy.com/overview/resources/polarion-version-support
How Nextedy supports Polarion versions across all products — Siemens' supported versions plus one additional year.
We've standardized how we handle Polarion version support across **all Nextedy products** to ensure greater clarity and consistency.
## Our support policy
Nextedy supports all Polarion versions that are officially supported by Siemens, **plus an additional year** beyond Siemens' official support period. This approach gives you more flexibility and peace of mind when planning upgrades or managing legacy environments.
It also means that all Nextedy products are **fully compatible with the newest Polarion version** as soon as it is released.
As a general rule, Polarion typically supports versions released in the last two years, and our policy extends that window by one more year. Your organization therefore benefits from extended compatibility and a longer support horizon for each version.
## Example
If Siemens supports Polarion version 2304 until the end of April 2025, then:
* Nextedy tools released **up to the end of April 2026** will continue to support Polarion 2304.
* After that date, any **newly released** Nextedy tools will require **at minimum** version 2310 of Polarion.
## Check the supported versions
To check the Polarion versions currently supported by Siemens, visit the official Polarion support page:
Siemens' official list of supported Polarion versions.
## Need help?
If you need any assistance, [submit a ticket](https://support.nextedy.com/support/tickets/new) and the Nextedy support team will help you out.
# Release Notes
Source: https://learn.nextedy.com/overview/resources/releases
Latest releases and updates for Nextedy products and solutions.
## Latest Releases
Stay up to date with the latest Nextedy product releases, feature additions, and improvements.
Release announcements and detailed changelogs are published on the [Nextedy Insights blog](https://www.nextedy.com/news/).
## Recent Updates
### Risksheet AI Assistant (2026)
AI-powered risk analysis assistance for Risksheet. Helps teams identify failure modes, suggest mitigations, and assess risk levels using industry knowledge.
[Read more on nextedy.com](https://www.nextedy.com/news/)
### Polarion 2404 Support
All Nextedy products are fully compatible with Siemens Polarion 2404, including support for the updated extension API and new document editor.
### Continuous Improvements
Nextedy products receive regular updates with bug fixes, performance improvements, and feature enhancements.
## Version Compatibility
| Polarion Version | Nextedy Support Status |
| ---------------- | ----------------------------- |
| 2404+ | Fully supported (recommended) |
| 2304 | Fully supported |
| 2204 | Limited support |
| Older | Not supported |
## Stay Informed
* **Blog**: [nextedy.com/news](https://www.nextedy.com/news/) — Product announcements and industry insights
* **LinkedIn**: [Nextedy on LinkedIn](https://www.linkedin.com/company/nextedy/) — Company updates and community
* **Support**: [Submit a ticket](https://support.nextedy.com/support/tickets/new) — Get help and report issues
# Compliance and Assessments
Source: https://learn.nextedy.com/overview/security-and-privacy/compliance
Security assessments, certifications, and regulatory relevance for Nextedy products.
## Security Assessments
Nextedy products have undergone the following security evaluations:
### Siemens IT Security Review
Nextedy products are approved for deployment on Polarion X (Siemens-managed SaaS). The Siemens IT security review evaluated the product architecture, data handling, and third-party dependencies before granting clearance.
### Cybersecurity Governance Assessment (CGAQ)
Nextedy has completed the Siemens Cybersecurity Governance Assessment Questionnaire, which covers organizational security practices, development processes, incident response capabilities, and supply chain management.
### Threat and Risk Analysis
A formal Threat and Risk Analysis identified potential attack vectors and defined over 40 security controls. These controls address areas including input validation, access control enforcement, session management, and dependency security.
### Static Analysis and Dependency Scanning
| Assessment | Tool / Method | How it runs |
| ----------------------------------- | ------------------------- | ------------------------------------------------------------------------------------------ |
| Static Application Security Testing | SonarQube | Runs continuously in the pipeline; findings triaged before each release |
| Software Bill of Materials | Syft, in CycloneDX format | Generated for every build and archived with the release |
| Dependency vulnerability monitoring | Dependency-Track | Release SBOMs are ingested for CVE tracking, licence compliance, and continuous monitoring |
| Functional testing | Automated suite | Runs in the pipeline on every change |
These scans run continuously as part of the development pipeline. Results are reviewed before each release.
## Why No Independent ISO 27001 or SOC 2?
Nextedy products run entirely within the Polarion platform. They do not operate independent infrastructure, manage their own data stores, or provide standalone network services. The security boundaries that ISO 27001 and SOC 2 typically assess (data centers, network controls, access management systems, backup infrastructure) are all provided by the Polarion platform.
For on-premise deployments, the customer's own ISO 27001 or SOC 2 certification covers the infrastructure. For Polarion X, Siemens maintains the relevant certifications for the managed platform.
Nextedy's security assurance is demonstrated through the Siemens security review, CGAQ, threat analysis, and continuous code-level scanning described above.
## Industry Relevance
Nextedy products are used by teams working under stringent regulatory frameworks. The product security model supports compliance with:
| Standard | Domain | How Nextedy Supports It |
| ------------------- | ------------------------------ | ---------------------------------------------------------------------------------- |
| ISO 26262 | Automotive functional safety | FMEA and HARA workflows in Risksheet maintain full audit trail in Polarion |
| DO-178C / ARP 4754A | Aerospace software and systems | Requirements traceability and risk analysis with versioned artifacts |
| IEC 62304 | Medical device software | Risk management and traceability matrices stored in validated Polarion environment |
| ISO/SAE 21434 | Automotive cybersecurity | TARA workflows for threat analysis and risk assessment |
| IEC 61508 | Industrial functional safety | Hazard analysis and safety integrity level tracking |
In all cases, the compliance evidence (versioned documents, audit trails, approval records) is stored in Polarion and benefits from the platform's validation and electronic signature capabilities.
Nextedy can provide security documentation packages on request, including the Threat and Risk Analysis summary, SBOM, and assessment results. Contact [security-alerts@nextedy.com](mailto:security-alerts@nextedy.com) for details.
# Data Security
Source: https://learn.nextedy.com/overview/security-and-privacy/data-security
How data is stored, encrypted, isolated, and backed up when using Nextedy products in Polarion.
## Data Storage
Nextedy products store 100% of their data in Polarion's existing storage layer. This includes Polarion's SVN repository (for document and work item versioning) and the relational database (for structured queries and indexing).
Nextedy products do not:
* Create or use separate databases
* Write data to the local filesystem outside of Polarion's storage
* Transmit data to external services, APIs, or cloud endpoints
* Maintain caches or data stores outside of Polarion's JVM
## What Data Do the Products Modify?
Nextedy products read and write standard Polarion data objects within the authenticated user's permission scope:
| Data Type | Examples | Storage Location |
| ------------------ | ------------------------------------------------------ | ------------------------------------- |
| Work item fields | Risk severity, occurrence, detection ratings | Polarion database + SVN |
| Work item links | Trace links between requirements and risks | Polarion database + SVN |
| Custom fields | Product-specific fields (e.g., ASIL level, risk class) | Polarion database + SVN |
| Document structure | LiveDoc section ordering, table layouts | Polarion SVN |
| Configuration | Sheet layouts, column definitions, model YAML | Polarion SVN (`.polarion/` directory) |
All modifications are attributed to the authenticated Polarion user and recorded in Polarion's audit trail.
## Encryption in Transit
All communication between the user's browser and the Polarion server uses HTTPS with TLS 1.2 or higher. This encryption is configured and managed at the Polarion platform level (or by the infrastructure provider for Polarion X).
Nextedy products do not establish separate network connections. All data flows through Polarion's existing HTTPS endpoint.
## Encryption at Rest
Encryption of data at rest is the responsibility of the infrastructure owner:
* **On-premise** — The customer manages disk encryption, database encryption, and SVN repository encryption according to their own security policies.
* **Polarion X** — Siemens manages encryption at rest as part of the Polarion X infrastructure.
Nextedy products do not implement their own encryption layer because all data resides in Polarion's storage.
## Data Isolation
Polarion provides project-level access control. Each Polarion project has its own set of roles, permissions, and membership. Nextedy products respect this isolation:
* Users only see data from projects they have been granted access to.
* Cross-project queries are filtered by Polarion's permission engine before results reach the product.
* Sheet configurations and model definitions are scoped to individual projects.
## Logging and Auditability
Nextedy products rely on Polarion's logging and audit infrastructure and follow Polarion's standard logging levels (Log4j). Security-relevant events such as authentication, authorization decisions, and configuration changes are logged at the platform level. The products do not introduce a separate security logging or monitoring subsystem.
At the transaction level, product activity is recorded by Polarion's transaction logger (TXLOGGER) in the standard Polarion log files. TXLOGGER entries include:
* The authenticated user name
* The request URL, including project ID, document path, and API endpoint
* Transaction performance data
* Permission check details
Log entries do not contain credentials, work item content, or field values beyond identifiers.
Beyond TXLOGGER, Polarion's standard Log4j logging captures application-level events, errors, and diagnostic information at configurable severity levels. Nextedy products use these same logging categories and levels — no custom logging framework is introduced.
Administrators should use the existing Polarion logs and operational monitoring to detect misconfiguration or unusual behavior.
## Backup and Restore
Because all Nextedy data lives in Polarion's storage, backup and restore is handled entirely by the Polarion administrator or infrastructure provider. No separate backup process is needed for Nextedy product data.
Standard Polarion backup strategies (SVN repository backup, database backup, filesystem snapshots) capture all Nextedy-related data automatically.
# Incident Management
Source: https://learn.nextedy.com/overview/security-and-privacy/incident-management
How Nextedy monitors, triages, and responds to security incidents — contacts, SLAs, and escalation process.
## Security Contact
Report security vulnerabilities or incidents to:
| Channel | Details |
| ------------ | ----------------------------------------------------------------- |
| **Email** | [security-alerts@nextedy.com](mailto:security-alerts@nextedy.com) |
| **Response** | Acknowledged within 1 business day |
This is a monitored Google Workspace Group with automatic forwarding to the security team's Slack channel (`#security-alerts`) for real-time notification.
## Monitoring
Nextedy maintains 24/7 monitoring for security events through:
* **Dependency vulnerability alerts** — Release SBOMs are monitored continuously in Dependency-Track, which notifies the team when a new CVE affects a tracked component.
* **Code scanning alerts** — SonarQube flags security-relevant findings in new code.
* **Incident inbox** — The `security-alerts@nextedy.com` address accepts reports from customers, partners, and automated scanning tools.
All alerts are routed to the security team via Slack integration for immediate visibility.
## Incident Response Process
### 1. Intake
When a security issue is reported or detected, the security team:
* Acknowledges receipt within 1 business day
* Assigns an incident owner
* Creates a tracking record with initial details
### 2. Triage and Severity Assessment
The incident owner assesses severity based on:
| Severity | Criteria | Examples |
| ------------ | ----------------------------------------------------------------------- | ------------------------------------------------------------- |
| **Critical** | Active exploitation possible, affects data integrity or confidentiality | Remote code execution, authentication bypass |
| **High** | Exploitable vulnerability with significant impact | Privilege escalation, data exposure under specific conditions |
| **Medium** | Vulnerability with limited exploitability or impact | Information disclosure with low sensitivity |
| **Low** | Minimal risk, defense-in-depth improvement | Hardening recommendation, minor configuration issue |
### 3. Remediation
The security team develops and tests a fix. The remediation timeline depends on severity:
| Severity | Patch SLA |
| ------------ | ---------------------------------- |
| Critical | Within 5 business days |
| High | Within 10 business days |
| Medium / Low | Next scheduled release (quarterly) |
### 4. Notification
* **Breach notification** — If a confirmed breach affects customer data, Nextedy notifies affected customers within 24 hours.
* **Patch notification** — Security patches are communicated through the support portal and direct customer contact.
* **Advisory publication** — For vulnerabilities affecting released versions, Nextedy publishes a security advisory with affected versions, remediation steps, and upgrade instructions.
## Evidence and Traceability
All security incidents are tracked with:
* Unique incident identifier
* Timeline of discovery, triage, and resolution
* Root cause analysis (for high and critical incidents)
* Verification that the fix resolves the issue
This record is retained for audit purposes and is available to customers under NDA upon request.
# Overview
Source: https://learn.nextedy.com/overview/security-and-privacy/index
How Nextedy protects your data — security architecture, compliance, incident response, and privacy practices.
Nextedy products run inside the Siemens Polarion ALM application server. They share the same JVM process, the same authenticated session, and the same data storage as Polarion itself. This architecture means that Nextedy does not introduce a separate attack surface — security controls are inherited directly from the Polarion platform.
## Core Principle: Inherited Security
Nextedy products do not maintain their own databases or authentication systems. While the products expose their own REST endpoints, these endpoints are accessible only within the Polarion server perimeter and are protected by Polarion's authentication and session management. Every operation executes within the security context of the currently authenticated Polarion user. The practical consequence is that the security posture of a Nextedy deployment is determined by the security posture of the underlying Polarion installation.
This leads to a clear responsibility model:
| Responsibility | Owner |
| ------------------------------------------------------------------ | ----------------------------------------------------- |
| Secure product code, dependency management, vulnerability scanning | **Nextedy** |
| Polarion platform security, authentication, encryption, backup | **Customer** (on-premise) or **Siemens** (Polarion X) |
| User provisioning, access control policies, project permissions | **Customer** |
## Deployment Modes
Nextedy products support both deployment models offered by Polarion:
* **On-premise** — The customer manages the entire Polarion infrastructure, including OS, JVM, TLS certificates, backup, and network security.
* **Polarion X (SaaS)** — Siemens manages the Polarion infrastructure. Nextedy products have been cleared by Siemens IT security review for deployment on Polarion X.
## Explore This Section
Product architecture, authentication model, secure development practices.
Data storage, encryption, isolation, and backup.
Security assessments, certifications, and industry relevance.
Data processing scope, GDPR approach, and data residency.
Security monitoring, triage, patching SLAs, and breach notification.
SBOM, third-party component tracking, and vulnerability scanning.
# Privacy
Source: https://learn.nextedy.com/overview/security-and-privacy/privacy
How Nextedy handles personal data — processing scope, GDPR approach, and data residency.
## Data Processing Scope
Nextedy products process only the data that exists within Polarion. The scope is limited to:
* **Work item fields** — Reading and writing field values (e.g., risk ratings, requirements text, status)
* **Work item links** — Creating and querying traceability links between items
* **Document structure** — Rendering and organizing LiveDoc content
* **Configuration** — Reading project-level sheet and model configurations from the `.polarion/` directory
Nextedy products do **not**:
* Collect personally identifiable information (PII) beyond what Polarion already stores
* Create or maintain separate user databases or user profiles
* Transmit data to external services, analytics platforms, or third-party APIs
* Store data outside of Polarion's storage layer
* Track user behavior, usage patterns, or telemetry
## Personal Data in Polarion
Polarion stores user information as part of its standard operation (usernames, email addresses, role assignments, activity history). Nextedy products may read this data — for example, displaying the author of a work item or the assignee of a task — but only within the Polarion user interface and only for users who have permission to see it.
Nextedy products do not copy, export, or aggregate this personal data. The data remains in Polarion and is subject to Polarion's access control.
## GDPR Compliance
Because Nextedy products do not independently collect, store, or process personal data, GDPR compliance is managed at the Polarion platform level:
| GDPR Requirement | How It Is Addressed |
| -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Lawful basis for processing** | Determined by the customer's Polarion deployment and data processing agreements |
| **Data subject rights** (access, rectification, erasure) | Handled through Polarion's user management and data administration tools |
| **Data protection by design** | Nextedy's architecture ensures no additional PII processing beyond Polarion |
| **Data processing agreements** | Between the customer and Siemens (for Polarion X) or managed internally (for on-premise) |
| **Data breach notification** | Covered by Nextedy's [incident management process](/overview/security-and-privacy/incident-management) for product-related issues; platform-level breaches handled by the infrastructure owner |
Nextedy does not act as an independent data controller or data processor. Each product operates as a component of the Polarion platform, which is governed by the customer's existing data protection framework.
## Data Residency
* **On-premise deployments** — The customer has full control over data residency. All Polarion data, including data managed by Nextedy products, resides on the customer's own infrastructure in the jurisdiction of their choice.
* **Polarion X deployments** — Data residency is determined by the Siemens Polarion X hosting region selected by the customer. Nextedy products do not influence or override the hosting region.
In both cases, no data is transmitted outside the Polarion environment by Nextedy products.
## No Third-Party Data Sharing
Nextedy products do not share data with any third party. There are no:
* Analytics or tracking integrations
* Advertising or marketing data flows
* External API calls from the products to non-Polarion services
* Telemetry or usage reporting to Nextedy servers
The products operate entirely within the Polarion server boundary.
# Product Security
Source: https://learn.nextedy.com/overview/security-and-privacy/product-security
How Nextedy products integrate with Polarion's security model — shared responsibility, authentication, authorization, privileged configuration, and rendering safety.
## Architecture
Nextedy products (Risksheet, Powersheet, Gantt, Checklist, Planningboard) are deployed and executed entirely within the customer's Polarion environment. They run in the same JVM process as Polarion itself, not as separate services, and they introduce no independent authentication system and no external network exposure.
Each product registers its own endpoints within the Polarion server. These endpoints are:
* **Accessible only within the Polarion perimeter** — Product endpoints are served by the same web container as Polarion itself. They are not exposed on separate ports or external URLs, and are reachable only through an authenticated Polarion session.
* **Protected by Polarion authentication** — Every request to a product endpoint is authenticated through Polarion's session management. Unauthenticated requests are rejected before reaching product code.
* **Subject to Polarion's access control** — Product endpoints enforce the same project-level and role-based permissions as the rest of Polarion.
Additional security properties:
* **No separate TLS configuration** — Product endpoints inherit the server's TLS settings.
* **No debug interfaces in production** — Nextedy products do not include diagnostic endpoints, admin consoles, or debug ports in production builds.
## Shared Responsibility Model
Because the products run inside Polarion, security responsibilities are shared between the platform and the apps, with clear boundaries.
**Provided and enforced by the Polarion platform** (and by the customer's deployment configuration):
* User authentication and authorization — roles, permissions, project access
* Session management and identity context
* HTTPS/TLS termination and certificate management
* Content Security Policy (CSP) configuration at the HTTP(S) server level
* CSRF protection on state-changing operations
* Network exposure, firewalling, and perimeter security
* Operating system, JVM, and database hardening
* Central logging and monitoring infrastructure
* SQL injection prevention at the database access layer, including restricted SQL commands and project-level query filtering (since Polarion 2410)
* Secure secrets storage through the User Account Vault
Nextedy products rely on these platform mechanisms and do not bypass or replace them.
**The responsibility of Nextedy products:**
* Correct and secure use of the Polarion APIs
* Respecting the authenticated user context provided by Polarion
* Applying safe rendering patterns when presenting user-controlled data
* Avoiding direct insertion of untrusted HTML or JavaScript into the DOM in regular user paths
* Providing conservative default limits for queries and data processing
* Clearly separating regular usage from privileged configuration capabilities
## Authentication
Nextedy products delegate all authentication to the Polarion platform. They do not implement their own login mechanism and do not store or manage user credentials.
Polarion supports the following authentication methods, all of which work transparently with Nextedy products:
| Method | Protocol | Notes |
| --------------------------- | ----------------------- | ------------------------------------------- |
| Single Sign-On | SAML 2.0, OIDC | Federated identity via corporate IdP |
| Multi-Factor Authentication | Configured at IdP level | Enforced before Polarion session starts |
| Local accounts | Polarion built-in | Username/password managed by Polarion admin |
| LDAP/Active Directory | LDAP, LDAPS | Synchronized or delegated authentication |
Nextedy products never see user passwords. They receive the authenticated user context from Polarion's session management layer.
## Authorization
Nextedy products read Polarion's permission model at runtime to determine what the current user is allowed to see and do. The products cannot bypass or escalate Polarion permissions.
Specifically:
* **Project access** — If a user does not have access to a Polarion project, Nextedy products will not display data from that project.
* **Work item permissions** — Read/write access to work items respects Polarion's role-based permissions.
* **Field-level access** — Custom field visibility and editability follow Polarion's field configuration.
* **Document permissions** — LiveDoc access is governed by Polarion's document-level permissions.
## Session Management
Nextedy products use Polarion's session management. There are no separate sessions, tokens, or cookies introduced by the products. When a Polarion session expires or is invalidated, the product's session ends automatically.
## Privileged and Scriptable Configuration
Some Nextedy products provide advanced configuration capabilities, including scriptable or programmable behavior, to support flexible customer-specific use cases. Because such capabilities may execute custom logic and therefore carry increased security risk, **access to scriptable or otherwise privileged configuration is intentionally restricted to trusted roles.**
Throughout this section, "administrator" means a user with Project Administrator privileges or an equivalent trusted role.
This restriction follows Polarion's established security model and is enforced using one of two patterns, depending on the product:
* **Restricted widgets** (Polarion 2506 and later) — Certain widgets are classified as restricted and require the `Pages.MODIFY RESTRICTED WIDGETS` permission to configure. Regular users can use preconfigured widgets but cannot modify their configuration or inject scripts.
* **Administrator-only configuration pages** — Advanced configuration is available only through dedicated administration pages, accessible exclusively to users with at least Project Administrator privileges.
Restricted widget support requires Polarion 2506 or newer. On older Polarion versions, any user holding the `Pages.MODIFY` permission can access widget configuration. If you run an older Polarion version, restrict `Pages.MODIFY` to trusted roles to achieve equivalent protection.
Product customization is provided through three mechanisms, all protected by the role-based restrictions above:
| Mechanism | Executes | Available APIs |
| ---------------------- | --------------- | --------------------------------------------------------------- |
| Server-side JavaScript | Polarion server | Polarion Open API, Polarion Rendering API, Nextedy product APIs |
| Client-side JavaScript | Browser | Nextedy product JavaScript APIs |
| Server-side Velocity | Polarion server | Polarion Open API, Polarion Rendering API, Nextedy product APIs |
Nextedy products do not attempt to sandbox or validate arbitrary custom scripts beyond this role-based restriction model. Assigning appropriate roles — and ensuring that only trusted administrators or power users can reach restricted or scriptable configuration — is the customer's responsibility.
## Input Handling and Rendering Safety
Nextedy products provide administrator-configurable rendering contexts, including custom cell renderers, top panel content, PDF cover pages, formula definitions, and other template-driven output. These are configured through Velocity templates, JavaScript expressions, or declarative configuration, and they control how work item data is processed and displayed.
The security of these rendering paths depends on which Polarion API the administrator chooses:
* **Rendering API** (for example `$workItem.title.render`) performs built-in HTML sanitization. Content rendered through this API is safe for display. **Nextedy strongly recommends using the Rendering API in all administrator-configurable rendering contexts.**
* **Open API / raw data access** (for example `$workItem.title` via `IWorkItem`) returns raw, unsanitized content that the platform does not HTML-escape.
If an administrator uses raw Open API output in a custom render function, sanitizing that output before display is the administrator's responsibility. Polarion provides escape utilities for this purpose:
| Context | Escape pattern |
| ----------------------------- | ----------------------------------------------------- |
| LiveDocs and LiveReport Pages | `$esc.html($workItem.title)` |
| Wiki Pages | `$esc.escape($esc.escapeForHtmlTag($workItem.title))` |
Custom render functions are configurable by administrators only. Where raw API output is used without sanitization, this represents an accepted administrative risk. This is consistent with Polarion's own security model, whose documentation warns that poorly written code on Wiki Pages, LiveDocs, or LiveReport Pages can expose the system to XSS, and recommends restricting modification access to trusted users.
## Protection Against Common Web Attacks
| Attack class | How it is mitigated |
| ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **XSS** (Cross-Site Scripting) | Strict use of Polarion's Rendering API for regular user-facing data display; administrator-only access to configuration paths that may render raw HTML; controlled handling of user-generated content in non-admin paths; internal code review checking for unsafe DOM manipulation |
| **CSRF** (Cross-Site Request Forgery) | State-changing operations rely on Polarion's platform-level CSRF protection. Products operate within the platform's security context and do not bypass these protections |
| **CSP** (Content Security Policy) | CSP is managed at the Polarion HTTP(S) server level. Nextedy components operate strictly within the CSP defined by the deployment — no CSP relaxations are required |
## Query and Processing Limits
Some product features issue queries or process large data sets. While this is required for advanced use cases, misconfiguration or excessive limits may affect system performance.
To mitigate operational risk:
* Conservative default limits are applied where applicable.
* Configuration options that increase load are restricted to privileged users.
* Administrators should evaluate the performance impact before increasing limits or applying changes in production.
Performance-related misconfiguration is considered an administrative risk and should be managed accordingly.
## Per-Product Considerations
Risksheet uses document-based configuration stored and managed within the Polarion platform.
* Configuration is stored as document data (for example attachments and metadata) and is subject to Polarion's standard permission model.
* Access to the configuration editor in the UI is restricted to users with at least Project Administrator privileges.
* Configuration is typically defined on a **template document**, which individual Risksheet instances reference.
* Because configuration is stored as document data, administrators must ensure that permissions on template documents, attachments, and related metadata are appropriately restricted. If regular users have edit access to template documents or configuration attachments, they may be able to change configuration indirectly through standard Polarion mechanisms.
* Configurable limits are applied to the amount of data processed and rendered, with conservative defaults.
Powersheet uses centrally managed configuration stored in the Polarion repository.
* Configuration is managed through administration interfaces intended for users with at least Project Administrator privileges.
* Configuration is stored in the Polarion SVN repository (the `.polarion` location). By default, Polarion permission schemes restrict write access to these repository locations to administrators; regular users have no write access.
* Configuration may include advanced or scriptable behavior and is therefore treated as privileged.
* Regular users work with Powersheet data through configured views but cannot modify configuration or inject custom logic.
See also the [Powersheet security architecture](/powersheet/concepts/architecture#security-architecture).
Gantt provides advanced visualization and planning that may process and render large data sets.
* Gantt is implemented as a **restricted widget**, so configuration requires elevated permissions.
* Regular users can use preconfigured views but cannot modify configuration or inject scripts.
* Configurable limits are applied to the amount of data processed and rendered in a single view, with conservative defaults. Increasing these limits may significantly affect Polarion performance and should be evaluated carefully, preferably outside production.
Planningboard follows the same security model as Gantt for advanced configuration.
* Implemented as a **restricted widget**, with elevated permissions required for configuration.
* Regular users can use preconfigured views but cannot modify configuration or inject scripts.
* Configurable limits are applied conservatively by default.
Checklist renders structured content from Polarion fields as a visual checklist editor.
* Checklist **does not support scripting** or execution of custom logic.
* Checklist templates are defined on template work items and are subject to Polarion's standard permission model.
* The product relies entirely on Polarion's platform-level security mechanisms.
## Secure Development Practices
Nextedy applies the following practices to product development:
| Practice | Tool / Method | How it runs |
| ------------------------------------------ | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| Static Application Security Testing (SAST) | SonarQube | Runs continuously in the development pipeline; findings triaged before each release |
| Software Bill of Materials | Syft, in CycloneDX format | Generated for every build and archived with the release; provided as part of the security package |
| Dependency vulnerability monitoring | Dependency-Track | Each release SBOM is ingested for CVE tracking, licence compliance, and continuous monitoring as new vulnerabilities are disclosed |
| Code review | Peer review on all changes | Required before merge, including checks for unsafe DOM manipulation |
| Functional testing | Automated test suite | Runs in the pipeline on every change |
All security findings are triaged before each release. Critical and high findings must be resolved before a release is approved. See [Supply Chain Security](/overview/security-and-privacy/supply-chain) for SBOM details.
## Administrator Checklist
When deploying and operating Nextedy products, ensure that:
* Access to restricted widgets and administrator-only configuration pages is limited to trusted roles. In particular, grant `Pages.MODIFY RESTRICTED WIDGETS` only to trusted users.
* Template documents, configuration attachments, and repository-based configuration artifacts are write-protected for regular users, using Polarion mechanisms such as space-level permissions or custom permission sets.
* Scriptable or advanced configuration is reviewed, approved, and maintained only by trusted administrators.
* Default performance-related limits are kept unless a change is explicitly required and its impact has been evaluated.
* Configuration changes are tested outside production where possible.
* Polarion platform security features — authentication, authorization, HTTPS/TLS, permissions, and logging — remain enabled and correctly configured.
* The SQL and Lucene query restrictions introduced in Polarion 2410 remain at their default (restricted) settings.
## Out of Scope
The following areas are outside the scope of Nextedy products and remain the responsibility of the Polarion deployment and customer operations:
* Operating system and infrastructure security
* Network perimeter protection and segmentation
* Database encryption and backup protection
* Centralized security monitoring (SIEM)
* Disaster recovery and backup strategies
# Supply Chain Security
Source: https://learn.nextedy.com/overview/security-and-privacy/supply-chain
Software Bill of Materials, third-party component management, and vulnerability scanning for Nextedy products.
## Software Bill of Materials (SBOM)
Nextedy maintains a complete inventory of all third-party components included in its products. The SBOM is generated in an industry-standard format:
| Format | Standard | Use Case |
| ------------- | --------------- | ------------------------------------------------------------------ |
| **CycloneDX** | OWASP CycloneDX | Vulnerability management, licence compliance, and security tooling |
The SBOM covers every third-party component shipped with the products, including open-source libraries, OSGi framework dependencies, and utility packages.
## Continuous Vulnerability Scanning
Every build generates a CycloneDX SBOM with Syft; release SBOMs are then ingested into Dependency-Track for continuous vulnerability monitoring. The process:
1. **SBOM generation** — Syft scans the source tree on every build and produces a CycloneDX SBOM, archived alongside the build.
2. **Alert routing** — New vulnerabilities are flagged immediately and routed to the security team.
3. **Triage** — Each finding is assessed for exploitability in the context of the Polarion product environment.
4. **Remediation** — Critical and high findings are patched according to the [incident management SLAs](/overview/security-and-privacy/incident-management). Lower-severity findings are addressed in the next scheduled release.
## FOSS and COTS Reporting
For each third-party component, Nextedy tracks:
* **Component name and version**
* **License type** (e.g., Apache 2.0, MIT, EPL)
* **Known vulnerabilities** (from Dependency-Track's CVE feeds, including NVD)
* **Usage context** (what the component is used for in the product)
This information supports customer procurement processes and regulatory submissions where a full software composition analysis is required.
## Release Security Gate
Every Nextedy release passes through a security gate before publication:
1. **SAST scan** — SonarQube analyses the source and exports a Security Hotspots report.
2. **Dependency review** — The release SBOM is ingested into Dependency-Track and its findings are reviewed.
3. **SBOM generation** — An updated CycloneDX document is produced and archived.
4. **Review** — The security team signs off on the scan results and SBOM accuracy.
Critical and high findings are triaged and must be resolved or explicitly accepted before a release is approved.
## Relevance for Regulated Industries
Supply chain transparency is a regulatory requirement in several industries where Nextedy products are deployed:
* **Automotive** — ISO/SAE 21434 requires cybersecurity management of third-party software components. UNECE WP.29 R155 mandates supply chain risk management.
* **Aerospace** — DO-178C and DO-330 require identification and verification of COTS and reusable software components.
* **Medical devices** — IEC 62304 requires documentation of SOUP (Software of Unknown Provenance) components with risk assessment.
Nextedy's SBOM and continuous scanning process provide the evidence needed to satisfy these requirements.
SBOM documents in CycloneDX format are available on request. Contact [security-alerts@nextedy.com](mailto:security-alerts@nextedy.com) to obtain the latest SBOM for your Nextedy product version.
# Swimlane Assignment Modes
Source: https://learn.nextedy.com/planningboard/concepts/assignment-modes
Swimlanes are the horizontal rows on a Nextedy PLANNINGBOARD. Every card on the board belongs to exactly one swimlane, and the rule that determines *which* swimlane a card belongs to is the **swimlane assignm
This page explains what each mode means, how the board derives swimlane membership from it, and the constraints that come with each choice. For step-by-step configuration, see the [Guides](/planningboard/guides/index).
***
## The Core Idea: One Rule, Many Rows
Think of the assignment mode as a classification function. Given a work item, it answers the question: "which bucket does this belong in?" Each unique bucket becomes a swimlane row. When a work item is dragged from one swimlane to another, Planningboard does not just move a visual tile — it actually **writes back** to Polarion, updating the underlying field (assignee, parent link, enum value, or SAFe team reference) that the mode is based on.
This write-back behavior is what makes Planningboard more than a read-only view. The swimlane you drop a card into becomes the new value of the assignment field for that work item.
***
## Available Assignment Modes
The `assignmentMode` widget parameter accepts one of the following values. Each is described below.
### Users (Assignee) (`ASSIGNEE`)
Each swimlane row represents one user who holds a specified role in the project. The board reads the project's role assignments to determine which users appear as rows, then places each work item under the row matching its assignee.
**How rows are populated:** Planningboard queries the project's User Management for all users holding the configured **User Role** (for example, `project_user`). Only users with that role get a swimlane. If you later add a user to that role, a new row appears on the board automatically.
**What the drag-drop writes back:** When you drag a card to a different user's swimlane, Planningboard updates the work item's assignee field in Polarion to that user.
**Key limitation — multiple assignees:** When a work item has more than one assignee, it currently appears under only one swimlane, not under all assigned users' rows. Users expecting the card to be duplicated across all assignees' lanes will not see that behavior. This is a known product limitation, with an enhancement tracked to display items under all assignees in a future release.
**Filtering by Team (optional):** If the Teams Service is enabled (`useTeamsService = true`), the Users (Assignee) mode can filter swimlane users to members of a specific team rather than all role-holders project-wide. This requires coordinating two settings: the Team page parameter (which filters swimlane rows) and a Plans query (which filters iterations to the same team). Configuring only one of them leads to a mismatch where swimlanes filter but iterations do not, or vice versa.
**Filtering by Plan range (optional):** Starting with version 25.12.0, you can enable `nextedy.planningboard.activeTeamAssignmentsInPlanRangeOnly=true` in Polarion Configuration Properties. When enabled, users whose Team Assignments fall entirely outside the date range of the currently displayed Plans are hidden. Work items still assigned to those users move to the "Not Assigned/Other" row. This keeps the board focused on active capacity only.
The property `nextedy.planningboard.activeTeamAssignmentsOnly=true` introduced in version 25.3.0 has been **deprecated** as of version 25.12.0 in favour of `activeTeamAssignmentsInPlanRangeOnly=true`, which is Plan-range-aware. Do not use the deprecated property in new setups.
***
### Parent Item (`PARENT`)
Each swimlane row represents one **parent work item**. Child items appear under the row of their parent. This mode is ideal for seeing task distribution across features, epics, or other hierarchical groupings — for example, checking how tasks break down under each user story in a sprint.
**How rows are populated:** The parent items are discovered via a Lucene query (the **Parent Query** parameter) and optionally filtered by a link role (the **Parent Role** parameter, for example `implements`). Only work items matching the parent query appear as swimlane rows. The `parentWorkItemType` property can further restrict parents to a specific type.
**What the drag-drop writes back:** Unlike other modes, when you drag a card to a parent's swimlane, Planningboard does **not** let you place it under an unrelated parent. Because the card's parent relationship is structural data, the system enforces the correct parent automatically — if you drop a card in the wrong row, it snaps back to the row its actual parent occupies. Swimlane assignment here is derived from the existing link structure, not freely chosen.
**Sorting:** Planningboard supports sorting parent swimlanes by any custom property, including priority (available since version 25.9.0). The **Sort By** parameter controls the vertical order of parent rows.
**Important constraint — normalization:** The Parent Item mode does **not** support plan normalization (`planCellsMode`). If you need capacity normalization across Plans, use a different assignment mode.
***
### Enumeration Field (`ENUM`)
Each swimlane row represents one value from a chosen **enumeration custom field** (for example, a `team` field with values `Frontend`, `Backend`, `QA`). This mode works with both single-value and multi-value enum fields.
**How rows are populated:** Planningboard reads all available option values of the configured enum field (`enumFieldId`) and creates one row per value. You can restrict which values appear as rows using the **Rows Filter** parameter — selecting a subset of enum values means only those values produce swimlane rows.
**What the drag-drop writes back:** Dragging a card to a different row updates the enum field on the work item in Polarion to the value that row represents.
**Multi-value enum fields:** When the field allows multiple values and a work item carries more than one, it can appear in multiple swimlane rows simultaneously, one row per value it holds. This is the key behavioral difference from other modes.
**Field type restrictions:** Not all enum-typed fields are valid. The `status`, `resolution`, and `type` system fields are not supported for swimlane grouping with this mode. Use a custom enumeration field.
Enum field options are configured per work item type in Polarion. If you change the work item type filter on the board, the available enum values in the rows filter change accordingly — the filter reflects only the options defined for the currently selected type.
***
### Project (`PROJECT`)
Each swimlane row represents one sub-project within the current project group. This mode is designed for **cross-project planning** — useful for portfolio and program boards where work spans multiple Polarion projects.
**How rows are populated:** Planningboard discovers all sub-projects readable by the current user within the project group, then creates one row per sub-project. The current project itself is excluded from the row list (to avoid double-counting). Projects the user cannot read are also excluded silently.
**What the drag-drop writes back:** Moving a card between project swimlanes reassigns the work item to the target project in Polarion.
**Scoping which projects appear:** By default, all readable sub-projects of the current project group appear as swimlanes. The **Project Query** parameter narrows this to a specific set of projects with a Lucene query — see [Scoping and Filtering Project Swimlanes](/planningboard/concepts/project-swimlane-scoping) for the full breakdown, including driving it from a page parameter and how dependency-role menus and Plan columns behave across projects.
***
### SAFe Assignment Types
Three assignment modes are designed specifically for **SAFe (Scaled Agile Framework)** environments. They require a Polarion SAFe Solution configuration to be in place:
| Mode | What each row represents | Configuration required |
| ----------------- | ------------------------------------------------- | ------------------------------------------- |
| `SAFE_TEAM` | SAFe teams within the current program | SAFe Solution; `safeTeamField` custom field |
| `SAFE_TRAIN_TEAM` | Teams within a specific Agile Release Train (ART) | SAFe Solution; ART ID parameter |
| `SAFE_PROGRAMS` | SAFe programs within a solution train | SAFe Solution at portfolio level |
**Program / Solution Teams (SAFe)** (`SAFE_TEAM`) — swimlane rows are the SAFe teams active in the current program, sourced from Polarion SAFe Solution data. Dragging a card updates the `safeTeamField` custom field on the work item. The default custom field ID is `safeTeam`.
**Agile Release Train Teams (SAFe)** (`SAFE_TRAIN_TEAM`) — similar to Program / Solution Teams (SAFe) (`SAFE_TEAM`), but restricted to teams belonging to a specific ART (specified via the ART ID parameter). Useful for ART-level sprint boards.
**Programs (SAFe)** (`SAFE_PROGRAMS`) — swimlane rows are SAFe programs within a solution train. This is for portfolio-level planning. Uses the `safeProgramField` custom field (default ID: `safeProgram`).
If your organization uses SAFe and you want to enable these swimlane options, contact Nextedy support for setup guidance. SAFe assignment modes depend on the Polarion SAFe Solution extension being correctly configured in your instance.
For the broader context of how Planningboard integrates with SAFe, see [SAFe Integration](/planningboard/concepts/safe-integration).
***
### No Swimlanes (`NONE`)
This mode disables swimlane grouping entirely. All cards appear in a single undivided board area without row separation. The board still has Plans as columns, but there is no horizontal grouping of rows.
**When this makes sense:** For high-level planning or quick overviews where the volume of items is manageable and team-based or hierarchy-based partitioning would add complexity rather than clarity. Also appropriate when capacity tracking per resource is not needed.
***
## Shared Behaviors Across Modes
### Empty Swimlanes
By default (`showEmptySwimlanes = false`), swimlane rows with no work items assigned are hidden. Setting `showEmptySwimlanes = true` forces all possible rows to appear even if empty. This is useful when you want to see the full set of team members or enum values on the board, regardless of current workload.
### Collapsible Swimlanes
All modes support collapsing individual swimlane rows (`collapsibleSwimlanes = true` by default). Users can collapse rows they are not currently working with to reduce visual noise on dense boards.
### Swimlane Sort Order
The `swimlaneSort` parameter controls the vertical ordering of rows. The default value is `alphabetical`. For the Parent Item mode, custom sorting by properties like priority is supported (see the Parent Item section above). Note that the swimlane sort order and the item sort order within each lane are coupled — changing one can affect the other.
### The "Not Assigned / Other" Row
When a work item does not match any defined swimlane row — for example, it has no assignee, its parent is not in the parent query, or its enum field is empty — it falls into an overflow row typically labeled "Not Assigned" or "Other". This row is always present unless the board has no such items.
***
## Choosing the Right Mode
The table below summarizes the primary use case for each mode:
| Mode | Best for | Write-back field |
| ----------------- | ------------------------------------------------------- | --------------------------------------------- |
| `ASSIGNEE` | Workload planning per team member | Assignee field |
| `PARENT` | Hierarchy visibility; task-under-feature grouping | Parent link (enforced; not freely changeable) |
| `ENUM` | Custom categories (team, component, priority) | Custom enum field |
| `PROJECT` | Cross-project portfolio or program boards | Project membership |
| `SAFE_TEAM` | SAFe team sprint boards | SAFe team custom field |
| `SAFE_TRAIN_TEAM` | ART-level sprint boards | SAFe team custom field |
| `SAFE_PROGRAMS` | Portfolio-level SAFe planning | SAFe program custom field |
| `NONE` | Simple single-stream boards; no per-row capacity needed | — |
The clearest way to choose a mode is to ask: "when a planner moves a card from one row to another, what should change on the work item in Polarion?" The answer maps directly to a mode. If the answer is "reassign it to a different person" → Users (Assignee) (`ASSIGNEE`). "Move it under a different feature" → Parent Item (`PARENT`). "Change its team field" → Enumeration Field (`ENUM`) or a SAFe mode.
***
## Common Misconceptions
**"I can place a card under any parent swimlane."** Not with Parent Item mode — the row a card belongs to is determined by its actual parent link in Polarion. Dropping it in the wrong parent's row causes it to snap back to its real parent's row. To change the parent, update the link in Polarion, not by dragging on the board.
**"Swimlanes and columns are the same thing."** Swimlanes are horizontal rows; columns are Plans (time-based). The assignment mode controls rows only. Plan display is governed separately by `plansMode` — see [Plans Modes](/planningboard/concepts/plans-modes).
**"An item with two assignees appears in both assignee swimlanes."** Currently it does not. Multi-assignee items appear in only one swimlane. See the Users (Assignee) section above for details on this known limitation.
**"Any enum field can be used for the Enumeration Field mode."** System fields `status`, `resolution`, and `type` are not supported. Use a custom enumeration field.
***
## Related Concepts
* [Scoping and Filtering Project Swimlanes](/planningboard/concepts/project-swimlane-scoping) — deep dive into Project mode's Project Query parameter and cross-project board behavior
* [Board Structure](/planningboard/concepts/board-structure) — how Plans (columns) and swimlanes (rows) combine into the full board layout
* [Plans Modes](/planningboard/concepts/plans-modes) — the equivalent concept governing column (Plan) organization
* [Capacity Tracking](/planningboard/concepts/capacity-tracking) — how capacity bars relate to swimlane rows
* [SAFe Integration](/planningboard/concepts/safe-integration) — deeper context for the SAFe assignment modes
* [Teams Service](/planningboard/concepts/teams-service) — how the Teams Service integrates with the Users (Assignee) mode for team-filtered swimlanes
**KB Articles**
* Swimlane Assignment Types
* Introduction to Planningboard
* Filter user swimlanes by Plan range
**Support Tickets**
* [#6681](https://support.nextedy.com/helpdesk/tickets/6681)
* [#5922](https://support.nextedy.com/helpdesk/tickets/5922)
* [#5760](https://support.nextedy.com/helpdesk/tickets/5760)
**Source Code**
* `AssignmentMode.java`
* `PlanningBoardWidget.java`
* `PlanningBoardWidgetDependenciesProcessor.java`
* `PlanningBoardWidgetRenderer.java`
* `Config.java`
# Board Structure
Source: https://learn.nextedy.com/planningboard/concepts/board-structure
Nextedy PLANNINGBOARD organises Polarion Plans and work items into a two-dimensional grid that makes planning capacity visible at a glance.
## The Two-Dimensional Grid
Think of the board as a spreadsheet where **columns represent time** (Plans) and **rows represent ownership or scope** (swimlanes). Every cell at a column–row intersection is a planning slot. When you drag a card into a cell, you are simultaneously saying *when* the work is scheduled (the Plan column) and *who or what owns it* (the swimlane row).
This is distinct from a simple Kanban board, where columns represent workflow states. On Planningboard, columns represent Polarion Plans — iterations, sprints, program increments — not status values. Status progression happens inside Polarion as usual; the board's job is to answer "what is planned in which sprint, for which team member?"
## Columns: Plans
Each column on the board corresponds to one Polarion **Plan** (a sprint, iteration, program increment, or custom planning period). The Plans shown are determined by the **Plan query** configured in the widget parameters, together with two count parameters: `lastPlans` (default `1`) controls how many past or completed Plans are visible, and `nextPlans` (default `5`) controls how many upcoming Plans are shown. This windowing approach keeps the board focused on the near-horizon without showing an overwhelming history.
The `plansMode` widget parameter determines which kind of Plan objects are used as columns — for example, **Project Plans** (`PROJECT_PLANS`) or SAFe Program Increments. Changing `plansMode` changes which configuration options are available for Plans, which is why the widget configuration UI looks different depending on the mode selected.
A common first-time misconception is that columns represent work item statuses (To Do → In Progress → Done). They do not. Columns are Polarion Plan artifacts — time-boxed planning containers. Moving a card between columns re-assigns it to a different Plan; it does not change the work item's status field.
## Rows: Swimlanes
Swimlanes divide the board horizontally. Each swimlane represents a grouping of work items sharing a common attribute — an assignee, a parent work item, a project, or a custom enumeration field value. The **swimlane assignment type** (`assignmentMode`) determines which attribute drives the grouping.
The available assignment modes are:
| Assignment mode | What each row represents |
| ----------------- | -------------------------------------------------------------------------------- |
| Users (Assignee) | Each team member assigned to the project via a specified user role |
| Parent Item | Each parent work item (e.g. feature, epic) linked to child tasks |
| Enumeration Field | Each value of a custom enumeration field (e.g. Team, Priority) |
| Project | Each Polarion project, for cross-project planning |
| SAFe types | SAFe Programs, Program Teams, or Agile Release Train Teams (requires SAFe setup) |
| No Swimlanes | All items appear in a single unified row |
### The Not Assigned/Other Row
When a swimlane assignment mode is active, items that have no value for the grouping attribute appear in a special **Not Assigned/Other** row (`UNASSIGNED`). This row is not just a display location — it is also a drag-drop target. Dragging a card from a user swimlane to the Not Assigned/Other row removes that specific user from the work item's field, which is particularly relevant for multi-valued fields where an item can appear in more than one swimlane simultaneously.
### Multi-value Swimlane Appearance
When the grouping field supports multiple values (for example, a multi-user assignee field or a multi-enum custom field), a single work item can appear in more than one swimlane row at the same time. Each appearance represents one of the item's values. This means the same card can be visible in Alice's row and Bob's row if both are assigned. Dragging from one of those rows to the Not Assigned/Other row removes only that row's value, leaving the other assignments intact.
### Swimlane Sort Order
The `swimlaneSort` property (default `alphabetical`) controls the vertical order of rows. For the **Parent Item** assignment mode, sort order can be configured by custom properties such as priority — a capability added in Planningboard 25.9.0. Note that the swimlane sort order is coupled to the item sort order within each swimlane; there is currently no independent sort control for items within a lane versus the lane itself.
When you change the swimlane sort order, the ordering of work items within each swimlane changes in tandem. This is a known limitation — independent sort controls are not available in the current version.
## Cards: Work Items
Each **card** on the board represents a single Polarion work item. The card's position in the grid encodes two pieces of planning information simultaneously: which Plan it belongs to (column) and which swimlane group it belongs to (row).
Card content is customizable through widget parameters, but the fundamental planning semantics — column = Plan, row = swimlane grouping — are fixed by the board's structural model.
Clicking a card opens the **Work Item Properties** sidebar, which shows configurable fields and allows in-context edits without leaving the board. The board preserves your swimlane and scroll position when you save sidebar changes, so you can work through a list of cards without losing your place on large boards.
When hovering over a card, three quick actions become available: **Show Links** (highlights linked cards and hides all others), **Add Link** (creates a link to another card), and **Unplan item** (moves the card back to the Unplanned section).
Cards with the work item status **Verified** cannot be moved or unplanned once placed. This is an intentional lock to protect verified work from accidental replanning.
## The Unplanned Section
The Unplanned section on the right side of the board is a backlog panel — a holding area for all work items that have not yet been assigned to any Plan. It is the starting point for the primary board interaction: drag a card from the Unplanned section onto a Plan column and swimlane row to schedule it.
The Unplanned section can be filtered by assignee, team, or predefined queries to help surface the right cards for the planning session. It can also be toggled off using the **Show Unplanned** toolbar button when you want to focus entirely on the board grid.
## Capacity Bars
Each cell at the intersection of a Plan column and a swimlane row can show a **capacity bar** — a visual indicator of how much capacity is consumed versus available for that swimlane within that Plan. Capacity bars require explicit configuration through widget parameters.
Hovering over a capacity bar shows a detailed tooltip with per-user capacity data, including allocated capacity (sum of remaining estimates for assigned work items), total capacity (from the team calendar), and available capacity (the difference). Negative available capacity signals overallocation.
Capacity data is calculated server-side and embedded in the board when the page loads. Users whose team calendar has no entries default to a total capacity of 0.0.
Capacity bars do not appear by default. They are enabled through widget parameters for capacity loading (`capacityLoad`, `userCapacityLoad`, `capacityField`). See the [Capacity Tracking](/planningboard/concepts/capacity-tracking) concept page for how capacity calculation works.
## Toolbar Controls
The toolbar in the upper-left corner of the board provides board-wide controls that complement the structural layout:
| Control | Effect |
| --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| Collapse / Expand all | Folds or unfolds all swimlane rows at once (individual rows can also be toggled by clicking them directly) |
| Refresh data | Reloads board data from Polarion without a full page reload |
| Toggle Resource Load | Shows or hides the capacity bars across all swimlanes |
| Show Unplanned | Toggles the visibility of the Unplanned section |
| Prioritize | Enables the Prioritization mode for ordering items within swimlanes |
| Show Dependencies | Reveals all dependency links between cards across the entire board (requires dependency link roles to be configured in widget parameters) |
The **Show Dependencies** toolbar action is distinct from the **Show Links** card-level action. Show Links highlights only the links of the single card you hover; Show Dependencies reveals all dependency connections across the board simultaneously.
## How the Structure Fits Together
The structural model of Planningboard can be summarised as a deliberate mapping from Polarion concepts to spatial positions:
This mapping is what makes drag-and-drop on the board meaningful: placing a card at a specific (column, row) intersection updates the work item's `plannedIn` Plan in Polarion and, depending on the assignment mode, may also update the field used for swimlane grouping (such as the assignee field).
## Common Misconceptions
**"Moving a card changes its status."** It does not. Column position reflects Plan assignment, not workflow state. Status is a separate Polarion field edited through the sidebar or Polarion itself.
**"Swimlane rows are always assignees."** The assignment mode is configurable. Rows can represent parent work items, projects, enumeration field values, or SAFe structural roles — not just users.
**"The capacity bar shows story points remaining."** The capacity bar represents capacity consumed relative to available capacity, derived from team calendar data and the `capacityField` you configure. The unit depends on your configuration (hours, story points, or another numeric field).
**"All work items in the project appear on the board."** The work item dataset is filtered by the `query` widget parameter and capped at `maxItems` (default `1000`). Items outside the query result are not visible even if they exist in Polarion.
## Related Concepts
To understand the individual structural elements in depth, see:
* [Swimlane Assignment Modes](/planningboard/concepts/assignment-modes) — how each assignment type works and when to choose it
* [Plans Modes](/planningboard/concepts/plans-modes) — how Plan columns are generated for different planning methodologies
* [Capacity Tracking](/planningboard/concepts/capacity-tracking) — how capacity is calculated and displayed in each cell
* [Normalization](/planningboard/concepts/normalization) — how capacity figures are normalised across swimlanes with different team sizes
* [Prioritization](/planningboard/concepts/prioritization) — how item ordering within swimlanes works
For practical setup, see [Create Your First Planningboard](/planningboard/getting-started/first-planning-board) and [Basic Board Interactions](/planningboard/getting-started/basic-interactions).
**KB Articles**
* Introduction to Planningboard
* Planningboard interface & basic interactions
* Swimlane Assignment Types
**Support Tickets**
* [#6681](https://support.nextedy.com/helpdesk/tickets/6681)
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#6509](https://support.nextedy.com/helpdesk/tickets/6509)
**Source Code**
* `AssignmentMode.java`
* `Config.java`
* `enum-rows-filter.cy.ts`
* `PlanningBoardWidget.java`
* `enum-rows-filter-folder-scope.cy.ts`
# Capacity Tracking
Source: https://learn.nextedy.com/planningboard/concepts/capacity-tracking
Capacity tracking in Nextedy PLANNINGBOARD answers a fundamental planning question: **how much work can a team actually take on in a given sprint or iteration?** Rather than treating all swimlanes as equal co
This page explains what capacity tracking is, how Planningboard calculates and visualises it, and the important limitations you need to understand before relying on it for planning decisions.
***
## The mental model: filling buckets
Think of each swimlane as a bucket. A sprint's capacity represents how full that bucket can get. Work items added to the swimlane pour effort into the bucket. The **capacity bar** — the progress indicator visible at the top of each plan column within a swimlane — shows how full the bucket is relative to its total size.
The bar turns into an at-a-glance signal: a nearly full bar means this assignee's sprint is close to committed; an overflowing bar means the team has planned more than the person can realistically deliver.
***
## How capacity is calculated
Planningboard derives capacity from two sources, depending on how the board is configured.
### From the Teams Service (recommended)
When `useTeamsService` is enabled, Planningboard integrates with the Nextedy Teams Service to obtain per-user capacity per sprint. The Teams Service computes available hours based on the user's calendar and their percentage assignment to the project. This means a user on part-time allocation or away during part of a sprint automatically has reduced capacity for that sprint — the capacity bar reflects their actual availability, not a fixed number.
This is the most accurate mode. It requires the Teams Service to be configured and running for the project. See [Teams Service](/planningboard/concepts/teams-service) for setup details.
### From a fixed hours-per-day value
Without the Teams Service, capacity is estimated using the `hoursPerDay` property (default: `8`). Planningboard multiplies this value by the number of working days in the plan to arrive at a total capacity figure for each swimlane-column cell. This is a simplified model: it does not account for holidays, part-time allocation, or any individual variation in availability.
Capacity configuration properties are whitespace-sensitive. Extra spaces around values in your widget parameters can silently cause capacity not to display or calculate incorrectly. If capacity bars are missing or show unexpected values, verify that property values contain no leading or trailing whitespace.
### Effort tracking: what counts as work
Planningboard measures the "water in the bucket" — the effort committed — in one of two ways:
* **Time-based:** Uses `remainingEstimate` and `initialEstimate` fields from Polarion work items. Planningboard sums these across items in a swimlane-column cell to arrive at total effort, then converts to hours using `hoursPerDay`.
* **Custom field:** When `capacityField` is set to a field ID, Planningboard reads effort from that field (for example, a story-points field) instead of time estimates.
Resolved work items are treated as fully done: their effort is counted as `effortDone` with `effortTodo` set to zero.
***
## Capacity modes
Planningboard offers three capacity modes, controlled by widget parameters:
| Parameter | Default | Purpose |
| ------------------- | ------- | --------------------------------------------------------------------------------------------- |
| `capacityLoad` | `false` | Enables column-level capacity bars (one bar per plan column, aggregated across all swimlanes) |
| `multiCapacityLoad` | `false` | Enables per-cell capacity bars (one bar per swimlane–column intersection) |
| `userCapacityLoad` | `false` | Enables per-user capacity bars, driven by the Teams Service |
**Single capacity (`capacityLoad`)** is the simplest mode. One capacity bar appears per plan column, showing total effort committed in that sprint across all swimlanes combined. Use this for a quick column-wide load signal when swimlane-level granularity is not needed.
**Multi-capacity (`multiCapacityLoad`)** is the richer mode. Each swimlane-column cell gets its own capacity bar. This is what enables the "bucket per person per sprint" view described above — you can see at a glance which assignees are over capacity in which sprints. This mode requires each swimlane to carry its own capacity value, typically populated by the Teams Service.
**User capacity (`userCapacityLoad`)** works alongside the Teams Service to show capacity at the individual user level. This mode is most useful when swimlanes represent individual team members (the `ASSIGNEE` assignment mode).
***
## The capacity tooltip
Hovering over a capacity bar on a Plan column reveals a **capacity tooltip** with detailed breakdown information. This tooltip is only available when capacity display has been configured via widget parameters.
The tooltip gives you a precise read of the numbers behind the visual bar — useful when the bar alone is ambiguous (for example, when two plans have similarly-full bars but very different absolute effort values).
***
## Toggling the resource load view
The toolbar's **Toggle Resource Load visualization** button shows or hides the current load of each assignee in the swimlanes. This is a display toggle — it does not change how capacity is calculated, only whether the visualisation is shown on screen.
This button is useful when you want to temporarily declutter the board view while still having capacity data available on demand.
***
## Known limitations
Planningboard's capacity tracking covers the common single-assignee sprint planning case well, but has meaningful gaps compared to Nextedy GANTT's capacity model. Be aware of these before relying on capacity data for critical planning decisions:
### No multi-assignee capacity distribution
Planningboard does not support work items with multiple assignees for capacity purposes. If a work item is assigned to more than one person, the capacity load is not split or distributed across those assignees. This is a confirmed gap versus GANTT's capacity model. For teams where work items routinely carry multiple assignees, capacity figures in Planningboard will undercount actual load.
### No sub-item effort rollup
Planningboard calculates capacity from the effort fields on the work items directly visible on the board. It does not recurse into sub-items to roll up their effort. If your planning practice records effort on child tasks rather than on the parent feature or story, those child-item estimates will not appear in the capacity bar.
Nextedy GANTT's capacity model supports multi-assignee distribution and sub-item effort rollup. If your team relies on either of these patterns, evaluate whether GANTT's capacity view better meets your needs for detailed capacity analysis, while using Planningboard for the board-style planning interaction.
### Swimlane sort order coupling
The sort order of swimlanes affects item sort order on the board. This coupling means that adjusting swimlane ordering for visual reasons can inadvertently reorder work items within those lanes.
***
## How capacity varies sprint by sprint
A key insight of Teams Service–driven capacity is that the same user's capacity bar is not constant across sprints. If Alice takes leave during Sprint 3, her bucket is smaller for that sprint — Planningboard reflects this by showing a lower total capacity for her Sprint 3 column. This makes it immediately visible that Sprint 3 has less room for Alice's work, which should inform how items are distributed during planning.
Without the Teams Service, Planningboard uses the fixed `hoursPerDay` multiplied by sprint duration, which produces the same capacity for every sprint for every user regardless of actual availability.
This difference matters most for teams with variable availability, part-time contributors, or multi-sprint planning horizons.
***
## Relationship to swimlane assignment types
Capacity tracking only produces meaningful per-swimlane numbers when swimlanes represent identifiable resources — typically individual users (the `ASSIGNEE` assignment mode) or teams. When swimlanes are grouped by a custom enumeration field or by parent work item, capacity bars reflect effort aggregated within that grouping, but there is no inherent "available capacity" for an enum value or a parent item in the same way there is for a person.
For capacity-driven sprint planning, the **Users (Assignee)** swimlane assignment type combined with `multiCapacityLoad` and `userCapacityLoad` is the recommended combination. See [Swimlane Assignment Modes](/planningboard/concepts/assignment-modes) for a full explanation of how each assignment type structures the board.
***
## Normalization and capacity together
**Normalization** is a related but distinct concept. Where capacity tracking shows how much work fits into a swimlane relative to a person's availability, normalization adjusts how capacity is compared across swimlanes of different sizes (for example, swimlanes representing teams of different headcount). Read [Normalization](/planningboard/concepts/normalization) for a full explanation.
***
## Practical guidance
For planning teams setting up capacity tracking for the first time:
* Start with `capacityLoad = true` and the fixed `hoursPerDay` to verify that effort data is flowing correctly from work items to the bars.
* Once effort data looks correct, enable `multiCapacityLoad = true` if you need per-assignee visibility.
* Connect the Teams Service and enable `userCapacityLoad = true` to get sprint-variable capacity that reflects real availability.
* Set `capacityField` only if your team records effort in a custom field (such as story points) rather than Polarion's standard time estimate fields.
For step-by-step configuration instructions, see the capacity guides under [Guides](/planningboard/guides/index).
**KB Articles**
* Introduction to Planningboard
* Planningboard interface & basic interactions
* Swimlane Assignment Types
**Support Tickets**
* [#6681](https://support.nextedy.com/helpdesk/tickets/6681)
* [#6777](https://support.nextedy.com/helpdesk/tickets/6777)
* [#6605](https://support.nextedy.com/helpdesk/tickets/6605)
**Source Code**
* `AssignmentMode.java`
* `PlanningBoardDataService.java`
* `planningboard.js`
* `Config.java`
* `PlanningBoardWidget.java`
# Dependencies and Links
Source: https://learn.nextedy.com/planningboard/concepts/dependencies
In any project that contains more than a handful of work items, some items cannot start
***
## What a "link" is in Polarion
Polarion models every relationship between work items as a **link**, typed by a **link
role**. A link role is an identifier such as `depends_on`, `implements`, `parent`, or any
custom role your project defines. When you create a link between two work items in Polarion
(from the work-item form, from a document, or from inside Nextedy PLANNINGBOARD itself), you are
attaching a directed, typed relationship edge to both items in the Polarion data model.
Planningboard does not maintain its own relationship store. It reads the links that already
exist in Polarion and renders them visually on the board. This means:
* **Links are owned by Polarion**, not by the board. A link created on the board is
immediately visible in Polarion's work-item form, and vice versa.
* **Which links appear** on the board depends on which link roles you configure in the
widget parameter `PARAMETER_DEPENDENCY_LINK_ROLE`. Only the roles you specify are
visualized as dependencies.
* **Unrecognized link roles** are not shown on the board — not because the links are
broken, but because the board only renders the roles it is told to watch.
**Terminology**
In Planningboard documentation, the word **link** refers to the raw Polarion relationship
data (any role). The word **dependency** refers specifically to a link whose role has been
designated for visualization via `PARAMETER_DEPENDENCY_LINK_ROLE`. The two terms overlap
in casual conversation, but the distinction matters when configuring the board.
***
## Two entry points for exploring links
Planningboard provides two distinct modes for seeing links, serving different planning
contexts.
### Card-level: Show Links
When you hover over any card, a quick-action icon appears in its upper-right corner. The
**Show Links** action (the chain icon) filters the board to show only the selected card and
the cards that are directly linked to it. All other cards are temporarily hidden.
This is a **focused, single-item lens**. It answers the question: "What is this specific
item connected to?" without altering any configuration. The view is transient — dismiss it
and the full board reappears.
You can also **add a link** from a card using the Add Link quick action (the second icon in
the hover menu). After clicking it, the same icon appears on all other cards. Clicking a
second card creates a link between the two. If the icon appears red on a card, a link
already exists — clicking it removes the connection instead.
### Board-level: Show Dependencies
The toolbar at the upper-left of the board contains a **Show Dependencies** toggle. When
activated, it overlays connection lines across the entire board, drawing a line between
every pair of cards that share a link role listed in `PARAMETER_DEPENDENCY_LINK_ROLE`.
**Widget parameter required**
**Show Dependencies** in the toolbar is only active when the widget parameter
`PARAMETER_DEPENDENCY_LINK_ROLE` has been configured. If no dependency link role is
set, the toolbar button has no effect. Configure the parameter in the widget's
**Work Items Dataset Configuration** section.
The board-level view answers a different question from the card-level view: "Given the
current distribution of work across Plans, where are the cross-Plan dependencies?" This
is most useful during release planning, when you need to spot cards in an early sprint that
block cards scheduled for a later sprint — a cross-Plan dependency that drag-and-drop
alone cannot reveal.
***
## How dependency lines are drawn
When Show Dependencies is active, Planningboard calculates a visual line between each pair
of linked cards that are currently visible on the board. The line connects the card
positions as they appear in the current grid — columns are Plans, rows are swimlanes.
A few properties of dependency rendering to keep in mind:
* **Only visible cards produce lines.** If a linked card is in a collapsed swimlane, or
filtered out of the current board view, its connection lines are not drawn. This means
dependency coverage is partial when the board is heavily filtered.
* **Lines are cosmetic, not enforced.** Planningboard draws the lines to inform your
decisions; it does not prevent you from moving cards in ways that violate dependency
order. Planning intent is yours to apply.
* **Direction follows the link role's directionality** as defined in Polarion. If a
`depends_on` role is configured as directed, the arrow points from the dependent item to
the item it depends on.
***
## Parent–child links and swimlane assignment
A special category of links is the **parent–child relationship**, used when swimlanes are
configured with the **Parent Item** assignment type. In this mode, each swimlane represents
a parent work item (for example, a Feature), and the cards inside it are child items (for
example, Tasks or Stories) linked to that parent via the configured **Parent Role** (such
as `implements`).
This introduces a constraint that distinguishes parent-mode swimlanes from other swimlane
types: when you drag a card, Planningboard resolves which parent that card belongs to via
its link, then places the card in the corresponding swimlane. You cannot drop a card into
an arbitrary parent row — the assignment follows the link, not the drop target.
**Automatic swimlane correction**
If you drag a card toward the wrong parent swimlane, Planningboard will move it to the
correct parent row after the drop. This is not a bug — it is the board enforcing link
integrity in the Polarion data model. The card's parent link determines its swimlane
position.
The **Parent Query** parameter (optional) can filter which parent items appear as swimlanes,
letting you narrow the board to a relevant subset of the hierarchy without hiding the
child cards.
***
## Links created on the board vs. links managed in Polarion
When you add a link between two cards using the Add Link quick action, Planningboard writes
a Polarion link in the background. The board is simply a convenient interface for an
operation that could equally be performed in Polarion's work-item form.
From a planning perspective, this means:
* **Changes are immediately persistent.** There is no draft state — clicking the icon saves
the link to Polarion.
* **All Polarion link roles are available.** The Add Link action creates a link; the role
that Planningboard assigns depends on the `PARAMETER_DEPENDENCY_LINK_ROLE` configuration.
* **Deleting a link on the board removes it from Polarion.** Clicking the red icon on a
card that already has a link removes that link from the Polarion data model. This affects
all views that display the same relationship (Polarion's native work-item view, other
boards, reports).
***
## Verified items and link management
One important constraint applies to cards with the **Verified** status: they are locked and
cannot be moved or unplanned on the board. This lock extends to link operations — a
Verified card's position is treated as fixed from a planning perspective, even if its links
remain visible in Show Links or Show Dependencies mode.
**Locked cards**
Cards in **Verified** status cannot be dragged to a different Plan or swimlane, and
cannot be moved back to the Unplanned section. Plan around them, not through them.
***
## Mental model: the board as a link viewport
A useful way to think about Planningboard's dependency features is as a **viewport onto
Polarion's link graph**, filtered and arranged spatially by your planning dimensions (Plans
as columns, swimlanes as rows).
The full link graph exists in Polarion regardless of what the board shows. Planningboard
takes a slice of that graph — the work items matching your `query` parameter, arranged
across the Plans and swimlanes you have configured — and renders the edges within that
slice when you activate Show Dependencies.
This has two practical consequences:
1. **Board configuration shapes dependency visibility.** A narrow query or aggressive
swimlane filter may hide cards that are part of important dependency chains. Expanding
the view (broader query, fewer filters) reveals more of the graph.
2. **The board does not show you what it cannot see.** Dependencies that cross the boundary
of your current board configuration — items in other projects, items excluded by the
query, items in plans outside the `lastPlans`/`nextPlans` window — are silently absent.
They are real links in Polarion, but invisible on this board.
***
## Relationship to board structure concepts
Dependencies and links are one dimension of Planningboard's data model. They interact with
other structural concepts:
* **Board Structure** — the column/row grid that gives spatial meaning to where dependency
lines cross. See [Board Structure](/planningboard/concepts/board-structure).
* **Swimlane Assignment Modes** — particularly the Parent Item mode, which uses link roles
to define swimlane membership. See [Swimlane Assignment Modes](/planningboard/concepts/assignment-modes).
* **Prioritization** — item ordering within a Plan may interact with dependency order in
your process, though Planningboard does not enforce ordering constraints. See
[Prioritization](/planningboard/concepts/prioritization).
***
## Common misconceptions
**"Show Dependencies shows all links on the board."**
No — it shows only links whose roles match `PARAMETER_DEPENDENCY_LINK_ROLE`. If your items
have `parent`, `implements`, and `depends_on` links in Polarion, but only `depends_on` is
configured as the dependency role, only `depends_on` connections are drawn.
**"Adding a link on the board creates a board-local relationship."**
No — every link created via the Add Link quick action is written directly to Polarion and
is globally visible across all Polarion views, not just this board.
**"Dependency lines enforce scheduling constraints."**
No — the lines are visual aids. Planningboard does not prevent you from placing a card
in a Plan that conflicts with its dependency order. Enforcement is a process concern, not
a board constraint.
**"Collapsing a swimlane hides the dependency lines for those cards."**
Yes — collapsed swimlane cards are not rendered, so their dependency lines do not appear.
If you need to verify cross-swimlane dependencies, ensure the relevant swimlanes are
expanded.
***
## Further reading
* [Basic Board Interactions](/planningboard/getting-started/basic-interactions) — practical walkthrough
of the Show Links quick action and the Show Dependencies toolbar button.
* [Board Structure](/planningboard/concepts/board-structure) — how Plans (columns) and swimlanes (rows) define
the spatial layout that gives dependency lines their meaning.
* [Swimlane Assignment Modes](/planningboard/concepts/assignment-modes) — detailed explanation of the Parent
Item mode and how link roles drive swimlane assignment.
**KB Articles**
* Introduction to Planningboard
* Planningboard interface & basic interactions
* Swimlane Assignment Types
**Support Tickets**
* [#6681](https://support.nextedy.com/helpdesk/tickets/6681)
* [#6546](https://support.nextedy.com/helpdesk/tickets/6546)
* [#6777](https://support.nextedy.com/helpdesk/tickets/6777)
**Source Code**
* `AssignmentMode.java`
* `Config.java`
* `PlanningBoardWidget.java`
* `enum-rows-filter.cy.ts`
* `enum-rows-filter-folder-scope.cy.ts`
# Concepts
Source: https://learn.nextedy.com/planningboard/concepts/index
This section explains the core ideas behind Nextedy PLANNINGBOARD — how it models Plans and work items as cards, how swimlanes organize the board, and how capacity tracking and prioritization support planning decisions.
## Board structure and Plans
[**Introduction to Planningboard**](/planningboard/concepts/introduction) — What the board is, how it fits into Polarion, and the relationship between Plans and the board view.
[**Board Structure**](/planningboard/concepts/board-structure) — The anatomy of the board: swimlanes, cards, columns, and how work items and Plans appear on the board surface.
[**Plans Modes**](/planningboard/concepts/plans-modes) — How the board selects and displays Plans using a Plan query, and the different modes in which Plans can be presented.
## Swimlanes
[**Swimlane Assignment Modes**](/planningboard/concepts/assignment-modes) — The available swimlane assignment types that control how work items are grouped into swimlane rows.
## Capacity
[**Capacity Tracking**](/planningboard/concepts/capacity-tracking) — How the capacity bar reflects effort against available capacity per swimlane, and how the board surfaces overloaded and underloaded swimlanes.
[**Normalization**](/planningboard/concepts/normalization) — How capacity normalization adjusts effort values so that swimlanes with different team sizes or sprint lengths can be compared consistently.
## Planning workflows
[**Prioritization**](/planningboard/concepts/prioritization) — How the board's ordering mechanism controls the priority of work items within and across swimlanes.
[**Dependencies and Links**](/planningboard/concepts/dependencies) — How work-item link roles surface as dependency indicators on cards.
[**SAFe Integration**](/planningboard/concepts/safe-integration) — How Planningboard supports Scaled Agile Framework planning structures within Polarion.
[**Teams Service**](/planningboard/concepts/teams-service) — How the Teams Service provides team membership and capacity data consumed by the board.
If you are new to Planningboard, read [Introduction to Planningboard](/planningboard/concepts/introduction) first, then [Board Structure](/planningboard/concepts/board-structure). For capacity planning, continue with [Capacity Tracking](/planningboard/concepts/capacity-tracking) and [Normalization](/planningboard/concepts/normalization).
**KB Articles**
* Introduction to Planningboard
* Swimlane Assignment Types
* Planningboard interface & basic interactions
**Support Tickets**
* [#6681](https://support.nextedy.com/helpdesk/tickets/6681)
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#6777](https://support.nextedy.com/helpdesk/tickets/6777)
**Source Code**
* `AssignmentMode.java`
* `Config.java`
* `PlanningBoardWidget.java`
* `enum-rows-filter.cy.ts`
* `enum-rows-filter-folder-scope.cy.ts`
# Introduction to Planningboard
Source: https://learn.nextedy.com/planningboard/concepts/introduction
Nextedy PLANNINGBOARD is a capacity-aware planning app for Siemens Polarion ALM.
This page explains the core mental model behind Planningboard: what it is, how it structures information, and why it is designed the way it is. For setup instructions, see [Getting Started](/planningboard/getting-started/index). For the individual concept pages, see [Concepts](/planningboard/concepts/index).
***
## The core idea: plans as a spatial canvas
Traditional ALM planning happens in lists. A plan holds a queue of work items, and understanding workload means reading rows of text or interpreting summary counts. Planningboard turns those lists into a spatial canvas: each Plan becomes a column, each work item becomes a **card**, and the column cells are divided into horizontal **swimlanes** that represent a grouping criterion — such as the assignee, the parent work item, or a custom field value.
The result is a two-dimensional grid. Moving a card from one column to another changes which Plan it belongs to. Moving it from one swimlane to another changes its swimlane assignment (for example, its assignee). Both operations happen through drag-and-drop and persist back to Polarion immediately.
This spatial model is borrowed from Kanban-style boards, but Planningboard adapts it specifically for release and sprint planning in Polarion: the columns are Plans (sprints, program increments, or project milestones), not workflow states.
***
## The board layout
The board is split into two main sections:
* **Unplanned section** (right): cards that are not yet assigned to any Plan. This is the backlog — items waiting to be scheduled.
* **Planningboard area** (left): a grid of columns (Plans) and rows (swimlanes). Cards here are scheduled.
The number of columns shown is controlled by the `lastPlans` and `nextPlans` widget parameters (defaulting to 1 past plan and 5 future plans). The columns are Polarion Plans, selected by a **Plan query** (`plansQuery` parameter).
***
## Cards
Every card on the board represents a Polarion work item. The card is a compact visual summary: it shows a configurable set of fields and offers quick actions when hovered (show links, add link, unplan item). Clicking a card opens the **Work Item Properties** sidebar, where fields can be reviewed and edited without leaving the board.
Once a card reaches the Verified status, it cannot be moved or unplanned. This protects completed work from accidental rescheduling.
The content displayed on each card — which fields appear, what font or color is used — is configurable through widget parameters. The card is the primary unit of interaction on the board.
***
## Swimlanes
A **swimlane** is a horizontal row that groups cards by a shared criterion. Swimlanes are the vertical axis of the board: they tell you not just *when* something is planned (the column) but *who* is doing it, *which parent initiative* it belongs to, or *which team* owns it.
The grouping criterion is called the **swimlane assignment type**. Planningboard supports several:
| Assignment Type | What each swimlane represents |
| ----------------- | ------------------------------------------------------------- |
| Users (Assignee) | One swimlane per project member matching a configured role |
| Parent Item | One swimlane per parent work item (e.g., per Feature or Epic) |
| Enumeration Field | One swimlane per value of a custom enumeration field |
| Project | One swimlane per Polarion project (for cross-project views) |
| SAFe types | Program/Solution Teams, Agile Release Train Teams, Programs |
| No Swimlanes | All cards in a single unified view |
The assignment type is set via the `assignmentMode` widget parameter. Swimlane ordering is controlled by `swimlaneSort` (default: alphabetical). Individual swimlanes can be collapsed or expanded.
### Multi-valued field swimlanes
When a work item has multiple values for the swimlane field — for example, two assignees — the card appears in *each* relevant swimlane simultaneously. Dragging the card from one user's swimlane to the **UNASSIGNED** row removes that specific user from the field, without affecting other assignments.
### Parent Item swimlanes and placement rules
When the assignment type is **Parent Item**, Planningboard enforces placement: a card can only be placed in the swimlane corresponding to its actual parent. If you drag it to a different parent's swimlane, it will snap back to the correct one. This ensures the parent–child relationship in Polarion always stays consistent.
Since Planningboard 25.9.0, parent swimlanes can be sorted by any custom property, including priority. See [Swimlane Assignment Modes](/planningboard/concepts/assignment-modes) for configuration details.
***
## Capacity bars
Each column cell (the intersection of a Plan column and a swimlane row) can show a **capacity bar** — a visual indicator of how loaded that swimlane is within that Plan. Hovering over the capacity bar reveals a tooltip with detailed numbers: allocated capacity, total capacity, and available capacity.
Capacity calculations depend on the planning configuration:
* **Allocated capacity** — the sum of remaining estimates for tasks assigned to the swimlane's resource within the Plan.
* **Total capacity** — the resource's available hours for that Plan period, drawn from the Polarion Teams service calendar.
* **Available capacity** — total minus allocated. Negative values indicate overallocation.
All Plans in the project must use the same calculation type. Mixing calculation types across Plans produces incorrect capacity totals. If your capacity numbers look wrong, verify that every Plan uses the same type.
Capacity bars are enabled via `capacityLoad` (or `userCapacityLoad` when using the Teams service). The `hoursPerDay` parameter (default: 8) controls how hours are converted from estimates.
### Enabling team-level capacity
The `useTeamsService` widget parameter connects Planningboard to the Polarion Teams service. With this enabled, capacity is visualized per user within each swimlane, drawing from the team calendar. Without it, total capacity defaults to zero for users without manual capacity configuration.
***
## Plans and plan queries
Planningboard does not show all Plans in a project. Instead, a **Plan query** (`plansQuery` parameter) filters which Plans appear as columns. This lets you focus the board on the current sprint window, a specific release, or a filtered set of iterations.
The `plansMode` parameter determines what kind of Plans are displayed:
* **`PROJECT_PLANS`** (default) — standard Polarion project Plans.
* **SAFe modes** — SAFe Sprints, Program Increments, or Solution Increments for organizations using the Scaled Agile Framework.
* **Custom stemming** — Plans generated automatically from resource field values.
The number of Plans visible at once is controlled by `lastPlans` (past Plans, default 1) and `nextPlans` (future Plans, default 5).
***
## How Planningboard fits into Polarion
Planningboard embeds in Polarion LiveDoc and Wiki pages. One page can contain one or more Planningboard instances, each independently configured via its own **widget parameters**. This means different teams can have different board views on the same Polarion project, each with their own swimlane grouping, Plan query, and capacity settings.
Configuration happens at two levels:
* **Widget parameters** — per-instance configuration, set by editing the widget on the page. These control what the board shows and how it behaves.
* **Administration properties** — system-wide settings applied globally (for example, `nextedy.planningboard.useTeamsService`).
***
## What Planningboard is not
Understanding what Planningboard is *not* prevents misconfiguration and mismatched expectations.
**It is not a workflow board.** The columns are Plans, not workflow states (like "To Do → In Progress → Done"). If you want a Kanban-style board organized by status, that is a different tool. Planningboard's columns represent *time* (sprints, iterations, releases), not *status transitions*.
**It is not a Gantt chart.** Planningboard shows the relative allocation of items across Plans but not calendar timelines, bar lengths proportional to duration, or dependency arrows on a timeline. That is what Nextedy GANTT provides. Planningboard and Gantt are complementary: Gantt for timeline reasoning, Planningboard for capacity-aware sprint allocation.
**It does not replace Polarion's built-in plan management.** The Plans shown on the board are real Polarion Plans. Planningboard is a visual layer over them — changes made on the board (dragging cards, updating fields in the sidebar) write back to Polarion. The Plans themselves are still managed in Polarion's plan administration.
***
## Known limitations
* **No multi-assignee capacity distribution.** When a work item has multiple assignees, Planningboard does not distribute its effort across them. Capacity load is calculated per single assignee. This differs from Nextedy GANTT's multi-assignee support.
* **Swimlane sort order is coupled to item sort order.** The sort order applied to swimlanes affects the ordering of items within those swimlanes. These cannot be independently controlled.
* **Custom-enum card coloring** parity with SCRUMBOARD is not fully implemented. Coloring behavior for custom enumeration fields may differ between the two boards.
* **Capacity configuration parameters are whitespace-sensitive.** Extra spaces in parameter values can cause capacity calculations to silently fail.
***
## Where to go next
* [Board Structure](/planningboard/concepts/board-structure) — detailed breakdown of columns, swimlanes, cards, and the unplanned section.
* [Swimlane Assignment Modes](/planningboard/concepts/assignment-modes) — how each assignment type works and when to choose it.
* [Capacity Tracking](/planningboard/concepts/capacity-tracking) — how capacity is calculated and how to configure it.
* [Plans Modes](/planningboard/concepts/plans-modes) — the different plan display modes including SAFe.
* [Getting Started](/planningboard/getting-started/index) — installation and first board setup.
**KB Articles**
* Introduction to Planningboard
* Planningboard interface & basic interactions
* Swimlane Assignment Types
**Support Tickets**
* [#6681](https://support.nextedy.com/helpdesk/tickets/6681)
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#6496](https://support.nextedy.com/helpdesk/tickets/6496)
**Source Code**
* `Config.java`
* `AssignmentMode.java`
* `displayingMultiEvents.cy.ts`
* `enum-rows-filter.cy.ts`
* `PlanningBoardWidget.java`
# Normalization
Source: https://learn.nextedy.com/planningboard/concepts/normalization
**Normalization** is the mechanism by which Nextedy PLANNINGBOARD reconciles the relationship between a work item and the swimlane or Plan cell it belongs to when that assignment is computed — rather than sim
***
## The Core Problem: Derived vs. Stored Assignment
On a simple Kanban board, moving a card from one column to another is a direct write: the card's status field is updated and the card stays where you dropped it. Planningboard works differently for some swimlane modes because the swimlane a card appears in is **derived** from the card's field values — it is not an independent piece of board state.
Consider a board where swimlanes represent assignees. The swimlane a card appears in is determined by the work item's `assignee` field. If you drag the card to a different swimlane, Planningboard updates the `assignee` field on the underlying work item — the board then re-derives the swimlane from the updated field. The visible result is the same, but the mechanism matters: the board is always a read-consistent projection of your Polarion data, not a separate ordering layer.
Normalization is what happens during that re-derivation step. It ensures that after any change — a drag-and-drop, a field edit in Polarion, or a board refresh — each card ends up in exactly the swimlane(s) consistent with its field values.
***
## Assignment Modes and Normalization Behavior
Different swimlane assignment modes have different normalization behaviors because the underlying field types differ.
When `assignmentMode` is set to **Parent Item** (`PARENT`), plan cells mode (`planCellsMode`) is not supported. This means items assigned via parent links cannot participate in the stemming or SAFe plan-cell normalization described below. Use the **Users (Assignee)** (`ASSIGNEE`) or **Enumeration Field** (`ENUM`) modes if you need combined plan-and-swimlane normalization.
***
## Multi-Valued Fields: One Card in Many Swimlanes
A key aspect of normalization that surprises many users is what happens with multi-valued fields. When a work item has two assignees — say, Alice and Bob — Planningboard does not arbitrarily pick one swimlane. Instead, it displays the card in **both** Alice's row and Bob's row simultaneously.
This display is read-consistent: both instances of the card reflect the same Polarion work item. The board does not create duplicates — it creates multiple projections of a single record.
The same principle applies to multi-value enumeration fields. A work item tagged with two enum values (e.g. `team: alpha` and `team: beta`) appears in both swimlanes.
### The Not Assigned/Other Row
Planningboard always provides a **Not Assigned/Other** swimlane row for items that have no value in the grouping field. This row is the normalization target when you want to remove a value:
* Dragging a card from Alice's row to **Not Assigned/Other** removes Alice from the item's multi-user field — it does not clear all assignees. Bob remains.
* Dragging a card from the `alpha` enum lane to **Not Assigned/Other** removes the `alpha` value from the multi-enum field — other enum values remain.
When a work item appears in multiple swimlanes because of a multi-valued field, you remove one specific value by dragging the card from that value's row to the Not Assigned/Other row. The other values — and their corresponding swimlane appearances — are unaffected.
***
## Plan Cells Mode (planCellsMode)
Standard board mode assigns each card to a Plan (column) and a swimlane (row) independently. **Plan cells mode** (`planCellsMode`) introduces a tighter constraint: a card belongs to a specific *cell* — the intersection of a Plan column and a swimlane row — and the board enforces that pairing.
Plan cells mode is activated when using stemming-based planning or SAFe plan modes. In these modes, the Plan a work item belongs to and the resource (swimlane) it belongs to are encoded together — for example, in a resource field that pairs a team with a sprint. Normalization in this mode means the board reads that combined value, maps it to the correct cell, and places the card there. Moving the card to a different cell updates the combined value in Polarion accordingly.
When normalization is off, each team-iteration combination becomes its own column. The result is a wide board where Iteration 5 - Alpha, Iteration 5 - Beta, and Iteration 5 - Gamma appear as three separate columns even though they cover the same date range:
When normalization is enabled, same-numbered iterations across teams are merged into a single column. The board becomes a grid where each cell is a Team × Iteration combination:
The underlying Polarion plans share the same start and due dates (e.g. all Iteration 5 plans run Oct 20 – Nov 2, 2025), which is what allows the board to treat them as one column:
When you drag a card from one cell to another, Planningboard updates both the Plan assignment and the swimlane field. For example, dragging a card from the Alpha / Iteration 5 cell to the Gamma / Iteration 5 cell updates the work item's Team field from Alpha to Gamma, and the Plan assignment from Iteration 5 - Alpha to Iteration 5 - Gamma:
After the drag, the card moves to the Gamma row and the properties panel reflects the updated Team and Plan values:
The exact field format used to encode plan-resource pairs in stemming mode depends on your configuration. Consult the reference documentation for `stemming` and `planCellsMode` widget parameters for the encoding details applicable to your setup.
***
## Why a Card "Snaps Back"
A common source of confusion is dragging a card to a swimlane and seeing it immediately return to its original position. This happens because normalization re-derives swimlane membership from the work item's field value — and the field value was not (or could not be) updated by the drag.
The most common causes:
| Situation | Why it snaps back |
| -------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| **Parent Item** (`PARENT`) assignment mode | A card can only appear under its actual linked parent. Planningboard enforces the parent link; you cannot override it by dragging. |
| Read-only cross-project view | In cross-project views, the board may render as read-only. Drags are not persisted. |
| Multi-enum swimlane (field update fails) | If the field update fails server-side (e.g. due to a validation error), the board re-normalizes from the unchanged field value. |
| `showEmptySwimlanes = True` with no matching value | If you drag to a lane whose value does not exist on the item and the update is rejected, the card returns to its previous lane. |
When a card snaps back, Planningboard is telling you that the field update did not happen. Check the work item directly in Polarion to understand why the field value was not updated (workflow constraint, required field, permissions, or field type mismatch).
***
## Swimlane Sort Order and Normalization
One consequence of normalization worth understanding: **swimlane sort order is coupled to item sort order**. Because swimlanes are derived from field values rather than being independent objects with their own position, the vertical order of swimlanes on the board is controlled by the `swimlaneSort` parameter (e.g. `alphabetical`), not by dragging the swimlane headers themselves.
As of Planningboard 25.9.0, parent swimlanes can be sorted by any custom property, including priority. This applies to the **Parent Item** (`PARENT`) assignment mode and gives teams control over which parent swimlane appears first without altering the underlying work item structure.
***
## Normalization and Capacity
Capacity bars per swimlane are computed from the normalized state: the board sums capacity values for all cards in a swimlane as derived from the current field values. This has one important consequence for multi-valued fields — **a work item's capacity can be counted more than once** if it appears in multiple swimlanes.
For example, if WI-42 is assigned to both Alice and Bob and carries a `storyPoints = 5` capacity value, it contributes 5 points to Alice's capacity bar and 5 points to Bob's capacity bar.
There is no automatic capacity distribution across swimlanes for multi-valued fields. Each swimlane sees the full capacity of every card it contains. Teams using multi-user or multi-enum swimlanes should account for this double-counting when interpreting capacity bars.
For deeper discussion of capacity calculation and display, see [Capacity Tracking](/planningboard/concepts/capacity-tracking).
***
## Mental Model Summary
Think of Planningboard as a **live query view** over your Polarion work items, not a standalone board with its own card positions:
1. **The board's state is always derived from Polarion field values.** There is no separate "board position" stored independently.
2. **Drag-and-drop is a shortcut for a field update.** Moving a card changes the underlying field; normalization then re-renders the board from the updated data.
3. **Multi-valued fields produce multiple swimlane appearances.** This is correct and intentional — it reflects the item's actual field state.
4. **Snapping back means the field update did not happen.** The board is giving you accurate feedback about your Polarion data.
5. **Plan cells mode tightens the constraint.** Each card belongs to one cell, and moves update the combined plan-resource field.
***
## Related Concepts
* [Swimlane Assignment Modes](/planningboard/concepts/assignment-modes) — the full list of assignment modes and their configuration options
* [Capacity Tracking](/planningboard/concepts/capacity-tracking) — how capacity values are aggregated per swimlane and displayed
* [Plans Modes](/planningboard/concepts/plans-modes) — plan types (Project Plans, SAFe modes) and how they interact with plan cells normalization
* [Board Structure](/planningboard/concepts/board-structure) — the overall anatomy of the board (columns, rows, cards, sidebars)
**KB Articles**
* What is 'Normalization'
* Introduction to Planningboard
* Swimlane Assignment Types
**Support Tickets**
* [#6681](https://support.nextedy.com/helpdesk/tickets/6681)
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#6777](https://support.nextedy.com/helpdesk/tickets/6777)
**Source Code**
* `AssignmentMode.java`
* `Config.java`
* `enum-rows-filter.cy.ts`
* `PlanningBoardWidget.java`
* `enum-rows-filter-folder-scope.cy.ts`
# Plans Modes
Source: https://learn.nextedy.com/planningboard/concepts/plans-modes
Nextedy PLANNINGBOARD organises its columns around a single controlling concept: the **Plans Mode**.
## What a Plans Mode Is
Think of the Plans Mode as a lens. The same pool of work items sits behind the board in every case; the mode controls which Plans frame them as columns. Changing the mode does not change your work items or your swimlane configuration — it changes what the columns *are* and which planning hierarchy they reflect.
Planningboard supports five Plans Modes, controlled by the `plansMode` widget parameter:
| Mode identifier | Description |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `PROJECT_PLANS` | **Project Plans** — standard Polarion Plans from the current project, selected by a custom query |
| `safeSprints` | **SAFe Sprints (Program)** — iteration plans within a SAFe Agile Release Train at Program level |
| `safePflSprints` | **SAFe Sprints (Portfolio)** — iteration plans across all programs in a Solution portfolio |
| `safePIs` | **SAFe Program Increments (Program)** — PI-level planning within an Agile Release Train |
| `safeSIs` | **SAFe Program Increments (Solution)** — PI-level planning coordinated across multiple Agile Release Trains in a Solution train |
The default is **Project Plans** (`PROJECT_PLANS`), which is appropriate for most standard Polarion projects that do not use the SAFe solution structure.
***
## Project Plans Mode
In Project Plans mode, Planningboard loads Plans directly from the current project using a Lucene query you supply. This mode imposes no structural assumptions about your planning hierarchy — if the Plans exist in the project and match the query, they appear as columns.
The relevant widget parameters are:
* `plansQuery` — a Lucene query that selects which Plans to show. When empty or absent, no filter is applied.
* `lastPlans` — how many already-completed Plans to include (default `1`). Showing past Plans lets planners compare what was done against what is being planned now.
* `nextPlans` — how many upcoming Plans to include (default `5`). A wider window gives a longer planning horizon; too many columns can make the board dense.
* `planLink` — a URL template used to link each Plan column header to its Polarion Plan record, supporting `${plan.*}` variables (default points to the Polarion plan detail page).
Plans are ordered chronologically. If your Plans have irregular dates or naming, the chronological order may not match your intuitive sprint sequence — in that case, tighten the `plansQuery` to select only the Plans that matter.
Loading many Plans means loading many work-item sets. Keep `nextPlans` to a practical window (5–8) and use `plansQuery` to exclude irrelevant Plans. The `maxItems` parameter (default `1000`) caps total work items loaded regardless of mode.
***
## SAFe Plans Modes
The four SAFe modes — **SAFe Sprints in Program** (`safeSprints`), **SAFe Sprints in Portfolio** (`safePflSprints`), **SAFe Program Increments in Program** (`safePIs`), and **SAFe Program Increments in Solution** (`safeSIs`) — are designed for organisations using Siemens Polarion ALM's native SAFe Solution structure. They differ in **level** (Sprint vs PI) and **scope** (Program vs Portfolio/Solution).
### Why SAFe modes exist separately
In a SAFe deployment, Plans are not just arbitrary date ranges — they belong to a hierarchy: Team Iterations live inside Program Increments, Programs belong to Agile Release Trains (ARTs), and ARTs belong to a Solution. Planningboard needs to know which level you are planning at so it can load the right set of Plans and present the right column granularity.
When you select **SAFe Sprints in Program** (`safeSprints`), for example, Planningboard automatically queries for Plans using the `iterationPlan` template — you do not write a manual `plansQuery`. The SAFe structure in Polarion drives the discovery.
### SAFe Sprint modes
**SAFe Sprints in Program** (`safeSprints`) and **SAFe Sprints in Portfolio** (`safePflSprints`) both show iteration-level Plans (two-week sprints or similar). The difference is scope:
* **SAFe Sprints in Program** (`safeSprints`) — iterations within the current ART. Planners see one sprint per column for the teams inside a single Program.
* **SAFe Sprints in Portfolio** (`safePflSprints`) — iterations across all programs in the Solution. Use this for portfolio-level coordination when you need to see sprint cadence across multiple ARTs at once.
### SAFe Program Increment modes
**SAFe Program Increments in Program** (`safePIs`) and **SAFe Program Increments in Solution** (`safeSIs`) both show PI-level Plans (typically 8–12 week increments). The difference again is scope:
* **SAFe Program Increments in Program** (`safePIs`) — PIs within a single Agile Release Train. Typical use: an RTE or Product Manager planning features across the teams in one ART.
* **SAFe Program Increments in Solution** (`safeSIs`) — PIs across the entire Solution train, coordinating multiple ARTs. Use this for Solution-level planning where a Solution Train Engineer needs a consolidated view.
The four SAFe Plans Modes only work when your Polarion instance has the SAFe Solution structure configured. Without it, these modes will not find any Plans to display. If you are not using the Polarion SAFe framework, use `PROJECT_PLANS` (Project Plans) mode.
The four SAFe Plans Modes only work when your Polarion instance has the SAFe Solution structure configured. Without it, these modes will not find any Plans to display. If you are not using the Polarion SAFe framework, use **Project Plans** (`PROJECT_PLANS`) mode.
SAFe configuration in Planningboard is highly context-dependent. The widget parameters exposed in the configuration UI differ depending on which Plans Mode you select — `PROJECT_PLANS` shows Scope/Query/Type fields, while SAFe modes show different fields such as the Program Increment Parameter ID. Each SAFe hierarchy level (Portfolio, Program, Team) requires distinct configuration. If you are setting up a SAFe Planningboard for the first time, consult the SAFe Integration concept page: [SAFe Integration](/planningboard/concepts/safe-integration).
SAFe configuration in Planningboard is highly context-dependent. The widget parameters exposed in the configuration UI differ depending on which Plans Mode you select — Project Plans mode shows Scope/Query/Type fields, while SAFe modes show different fields such as the Program Increment Parameter ID. Each SAFe hierarchy level (Portfolio, Program, Team) requires distinct configuration. If you are setting up a SAFe Planningboard for the first time, consult the SAFe Integration concept page: [SAFe Integration](/planningboard/concepts/safe-integration).
***
## How Plans Mode Interacts with Other Configuration
Plans Mode is not an isolated setting — it affects what other configuration options are available and meaningful.
### Effect on Plan query fields
When `plansMode` is set to Project Plans (`PROJECT_PLANS`), you write your own `plansQuery`. When any SAFe mode is active, the Plans query is set automatically (for example, SAFe Sprints in Program (`safeSprints`) hardcodes the iteration plan template filter) — your manual `plansQuery` is not used for Plan discovery in those modes.
### Effect on plan cells mode and normalization
`planCellsMode` — which enables capacity normalization per plan–resource cell — works with Project Plans (`PROJECT_PLANS`), SAFe Sprints in Program (`safeSprints`), and SAFe Sprints in Portfolio (`safePflSprints`) modes. It is **not** compatible with **Parent Item** (`PARENT`) assignment mode. If you are using parent items as swimlanes, plan cells mode (and therefore normalization) is unavailable regardless of which Plans Mode you choose.
See [Normalization](/planningboard/concepts/normalization) and [Capacity Tracking](/planningboard/concepts/capacity-tracking) for the relationship between Plans Mode, plan cells, and capacity bars.
### Effect on the Plans column window
`lastPlans` and `nextPlans` apply in Project Plans mode. In SAFe modes, the Plans visible are determined by the SAFe hierarchy structure and not by a numeric past/future window.
***
## Choosing the Right Mode
The following decision points help you select the appropriate mode:
For the majority of Polarion projects without SAFe, **Project Plans** is the right starting point. It gives you full control via `plansQuery` to select exactly which Plans appear as columns.
***
## Common Misconceptions
**"Plans Mode controls what work items are shown."** No — `plansMode` controls which Plans become columns. Which work items appear is controlled by the `query` widget parameter and the `wiType` filter. Plans Mode and work-item filtering are independent.
**"Changing Plans Mode changes the swimlane configuration."** No — swimlanes are determined by the `assignmentMode` and related parameters. You can combine any Plans Mode with any swimlane Assignment Mode. Plans Mode affects columns; Assignment Mode affects rows.
**"SAFe Sprint modes require a manual plansQuery."** No — in SAFe modes, the Plans query is automatic (e.g. SAFe Sprints in Program (`safeSprints`) uses the iteration plan template). You do not write a Lucene `plansQuery` for Plans discovery in SAFe modes.
**"lastPlans and nextPlans always apply."** Only in Project Plans mode. SAFe modes discover Plans from the SAFe structure, not from a numeric window relative to today.
***
## Limitations
* Planningboard swimlane configuration does not support Polarion page parameters (e.g. `$pageParameters.xxx`) for dynamic plan filtering. Plan selection through `plansQuery` uses static Lucene expressions.
* Custom Team work item types (as opposed to Nextedy's standard Team work item) are not supported in Planningboard for swimlane configuration. If your deployment uses custom Team work item types, consider using Nextedy GANTT (which added support for custom team types in version 25.5.0) as the primary planning tool for team-based scenarios.
* SAFe modes require Polarion's SAFe Solution structure. There is no partial or emulated SAFe Plans Mode for projects that model SAFe hierarchies with custom work item types outside the Polarion SAFe plugin.
***
## Related Concepts
* [Board Structure](/planningboard/concepts/board-structure) — how Plans (columns), swimlanes (rows), and cards fit together
* [Swimlane Assignment Modes](/planningboard/concepts/assignment-modes) — how work items are grouped into rows
* [Capacity Tracking](/planningboard/concepts/capacity-tracking) — how capacity bars relate to Plans and their work item loads
* [Normalization](/planningboard/concepts/normalization) — how plan cells mode distributes capacity across Plans
* [SAFe Integration](/planningboard/concepts/safe-integration) — detailed guidance for SAFe Plans Mode configuration at each hierarchy level
**KB Articles**
* Introduction to Planningboard
* Swimlane Assignment Types
* Planningboard interface & basic interactions
**Support Tickets**
* [#6681](https://support.nextedy.com/helpdesk/tickets/6681)
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#6546](https://support.nextedy.com/helpdesk/tickets/6546)
**Source Code**
* `AssignmentMode.java`
* `Config.java`
* `PlansMode.java`
* `PlanningBoardWidget.java`
* `enum-rows-filter.cy.ts`
# Prioritization
Source: https://learn.nextedy.com/planningboard/concepts/prioritization
Prioritization in Nextedy PLANNINGBOARD is the mechanism by which work items are ordered within a swimlane and across the board.
## What prioritization means on the board
In most project management contexts, "priority" is a field on a work item: a value like *High*, *Must Have*, or *Blocker* that describes its importance in isolation. Planningboard supports that field-based concept through swimlane grouping (for example, grouping rows by a `severity` or priority enumeration field), but **prioritization as a board concept is distinct**: it refers to the *relative order* of cards within a column-and-swimlane cell.
Think of a physical card wall. The card pinned at the top of a swimlane column is worked on first; the card at the bottom waits its turn. Planningboard models this same convention — the vertical order of cards within a cell reflects their priority for that Plan and swimlane combination.
## The Prioritize mode
Prioritization is not always active. The toolbar contains a **Prioritize** button that toggles prioritization mode on and off. When Prioritize is off, the board displays cards in their default sort order (driven by the work item query's sort settings). When Prioritize is on, the board switches to a manually maintained order that persists across sessions.
This is an intentional design decision: most of the time, teams want to see cards sorted predictably (by ID, status, or estimate). Enabling Prioritize is a deliberate signal that the team is actively reordering work for an upcoming planning cycle.
When Prioritize mode is active, each card displays its current priority value in brackets alongside the configured priority field. This makes the relative ordering explicit:
**Prioritize is a board-level toggle**
The Prioritize button applies to the entire board instance, not to individual swimlanes or columns. When you enable it, all cells on that board switch to manually ordered mode simultaneously.
## How card order is stored
When Prioritize mode is active and you drag a card to a new position within a cell, Planningboard records that relative position and saves it. The order is associated with the board widget (the specific Polarion page and widget instance), not with the work item itself. This means:
* The same work item can have a different position on two different Planningboard boards in the same project.
* Moving a card to a new Plan column (assigning it to a different Plan) resets its position within that new cell to the default.
* The priority order is independent of the work item's own priority field — reordering on the board does not write back to any Polarion field unless your configuration explicitly maps it.
## Swimlane sort order and its effect on prioritization
One important constraint to understand: **the sort order of swimlanes is coupled to the sort order of items within swimlanes**. Planningboard does not maintain entirely independent sort axes for rows and for card positions within rows. When the swimlane assignment type is set to Parent Item, the `Sort By` configuration determines both how parent swimlanes are ordered vertically and how items within those swimlanes are initially sequenced.
This means that if you change the swimlane sort setting (for example, switching from alphabetical to a custom property like priority), the card order within cells may also be affected. Plan for this when rolling out a prioritization workflow — agree on the swimlane sort order before teams begin manually reordering cards.
**Known limitation: swimlane sort and item sort are coupled**
Swimlane sort order is coupled to item sort order in the current implementation. Changing the swimlane sort configuration after manual prioritization has been established may disrupt the card order teams have set up. This is a known architectural constraint, not a configuration error.
## Relationship to the Unplanned section
Cards in the **Unplanned section** (the backlog on the right) are also subject to ordering. When you enable Prioritize mode, the unplanned list becomes manually orderable as well. This is useful for agreeing on backlog priority before pulling items onto the board for a sprint or release.
The Unplanned section can be filtered by assignee, team, or custom query — but those filters do not change the underlying priority order; they only affect visibility. Once you remove a filter, the full ordered list reappears with positions intact.
## Priority as a swimlane grouping field
Separate from the Prioritize ordering mode, teams often want to *visualize* priority as a dimension of the board itself. Planningboard supports this through the **Enumeration Field** swimlane assignment type.
When you configure swimlanes by an enumeration field such as `severity` (which may contain values like *Must Have*, *Should Have*, *Could Have*, *Won't Have* in a MoSCoW model), each priority value becomes its own swimlane row. Cards with that priority level appear in the corresponding row, giving an immediate visual overview of the priority distribution across Plans.
This approach answers a different question than the Prioritize toggle:
| Approach | Question answered |
| ----------------------------- | ---------------------------------------------------------------------------- |
| Prioritize mode (card order) | *In what order should we work on these items within this Plan and swimlane?* |
| Swimlane by enumeration field | *How many items of each priority level are assigned to each Plan?* |
Both can be used simultaneously: you can have swimlanes grouped by `severity` *and* enable Prioritize mode so that cards within each severity row are manually ordered.
**MoSCoW on the board**
If your work items have a `severity` field with MoSCoW values (*Must Have*, *Should Have*, *Could Have*, *Won't Have*), configure the Enumeration Field swimlane assignment type with `Field ID: severity`. Each row then shows a distinct priority tier, and the capacity bar on each row shows how much work is committed at that tier.
## What happens when Verified items are present
Cards with the status **Verified** are locked on the board — they cannot be moved or unplanned. This lock applies in Prioritize mode as well: you cannot drag a Verified card to a new position. Non-Verified cards around it can be repositioned, but the Verified card itself remains anchored.
This behavior ensures that completed and verified work does not accidentally get deprioritized or moved out of its Plan during an active reordering session. Use the **Filter columns** option in the Unplanned section to hide Verified items from the board if they create visual clutter during prioritization.
## Priority and dependencies
When work items have dependency links between them (configured via the `PARAMETER_DEPENDENCY_LINK_ROLE` widget parameter), the board can display those relationships visually using the **Show Dependencies** toolbar button. Prioritization and dependency visualization work independently: enabling Prioritize mode does not automatically enforce dependency ordering. It is the team's responsibility to ensure that the manual card order respects dependencies.
The **Show Links** quick action on individual cards (hover → link icon) lets you check which cards a specific item depends on before repositioning it. This is the recommended workflow when using Prioritize mode in conjunction with dependency visualization.
## How same-priority cards are handled
When two or more cards have the same initial priority value, Planningboard still assigns a deterministic order when you drag one of them. The algorithm adds a fixed increment or calculates an average to spread the values apart.
**Two cards with the same priority:** when both cards share the same value (e.g., 50.0), dragging one above the other adds 10 points to the top card. The cycle can repeat, always maintaining a 10-point difference:
After dragging PB-204 above PB-120, PB-204 receives a value of 60.000 (+10), while PB-120 stays at 50.000:
**Three cards with the same priority:** when all three share the same value (e.g., 50.0), the top card receives +10 (60.0), and the middle card receives the average of its two neighbours:
After moving PB-205 to the middle position, it receives the average value between the top (60.0) and bottom (50.0) cards — resulting in 55.0:
The final ordered state shows the three cards with evenly spread priority values:
## Common misconceptions
**"Enabling Prioritize mode changes the work item's priority field in Polarion."**
It does not. Prioritize mode manages the visual order of cards on the board. It does not write to any Polarion field. If you need priority changes to be reflected in a Polarion custom field, that requires a separate workflow outside Planningboard.
**"The card order I set in one board applies everywhere."**
Card order is scoped to the individual board widget. Two boards on different Polarion pages, even in the same project, maintain independent priority orders.
**"Sorting swimlanes by a custom property is the same as prioritizing cards."**
Sorting swimlanes (via the Parent Item assignment type's `Sort By` setting) reorders the rows, not the cards within rows. These are distinct concepts, though they share the same underlying sort mechanism and can interfere with each other as noted above.
**"All swimlane assignment types support the same prioritization behavior."**
The Parent Item assignment type has one important constraint: you cannot freely place a card in any parent's swimlane. When you drag a card, Planningboard automatically places it under its actual parent. This means manual card positioning within a cell is still possible, but cross-swimlane repositioning is constrained by the hierarchy.
## Putting it together: a mental model
Imagine the Planningboard as a physical sprint planning wall:
* **Columns** = Plans (sprints, releases, iterations)
* **Rows** = Swimlanes (assignees, teams, priority tiers, parent features)
* **Cards** = Work items
* **Card position within a cell** = Priority order (top = highest, bottom = lowest)
* **Unplanned section** = The backlog tray beside the wall
When the team sits down for sprint planning, they enable **Prioritize** — like picking up the cards and arranging them deliberately. When the session ends, the order is saved and the wall remembers it. The Prioritize toggle is the signal that says "we are actively reordering" versus "just showing me the default view."
The key insight is that prioritization in Planningboard is a *board-level* activity, not a field update. It is a planning gesture — a way to communicate intent visually, across the team, within the planning session.
## Related pages
* [Board Structure](/planningboard/concepts/board-structure) — how columns, swimlanes, and cells are organized
* [Swimlane Assignment Modes](/planningboard/concepts/assignment-modes) — configure rows by assignee, parent, enumeration field, or project
* [Capacity Tracking](/planningboard/concepts/capacity-tracking) — understand how card order interacts with capacity bars
* [Dependencies and Links](/planningboard/concepts/dependencies) — visualize and manage work item dependencies alongside prioritization
**KB Articles**
* Introduction to Planningboard
* Planningboard interface & basic interactions
* Swimlane Assignment Types
**Support Tickets**
* [#6681](https://support.nextedy.com/helpdesk/tickets/6681)
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#6496](https://support.nextedy.com/helpdesk/tickets/6496)
**Source Code**
* `AssignmentMode.java`
* `Config.java`
* `PlanningBoardWidget.java`
* `enum-rows-filter.cy.ts`
* `displayingMultiEvents.cy.ts`
# Scoping and Filtering Project Swimlanes
Source: https://learn.nextedy.com/planningboard/concepts/project-swimlane-scoping
A deep dive into how Nextedy PLANNINGBOARD's Project assignment mode scopes which sub-projects appear as swimlanes using the Project Query parameter, and what changes once a board spans multiple projects.
This page is a deep dive into [Project Mode](/planningboard/concepts/assignment-modes) swimlane scoping — how a board that spans multiple Polarion projects controls exactly which projects appear, and what else changes once it does.
***
## Scoping with Project Query
Project Mode's swimlane list isn't limited to "every sub-project in the current group." The **Project Query** widget parameter is a Lucene query, evaluated once per board load, that defines exactly which projects belong on the board. Set it to describe the projects you're planning for, and only those appear.
Project Query filters three things at once, from the same query:
* Which projects show up as swimlanes.
* Which work items get loaded onto the board.
* Which Plans appear as columns.
The unplanned-items sidebar respects it too. Because the scope lives in the query rather than in the page the widget is embedded on, the same board keeps working even if projects are later reorganized into different project groups.
If no Project Query is set, the board falls back to discovering sub-projects of the current project group, as described in [Project Mode](/planningboard/concepts/assignment-modes). Setting Project Query explicitly is recommended for any board meant to keep tracking a specific, fixed set of projects.
### Query Examples
| Goal | Query |
| ------------------------------------------- | -------------------------------------- |
| Only projects with "Team" in the name | `name:*Team*` |
| A fixed, small set of projects | `id:(team-alpha team-beta team-gamma)` |
| Every project whose ID starts with a prefix | `id:squad-*` |
| Combine conditions | `name:*2025* AND id:proj-*` |
| Everything except one project | `name:*Team* AND NOT id:team-archived` |
Any indexed project field can be used — not just `id` and `name` — including custom project fields.
Changing the Project Query re-computes swimlanes, loaded work items, and the dependency/parent role menus (below) immediately — there's nothing else to refresh.
***
## Filtering with a Page Parameter
To let planners choose the projects themselves — rather than editing a fixed query each time — Project Query can be driven by a page parameter instead of a literal string.
This starts with a page parameter that lets planners pick one or more projects — for example, one named `Projects`, added via the page's **Parameters** flyout (gear icon). Its type is typically Enumeration, so people can select from real Polarion projects rather than typing IDs.
Unlike the general work-items **Query** field, which accepts Velocity syntax typed directly into the field, **Project Query does not** — typing a page-parameter reference straight into it does not work. Project Query only supports binding to a page parameter through the gear icon, and only to a **String**-typed parameter. `Projects` itself, being Enumeration-type, isn't String-typed, so it can't be bound directly either — it never appears in that gear icon's list at all.
The fix is a **Page Script** that reads `Projects`, computes the full query clause as a string, and exposes it as a new scripted parameter:
```velocity theme={null}
#set($projectsQuery = "")
#if($pageParameters.Projects && !$pageParameters.Projects.values().isEmpty())
#set($ids = $pageParameters.Projects.toLucene())
#set($projectsQuery = "id:($ids)")
#end
$!scriptedPageParameters.put("projectsQuery", $factory.string("Projects Query").value($projectsQuery).build())
```
Then click the gear icon on **Project Query** → **Parameters**, and select **Projects Query** — the scripted parameter, not the raw project-picker parameter.
The scripted parameter's value becomes the *entire* content of the Project Query field — there's no surrounding `id:(...)` for it to slot into. Compute the complete clause, including the field prefix, inside the Page Script itself; don't expose just the bare `.toLucene()` output.
The page parameter's selectable projects still need to fall within **Scope** — Scope restricts the searchable project set before Project Query ever runs. A project outside Scope never appears, no matter what Project Query says.
The `id:` field prefix used above has not been independently confirmed against a live Project Query field — it's inferred from the static query examples elsewhere on this page, which query project documents directly. A related, more general Planningboard query field uses `project.id:` instead (see [Work Items Parameters](/planningboard/reference/widget-parameters/work-items-parameters)), which filters work items rather than projects. Confirm which prefix Project Query actually expects before relying on this in production.
***
## Cross-Project Board Behavior
### Dependency and Parent Role Menus
Two menus need to work across every project a board shows: **Work Items → Dependency Roles** and **Unplanned Sidebar → Parent Roles**. Each Polarion project can define its own `workitem-link-role` enumeration, which replaces the global one — so the same logical role (e.g. "depends on") can have a different internal ID per project.
Both menus are built from the union of link roles across every project the board currently shows, so a role from any in-scope project can be selected, regardless of which project's page the board lives on.
How roles are labelled:
* Options are keyed by role **ID**, titled by role **name**.
* If multiple projects use the same ID with different names, they collapse into one option listing all names joined by `/` — e.g. `depends on / requires`.
* If a role has no name anywhere, its ID is shown as the title.
* Once more than one project is in scope, a selected role's ID is appended in parentheses — `depends on (depends_on)` — so overlapping names stay distinguishable. Only selected roles get this treatment, to keep the rest of the list readable.
See [Dependencies and Links](/planningboard/concepts/dependencies) for the general link/dependency model this builds on.
### Swimlane Order
Project Query is a pure include/exclude filter — it doesn't control order. Swimlanes are ordered the same way projects appear in the Polarion project tree (the project group hierarchy), and the query is applied after that order is resolved.
For example, if a group contains `[alpha, beta, gamma, delta]` in that order and the query matches `[beta, delta]`, the swimlanes appear as `beta | delta` — in hierarchy order, not query-match order.
### Merged Iteration/Release Columns
Say two projects each run a Plan with the same plan ID — `Iteration_35`. The board's column key used to combine the project with the plan (effectively `alpha/Iteration_35` vs. `beta/Iteration_35`), so two projects sharing a plan ID produced two separate columns with the same name — and the more projects on the board, the more duplicate columns piled up.
Plans that share the same plan ID now collapse into a single column, regardless of how many projects define them:
* One column per iteration/release ID, however many projects run it.
* A work item still belongs to the Plan of its own project — it shows up in the merged column, in its own project's swimlane row.
* Dropping a card into a merged column plans it into that project's own Plan with that ID; nothing is written to other projects' Plans.
* Matching is on the full plan ID, not a prefix — `Iteration_35` and `Iteration_350` stay separate columns.
***
## Common Misconceptions
**"Which projects appear is decided by where the widget is placed."** Only when Project Query is left empty. Placement (inside a project, inside a project group, or at global scope) is a fallback default, not the primary mechanism — Project Query is what actually controls scope.
**"Project Query and Scope are the same setting."** They aren't. Scope restricts the searchable project set before Project Query ever runs; Project Query then filters within whatever Scope allows. A project excluded by Scope never appears, regardless of what Project Query says.
**"Project Query controls the order swimlanes appear in."** It doesn't — it's a pure include/exclude filter. Order always follows the Polarion project group hierarchy, applied after the query has already narrowed the set.
**"Two projects with a plan of the same ID always produce duplicate columns."** Not anymore. Plans sharing the same plan ID collapse into a single column regardless of how many projects define them — see Merged Iteration/Release Columns above.
***
## Related Concepts
* [Swimlane Assignment Modes](/planningboard/concepts/assignment-modes) — the full set of assignment types, including Project mode's basics
* [Dependencies and Links](/planningboard/concepts/dependencies) — the general link/dependency model referenced above
* [Plans Modes](/planningboard/concepts/plans-modes) — how Plan columns are organized, independent of swimlane rows
# SAFe Integration
Source: https://learn.nextedy.com/planningboard/concepts/safe-integration
Nextedy PLANNINGBOARD includes native support for **Scaled Agile Framework (SAFe)** environments, enabling planning at the portfolio, program, and team hierarchy levels directly within Siemens Polarion ALM.
***
## What SAFe integration means in Planningboard
In a standard Planningboard setup, columns represent Polarion Plans and rows represent swimlanes based on assignees, projects, or custom fields. SAFe integration extends both of these axes to reflect the multi-level planning hierarchy that SAFe introduces: **Program Increments (PIs)**, **Sprints**, **Agile Release Trains (ARTs)**, and **Programs** within a Solution Train.
Rather than treating SAFe-level planning as a workaround involving custom fields and manual queries, Planningboard exposes dedicated plan modes and swimlane assignment types that map directly onto SAFe structures stored in Polarion's SAFe Solution data. The result is that the planning hierarchy you configured in Polarion's SAFe module — with its ARTs, teams, and PIs — surfaces on the board without duplicate configuration.
***
## The two axes of a SAFe board
Understanding how SAFe integration works requires seeing how SAFe concepts map onto the board's two independent axes.
**Columns (Plans Mode)** determine what appears as the board's time axis. SAFe-specific plan modes are:
* **SAFe Sprints in Program** (`safeSprints`) — SAFe Sprint iterations within a Program (ART level). Plans are loaded automatically using Polarion's Iteration Plan template; no manual plan query is required.
* **SAFe Sprints in Portfolio** (`safePflSprints`) — SAFe Sprint iterations at the Portfolio level, spanning multiple programs in a solution portfolio.
* **SAFe Program Increments in Program** (`safePIs`) — Program Increments at the ART (Program) level, showing the 8–12 week PI cadence.
* **SAFe Program Increments in Solution** (`safeSIs`) — Program Increments at the Solution level, coordinating PIs across multiple ARTs in a Solution Train.
**Rows (Swimlane Assignment Type)** determine which SAFe organizational unit each row represents. SAFe-specific assignment modes are:
* **Program / Solution Teams (SAFe)** (`SAFE_TEAM`) — Swimlanes for each SAFe team within the current program, discovered from Polarion's SAFe Solution data.
* **Agile Release Train Teams (SAFe)** (`SAFE_TRAIN_TEAM`) — Swimlanes for teams within a specific Agile Release Train, filtered by ART ID.
* **Programs (SAFe)** (`SAFE_PROGRAMS`) — Swimlanes for SAFe programs within a Solution Train, used for portfolio-level planning.
The two axes are independent: you can combine **SAFe Program Increments in Program** (`safePIs`) columns with **Program / Solution Teams (SAFe)** (`SAFE_TEAM`) swimlanes for a classic PI planning view, or use **SAFe Sprints in Program** (`safeSprints`) columns with **Programs (SAFe)** (`SAFE_PROGRAMS`) swimlanes for cross-program sprint coordination.
***
## How SAFe data is sourced
A critical difference from non-SAFe configuration is *where* the board gets its data.
In Project Plans mode, Planningboard reads plans from the current Polarion project using a Lucene query you supply. In SAFe modes, the board reads from **Polarion's SAFe Solution model** — the structured ART, team, PI, and program data managed by Polarion's SAFe module, not from custom fields you define yourself.
This means:
* Teams appearing in **Program / Solution Teams (SAFe)** (`SAFE_TEAM`) swimlanes come from Polarion's SAFe team registry, not from a custom field called `team`.
* PIs appearing as columns in **SAFe Program Increments in Program** (`safePIs`) mode are the actual PI plans tracked by Polarion's SAFe module, not plans matching a user-defined query.
* ART filtering in **Agile Release Train Teams (SAFe)** (`SAFE_TRAIN_TEAM`) mode is driven by the ART ID from Polarion's SAFe configuration, not by a tag or custom field value.
The practical consequence: **SAFe integration requires that Polarion's SAFe Solution is already configured** for the relevant project or project group. Planningboard reads from that configuration; it does not substitute for it.
**SAFe Solution is a prerequisite**
The **Program / Solution Teams (SAFe)** (`SAFE_TEAM`), **Agile Release Train Teams (SAFe)** (`SAFE_TRAIN_TEAM`), and **Programs (SAFe)** (`SAFE_PROGRAMS`) assignment modes, and the **SAFe Program Increments in Program** (`safePIs`), **SAFe Program Increments in Solution** (`safeSIs`), **SAFe Sprints in Program** (`safeSprints`), and **SAFe Sprints in Portfolio** (`safePflSprints`) plan modes, all require that Polarion's SAFe Solution is active and configured for the current project context. Without it, these modes cannot discover teams, ARTs, or PIs.
***
## SAFe fields on work items
For SAFe swimlane assignment to work correctly, work items must carry SAFe-specific custom fields that Planningboard reads to route them into the right row. Two field IDs matter:
* `safeTeam` — stores the SAFe Team assignment for a work item. Used when `assignmentMode` is `SAFE_TEAM` or `SAFE_TRAIN_TEAM`.
* `safeProgram` — stores the SAFe Program assignment for a work item. Used when `assignmentMode` is `safePrograms` (SAFE\_PROGRAMS).
These field IDs are the defaults. If your Polarion project uses different field IDs for team and program assignment, the widget parameters `safeTeamField` and `safeProgramField` let you override them.
**Field IDs are configurable but whitespace-sensitive**
Capacity configuration parameters and field ID overrides are whitespace-sensitive. A trailing space in a field ID value will cause the field to go unresolved silently. Always trim values when entering them in the widget parameter panel.
***
## Planning hierarchy levels and their configurations
SAFe planning happens at different levels of the hierarchy. The configuration that works at one level does not simply transfer to another — the Plans Mode selection, the swimlane assignment type, and sometimes the portfolio suffix all change.
A common source of confusion: when you switch Plans Mode from **Project Plans** (`plans`) to **SAFe Program Increments in Program** (`safePIs`), the configuration UI in the widget parameter panel changes. Fields that were visible for Project Plans — such as Scope, Query, and Type — are replaced by SAFe-specific fields including the **Program Increment Parameter ID** field. This is not a UI bug; it reflects that the two modes require fundamentally different inputs. Expecting the same configuration fields across plan modes is a misconception that frequently causes configuration errors.
**Configuration UI changes with Plans Mode**
Selecting **SAFe Program Increments in Program** (`safePIs`) or **SAFe Sprints in Program** (`safeSprints`) as the Plans Mode replaces the standard plan query fields with SAFe-specific configuration fields. If you see unexpected or missing fields after switching Plans Mode, this is expected behaviour — check the SAFe-specific parameters rather than looking for the standard plan query fields.
***
## Page Parameters and Program Increment Parameter ID
One aspect of SAFe configuration that frequently causes confusion is the use of **Page Parameters**. In SAFe mode, the board may need to know which specific PI or ART to display — and this information is often passed as a page parameter rather than being hardcoded in the widget.
The **Program Increment Parameter ID** field in the widget configuration references a Page Parameter defined on the Polarion page containing the widget. This indirection exists so that a single board widget can be reused across multiple PIs or ARTs by changing the page parameter value, rather than reconfiguring the widget each time.
The setup flow is:
1. A Page Parameter is created on the Polarion page (not inside the widget).
2. The widget's **Program Increment Parameter ID** field references that page parameter's ID.
3. The page parameter's value supplies the actual PI ID or ART ID to the board at runtime.
If Page Parameters are not explicitly created and referenced, the board cannot resolve the PI or ART context and will either show an empty board or fall back to unexpected defaults.
**Page Parameters must be created explicitly**
Page Parameters do not exist by default. They must be created on the Polarion page containing the Planningboard widget before the **Program Increment Parameter ID** field can reference them. If the board shows no SAFe plans or teams after configuration, verify that the Page Parameter exists and that its ID matches the value entered in the widget.
***
## SAFe-specific swimlane assignment types and support
The KB lists three SAFe swimlane assignment types as available for SAFe environments:
* **Program / Solution Teams (SAFe)**
* **Agile Release Train Teams (SAFe)**
* **Programs (SAFe)**
**Verify in application**
Enabling SAFe swimlane assignment types requires setup guidance specific to your Polarion SAFe Solution configuration. If these swimlane options do not appear in the Assignment Type dropdown of your Planningboard widget, contact Nextedy support for setup assistance — the options require the SAFe Solution to be active and may require additional configuration steps beyond the widget parameter settings.
***
## SAFe sprints: auto-applied plan query
One small but important detail about **SAFe Sprints in Program** (`safeSprints`) mode: the plan query is **automatically set** to filter plans by Polarion's Iteration Plan template (`template.id:iterationPlan`). You do not need to — and should not — supply a manual plan query when using **SAFe Sprints in Program** mode. The auto-applied filter ensures only iteration-level plans appear as columns, preventing PI-level or other plan types from mixing into the sprint view.
This contrasts with Project Plans mode, where the plan query is entirely user-defined.
***
## Common misconceptions
**"I can use a custom `team` enum field instead of the SAFe team field."**
You can use **Enumeration Field** (`ENUM`) swimlane assignment mode with a custom team field for non-SAFe team planning, but this is a different configuration from **Program / Solution Teams (SAFe)** (`SAFE_TEAM`) mode. The two approaches differ in how teams are discovered (custom enum options vs. Polarion's SAFe team registry) and in the drag-and-drop behaviour when moving cards between swimlanes. Do not use one as a substitute for the other in a genuine SAFe environment.
**"The SAFe plan modes work like Project Plans mode with a pre-filled query."**
SAFe plan modes use Polarion's SAFe Solution data source, not the standard plan query mechanism. This is why the configuration UI differs: the inputs required are structurally different, not just different query strings.
**"Changing Plans Mode just changes which plans are shown."**
Changing Plans Mode also changes the configuration schema the widget expects. Fields available in one mode may not exist in another. Always re-check the widget configuration panel after switching Plans Mode.
**"Global enumeration custom fields can be used for SAFe-style swimlanes."**
There is a known limitation: global enumeration custom fields may fail validation after saving in Planningboard swimlane configuration, even if they appear to resolve during initial setup. If you need enum-based swimlanes, use project-scoped enumeration fields. See [Swimlane Assignment Modes](/planningboard/concepts/assignment-modes) for the full discussion of field scope requirements.
***
## Relationship to Plans modes and assignment modes
SAFe integration is not a separate feature switch — it is realized through the combination of the **Plans Mode** setting and the **swimlane assignment type** setting. The concepts page for [Plans Modes](/planningboard/concepts/plans-modes) covers all available plan mode values. The [Swimlane Assignment Modes](/planningboard/concepts/assignment-modes) page covers the full set of assignment types including the SAFe-specific ones.
Capacity tracking in SAFe environments follows the same capacity bar and normalization model as non-SAFe boards, with the same limitations: no multi-assignee capacity distribution and no sub-item effort distribution. See [Capacity Tracking](/planningboard/concepts/capacity-tracking) for details.
***
## Summary: the mental model
Think of Planningboard's SAFe integration as a **translation layer** between Polarion's SAFe Solution data model and the board's column/row grid. The board does not manage SAFe structure — it reads it. Your ARTs, teams, and PIs exist in Polarion's SAFe module; Planningboard surfaces them as columns and swimlanes for visual, drag-and-drop planning without leaving the ALM environment.
The configuration challenge is choosing the right Plans Mode for your hierarchy level, ensuring the corresponding SAFe data exists in Polarion, and wiring up any Page Parameters the board needs to resolve the specific PI or ART context. Once those three things align, the board constructs itself from live Polarion data rather than from manually maintained lists.
For practical configuration steps, refer to the [Guides](/planningboard/guides/index) section when those pages become available.
**KB Articles**
* Introduction to Planningboard
* Swimlane Assignment Types
* Planningboard interface & basic interactions
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#6681](https://support.nextedy.com/helpdesk/tickets/6681)
* [#6734](https://support.nextedy.com/helpdesk/tickets/6734)
**Source Code**
* `AssignmentMode.java`
* `Config.java`
* `PlanningBoardWidgetRenderer.java`
* `PlansMode.java`
* `enum-rows-filter.cy.ts`
# Teams Service
Source: https://learn.nextedy.com/planningboard/concepts/teams-service
The **Teams Service** is the subsystem within Nextedy PLANNINGBOARD that models your organization's team structure as first-class Polarion data.
This page explains what the Teams Service is, how it is structured, and why it exists — not how to configure it step by step.
## Why a Teams Service Exists
Planningboard already supports organizing swimlanes by assignee (the **Users (Assignee)** assignment type). That mode reads Polarion user roles and populates one swimlane per user in the project. It works well when you have a small, stable project with no multi-team overlay.
As soon as you need to answer questions like "which users belong to Team Alpha this sprint?" or "how much capacity does the backend team have in weeks 3 and 4 of this PI?", a flat user-role list is not enough. You need a model that captures:
* **Team identity** — a named entity that can be referenced across projects
* **Membership over time** — people join and leave teams; a member's availability changes
* **Capacity per member** — each person may be allocated at a different percentage
* **Aggregate team capacity** — the total hours the team can deliver in a window
The Teams Service provides exactly this model, represented entirely inside Polarion as standard work items with custom fields — no external database or API is required.
## How Teams Are Represented
Each team is a **Polarion work item** of a specific type (the "Team WI"). The Teams Service locates teams by querying work items in the current project (and any supporting projects assigned to it). Because teams are ordinary work items, they inherit all Polarion capabilities: access control, custom fields, workflow, documents, and links.
Team membership is also represented as work items — one work item per team assignment — with at minimum two date fields (`from` and `to`) that bracket the period during which a person belongs to a team. The Teams Service reads these assignment work items when it resolves "which users are on this team right now?" and "which users were active during this specific date range?"
A "supporting project" is a Polarion project whose teams are made available to the current project. The Teams Service discovers teams from both the current project and any supporting projects automatically, using a query that matches both `project.id` and the supporting project field. Team IDs from supporting projects are remapped transparently so callers always work with local references.
## The Capacity Model
When `useTeamsService` is enabled together with `userCapacityLoad`, the board calculates capacity from the ground up rather than from a flat hours-per-day figure.
The calculation chain works as follows:
Each member's **working calendar** is resolved individually. If a user has no calendar configured, the system falls back to a base user's calendar (configured via the `nextedy.gantt.calendarHolder` property) and then to the system-default calendar. This means capacity values vary correctly from sprint to sprint as holidays and leave change the available working days.
The result is a `Map` — user IDs mapped to individual capacity hours — which the board uses to populate per-user capacity bars inside swimlanes.
### Capacity Modifiers
An optional layer called **capacity modifiers** can reduce team capacity by a percentage. This is controlled by the `nextedy.gantt.useTeamCapacityModifiers` configuration property (default: `false`). When enabled, the Teams Service reads two integer fields from the team work item — by default `capModA` and `capModB` (overridable via `nextedy.gantt.capacityModifierAField`) — and applies the percentage reduction before returning capacity figures.
Capacity modifiers let you account for overhead, ceremonies, or planned unavailability at the team level without adjusting individual member calendars.
## What the Service Exposes to the Board
The Teams Service interface (`IPlanningBoardTeamsService`) provides the following logical operations to the board engine:
| Operation | What it returns |
| ---------------------------- | ------------------------------------------------------------------- |
| Get team work item | The work item representing a specific team (by team ID and project) |
| Get all teams | All teams in the project, including teams from supporting projects |
| Get team user IDs (basic) | All user IDs assigned to the team |
| Get team user IDs (filtered) | User IDs filtered by active-only flag and/or date range |
| Get team users (basic) | Full user objects for all team members |
| Get team users (filtered) | Full user objects filtered by active-only flag and/or date range |
| Get team capacity | Total team capacity in hours for a date range |
| Get user capacity | Individual user capacity in hours within a team for a date range |
| Get all user capacities | Map of user ID → capacity hours for all team members |
Two variants exist for date-range operations: one that accepts `Date` objects (with time component) and one that accepts `DateOnly` objects (date only, no time zone consideration). The board uses the variant appropriate to the planning context — sprint planning typically works with date-only boundaries.
Users that cannot be resolved in Polarion are excluded from filtered results. This means a stale assignment work item pointing at a deleted user account does not cause errors; the user simply does not appear in membership or capacity results.
## How This Connects to Swimlane Configuration
When `useTeamsService = true` and the `assignmentMode` is set to `ASSIGNEE`, the board does not fall back to the flat project-role list. Instead it uses the Teams Service to resolve which users belong to the selected team (`selectedTeam`), and only those users appear as swimlane rows. This is fundamentally different from the standard Users (Assignee) mode:
The swimlane rows therefore reflect **team membership at the time of planning**, not the static project-role assignment. A user who left the team before the sprint starts will not appear; a user who joins mid-sprint can appear depending on the active-only and date-range filters.
**Coordination required for full team filtering**
Team-based swimlane filtering requires two coordinated configurations: a `selectedTeam` parameter on the board widget (filters the swimlane rows) **and** a matching Plans query that filters iterations by team. If only one of the two is configured, swimlanes may filter correctly while the columns do not (or vice versa), producing a misleading view. See the swimlane assignment types guide for details.
## Known Limitations
The Teams Service capacity model has gaps compared to Nextedy GANTT's capacity features. These are confirmed limitations, not planned features:
* **No multi-assignee support.** Capacity load is calculated from the single assignee field on each work item. Work items with multiple assignees are not currently handled.
* **No sub-item effort distribution.** Capacity calculations do not aggregate effort from child or sub-items. Only the direct work item's effort contributes to load.
* **Custom Team WI types are not supported.** Planningboard requires Nextedy's standard Team work item structure (specific custom fields on the Team WI). Custom team work item types — even if they hold equivalent data — are not compatible with the Teams Service. By contrast, Nextedy GANTT 25.5.0+ introduced support for custom team WI types. Teams planning multi-product deployments where Gantt and Planningboard coexist should use the standard Team WI type to ensure compatibility with both products.
* **Page parameters not supported in swimlane row configuration.** Swimlane configuration (including team selection) uses static widget parameters. Dynamic filtering via Polarion page parameters (e.g. `$pageParameters.xxx`) is not supported. A common workaround is to create one Planningboard page per team, each with a hardcoded `selectedTeam` value.
* **Configuration properties are whitespace-sensitive.** The capacity configuration properties (including `nextedy.gantt.calendarHolder`, `nextedy.gantt.useTeamCapacityModifiers`, and `nextedy.gantt.capacityModifierAField`) must not contain leading or trailing whitespace. Whitespace causes silent misconfiguration — the property is not rejected; it simply does not match.
## Mental Model: Teams as First-Class Planning Entities
A useful way to think about the Teams Service is as a **layer of indirection** between individual people and the board's swimlane/capacity machinery.
Without the Teams Service, the board knows about users directly: it queries the project, finds users by role, and creates one swimlane per user. Capacity, if enabled, applies a uniform hours-per-day figure.
With the Teams Service, the board knows about **teams**, and teams know about **members** across time. The board asks "who is on team X and how much can they do in this window?" — the Teams Service answers by consulting assignment work items, user calendars, and off-day entries. The board receives a prepared answer; it does not need to understand the membership or calendar mechanics itself.
This indirection pays off when the same team structure is needed across multiple boards or multiple projects: a single set of Team work items, maintained in one project (or a shared supporting project), drives membership and capacity consistently across all boards that reference it.
**Relationship to Gantt**
The `nextedy.gantt.calendarHolder` and `nextedy.gantt.useTeamCapacityModifiers` configuration properties are named with the `gantt` prefix because the Teams Service implementation is shared infrastructure between Planningboard and Nextedy GANTT. The properties apply to both products.
## Related Concepts
* [Capacity Tracking](/planningboard/concepts/capacity-tracking) — how capacity bars are computed and displayed on the board
* [Swimlane Assignment Modes](/planningboard/concepts/assignment-modes) — the full set of swimlane assignment types, including the Users (Assignee) mode that the Teams Service augments
* [Normalization](/planningboard/concepts/normalization) — how capacity values are normalized across swimlanes for comparison
**KB Articles**
* What is 'Normalization'
* Introduction to Planningboard
* Swimlane Assignment Types
**Support Tickets**
* [#6546](https://support.nextedy.com/helpdesk/tickets/6546)
* [#5760](https://support.nextedy.com/helpdesk/tickets/5760)
* [#6605](https://support.nextedy.com/helpdesk/tickets/6605)
**Source Code**
* `IPlanningBoardTeamsService.java`
* `PlanningBoardTeamsService.java`
* `Config.java`
* `AssignmentMode.java`
* `PlanningBoardWidgetRenderer.java`
# Capacity
Source: https://learn.nextedy.com/planningboard/faq/capacity
Common questions about how Nextedy PLANNINGBOARD tracks effort, calculates capacity, and displays load across Plans and swimlanes.
***
## What does "capacity" mean on the Planningboard?
Capacity refers to the total effort available for a Plan or swimlane compared with the effort already allocated to work items within it. Planningboard visualizes this as a **capacity bar** per swimlane, giving planners an at-a-glance indicator of how loaded each resource or team is. When allocated effort approaches or exceeds total capacity, the bar signals overallocation.
***
## How do I enable the capacity bar?
Enable the `capacityLoad` widget parameter in the **Parameters for Plans (Columns)** section. Set **Show Capacity Load** to `true`. Once enabled, a capacity bar appears for each Plan column showing the load relative to available capacity.
```text theme={null}
Widget Parameter: capacityLoad = true
```
See the [Reference](/planningboard/reference/index) for the full list of capacity-related parameters.
***
## How is allocated capacity calculated?
Allocated capacity is the sum of the `remainingEstimate` values (or `initialEstimate` if remaining is not set) of work items assigned to a given user or swimlane within a Plan. If you configure a custom `capacityField` (for example, story points), Planningboard uses that field's values instead of time-based estimates. Resolved items are treated as fully done: their `effortDone` equals the full estimate and `effortTodo` equals zero.
```text theme={null}
Widget Parameter: capacityField =
Widget Parameter: hoursPerDay = 8 (default, for time-based modes)
```
***
## What is the difference between `capacityLoad` and `multiCapacityLoad`?
`capacityLoad` shows a single capacity bar per Plan column — useful when all swimlanes share the same total capacity budget. `multiCapacityLoad` enables per-swimlane (per-resource) capacity bars, so each row shows its own allocated vs. available capacity independently. Use `multiCapacityLoad` when different team members or resources have different capacities within the same Plan.
```text theme={null}
capacityLoad = true → column-level bar (shared budget)
multiCapacityLoad = true → per-swimlane bar (individual budgets)
```
***
## What is `userCapacityLoad` and when should I use it?
`userCapacityLoad` enables per-user capacity tracking when the **Teams Service** integration is active (`useTeamsService = true`). In this mode, total capacity comes from the team calendar rather than a fixed configuration, so each user's available hours reflect their actual calendar availability for the Plan period. Users without a calendar or team entry default to 0.0 total capacity.
```text theme={null}
Widget Parameter: useTeamsService = true
Widget Parameter: userCapacityLoad = true
```
***
## Can I see capacity for individual users in a Plan?
Yes, when `userCapacityLoad` is enabled together with `useTeamsService`, the board computes a per-user capacity breakdown for each Plan. Each user entry shows:
Values are rounded to one decimal place. A negative `availableCapacity` is a warning of overallocation — the capacity bar will visually exceed its maximum.
***
## What is normalization, and how does it affect capacity display?
Normalization adjusts how capacity is presented when Plans have different durations (for example, a two-week sprint vs. a one-week sprint). With normalization enabled, effort values are scaled proportionally so that Plans are visually comparable side by side. See the **Normalization** option under **Parameters for Plans (Columns)** in the widget parameters panel.
**When to enable normalization**
Enable normalization if your board shows Plans of different lengths and you want capacity bars to be comparable across columns rather than reflecting raw hours.
***
## Does Planningboard support multi-assignee capacity tracking?
Not currently. Capacity load is calculated per single assignee. If a work item has multiple assignees, the effort is not automatically distributed across them. This is a known gap relative to Nextedy GANTT, which supports multi-assignee effort distribution.
**Known limitation**
Multi-assignee capacity distribution is not supported in the current release. Workaround: assign each work item to a single primary assignee for accurate capacity accounting.
For related information see [Multiple Assignees](/planningboard/faq/multiple-assignees).
***
## Why does a user show 0.0 total capacity?
A total capacity of `0.0` means the user has no calendar entry in the Teams Service for the current Plan period, or `useTeamsService` is disabled. Verify that:
1. `useTeamsService = true` is set in the widget parameters.
2. The user is a member of the selected team (`selectedTeam` parameter).
3. The team calendar has an entry covering the Plan's date range.
Users without a calendar entry fall back to `0.0` by design (see the zero-fallback behavior in `NPT-1211`).
***
## How does the `hoursPerDay` parameter affect capacity?
`hoursPerDay` (default `8`) converts time-based capacity values from hours to days and back. It is used when capacity is tracked in time units (remaining/initial estimates). If your team works a different number of hours per day, adjust this parameter to keep capacity calculations accurate.
```text theme={null}
Widget Parameter: hoursPerDay = 7.5
```
**Whitespace sensitivity**
Capacity configuration parameters including `hoursPerDay` and `capacityField` are whitespace-sensitive. Do not add leading or trailing spaces when entering values in the widget parameters panel.
***
## Where can I learn more?
* [Swimlanes FAQ](/planningboard/faq/swimlanes) — how swimlane assignment types affect capacity grouping
* [Configuration FAQ](/planningboard/faq/configuration) — general widget parameter setup
* [Reference](/planningboard/reference/index) — full parameter reference including all capacity properties
* [Guides](/planningboard/guides/index) — step-by-step capacity configuration guides
**KB Articles**
* Swimlane Assignment Types
* Planningboard Widget Parameters
* Introduction to Planningboard
**Support Tickets**
* [#6777](https://support.nextedy.com/helpdesk/tickets/6777)
* [#6546](https://support.nextedy.com/helpdesk/tickets/6546)
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
**Source Code**
* `PlanningBoardWidget.java`
* `PlanningBoardDataService.java`
* `planningboard.js`
* `UserCapacityInfo.java`
* `licenseReadonly.cy.ts`
# Configuration
Source: https://learn.nextedy.com/planningboard/faq/configuration
Common questions about configuring Nextedy PLANNINGBOARD widget parameters, Plans modes, swimlane assignment types, and related settings.
***
## General Configuration
### Where do I configure Planningboard widget parameters?
All Planningboard configuration is done through the **Widget Parameters** panel of the Planningboard widget embedded in your Polarion LiveDoc or Wiki page. Open the widget's parameter editor to access sections for Work Items, Plans (Columns), Swimlanes (Rows), Queries, and New Plan. See the [Reference](/planningboard/reference/index) section for a full list of parameters.
### Which widget parameters control which work items appear on the board?
The **Work Items** section of Widget Parameters contains the key fields:
* `Scope` — defines the project scope for the current board
* `Query type` — sets the type of query to use
* `Query` — a Lucene query filtering which work items are shown (default: `NOT *:*`)
* `Add Planned` — when enabled, loads all planned items in addition to those matched by the query
* `Sort by` — defines how cards are ordered on the board
For details on Lucene query syntax in Polarion, refer to your Polarion documentation.
### What does the `Query` parameter default do, and why do I see no work items?
The default value of the `query` property is `NOT *:*`, which matches nothing. This is intentional — the widget ships without a pre-set query so that no items appear until you deliberately configure what to show. Set `Query` to a valid Lucene expression (for example, `type:story`) to populate the board with matching work items.
***
## Plans (Columns) Configuration
### How do I control which Plans appear as columns?
Use the **Plans (Columns)** section of Widget Parameters:
* `Plans Type` (`plansMode`) — selects the planning model: **Project Plans** (`PROJECT_PLANS`), **SAFe Sprints in Program** (`SAFE_SPRINTS`), **SAFe Sprints in Portfolio** (`SAFE_PFL_SPRINTS`), **SAFe Program Increments in Program** (`SAFE_PIS`), or **SAFe Program Increments in Solution** (`SAFE_SOLUTION`)
* `Plans` — defines which specific plans appear as columns
* `Show # of last plans` (`lastPlans`) — how many past/completed plans to display (default: 1)
* `Show # of next plans` (`nextPlans`) — how many upcoming plans to display (default: 5)
* `Show Capacity Load` (`capacityLoad`) — enables the capacity bar visualization per plan
**SAFe Plans Types**
**SAFe Sprints in Program** (`SAFE_SPRINTS`), **SAFe Sprints in Portfolio** (`SAFE_PFL_SPRINTS`), **SAFe Program Increments in Program** (`SAFE_PIS`), and **SAFe Program Increments in Solution** (`SAFE_SOLUTION`) are SAFe-specific modes. Contact Nextedy support for configuration guidance if your organization uses SAFe.
### What is the `Assign to Parent Plan` option and when should I enable it?
When `Assign to Parent Plan` is enabled, planning a work item into an iteration also automatically plans it into the parent Plan (for example, a Version). When disabled, the work item is only planned into the iteration you explicitly added it to. Enable this option when your project hierarchy requires parent Plans to reflect all work planned under them.
### Can I add a custom link to column (Plan) headers?
Yes. Use the `Report Link` field in the Plans (Columns) section. The link can be parameterized with plan variables. Example:
```
/polarion/#/project/${plan.objectId.projectId}/wiki/SOME_REPORT?plan=${plan.objectId.itemId}
```
This opens a report page filtered to the selected plan when you click the column header.
### Why does the configuration UI change when I switch Plans Type?
The widget dynamically shows or hides configuration fields based on the selected `Plans Type`. For example:
* **Project Plans** (`PROJECT_PLANS`) mode shows plan items configuration and the Sync to Parent option
* **SAFe Sprints in Program** (`SAFE_SPRINTS`) / **SAFe Sprints in Portfolio** (`SAFE_PFL_SPRINTS`) modes show the SAFe PI increment field instead
* Plan stemming fields appear only when stemming is enabled
This is by design — only the fields relevant to your selected mode are displayed.
```text theme={null}
Plans Type selected
|
+--- PROJECT_PLANS
| |-- Plan Items section (visible)
| |-- Sync to Parent (visible)
| |-- Plan Link field (visible)
|
+--- SAFE_SPRINTS / SAFE_PFL_SPRINTS
| |-- SAFe PI Increment (visible)
| |-- Plan Items section (hidden)
|
+--- SAFE_PIS / SAFE_SOLUTION
|-- Portfolio config (visible)
|-- Plan Items section (hidden)
```
***
## Swimlanes (Rows) Configuration
### What swimlane assignment types are available?
The **Assignment Type** (`assignmentMode`) controls how the board is divided into rows:
| Assignment Type | Groups swimlanes by |
| -------------------------------------------------------- | -------------------------------------------------- |
| Users (Assignee) | Project members matching a configured role |
| Parent Item | Parent work items linked via a specified link role |
| Enumeration Field | Values of a custom enumeration field (e.g. `team`) |
| Project | Sub-projects within the current project group |
| SAFe types (Program/Solution Teams, ART Teams, Programs) | SAFe organizational units |
| No Swimlanes | Disabled — all items in a single view |
For a detailed guide on each type, see [Swimlanes FAQ](/planningboard/faq/swimlanes).
### How do I configure swimlanes by a custom field?
Set **Assignment Type** to `Enumeration Field` and provide the **Field ID** — the identifier of your custom enumeration field (for example, `team`). Optionally set **Rows Filter** to limit which field values appear as rows. Only `IEnumType` fields and list fields whose items are enum-typed are supported; `status`, `resolution`, and `type` fields are not supported as swimlane grouping fields.
### Does Planningboard support page parameters (e.g. `$pageParameters.xxx`) in swimlane configuration?
No. Planningboard swimlane configuration does not support Polarion page parameters for dynamic filtering. If you need per-team filtering, the current supported approaches are: configuring a separate Planningboard page per team (using static link roles), or using Nextedy GANTT, which supports custom Team work item types from version 25.5.0 onwards.
**Custom Team work item types**
Planningboard does not support custom Team work item types in swimlane configuration. If your project uses a non-standard Team work item type, use Nextedy Gantt (25.5.0+) as the primary planning tool for team-based solutions.
### Can I sort parent swimlanes by a custom property like priority?
Yes, from Planningboard 25.9.0. In the swimlane settings for **Parent Item** assignment type, set the **Sort By** field to the custom property you want to use (for example, priority). Earlier versions only supported a limited set of built-in sort options.
***
## Unplanned Section and Queries
### How do I add predefined queries to the Unplanned section?
Use the **Queries** section in Widget Parameters. Add one or more named queries (each with a label and a Lucene query expression). These appear as filter options in the Unplanned section's filter panel (funnel icon), letting users quickly switch to a specific subset of unplanned items — for example, all work items with status `reviewed`.
### How deep should I set `PARAMETER_US_DEPTH` for the Unplanned sidebar hierarchy?
`PARAMETER_US_DEPTH` controls how many levels of parent work items are loaded in the Unplanned sidebar. Deeper values give a richer hierarchy view but increase load time on large projects. Start with a value of 1 or 2; increase only if your planning process requires navigating multi-level parent hierarchies in the Unplanned panel. Set `PARAMETER_PARENTS_LINK_ROLE` to the link role that defines parent-child relationships in your project.
***
## Access and Licensing
### What can unlicensed users do on a Planningboard?
Unlicensed users have read-only access. They can view the full board content — including swimlanes, cards, and capacity data — but cannot:
* Create new Plans (the Create New Plan button is hidden)
* Show/hide the Unplanned section
* Use the sidebar to edit work item fields
* Drag and drop cards between swimlanes (moves are blocked and not persisted)
Licensed users have full editing capabilities. See [Licensing FAQ](/planningboard/faq/licensing) for more.
***
**Configuration reference**
For the full list of widget parameters with their default values and accepted values, see the [Reference](/planningboard/reference/index) section.
**KB Articles**
* Swimlane Assignment Types
* Planningboard Widget Parameters
* Planningboard interface & basic interactions
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#6681](https://support.nextedy.com/helpdesk/tickets/6681)
* [#6546](https://support.nextedy.com/helpdesk/tickets/6546)
**Source Code**
* `Config.java`
* `PlanningBoardWidgetDependenciesProcessor.java`
* `licenseReadonly.cy.ts`
* `PlanningBoardWidgetRenderer.java`
* `PlanningBoardDataService.java`
# Customization
Source: https://learn.nextedy.com/planningboard/faq/customization
Common questions about customizing the appearance and behavior of Nextedy PLANNINGBOARD — swimlane layout, card display, widget parameters, and board configuration options.
***
## Swimlane configuration
### What swimlane assignment types are available?
Planningboard supports several **Assignment Types** in the **Swimlanes (Rows)** section of the Widget Parameters panel: **Users (Assignee)**, **Parent Item**, **Enumeration Field**, **Project**, SAFe-specific types (**Program / Solution Teams**, **Agile Release Train Teams**, **Programs**), and **No Swimlanes**. Each type changes how board rows are structured and what information they represent. See [Swimlanes FAQ](/planningboard/faq/swimlanes) for details on each type.
### How do I group swimlanes by a custom field instead of by assignee?
Select **Enumeration Field** as the Assignment Type and set the **Field ID** to the identifier of your custom enumeration field (for example, `team`). Optionally use the **Rows Filter** to restrict which enum values appear as rows. Note that `status`, `resolution`, and `type` fields are not supported in this mode — only custom enumeration fields.
### Can I filter swimlane rows using Polarion page parameters?
No — Planningboard swimlane configuration does not support Polarion page parameters (such as `$pageParameters.xxx`) for dynamic row filtering. If you need per-team boards, the recommended workaround is to create a separate Planningboard page per team, configured with a static swimlane filter or link role for that team.
**Custom Team WI types not supported in swimlanes**
Planningboard swimlane configuration does not support custom Team work item types. If your project uses a custom Team WI type (not Nextedy's standard Team WI with its required custom fields), consider using Nextedy Gantt (25.5.0+) as the primary planning tool, which does support custom team types.
### Can I sort parent swimlanes by priority or a custom property?
Yes — as of Planningboard 25.9.0, parent swimlanes can be sorted by any custom property, including priority. Set the **Sort By** field in the Parent Item assignment type configuration to the desired property. Earlier versions did not support custom property sorting for parent swimlanes.
***
## Card display
### Which fields appear on a card by default?
Cards display the work item ID and title by default (identified by `aria-label` attributes containing the work item ID and title). To configure which fields appear in the **sidebar** when a card is clicked, use the **Sidebar Fields** widget parameter (`PARAMETER_SIDEBAR_FIELDS`). The default sidebar fields are `title`, `status`, and `plannedIn`.
### How do I control which work items appear on the board?
Use the **Query** widget parameter to provide a Lucene query that filters which work items are loaded. You can also use **Work Item Type** (`wiType`) to restrict by type (for example, `task`, `story`, or `feature`), and set **Max Items** (`maxItems`, default 1000) to cap the number of items loaded. Enable **Add Planned** to include all already-planned items in addition to those selected by the query.
### How do I configure dependency arrows between cards?
Set the **Dependency Roles** widget parameter (`PARAMETER_DEPENDENCY_LINK_ROLE`) to the link role IDs that represent dependencies in your project. The board will then draw dependency indicators between cards that share those link roles.
***
## Plans (columns)
### How do I control which Plans appear as columns?
Use the **Plans** widget parameter to define which plans appear as columns, and the **Plans Type** (`plansMode`) to select the plan mode — for example, **Project Plans** (`PROJECT_PLANS`) for standard project plans. You can also set **Show # of last plans** (`lastPlans`, default 1) and **Show # of next plans** (`nextPlans`, default 5) to control how many past and upcoming plans are displayed. Use the **Plans Query** (`plansQuery`) parameter with a Lucene query to filter plans further.
### Can I add a link to an external report from a Plan column header?
Yes — use the **Report Link** parameter in the Plans (Columns) section. The link supports `${plan.*}` variables, for example:
```
/polarion/#/project/${plan.objectId.projectId}/wiki/SOME_REPORT?plan=${plan.objectId.itemId}
```
Similarly, swimlane labels also support a **Report Link** parameterised by the swimlane resource, for example:
```
/polarion/#/project/PlanningBoard/wiki/SOME_REPORT?user=${r.objectId.itemId}
```
### What does "Assign to Parent Plan" do?
When **Assign to Parent Plan** is enabled, dropping a work item into a plan also automatically plans it into that plan's parent Plan. This is useful in hierarchical planning (for example, assigning an item to an iteration automatically adds it to the parent version). When disabled, the item is planned only in the selected iteration.
***
## Board behavior
### How does drag and drop behave, and when is it blocked?
Licensed users can drag cards between swimlanes and plans; changes are persisted to the board. Unlicensed users can view the board but drag-and-drop operations are blocked — cards return to their original position. Drag is also blocked in prioritize mode and read-only mode.
Holding **Alt** while dragging creates a duplicate assignment to another resource (multi-resource assignment) instead of moving the card. Alt-drag to the **Not Assigned/Other** swimlane is not permitted, and duplicating from **Not Assigned/Other** automatically removes the **Not Assigned/Other** assignment.
**Parent Item swimlanes constrain drag targets**
When using the **Parent Item** assignment type, cards can only be dropped under their actual parent's swimlane. Dropping a card onto a different parent's row will automatically move the card to the correct parent swimlane.
### What sort order is used for cards within a swimlane?
Cards within each swimlane are sorted by: (1) resource name, (2) start date, (3) priority or custom sort field (if configured), and (4) work item ID as a tiebreaker. Configure the sort field using the **Sort by** widget parameter.
### How do I configure unplanned items in the sidebar?
Enable the **Unplanned Sidebar** in widget parameters to show work items that have not been planned into any column. Use `PARAMETER_US_DEPTH` to control how many levels of parent work items are loaded in the sidebar hierarchy (deeper hierarchies have performance implications). Set `PARAMETER_PARENTS_LINK_ROLE` to specify which link roles define parent-child relationships for building the hierarchy.
***
## Configuration overview
The table below summarizes the key widget parameters for customizing Planningboard behavior:
| Parameter | Description | Default |
| ---------------- | ---------------------------------------------------------------------- | --------------- |
| `query` | Lucene query to filter work items displayed | `NOT *:*` |
| `plansMode` | Plan organization mode (`PROJECT_PLANS`, SAFe modes, etc.) | `PROJECT_PLANS` |
| `assignmentMode` | Swimlane grouping mode (`ASSIGNEE`, `ENUM`, `PARENT`, `PROJECT`, SAFe) | `ASSIGNEE` |
| `enumFieldId` | Custom field ID for swimlanes when `assignmentMode` is `ENUM` | — |
| `wiType` | Work item type filter (e.g. `task`, `story`, `feature`) | — |
| `maxItems` | Maximum work items to load | `1000` |
| `lastPlans` | Number of past plans to display | `1` |
| `nextPlans` | Number of upcoming plans to display | `5` |
| `capacityLoad` | Enable per-plan capacity bar | `false` |
| `hoursPerDay` | Working hours per day for capacity calculations | `8` |
For a full parameter reference, see [Configuration FAQ](/planningboard/faq/configuration).
***
## SAFe-specific customization
### The configuration panel looks different when I select a SAFe Plans Type — why?
The widget parameter UI adapts based on the selected **Plans Type**. Selecting **Project Plans** (`PROJECT_PLANS`) shows the standard Scope/Query/Type fields and the plan items configuration section. Selecting a SAFe mode (for example, SAFe Program Increments) shows different fields — including the SAFe PI increment selector — and hides project-plan-specific options. This is by design: each mode surfaces only the relevant configuration for that planning level.
### Which SAFe swimlane types require additional setup?
The SAFe-specific swimlane assignment types (**Program / Solution Teams**, **Agile Release Train Teams**, **Programs**) require a Polarion SAFe Solution to be configured on your instance. Contact Nextedy support for setup guidance if your organization uses SAFe and you need these swimlane options enabled. See also [SAFe Integration FAQ](/planningboard/faq/safe).
***
*For questions about capacity configuration, see [Capacity FAQ](/planningboard/faq/capacity). For swimlane-specific questions, see [Swimlanes FAQ](/planningboard/faq/swimlanes).*
**KB Articles**
* Swimlane Assignment Types
* Planningboard Widget Parameters
* Planningboard: Customizable Statistics and Capacity Indicators
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#6681](https://support.nextedy.com/helpdesk/tickets/6681)
* [#6546](https://support.nextedy.com/helpdesk/tickets/6546)
**Source Code**
* `Config.java`
* `licenseReadonly.cy.ts`
* `PlanningBoardWidget.java`
* `PlanningBoardWidgetDependenciesProcessor.java`
* `PlanningBoardWidgetRenderer.java`
# General
Source: https://learn.nextedy.com/planningboard/faq/general
Common questions about Nextedy PLANNINGBOARD — what it is, how it works, and how to get started.
***
## What is Planningboard?
Planningboard is a visual planning app embedded in Siemens Polarion ALM. It arranges Polarion Plans and work items as **cards** across **swimlanes**, giving teams a capacity-aware, drag-and-drop interface for sprint and release planning — without leaving the ALM environment. It complements Nextedy GANTT's timeline view with a board-style view.
***
## How does Planningboard fit into Polarion?
Planningboard is installed on your Polarion server and renders in Polarion LiveDoc and Wiki pages. Each widget instance is independently configured via **widget parameters** — so different teams or projects can have different board layouts on the same Polarion instance. See [Installation](/planningboard/getting-started/installation) and [Create Your First Planningboard](/planningboard/getting-started/first-planning-board) for setup details.
***
## What are the main sections of the board?
The board is split into two areas:
Drag cards from the **Unplanned section** onto the board to assign them to a Plan. See [Basic Board Interactions](/planningboard/getting-started/basic-interactions) for a full walkthrough.
***
## What is a "card" on the board?
Each **card** represents a Polarion work item. The content of a card is fully customizable via widget parameters. Clicking a card opens the **Work Item Properties** sidebar, where you can review and edit fields without navigating away from the board. The sidebar fields displayed are configured via the `Sidebar Fields` widget parameter.
***
## What are swimlanes, and how do I choose the right type?
**Swimlanes** are the horizontal rows on the board that group work items. The grouping is controlled by the **swimlane assignment type**, set in **Widget Parameters > Swimlanes (Rows) > Assignment Type**. Available types include:
| Assignment Type | Groups items by… | Best for… |
| ----------------- | ---------------------------------- | ----------------------------------- |
| Users (Assignee) | Team members with a specified role | Workload balancing per person |
| Parent Item | Parent work items (e.g. Features) | Hierarchical planning |
| Enumeration Field | A custom field value (e.g. Team) | Category- or team-based planning |
| Project | Projects | Cross-project planning |
| SAFe types | SAFe Programs, ARTs, or Teams | SAFe environments (contact support) |
| No Swimlanes | — (single unified view) | Simple overviews |
For full details on each type, see [Swimlanes FAQ](/planningboard/faq/swimlanes).
***
## What happens when I drag a card to the wrong swimlane?
It depends on the swimlane assignment type. With **Parent Item** swimlanes, Planningboard enforces the parent–child relationship: if you drag a card to a swimlane where its parent does not belong, the card automatically snaps back to the correct parent's row. With **Users (Assignee)** and **Enumeration Field** types, placing a card in a swimlane reassigns the work item's field to that row's value.
***
## Can I move verified work items?
No. Once a card has the status **Verified**, it is locked in place and cannot be moved or unplanned via drag and drop. This prevents accidental replanning of completed work. Verified items can be filtered out of the Unplanned section using the filter controls in the toolbar.
***
## Who can edit the board, and who can only view it?
Planningboard enforces **license-based access control**:
* **Licensed users** have full editing capabilities: drag-and-drop cards, access the sidebar, toggle the Unplanned section, and create new Plans.
* **Unlicensed users** can view the full board content — including cards, swimlanes, and capacity bars — but all editing actions are blocked. Drag-and-drop operations do not persist for unlicensed users. Unlicensed user may still access the sidebar.
This means team members without a license can still follow progress on the board. See [Licensing FAQ](/planningboard/faq/licensing) for license setup.
Unlicensed users retain full read access so they can participate in planning reviews and track progress without needing a seat.
***
## What does the capacity bar show?
The **capacity bar** is a per-swimlane (per-plan column) visual indicator of how much effort is allocated relative to available capacity. Hovering over it shows a detailed tooltip. The capacity bar is only visible when **Show Capacity Load** is enabled in the widget parameters.
Capacity is calculated per user as:
* **Allocated capacity** — sum of remaining estimates for tasks assigned to that user within the plan
* **Total capacity** — user's available capacity from the team calendar for the plan period
* **Available capacity** — total minus allocated (negative values indicate overallocation)
Capacity-related widget parameters are whitespace-sensitive. Trailing spaces in property values can cause silent miscalculation. See [Capacity FAQ](/planningboard/faq/capacity) for details and known limitations.
***
## What Plans appear as columns on the board?
Plans displayed as columns are controlled by the **Plans** widget parameters:
* **Plans Type** — selects the plan mode (e.g. **Project Plans** (`PROJECT_PLANS`) for standard project plans, or SAFe modes for SAFe environments).
* **Plans** / **Plans Query** — a Lucene query that filters which Plans appear.
* **Show # of last plans** / **Show # of next plans** — controls how many past and upcoming Plans are loaded (defaults: 1 past, 5 future).
Only Plans matching the configured query and count window are shown. See [Configuration FAQ](/planningboard/faq/configuration) for widget parameter examples.
***
## Does Planningboard support SAFe?
Yes, with caveats. Planningboard includes SAFe-specific plan modes (**SAFe Sprints in Program** (`SAFE_SPRINTS`), **SAFe Sprints in Portfolio** (`SAFE_PFL_SPRINTS`), **SAFe Program Increments in Program** (`SAFE_PIS`), **SAFe Program Increments in Solution** (`SAFE_SOLUTION`)) and SAFe swimlane assignment types (SAFe Programs, Agile Release Train Teams, Program/Solution Teams). SAFe configuration is highly context-dependent: the configuration UI changes depending on which **Plans Type** you select, and each hierarchy level (Portfolio, Program, Team) requires different settings.
SAFe swimlane types and plan modes are available but require setup assistance. Contact Nextedy support to enable and configure them for your environment. See also [SAFe Integration FAQ](/planningboard/faq/safe).
***
## Where do I configure Planningboard?
All per-instance configuration is done through the **Widget Parameters** panel of the Planningboard widget on a Polarion LiveDoc or Wiki page. The main parameter groups are:
* **Parameters for Work Items** — scope, query, sort order, dependency roles, sidebar fields
* **Parameters for Plans (Columns)** — plan type, plan query, last/next plan counts, capacity display, assign-to-parent-plan
* **Queries** — custom queries for the Unplanned section
* **Swimlanes (Rows)** — assignment type, user role, report links
* **New Plan** — template, naming pattern, duration, Teams configuration
See [Configuration FAQ](/planningboard/faq/configuration) for a full parameter reference and examples.
# FAQ
Source: https://learn.nextedy.com/planningboard/faq/index
This section collects answers to the most common questions about Nextedy PLANNINGBOARD, grouped by topic.
## General and Licensing
**[General](/planningboard/faq/general)** — Foundational questions about what Planningboard is, what it does, and how it fits into Siemens Polarion ALM.
**[Licensing](/planningboard/faq/licensing)** — Questions about obtaining, installing, and validating a Planningboard license.
## Configuration and Customization
**[Configuration](/planningboard/faq/configuration)** — Questions about widget parameters, Plan queries, and board-level configuration properties.
**[Customization](/planningboard/faq/customization)** — Questions about card appearance, highlighting rules, and visual customization of the board.
## Swimlanes and Capacity
**[Swimlanes](/planningboard/faq/swimlanes)** — Questions about swimlane assignment types, swimlane sort order, filtering by Plan range, and related behavior.
**[Capacity](/planningboard/faq/capacity)** — Questions about capacity bars, capacity normalization, and known limitations in effort distribution.
**[Multiple Assignees](/planningboard/faq/multiple-assignees)** — Questions about how Planningboard handles work items with more than one assignee and current constraints.
## Planning Frameworks
**[SAFe Integration](/planningboard/faq/safe)** — Questions about using Planningboard within a SAFe (Scaled Agile Framework) planning context in Polarion.
## Troubleshooting
**[Troubleshooting](/planningboard/faq/troubleshooting)** — Step-by-step guidance for diagnosing common problems: cards not appearing, capacity bars showing unexpected values, widget parameters not taking effect, and similar issues.
***
**Not finding your answer?**
Browse the [Guides](/planningboard/guides/index) section for step-by-step how-to instructions, or the [Reference](/planningboard/reference/index) section for a complete list of widget parameters and configuration properties.
**KB Articles**
* Swimlane Assignment Types
* Planningboard Widget Parameters
**Support Tickets**
* [#6546](https://support.nextedy.com/helpdesk/tickets/6546)
* [#6681](https://support.nextedy.com/helpdesk/tickets/6681)
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
**Source Code**
* `PlanningBoardDataService.java`
* `PlanningBoardWidgetDependenciesProcessor.java`
* `licenseReadonly.cy.ts`
* `Config.java`
* `PlanningBoardWidget.java`
# Licensing
Source: https://learn.nextedy.com/planningboard/faq/licensing
Common questions about Nextedy PLANNINGBOARD licenses, evaluation mode, license states, and access control.
***
## Do I need a license to use Planningboard?
Planningboard can be used without a production license for a **30-day evaluation period**. During evaluation, all features are available. After the evaluation period ends, users without a production license are switched to read-only access — they can still view the board but cannot modify any planning data. To continue editing, a production license must be installed by a Polarion administrator.
## What happens during the 30-day evaluation?
During the evaluation period, Planningboard operates with full functionality — you can create Plans, drag cards between swimlanes, configure swimlanes and capacity, and use the unplanned sidebar. The evaluation mode notice is displayed in the Planningboard admin interface to remind administrators that a production license has not yet been applied. No data is lost when the evaluation ends; the board remains viewable in read-only mode.
## What happens to users who don't have a license after evaluation ends?
Unlicensed users receive read-only access to the board. They can view all board content — including cards, swimlanes, and calendar data — but editing actions are blocked. The following table summarizes the difference:
This design ensures stakeholders and observers can always see the current planning state without requiring a paid seat.
## How do I install a production license?
Follow the step-by-step instructions in [License Installation](/planningboard/getting-started/licensing). In summary:
1. Obtain your license file from Nextedy.
2. Place the file in the correct location on your Polarion server as described in the installation guide.
3. Restart Polarion.
4. Open the Planningboard admin interface and confirm the license status shows as valid.
The license view in the admin interface confirms whether the license was accepted and displays the full license details.
## Where can I check my current license status?
Navigate to the Planningboard administration interface in Polarion. The license page displays a color-coded status panel alongside the full license details. The **signature field is automatically redacted** from the display for security — the license is still validated server-side and the redaction does not affect functionality.
## What do the license status indicators mean?
The license status panel uses color-coded messages to indicate the current state of the installed license:
| Status | Meaning |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **INVALID** | The license file is missing, expired, or does not match this installation. Editing is blocked for all users. |
| **INFO** | The license was found but carries an informational notice — for example, an approaching expiry date or a license that covers a restricted set of users. |
| **Valid** | The production license is active. All licensed users have full editing access. |
**INVALID status blocks editing for all users**
When the status is INVALID, all users — including administrators — are restricted to read-only mode. Install or renew the license and restart Polarion to restore editing access. Check the admin interface for any error message in the status panel for guidance on what to fix.
## Why is the signature hidden in the license view?
Planningboard automatically removes the signature field from the displayed license text. This is a security measure to prevent the cryptographic signature from being copied or exposed via screenshots. The signature is still present in the license file and is validated server-side — hiding it in the UI does not affect license validation in any way.
## Can I see the Planningboard version in the admin interface?
Yes. The administration interface shows the current product version. The version string uses a runtime timestamp suffix (replacing the build qualifier at install time) to ensure browsers load the latest assets after an update rather than serving a cached version. If you need to report the version to Nextedy support, use the value shown in the admin interface rather than the plugin folder name.
## What support resources are available from the license page?
The Planningboard admin interface on the license page provides direct links to:
* **Support documentation** — opens the Planningboard support portal in a new tab.
* **Pricing information** — links to current licensing tiers and purchase options.
* **Contact support** — an email link to reach the Nextedy support team directly.
These links are always visible regardless of license status, so you can access help even when the license is invalid.
## Where can I find pricing and purchasing information?
Pricing details are available on the Nextedy website and are also linked directly from the Planningboard admin interface under the license section. For purchase, renewal, or volume licensing questions, contact the Nextedy support team via the link on the license page or by submitting a ticket at [support.nextedy.com](https://support.nextedy.com/support/tickets/new).
**Getting started with a new license**
For a full walkthrough of license installation — including file placement, verification steps, and common errors — see [License Installation](/planningboard/getting-started/licensing).
## Does each user need their own license, or is it per installation?
Contact Nextedy for details on the licensing model applicable to your organization size and deployment. The pricing page linked from the admin interface is the authoritative source for current licensing terms.
***
*For other common questions, see [General FAQ](/planningboard/faq/general), [Configuration FAQ](/planningboard/faq/configuration), or [Troubleshooting](/planningboard/faq/troubleshooting).*
**KB Articles**
* Swimlane Assignment Types
**Source Code**
* `viewLicense.vm`
* `licenseReadonly.cy.ts`
* `Config.java`
* `PlanningBoardWidgetDependenciesProcessor.java`
* `PlanningBoardWidgetRenderer.java`
# Multiple Assignees
Source: https://learn.nextedy.com/planningboard/faq/multiple-assignees
This page answers common questions about how Nextedy PLANNINGBOARD handles work items that have more than one assignee when swimlanes are configured with the **Users (Assignee)** assignment type.
***
## Does Planningboard support multiple assignees on a single work item?
Polarion itself allows a work item to have multiple assignees, and Planningboard will display the item on the board. However, when swimlanes use the **Users (Assignee)** assignment type, a work item with multiple assignees currently appears under **only one swimlane**, not under every assigned user's lane. This is a known product limitation.
**Known limitation**
Items with multiple assignees are not duplicated across all matching user swimlanes. Only one assignee's lane will show the card. If your team relies on per-person capacity tracking, treat this as a planning constraint until the enhancement is shipped.
***
## Which swimlane does a multi-assignee item appear in?
The item appears in the swimlane of one of its assignees. The exact assignee whose lane is used depends on how the data service resolves the assignment at render time; there is no user-configurable rule for choosing which assignee "wins." To avoid ambiguity, Nextedy recommends assigning items to a single user when using user-based swimlanes.
***
## Will multi-assignee items count toward capacity for all assigned users?
No. Because the card appears in only one swimlane, its effort is counted toward only that swimlane's capacity bar. The other assigned users' capacity bars are unaffected by the item. This means per-user capacity totals may be inaccurate when items carry multiple assignees.
**Capacity accuracy**
For accurate per-user capacity tracking, ensure each planned work item has a single assignee. If shared ownership is required, consider using a team-level swimlane (Project or Enumeration Field assignment type) instead of Users (Assignee).
***
## Is there a planned fix to show the card under all assignees' swimlanes?
Yes. The behavior — showing a multi-assignee item under all of the assigned users' swimlanes rather than just one — is a tracked enhancement. Until it ships, the workaround is to assign items to a single user per sprint, or to use an alternative swimlane assignment type that does not rely on individual user identity.
***
## What swimlane assignment types are available if Users (Assignee) does not fit my workflow?
Planningboard offers several swimlane assignment types. The table below summarizes the options and how they handle multi-assignee scenarios:
For team-based planning without the single-assignee constraint, the **Enumeration Field** assignment type using a `team` custom field is a practical alternative. See [Swimlanes FAQ](/planningboard/faq/swimlanes) for configuration details.
***
## Can I use page parameters to filter swimlanes dynamically by team or user?
No. Planningboard swimlane configuration does not currently support Polarion page parameters (for example, `$pageParameters.xxx`) for dynamic filtering of swimlane rows. Swimlane configuration is static per widget instance. The supported workaround for multi-team deployments is to create a separate Planningboard page per team, each with its own hardcoded swimlane configuration.
**Multi-team workaround**
Configure a dedicated Planningboard widget page for each team, with the swimlane **User Role** or **Enumeration Field** set to that team's scope. This avoids the need for dynamic page parameters.
***
## Does Planningboard support custom Team work item types for swimlane rows?
No. Planningboard swimlane row configuration requires Nextedy's standard Team work item type with the expected custom fields. Custom Team work item types — where you define your own fields and structure — are not supported in Planningboard swimlane rows. If your organization uses a custom Team WI type, consider using Nextedy GANTT (which supports custom team types from version 25.5.0 onward) as your primary planning tool, and use Planningboard as a complementary view.
***
## How do I configure the Users (Assignee) swimlane type correctly?
In the widget's **Swimlanes (Rows)** section, set **Assignment Type** to `Users (Assignee)` and set **User Role** to the Polarion role that identifies your project team members — for example, `project_user`. Only users holding that role in the current project will appear as swimlane rows. Users without the role are excluded regardless of whether they are assigned to work items.
```text theme={null}
Widget Parameters → Swimlanes (Rows)
Assignment Type : Users (Assignee)
User Role : project_user ← role defined in Administration > User Management > Roles
Report Link : (optional)
```
See [Swimlanes FAQ](/planningboard/faq/swimlanes) for the full list of assignment types and their configuration fields.
***
## Why does a user swimlane appear empty even though they have assigned items?
This usually means one of the following:
1. **User Role mismatch** — the user does not hold the role specified in the **User Role** parameter. Check **Administration > User Management > Roles** to confirm membership.
2. **Work item not matching the board query** — the item is excluded by the **Query** or **Query Type** parameters. Verify the query returns the item in question.
3. **Multi-assignee display limitation** — the item's card is being rendered in a different user's swimlane. Confirm the item has exactly one assignee matching this user.
**Debugging empty swimlanes**
Open the item directly in Polarion and verify both its assignee field and its role membership. If the item is correctly assigned and the user holds the right role, refresh the board using the **Refresh** button to reload the current state from the server.
***
## Where can I learn more about swimlane configuration?
* [Swimlanes FAQ](/planningboard/faq/swimlanes) — all assignment types, fields, and configuration examples
* [Configuration FAQ](/planningboard/faq/configuration) — general widget parameter questions
* [Capacity FAQ](/planningboard/faq/capacity) — how capacity bars and effort are calculated per swimlane
**KB Articles**
* Swimlane Assignment Types
* Introduction to Planningboard
* Planningboard Widget Parameters
**Support Tickets**
* [#5922](https://support.nextedy.com/helpdesk/tickets/5922)
* [#6546](https://support.nextedy.com/helpdesk/tickets/6546)
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
**Source Code**
* `PlanningBoardWidget.java`
* `PlanningBoardWidgetRenderer.java`
* `PlanningBoardDataService.java`
* `licenseReadonly.cy.ts`
* `PlanningBoardWidgetDependenciesProcessor.java`
# SAFe Integration
Source: https://learn.nextedy.com/planningboard/faq/safe
Common questions about using Nextedy PLANNINGBOARD with the Scaled Agile Framework (SAFe).
***
## What SAFe planning modes does Planningboard support?
Planningboard supports several SAFe-specific plans modes selectable via the `plansMode` widget parameter:
| Mode | Value | Description |
| ---------------------------------- | ---------------- | ---------------------------------------------------------------- |
| SAFe Sprints (Program) | `safeSprints` | Iteration plans within an Agile Release Train |
| SAFe Sprints (Portfolio) | `safePflSprints` | Iteration plans across multiple programs in a solution portfolio |
| SAFe Program Increments (Program) | `safePIs` | PI-level planning within an Agile Release Train |
| SAFe Program Increments (Solution) | `safeSIs` | PI planning across multiple ARTs in a solution train |
Standard **Project Plans** (`PROJECT_PLANS`) remain available for non-SAFe use. See [Configuration FAQ](/planningboard/faq/configuration) for general widget parameter guidance.
***
## What SAFe swimlane assignment types are available?
Three SAFe-specific swimlane assignment types exist alongside the standard types:
* **Program / Solution Teams (SAFe)** — swimlanes for SAFe teams within the current program, sourced from Polarion SAFe Solution data.
* **Agile Release Train Teams (SAFe)** — swimlanes for teams within a specific ART, filtered by an ART ID parameter.
* **Programs (SAFe)** — swimlanes for SAFe programs within a solution train, used for portfolio-level planning.
These assignment types require the Polarion SAFe Solution to be installed and configured. To enable them, contact Nextedy support. See [Swimlanes FAQ](/planningboard/faq/swimlanes) for the full list of assignment types.
***
## Why does the configuration panel look different when I select a SAFe plans mode?
The widget parameter panel changes dynamically based on your `plansMode` selection. When you select **Project Plans**, the panel shows fields for Scope, Query, and Type. When you select a SAFe mode such as **SAFe Program Increments**, a different set of fields appears — including the **Program Increment Parameter ID** field — and plan items configuration is hidden (it is only available in Project Plans mode).
This is by design: each plans mode exposes only the configuration fields that are relevant to it. If you expect to see a field and it is not visible, check that you have selected the correct plans mode first.
***
## What is the Program Increment Parameter ID field and when do I need it?
The **Program Increment Parameter ID** field links the board to a Page Parameter that determines which Program Increment (PI) is currently in scope. It is shown only in SAFe sprint modes (`safeSprints` and `safePflSprints`).
You must first create the Page Parameter on the Polarion page that hosts the board widget, then reference its ID in this field. Without a valid Page Parameter reference, the board cannot resolve which PI to display. This step is required for SAFe sprint planning to work correctly.
**Page Parameters must be created explicitly**
Page Parameters are not created automatically. You must add them manually on the Polarion Wiki or LiveDoc page before referencing them in the widget. If this field is left empty or references a non-existent parameter, the board may display no plans.
***
## How should I configure the board at each SAFe hierarchy level?
Configuration differs across portfolio, program, and team levels:
```text theme={null}
SAFe Hierarchy — Planningboard Configuration by Level
Portfolio Level
plansMode : safeSIs (Solution-level Program Increments)
assignmentMode : SAFE_PROGRAMS (programs as swimlanes)
Notes: Requires Polarion SAFe Solution at portfolio level
Program Level
plansMode : safePIs (Program Increments within an ART)
assignmentMode : SAFE_TRAIN_TEAM (teams within a specific ART)
Notes: Specify ART ID in the ART ID parameter
Team Level
plansMode : safeSprints (Iterations within the program)
assignmentMode : SAFE_TEAM (teams within the current program)
Notes: Teams discovered from Polarion SAFe Solution data
```
Each level requires its own board widget instance configured independently. The most common support issue is applying portfolio-level settings at program level or vice versa — verify `plansMode` and `assignmentMode` match the intended hierarchy level.
***
## Does Planningboard automatically sync SAFe parent plans when I reassign a team?
Yes. When a team assignment changes for a work item in SAFe mode, Planningboard automatically syncs the item's parent SAFe User Story to the correct Team Program Increment plan. This remapping is based on the new team assignment and happens when you drag a card to a different swimlane.
**SAFe-specific automation**
This automatic parent plan sync (`syncSAFEParentsFromChildren`) applies only in SAFe plans modes. It does not apply in standard Project Plans mode.
***
## Can I use capacity tracking with SAFe planning modes?
Capacity tracking via `capacityLoad` and `multiCapacityLoad` is available in SAFe modes. When using the Teams Service integration (`useTeamsService = true`), user-level capacity loading (`userCapacityLoad`) is also available and overrides the plan's default capacity values.
**Verify in application**
Multi-assignee capacity distribution and sub-item effort distribution are not currently supported. Each work item's effort is attributed to a single resource. This is a known limitation relative to Nextedy GANTT's capacity model.
***
## Why are SAFe swimlane types not visible in my assignment type dropdown?
SAFe swimlane assignment types (Program / Solution Teams, ART Teams, Programs) require the Polarion SAFe Solution to be installed on your Polarion instance. If your Polarion environment does not include the SAFe Solution, these options will not appear.
If the SAFe Solution is installed but the options are still not visible, contact Nextedy support for setup guidance. The SAFe swimlane types are not enabled by default and may require additional configuration.
***
## Where can I learn more?
* [Swimlanes FAQ](/planningboard/faq/swimlanes) — all swimlane assignment types including standard types
* [Configuration FAQ](/planningboard/faq/configuration) — general widget parameter reference
* [Capacity FAQ](/planningboard/faq/capacity) — capacity bar setup and normalization
* [Troubleshooting FAQ](/planningboard/faq/troubleshooting) — resolving common configuration errors
**KB Articles**
* Swimlane Assignment Types
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
**Source Code**
* `PlanningBoardWidgetRenderer.java`
* `Config.java`
* `licenseReadonly.cy.ts`
* `PlansMode.java`
* `PlanningBoardWidgetDependenciesProcessor.java`
# Swimlanes
Source: https://learn.nextedy.com/planningboard/faq/swimlanes
Common questions about configuring and using swimlanes in Nextedy PLANNINGBOARD.
***
## What are swimlanes and how do they work?
Swimlanes are the horizontal rows on the Planningboard that group cards by a chosen criterion — such as the assignee, a parent work item, a project, or a custom enumeration field. Each swimlane shows the cards belonging to that group within the visible Plan columns, and can display a capacity bar when capacity tracking is enabled. See [Concepts](/planningboard/concepts/index) for a broader overview of how Plans, cards, and swimlanes relate to each other.
***
## Which swimlane assignment types are available?
The **Assignment Type** widget parameter controls how work items are grouped into rows. The following modes are available:
You configure the type in the **Widget Parameters** panel under **Swimlanes (Rows) > Assignment Type**. Each type exposes its own set of sub-fields. For a full walkthrough of every type, see [Configuration FAQ](/planningboard/faq/configuration).
***
## How do I set up user (assignee) swimlanes?
Set **Assignment Type** to **Users (Assignee)** and supply the **User Role** field with the Polarion role ID whose members should appear as swimlane rows (for example, `project_user`). Planningboard displays one swimlane per user holding that role in the current project. Users outside that role are not shown.
**Role-based display**
Only users who hold the specified role in the current project appear as rows. If a team member is missing, verify their role assignment under **Administration > User Management > Roles**.
***
## How do I configure parent item swimlanes?
Set **Assignment Type** to **Parent Item**. You can then configure:
* **Sort By** — the property used to order parent swimlanes (custom properties including priority are supported as of version 25.9.0).
* **Parent Role** — the link role that connects child items to their parent (for example, `implements`).
* **Parent Query** (optional) — a Lucene query to restrict which parents appear as rows.
* **Filter Parents** — whether to limit visible parents to those matched by the query (`Yes` / `No`).
**Items snap to their real parent**
When using parent swimlanes, Planningboard enforces the parent–child relationship. If you drag a card to the wrong row, it automatically moves back to the swimlane of its actual parent. You cannot freely reassign parentage by dragging.
***
## How do I use a custom field (enumeration) as swimlanes?
Set **Assignment Type** to **Enumeration Field** and provide the **Field ID** of the enumeration custom field (for example, `team`). Planningboard creates one swimlane per enum value. You can optionally supply a **Rows Filter** to restrict which values appear as rows.
**Supported field types**
Both single-value enumeration fields and list-type fields whose items are enumeration values are supported. The `status`, `resolution`, and `type` built-in fields are not supported for swimlane grouping.
***
## How do I show only users active in the current Plan range?
Enable the configuration property `nextedy.planningboard.activeTeamAssignmentsInPlanRangeOnly=true` in **Polarion Administration > Configuration Properties**. When set, Planningboard hides users whose Team Assignments fall entirely outside the time range of the Plans currently displayed on the board. Users with no active assignment in the shown range have their cards moved to the **Not Assigned / Other** row.
This feature requires:
* A project with configured Teams and Team Assignments.
* User swimlanes derived from Team Assignments.
* Planningboard version **25.12.0** or later.
**Deprecated predecessor**
The earlier property `nextedy.planningboard.activeTeamAssignmentsOnly=true` (introduced in 25.3.0) only hid past Team Assignments and was deprecated in version 25.12.0. Use the new `activeTeamAssignmentsInPlanRangeOnly` property instead.
**Property not applying?**
If the property appears to have no effect, make a minor edit to Configuration Properties and save again to force a reload.
***
## Can I filter swimlanes to show only users from a specific team?
Yes, but it requires coordinating two separate configurations:
1. **Swimlane filter** — configure a Team page parameter on the Planningboard widget to restrict which team's members appear as swimlane rows.
2. **Plans filter** — add a query in the **Parameters for Plans (Columns)** section to filter the Plan columns to only iterations belonging to that team.
Both settings must be applied together. Configuring only the swimlane filter shows the correct users but still displays all iterations; configuring only the Plans query filters the columns but leaves all users visible as rows.
***
## Does Planningboard support page parameters (e.g. `$pageParameters.xxx`) in swimlane configuration?
No. Swimlane row configuration in Planningboard does not support Polarion page parameters. Available row configuration modes are static: hardcoded assignment type, link roles (one Planningboard page per team), or Nextedy's standard Team work item type via the Teams Service.
**Custom Team work item types**
Planningboard does not support custom Team work item types for swimlane configuration. If your project uses a custom Team WI type (as opposed to the standard Nextedy Team WI), consider using Nextedy GANTT (which added custom team type support in version 25.5.0) as your primary planning tool. See [SAFe Integration FAQ](/planningboard/faq/safe) for multi-team planning patterns.
***
## Can I collapse and expand individual swimlanes?
Yes. Swimlane collapsing is enabled by default (`collapsibleSwimlanes = true`). Users can click the swimlane header to collapse or expand individual rows, which is useful on boards with many lanes.
***
## Can I control whether empty swimlanes are shown?
Yes. The `showEmptySwimlanes` widget parameter controls this behavior. When set to `true`, all possible swimlane rows are shown even if they contain no cards. When `false` (the default), empty rows are hidden to keep the board compact.
***
## How are swimlane rows ordered?
The `swimlaneSort` parameter controls the vertical order of swimlane rows. The default value is `alphabetical`. As of version 25.9.0, parent item swimlanes can be sorted by any custom property, including priority — configure this via the **Sort By** field in the Parent Item assignment type settings.
**Swimlane sort order and card sort order are coupled**
A known limitation of Planningboard is that swimlane sort order is coupled to item sort order. Changing the card sort order can affect how swimlane rows are arranged. Plan swimlane ordering changes accordingly.
***
## What happens to cards when a user has no swimlane?
Cards assigned to a user who does not appear as a swimlane row (for example, because they lack the configured role, or their Team Assignment is outside the active Plan range) are moved to the **Not Assigned / Other** swimlane at the bottom of the board. From there, they can be reassigned or rescheduled.
***
## Where can I learn more about swimlane configuration?
* [Configuration FAQ](/planningboard/faq/configuration) — detailed widget parameter reference for all swimlane options.
* [Capacity FAQ](/planningboard/faq/capacity) — capacity bar behavior per swimlane.
* [SAFe Integration FAQ](/planningboard/faq/safe) — SAFe-specific swimlane assignment types.
* [Multiple Assignees FAQ](/planningboard/faq/multiple-assignees) — limitations around multi-assignee capacity in swimlanes.
* [Guides](/planningboard/guides/index) — step-by-step how-to guides including swimlane setup.
**KB Articles**
* Swimlane Assignment Types
* Filter user swimlanes by Plan range
* Planningboard Widget Parameters
**Support Tickets**
* [#6681](https://support.nextedy.com/helpdesk/tickets/6681)
* [#6546](https://support.nextedy.com/helpdesk/tickets/6546)
* [#5760](https://support.nextedy.com/helpdesk/tickets/5760)
**Source Code**
* `Config.java`
* `licenseReadonly.cy.ts`
* `PlanningBoardWidgetDependenciesProcessor.java`
* `PlanningBoardWidgetRenderer.java`
* `AssignmentMode.java`
# Troubleshooting
Source: https://learn.nextedy.com/planningboard/faq/troubleshooting
Common issues and fixes for Nextedy PLANNINGBOARD. For configuration questions, see the Configuration FAQ; for capacity questions, see the Capacity FAQ.
***
## Swimlane and Assignment Issues
### Why are items jumping to a different swimlane after I drag them?
When using the **Parent Item** assignment type, the board enforces parent–child relationships. You can only place a task under its actual parent — if you drag it to a different swimlane, the board automatically moves it back to the correct parent row. This is by design: Planningboard maintains data integrity by keeping items linked to their real parent work item. To reassign a task to a different parent, update the parent link role in Polarion directly, then refresh the board.
### Why is the "Enumeration Field" swimlane assignment type showing an error about the field not being an enumeration?
The **Enumeration Field** assignment type requires that the selected field is a valid Polarion enumeration field (not a string or integer field). If you see a field validation error, verify that the `Field ID` you entered references an actual enumeration custom field in your project. Global vs. project-specific field registration matters: fields defined only at project level may not resolve correctly in cross-project boards. After correcting the field ID, save the widget parameters and reload the page. If the error persists, rebuild the widget configuration from scratch.
**Multi-enum swimlanes**
Swimlanes based on **multi-select enumeration fields** (where a work item can belong to multiple enum values simultaneously) are not yet supported. This is a known feature gap planned for release. For resource capacity forecasting across matrix organizations that rely on multi-select fields, use a single-value enumeration field as a workaround, or contact support for the latest status.
### Why do my swimlane assignments not support page parameters like `$pageParameters.xxx`?
Planningboard swimlane configuration does **not** support Polarion page parameters for dynamic team filtering. Widget parameter values are static — you cannot pass `$pageParameters.team` into the swimlane row configuration to switch teams dynamically. As a workaround, create a separate Planningboard page per team, each configured with the appropriate static swimlane settings. See [Swimlanes](/planningboard/faq/swimlanes) for available swimlane assignment types and their constraints.
### Why do swimlanes not appear for a custom Team work item type I created?
Planningboard does not support custom Team work item types for swimlane configuration. Only the standard Nextedy Team work item (with its specific custom fields) is recognized by the Teams Service integration. If your project uses a custom Team WI type, the unified Gantt + Planningboard solution using the standard Nextedy Team WI is the recommended path. Consult [General](/planningboard/faq/general) for an overview of the supported planning model.
***
## Plans (Columns) Issues
### Why do I not see any plan columns on the board?
The most common causes are: (1) the **Plans Query** does not match any plans in your project — check the `plansQuery` field syntax and verify plans exist with a matching Lucene query; (2) the **Plans Type** (`plansMode`) does not match your project structure — **Project Plans** (`PROJECT_PLANS`) works for standard Polarion projects, while SAFe modes require the Polarion SAFe Solution to be active; or (3) the `lastPlans` and `nextPlans` counts are both set to `0`. Try setting **Show # of last plans** to `1` and **Show # of next plans** to `5` (the default).
### Why does the configuration panel look different when I switch Plans Type?
The widget parameter panel changes dynamically based on your **Plans Type** selection. **Project Plans** (`PROJECT_PLANS`) shows the full set of fields including Scope, Query, Type, and the Sync to Parent option. SAFe modes such as **SAFe Sprints in Program** (`SAFE_SPRINTS`) and **SAFe Sprints in Portfolio** (`SAFE_PFL_SPRINTS`) show different fields — notably the **Program Increment Parameter ID** field, and the plan items section is hidden. This is expected behavior: different planning modes expose only the relevant configuration options.
**SAFe configuration**
SAFe plans type selection is highly context-dependent. Each hierarchy level (Portfolio, Program, Team) requires a distinct configuration. If plans are not appearing after switching to a SAFe mode, check that Page Parameters are explicitly created and referenced in the **Program Increment Parameter ID** field. See [SAFe Integration](/planningboard/faq/safe) for level-specific guidance.
***
## Capacity Issues
### Why is a user showing `0.0` total capacity even though they are assigned to tasks?
`totalCapacity` is sourced from the **team calendar** — if a user has no calendar entry or is not a member of the configured team in the Teams Service, their total capacity defaults to `0.0`. Allocated capacity (sum of remaining estimates for their tasks) is calculated independently, so you may see a non-zero allocated value alongside zero total capacity. Verify that the user appears in the team calendar for the plan period, and that `useTeamsService` is enabled and `selectedTeam` points to the correct team.
### Why is capacity not displaying at all on the board?
Capacity bars are only shown when **Show Capacity Load** (`capacityLoad`) is enabled in the widget parameters. If capacity still does not appear after enabling it, check that a valid `capacityField` is set (or that work items have `remainingEstimate` / `initialEstimate` values populated), and that `hoursPerDay` is configured correctly for your team's working schedule. The **Parent Item** assignment mode (`PARENT`) does not support plan normalization (`planCellsMode`) — capacity display in that mode may be limited.
**Capacity configuration is whitespace-sensitive**
Property names and field IDs in the capacity configuration are whitespace-sensitive. A trailing space in `capacityField` or `selectedTeam` will silently fail to match. Copy-paste IDs directly from your Polarion field definitions to avoid invisible whitespace issues.
***
## Access and Licensing Issues
### Why can users view the board but not drag cards or access the sidebar?
Planningboard enforces **license-based access control**. Unlicensed users can view all board content — calendar data, swimlanes, and cards — but editing capabilities are restricted: drag-and-drop is blocked (cards return to their original position), the sidebar panel is hidden, and the **Create New Plan** and **Show Unplanned** buttons are not visible. This read-only mode is intentional for stakeholder visibility. To enable editing for a user, assign them a Planningboard license. See [Licensing](/planningboard/faq/licensing) for license installation steps.
### Why is the "Create New Plan" button not visible in the toolbar?
The **Create New Plan** button (`+` in the toolbar) is only visible to licensed users. If you have a license but still cannot see the button, verify that the **New Plan** section is enabled and configured in the widget parameters — `Template ID` must be set to a valid Polarion plan template (e.g., `iteration` or `release`). Without a `Template ID`, the new plan feature is inactive even for licensed users.
***
## Board Refresh and Data Issues
### Why is the board not reflecting recent changes made in Polarion?
The board renders from a server-side snapshot embedded at page load. After changes to plans, work items, or assignments in Polarion (or another board session), use the **Refresh** button (`#btnRefresh`) in the toolbar to reload the current state from the server. If changes made through drag-and-drop do not persist after refresh, check that the user has an active Planningboard license and that the Polarion session has write permissions to the affected plans and work items.
***
## Quick Diagnostic Decision Tree
For issues not covered here, submit a ticket at [support.nextedy.com](https://support.nextedy.com/support/tickets/new).
**KB Articles**
* Swimlane Assignment Types
* Planningboard Widget Parameters
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#6546](https://support.nextedy.com/helpdesk/tickets/6546)
* [#6777](https://support.nextedy.com/helpdesk/tickets/6777)
**Source Code**
* `PlanningBoardWidgetDependenciesProcessor.java`
* `PlanningBoardWidgetRenderer.java`
* `licenseReadonly.cy.ts`
* `Config.java`
* `PlanningBoardWidget.java`
# Basic Board Interactions
Source: https://learn.nextedy.com/planningboard/getting-started/basic-interactions
Learn the core interactions that make up day-to-day planning work in Nextedy PLANNINGBOARD: navigating the layout, moving cards between Plans, reviewing work item details, and using the toolbar controls.
## What you will achieve
By the end of this tutorial you will be able to:
* Orient yourself in the Planningboard layout (board area and unplanned section)
* Drag cards from the unplanned backlog onto a Plan
* Click a card to open and edit its details in the sidebar
* Use card quick actions (Show Links, Add Link, Unplan)
* Control board display with the toolbar (collapse swimlanes, refresh, toggle views)
* Read a capacity bar tooltip to check a Plan's load
***
## Prerequisites
* Planningboard is installed and a Planningboard page exists in your Polarion project. If not, follow [Installation](/planningboard/getting-started/installation) and [Create Your First Planningboard](/planningboard/getting-started/first-planning-board).
* You have a valid Planningboard license. Unlicensed users can view the board but cannot drag cards, open the sidebar, or access the unplanned section.
* At least one Plan and some unplanned work items are visible on the board.
***
## The board layout
When you open the Planningboard page, the screen is divided into two sections:
* **Board area (left):** Cards are arranged in a grid of columns (Plans) and rows (swimlanes). In a typical setup, columns are iterations or sprints and rows are assignees or teams — this is configurable via widget parameters.
* **Unplanned section (right):** Cards here are not yet assigned to any Plan. This is your backlog.
***
Before moving cards, narrow the unplanned list to the items relevant to you.
1. Click the **funnel icon** in the upper area of the unplanned section.
2. A filter panel opens. You can filter by assignee, by team, or by a predefined Query configured in the widget parameters.
3. Select the filter that matches your focus (for example, your own name as assignee).
**What you see:** The unplanned section refreshes and shows only the matching cards. Cards that do not match are hidden but not deleted.
To hide work items with status **Verified** from the unplanned list, click the upper-right button in the unplanned section header. A separate **Filter columns** option hides Verified work items that are already planned from the board area as well.
***
1. Locate a card in the unplanned section.
2. Click and hold the card, then drag it to the target cell in the board area — the intersection of the Plan (column) and swimlane (row) where you want to schedule it.
3. Release the card. Planningboard saves the assignment immediately.
**What you see:** The card disappears from the unplanned section and appears in the Plan column under the correct swimlane row. The capacity bar for that Plan updates to reflect the new load (if capacity tracking is enabled).
Cards whose status is **Verified** are locked in place. You cannot drag or unplan them once placed. This protects completed work from accidental re-scheduling.
***
1. **Click** any card on the board (not drag — just a single click).
2. The **Work Item Properties** sidebar opens on the right side of the screen.
3. Review the fields shown. The set of fields is configured by the board administrator via widget parameters (Sidebar Fields).
4. Edit any editable field and click **Save**.
**What you see:** After saving, Planningboard preserves your current swimlane and scroll position. The board does not jump back to the top, so you can continue working on nearby cards.
You can personalise the sidebar fields shown to you without affecting other users. Click the **gear icon** (Select Fields) in the sidebar header. Fields you add this way apply only to your session and affect all work items of the same type.
***
When you hover over any card, three quick-action icons appear in its upper-right corner.
| Icon | Action |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Show Links | Reveals all work items linked to this card. All other cards are hidden, leaving only the selected card and its linked cards visible. |
| Add Link | Enter link-creation mode. The same icon appears on every other card. Click a second card to create a link between them. A **red** icon on a card means a link already exists — clicking it removes the link. |
| Unplan item | Moves the card back to the unplanned section, removing its Plan assignment. |
**What you see after Show Links:** The board dims all unrelated cards. Only the selected card and its directly linked cards remain visible, making dependencies easy to trace.
***
The toolbar sits in the upper-left corner of the board area. Use it to control the overall board display.
| Button | What it does |
| ------------------------ | ------------------------------------------------------------------------------------------------------- |
| **Collapse all** | Collapses all swimlane rows to their header bar |
| **Expand all** | Expands all swimlane rows to show their cards |
| **Refresh data** | Reloads the board from the server — use this after external changes in Polarion |
| **Toggle Resource Load** | Shows the current capacity load of each assignee in the swimlane summary cells |
| **Show Unplanned** | Toggles visibility of the unplanned section (hide it to gain screen space) |
| **Prioritize** | Enables the Prioritization feature for reordering items within a Plan |
| **Show Dependencies** | Displays all links between all cards on the board simultaneously (must be enabled in widget parameters) |
You can also collapse or expand a **single swimlane** by clicking its row header directly.
**Show Dependencies** (toolbar) and **Show Links** (card hover) serve different purposes. Show Links is scoped to one card; Show Dependencies reveals all inter-card links across the entire board at once. Show Dependencies requires the feature to be enabled via widget parameters.
***
If capacity tracking is configured on your board, each Plan column shows a **capacity bar** below its header.
1. Hover over the capacity bar of any Plan column.
2. A tooltip appears with a detailed capacity breakdown for that Plan.
**What you see:** The tooltip shows allocated capacity, total available capacity, and remaining capacity per assignee (when user-level capacity tracking is enabled). Negative available capacity indicates overallocation.
**Verify in application**
Capacity tooltip content depends on your widget parameter configuration. If the tooltip does not appear, capacity tracking may not be configured for this board. Ask your board administrator to check the `capacityLoad` and related parameters.
***
## Next steps
You can now perform the fundamental planning interactions on a Planningboard. To go deeper:
* [**Concepts**](/planningboard/concepts/index) — Understand Plans, swimlanes, capacity bars, and how Planningboard maps Polarion data to the board view.
* [**Guides**](/planningboard/guides/index) — Task-oriented guides for swimlane configuration, capacity setup, card customization, and prioritization.
* [**Reference**](/planningboard/reference/index) — Complete widget parameter reference with default values and configuration examples.
* [**FAQ**](/planningboard/faq/index) — Answers to common questions about board behavior and configuration.
# Create Your First Planningboard
Source: https://learn.nextedy.com/planningboard/getting-started/first-planning-board
This tutorial walks you through creating a working Nextedy PLANNINGBOARD in an existing Polarion project — from adding the widget to a LiveReport page to seeing your Plans appear as columns with work items displayed as cards in swimlanes.
## What you will achieve
By the end of this tutorial you will have:
* A LiveReport page with a Planningboard widget embedded
* Plans from your project displayed as columns on the board
* Work items arranged as cards in swimlanes grouped by assignee
* A capacity bar visible
***
## Prerequisites
* Planningboard is installed on your Polarion server. See [Installation](/planningboard/getting-started/installation) if you have not done this yet.
* A valid Planningboard license is active. See [License Installation](/planningboard/getting-started/licensing).
* You have edit rights on at least one Polarion project that contains Plans and work items.
* Your Polarion user has the `planningboard` role assigned (ask your administrator if unsure).
***
Navigate to your Polarion project and open the **Documents & Pages** section from the left sidebar.
Choose the space where you want to host the board — for example, **Planning**.
If your project uses the E-Library template, a **Planning** space is already present. You can create the board page directly inside it.
**What you should see:** The space opens and shows any existing LiveDoc and Wiki pages in that space.
***
Inside the Planning space, click **New** and select **LiveReport Page**. Name the page **Planningboard**.
Planningboard runs as a widget embedded in a LiveReport page. It does **not** work in a standard LiveDoc or Wiki page — use a LiveReport page specifically.
**What you should see:** A blank LiveReport page editor opens.
***
In the page editor, open the widget picker. Scroll through the available widgets and select **Plans - Planningboard**.
**What you should see:** The widget is inserted onto the page and Planningboard loads immediately using the project's default planning settings. You will see columns (Plans) and swimlanes (assignees) populated from your project data.
If no plans appear, your project may not yet have any Plans defined. Create at least one Plan in Polarion's plan management view before continuing.
***
Click the widget's settings icon (gear/wrench) to open its parameters. The default configuration uses:
| Parameter | Default value | What it controls |
| -------------------------------------- | --------------- | -------------------------------------------- |
| **Plans Type** (`plansMode`) | `PROJECT_PLANS` | Loads Plans from the current project |
| **Assignment Type** (`assignmentMode`) | `ASSIGNEE` | Groups work items into swimlanes by assignee |
| **Show # of last plans** (`lastPlans`) | `1` | Number of past Plans shown |
| **Show # of next plans** (`nextPlans`) | `5` | Number of upcoming Plans shown |
| **Max Items** (`maxItems`) | `1000` | Maximum work items loaded |
Leave all parameters at their defaults for now. Save the widget configuration.
**What you should see:** The board refreshes and displays your project's Plans as columns, with work items arranged as cards in swimlane rows — one row per assignee.
***
* **Columns** — each column represents one Plan (sprint, release, etc.)
* **Swimlanes** — each row groups cards for one assignee
* **Cards** — each card is a work item; its ID and title are shown on the card
* **Capacity bar** — shown below the plans
* **Unplanned column** — work items not yet assigned to any Plan appear here
***
Open the widget parameters again. Under **Parameters for Plans (Columns)**, find the **Show Capacity Load** toggle and set it to **Yes**.
Save the widget configuration and reload the page.
**What you should see:** A capacity bar appears below the Plan's name, showing planned effort against that Plan's available capacity.
***
Click **Save** to publish your LiveReport page. The board is now accessible to other project members who have the `planningboard` role.
Users without a Planningboard license can view the board in read-only mode — they see all cards and swimlanes but cannot drag cards, create Plans, or access the sidebar. Licensed users have full editing capabilities including drag-and-drop scheduling.
**What you should see:** The page is saved and the Planningboard is live for your team.
***
## Troubleshooting
**Board shows "No Plans found"** Check that your project has at least one Plan and that **Plans Type** (`plansMode`) is set to `PROJECT_PLANS`. If your project uses a custom plan structure, consult your administrator about the correct **Plans** (`plansQuery`) value.
**All cards appear in the Unplanned column** Work items appear as unplanned when they are not assigned to any Plan. Drag them from the Unplanned column into the appropriate Plan column to schedule them.
***
## Next steps
Now that your first board is running, explore these topics to get more from Planningboard:
* [Basic Board Interactions](/planningboard/getting-started/basic-interactions) — drag cards between Plans, use the sidebar, and refresh the board
* [Setup into Existing Projects](/planningboard/getting-started/setup-existing-project) — configure Planningboard for projects with custom work item types and fields
* [Guides](/planningboard/guides/index) — deeper configuration guides for swimlanes, capacity, Plan queries, and card appearance
* [Reference](/planningboard/reference/index) — complete widget parameter reference
# Getting Started
Source: https://learn.nextedy.com/planningboard/getting-started/index
Nextedy PLANNINGBOARD is a planning app for Siemens Polarion ALM that arranges Plans and work items as cards across swimlanes for capacity-aware sprint and release planning.
Install Planningboard on your Polarion server.
Activate your Planningboard license after installation.
Add the Planningboard widget to a brand-new Polarion project.
Integrate Planningboard into a Polarion project that is already in use.
Configure the widget and display Plans and work items as cards on a board.
Navigate the board, move cards between swimlanes, and use drag-and-drop planning.
**Recommended order**
If you are setting up Planningboard for the first time, work through these pages in order: **Installation** → **License Installation** → **Setup into New Projects** or **Setup into Existing Projects** → **Create Your First Planningboard** → **Basic Board Interactions**.
```text theme={null}
Planningboard setup flow
========================
[ Polarion server ]
|
v
+--------------+
| Install | Copy plugin folder, restart Polarion
| plugin |
+--------------+
|
v
+--------------+
| Activate | Add license file via Administration
| license |
+--------------+
|
v
+--------------+
| Configure | Add Planningboard widget to a
| project | LiveDoc or Wiki page
+--------------+
|
v
+--------------+
| Set Plan | Define the Plan query so the board
| query | knows which Plans to display
+--------------+
|
v
+--------------+
| Configure | Choose swimlane assignment type,
| swimlanes | capacity, and card appearance
+--------------+
|
v
+---------------------------+
| Plan — drag, prioritize, |
| track capacity per lane |
+---------------------------+
```
**KB Articles**
* Install Planningboard
* How to setup Planningboard into existing projects (based on E-library template)
* Introduction to Planningboard
**Support Tickets**
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
**Source Code**
* `Config.java`
* `PlanningBoardWidgetRenderer.java`
* `PlanningBoardSetupService.java`
* `licenseReadonly.cy.ts`
* `capacityHelperData.cy.ts`
# Installation
Source: https://learn.nextedy.com/planningboard/getting-started/installation
Install Nextedy PLANNINGBOARD on your Polarion server: deploy the plugin folder, clear the plugin cache, restart, and verify the administration pages.
## What you will achieve
By the end of this tutorial you will have:
* The `com.nextedy.planningboard` plugin deployed on your Polarion server
* The plugin cache cleared and Polarion restarted so Planningboard is recognized
* The **Nextedy PLANNINGBOARD** administration section available, with the Setup and License pages accessible
## Prerequisites
* A running Polarion server with a [version still supported by Nextedy](https://support.nextedy.com/support/solutions/articles/48001270876-what-polarion-versions-do-you-support-)
* Administrator access to the Polarion server filesystem and web interface
* The Planningboard distribution archive (`nextedy_planningboard.zip`) downloaded from [nextedy.com/nextedy-planningboard](https://www.nextedy.com/nextedy-planningboard/)
* Optionally, a valid license file (`*-planningboard_lic.json`) from Nextedy — Planningboard also runs in trial mode without one
You can install and evaluate Planningboard without a license file. Unlicensed users can view boards in read-only mode but cannot drag cards, use the sidebar, or create Plans. See [License Installation](/planningboard/getting-started/licensing) for adding a license after the initial install.
Unpack the downloaded `nextedy_planningboard.zip`. Inside you will find a folder named `com.nextedy.planningboard`.
Copy this entire folder into your Polarion extensions directory:
```text theme={null}
[POLARION_INSTALL]/polarion/extensions/
```
Replace `[POLARION_INSTALL]` with your actual Polarion installation path (for example `/opt/polarion` on Linux or `C:\Polarion` on Windows).
**Do not rename the plugin folder**
Polarion locates the plugin by the folder name `com.nextedy.planningboard`. Renaming it prevents the server from loading Planningboard.
This step is critical. Remove the cached Polarion configuration directory so Polarion detects the new plugin on the next startup:
```text theme={null}
[POLARION_INSTALL]/data/workspace/.config
```
Delete the entire `.config` directory (not just its contents). Polarion regenerates it on the next startup. The `.config` cache holds only plugin-discovery data — it contains no project configuration or work items.
**Do not skip this step**
Failing to delete `[POLARION_INSTALL]/data/workspace/.config` is the most common cause of installation problems. If you skip it, the **Nextedy PLANNINGBOARD** Setup and License pages appear empty with no content. This step is required for both fresh installations and updates to a newer version.
Restart Polarion so it rebuilds its plugin registry from the updated `extensions/` folder:
* **Linux**: `systemctl restart polarion` or the Polarion-provided startup script
* **Windows**: restart the Polarion service through the Services management console
Wait for Polarion to fully start — this can take several minutes depending on your server and the number of installed extensions.
After Polarion restarts, log in as an administrator and navigate to:
**Administration > Nextedy PLANNINGBOARD > Setup**
You should see the Setup page render with content — the installed version with an up-to-date indicator, and the demo-template controls. This confirms Planningboard loaded successfully and the configuration cache was rebuilt during startup.
**Empty Setup page = cache issue**
If the Setup page loads but shows no content, the `.config` directory was not fully removed in the previous step. Stop Polarion, delete `.config` again, and restart.
Navigate to **Administration > Nextedy PLANNINGBOARD > License** to check your license status. The page shows the license details (type, expiry, named- and server-user counts), with the signature field redacted for security.
If you have not applied a production license, the page indicates evaluation/trial mode and Planningboard remains usable read-only. To apply a license, see [License Installation](/planningboard/getting-started/licensing).
**Named-user licensing**
Planningboard editing access is seat-based: it is granted to users assigned to the `nextedy_planningboard_users` group. Configure named users from the same License page — see [License Installation](/planningboard/getting-started/licensing).
## Troubleshooting
If the **Nextedy PLANNINGBOARD** section — or its Setup/License content — does not appear after installation:
1. Stop Polarion
2. Delete the cache directory: `[POLARION_INSTALL]/data/workspace/.config`
3. Restart Polarion
This forces Polarion to reinitialize the extension configuration and usually resolves recognition issues. If the Administration entry is missing entirely, confirm the `com.nextedy.planningboard` folder is present under `polarion/extensions/` and was not renamed.
## Post-installation checklist
| Item | How to verify |
| --------------------------------- | ------------------------------------------------------------------------------------------ |
| Plugin deployed to `extensions/` | `com.nextedy.planningboard` present in `[POLARION_INSTALL]/polarion/extensions/` |
| `.config` deleted and regenerated | Folder reappears after restart |
| Polarion restarted successfully | Server log shows a clean startup |
| Setup page loads with content | **Administration > Nextedy PLANNINGBOARD > Setup** renders the version + template controls |
| License page shows status | **Administration > Nextedy PLANNINGBOARD > License** loads with license details |
## Next steps
With the server plugin installed, choose your setup path:
* **Evaluate quickly** — use the demo project: open **Administration > Nextedy PLANNINGBOARD > Setup**, then create a project from the **Nextedy PLANNINGBOARD Demo** template.
* **Set up a new project** — [Setup into New Projects](/planningboard/getting-started/setup-new-project)
* **Set up an existing project** — [Setup into Existing Projects](/planningboard/getting-started/setup-existing-project)
* **Add or manage a license** — [License Installation](/planningboard/getting-started/licensing)
* **Build your first board** — [Create Your First Planningboard](/planningboard/getting-started/first-planning-board)
# License Installation
Source: https://learn.nextedy.com/planningboard/getting-started/licensing
Learn how to install a production license for Nextedy PLANNINGBOARD and transition out of evaluation mode so your team has full editing access to the Planningboard.
## What you will achieve
By the end of this tutorial you will have:
* Placed your production license file in the correct Polarion directory
* Verified the license status in the Planningboard administration interface
* Confirmed that licensed users can drag cards, use the sidebar, and create Plans
## Prerequisites
* Planningboard is already installed on your Polarion server (see [Installation](/planningboard/getting-started/installation))
* You have access to the Polarion server file system (or can ask your system administrator)
* You have received a license file named `-planningboard_lic.json` from Nextedy
Planningboard runs in **30-day evaluation mode** when no production license is present. In evaluation mode the board is read-only for all users — cards cannot be dragged, the sidebar is hidden, the **Create New Plan** button is not shown, and the **Show Unplanned** toggle is unavailable. View access to board content is retained.
***
Your license file was delivered by Nextedy when you purchased Planningboard. Its name follows the pattern:
```text theme={null}
-planningboard_lic.json
```
For example: `acme-planningboard_lic.json`.
If you cannot find your license file, contact [support@nextedy.com](mailto:support@nextedy.com).
***
Place the license file inside the Polarion installation's `license` folder:
```text theme={null}
[POLARION_INSTALL]/polarion/license/-planningboard_lic.json
```
Replace `[POLARION_INSTALL]` with your actual Polarion installation path (for example `/opt/polarion` on Linux).
**Do not rename the file**
The file name must remain exactly as delivered. Renaming the file can prevent the license from being recognized.
***
Polarion caches plugin state in a `.config` directory. You must remove it so Polarion picks up the new license on the next start.
```text theme={null}
Delete: [POLARION_INSTALL]/data/workspace/.config
```
**Safe to delete**
The `.config` directory holds only plugin discovery caches — no project data. Deleting it does not slow Polarion down and is recommended by Polarion support whenever a plugin changes.
***
Restart your Polarion server using your organization's standard procedure. The server must fully start before you proceed.
**What you should see:** Polarion starts normally with no errors related to Planningboard in the server log.
***
1. Log in to Polarion as an administrator.
2. Navigate to **Administration > Nextedy PLANNINGBOARD**.
3. Open the **Setup** (or license) page.
You will see a color-coded status panel:
The panel also shows the full license details. The signature field is automatically redacted from the display — this is intentional and does not affect validation.
**What you should see:** A green panel confirming the license is valid.
**Signature redacted**
The license signature is hidden in the UI for security. The server validates it server-side — you do not need to see it.
***
Open a Planningboard page in any project. Verify the following are now visible and functional for licensed users:
| Element | Expected state when licensed |
| -------------------------- | ------------------------------------------------------- |
| **Show Unplanned** button | Visible in the toolbar |
| **Create New Plan** button | Visible |
| Sidebar panel | Opens when a card is clicked |
| Drag and drop | Cards can be dragged between swimlanes; changes persist |
**Read-only persists for unlicensed users**
Planningboard enforces license-based access control per user. Users who do not hold a Planningboard license will still see the board in read-only mode — they can view cards and swimlanes but cannot drag, edit, or plan. This is by design to support collaboration and transparency.
***
## License states reference
| Status | Panel color | Meaning |
| ---------- | ----------- | --------------------------------------------------------------------------- |
| Valid | Green | Production license accepted; full editing enabled for licensed users |
| Info | Blue | License present but contains an informational notice; check the message |
| Invalid | Red | License not recognized or expired; board reverts to read-only for all users |
| No license | — | Evaluation mode; 30-day window; read-only for all users |
***
## Next steps
With a valid license installed, continue setting up your project:
* [Setup into New Projects](/planningboard/getting-started/setup-new-project) — install Planningboard into a brand-new Polarion project
* [Setup into Existing Projects](/planningboard/getting-started/setup-existing-project) — add Planningboard to a project already in use
* [Create Your First Planningboard](/planningboard/getting-started/first-planning-board) — add the widget to a LiveDoc page and run your first planning session
**KB Articles**
* Install Planningboard
* How to setup Planningboard into existing projects (based on E-library template)
* Planningboard interface & basic interactions
**Support Tickets**
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
**Source Code**
* `viewLicense.vm`
* `licenseReadonly.cy.ts`
* `Config.java`
* `PlanningBoardWidgetRenderer.java`
* `PlanningBoardSetupService.java`
# Setup into Existing Projects
Source: https://learn.nextedy.com/planningboard/getting-started/setup-existing-project
Learn how to add a Nextedy PLANNINGBOARD widget to an existing Polarion project so your team can start capacity-aware sprint and release planning without creating a new project.
## What you will achieve
By the end of this tutorial you will have a working Planningboard embedded in a LiveReport page inside your existing Polarion project, ready for you to configure Plans and swimlanes.
## Prerequisites
* Planningboard is installed on your Polarion server (see [Installation](/planningboard/getting-started/installation))
* A valid Planningboard license is applied (see [License Installation](/planningboard/getting-started/licensing))
* You have project administrator access to the target Polarion project
* The project contains at least one Plan with work items
***
Navigate to your existing project in Siemens Polarion ALM and open the **Documents & Pages** section from the left sidebar.
Choose a space where you want to host the Planningboard. For most teams the **Planning** space is a natural home, but you can use any space you have write access to.
If your project has no dedicated planning space, create one now. A descriptive space name such as **Planning** makes it easy for team members to find the board later.
**What you should see:** The Documents & Pages tree for your project, listing existing spaces and pages.
***
Inside the chosen space, create a new **LiveReport Page** and give it a recognizable name such as `PlanningBoard`.
Planningboard runs as a widget embedded inside a LiveReport page. It cannot be placed on a plain Wiki page — you must use a LiveReport page type.
**What you should see:** A blank LiveReport page open in edit mode, ready for widgets to be added.
***
With the LiveReport page open in edit mode, open the widget picker. From the list of available widgets, select **Plans - Planningboard**.
The widget is inserted into the page and loads the Planningboard using the project's existing Plan structure.
**What you should see:** The Planningboard widget renders on the page, displaying cards grouped into swimlanes based on the default configuration. Plans detected from the project appear as columns.
Only one Planningboard widget is supported per page. If you need boards for multiple teams or planning levels, create a separate LiveReport page for each board.
***
Save the page and view it in read mode. Confirm that:
* Plans appear as columns across the board
* Work items appear as cards within the swimlanes
* Swimlanes are populated (the default **Assignment Type** (`assignmentMode`) groups items by **assignee**)
If the board appears empty, your project's Plans may not match the default query. See Step 5 to configure the Plan query.
**What you should see:** A board with at least one Plan column and cards placed in swimlane rows corresponding to assignees.
***
Click the widget's settings icon to open its parameter panel. The two most important parameters for an initial setup are:
| Parameter | Purpose | Example value |
| -------------------------------------- | ----------------------------------------------------------- | ------------------ |
| **Plans** (`plansQuery`) | Lucene query selecting which Plans appear on the board | `type:releasePlan` |
| **Work Item Type** (`wiType`) | Work item type filter restricting which items load as cards | `story` |
| **Assignment Type** (`assignmentMode`) | How work items map to swimlanes | `ASSIGNEE` |
| **Show # of last plans** (`lastPlans`) | Number of past Plans to show | `1` (default) |
| **Show # of next plans** (`nextPlans`) | Number of future Plans to show | `5` (default) |
**Minimal example** — show release plans containing stories, grouped by assignee:
* **Plans**: `type:releasePlan`
* **Work Item Type**: `story`
* **Assignment Type**: `ASSIGNEE`
* **Show # of last plans**: `1`
* **Show # of next plans**: `5`
Start with the defaults before tuning. The board is usable without any parameter changes if your project already has Plans and assigned work items.
**What you should see:** After saving the widget parameters, the board refreshes to show only the Plans and work items matching your filters.
***
## Setup flow at a glance
***
## Next steps
With the board running in your project, explore these topics to get more out of Planningboard:
* [Create Your First Planningboard](/planningboard/getting-started/first-planning-board) — walk through a complete planning session end-to-end
* [Basic Board Interactions](/planningboard/getting-started/basic-interactions) — drag cards, use the sidebar, and refresh the board
* [Concepts](/planningboard/concepts/index) — understand swimlanes, capacity bars, Plan queries, and normalization
* [Guides](/planningboard/guides/index) — task-oriented how-to guides for swimlane configuration, capacity setup, and more
# Setup into New Projects
Source: https://learn.nextedy.com/planningboard/getting-started/setup-new-project
Set up Nextedy PLANNINGBOARD in a brand-new Polarion project by installing the demo project template — the fastest way to get a working Planningboard with sample data you can explore and adapt.
## What you will achieve
By the end of this tutorial you will have:
* A new Polarion project created from the Planningboard demo template
* A LiveReport page with a working Planningboard widget embedded
* Sample Plans and work items arranged on the board, ready to explore
## Prerequisites
* Planningboard is installed on your Polarion server (see [Installation](/planningboard/getting-started/installation))
* A valid Planningboard license is applied (see [License Installation](/planningboard/getting-started/licensing))
* You have Polarion **Administration** access
**One widget per page**
Planningboard supports only **one widget per LiveReport page**. If you need boards for multiple teams or projects, create a separate LiveReport page for each board.
***
1. Log in to Polarion and click the top-level **Administration** link (gear icon or the global Administration project).
2. In the left navigation, locate **Planningboard** and click **Setup**.
**What you should see:** The Planningboard Setup page lists available actions, including an option to install the demo project template.
If **Planningboard** does not appear in the Administration navigation, Planningboard is not loaded. Verify the installation steps in [Installation](/planningboard/getting-started/installation) — in particular that the `.config` file was deleted and Polarion was restarted.
***
On the Planningboard Setup page, follow the on-screen instructions to install the demo template into Polarion's project template registry.
**What you should see:** A confirmation message that the template was installed successfully. The template is stored in Polarion's template repository and will be available when you create a new project in the next step.
The installation is transactional — if anything fails, it rolls back automatically and no partial template is left behind. Re-run the setup action after resolving any error.
***
1. Navigate to **Polarion Administration > Projects** and click **Create Project**.
2. On the template selection screen, choose the **Planningboard** template (it appears in the list after Step 2).
3. Fill in the project name, ID, and any other required fields, then confirm.
**What you should see:** Polarion creates the project and pre-populates it with sample Plans, work items, and the Planningboard page.
***
1. Switch to your newly created project.
2. Open **Documents & Pages** in the left navigation.
3. Navigate to the **Planning** space and open the **Planningboard** LiveReport page.
**What you should see:** The Planningboard widget loads and displays the sample Plans as columns and work items as cards organised in swimlanes. The capacity bar for each swimlane shows the current load.
The board defaults to showing the last **1** completed Plan (`lastPlans = 1`) and the next **5** upcoming Plans (`nextPlans = 5`). You can adjust these via the widget parameters once you begin customising the board.
***
Take a few minutes to orient yourself:
* **Cards** — each work item appears as a card. Cards display the work item ID and title, for example `MAP-531 - My Story`.
* **Swimlanes** — rows that group cards by assignee (the default `assignmentMode`). Drag a card from one swimlane to another to reassign it.
* **Capacity bar** — the bar at the top of each swimlane shows load relative to capacity for the selected Plan.
* **Sidebar** — licensed users see an editing sidebar with filters and tools. Unlicensed users can view the board in read-only mode but cannot drag cards or access the sidebar.
**License-based access**
Users without a Planningboard license can view the board (cards, swimlanes, capacity bars) but editing actions — dragging cards, accessing the sidebar, creating or showing unplanned items — are disabled for them.
***
## Widget parameter reference (overview)
The Planningboard widget on the LiveReport page is configured through **widget parameters**. Here are the key parameters you will encounter first:
| Parameter | Default | What it controls |
| ---------------- | --------------- | ---------------------------------------------------------------------------------------- |
| `plansMode` | `PROJECT_PLANS` | How Plans are sourced — project plans, SAFe sprints, SAFe Program Increments, or custom |
| `assignmentMode` | `ASSIGNEE` | How work items map to swimlanes — by assignee, enum field, parent, project, or SAFe team |
| `query` | `NOT *:*` | Lucene query filtering which work items appear on the board |
| `plansQuery` | *(none)* | Lucene query filtering which Plans appear on the board |
| `lastPlans` | `1` | Number of past/completed Plans shown |
| `nextPlans` | `5` | Number of upcoming Plans shown |
| `maxItems` | `1000` | Maximum work items loaded |
| `wiType` | *(none)* | Work item type filter (e.g. `story`, `task`) |
**Whitespace in capacity parameters**
Capacity configuration parameters are whitespace-sensitive. Ensure there are no leading or trailing spaces when setting capacity-related widget parameters, as this can cause silent misconfiguration.
***
## Next steps
With the demo project running, continue with:
* [Create Your First Planningboard](/planningboard/getting-started/first-planning-board) — walk through building a board from scratch on an existing project
* [Basic Board Interactions](/planningboard/getting-started/basic-interactions) — learn drag-and-drop, the sidebar, and filtering
* [Setup into Existing Projects](/planningboard/getting-started/setup-existing-project) — add Planningboard to a project you already have
**KB Articles**
* Install Planningboard
* How to setup Planningboard into existing projects (based on E-library template)
* Introduction to Planningboard
**Support Tickets**
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#5796](https://support.nextedy.com/helpdesk/tickets/5796)
**Source Code**
* `Config.java`
* `PlanningBoardWidgetRenderer.java`
* `PlanningBoardSetupService.java`
* `capacityHelperData.cy.ts`
* `Item.java`
# Config Scripts
Source: https://learn.nextedy.com/planningboard/guides/advanced/config-scripts
Use a config script to modify the Nextedy PLANNINGBOARD widget configuration programmatically at render time — override properties, adjust capacity settings, or apply conditional logic before the board loads.
## What is a config script?
A config script is a JavaScript snippet you supply via the `advScript` widget parameter. The script runs in the Planningboard widget context and has access to the board configuration object before the board renders. This allows you to manipulate configuration values that are not exposed directly in the widget parameter editor, or to set them conditionally based on runtime context.
Config scripts execute client-side, in the Planningboard widget frame. They are not server-side scripts. Changes you make affect the current board session only — they do not persist to the widget parameter store.
## When to use config scripts
Config scripts are suited for:
* Overriding a configuration property that cannot be set through the standard widget parameters UI
* Applying conditional logic (for example: show different capacity settings for different teams)
* Injecting dynamic values that depend on page context or URL parameters
For most configuration tasks, use the [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) directly. Reach for a config script only when the standard parameters are insufficient.
## How config scripts are loaded
The `advScript` widget parameter value is passed into the board widget and exposed as `window.__pbAdvScript`. The Planningboard scheduler reads this property during initialization and evaluates it after the initial configuration object is assembled but before the board renders.
```text theme={null}
Widget parameter editor
|
| advScript = "window.__pbConfig.maxItems = 500;"
v
Planningboard widget iframe
|
| window.__pbAdvScript evaluated at schedulerInit
v
Config object modified --> Board renders with updated config
```
## Step-by-step: adding a config script
### 1. Open the widget parameter editor
Navigate to the Polarion LiveDoc or Wiki page that hosts the Planningboard widget. Switch to edit mode and open the widget parameters panel.
### 2. Locate the Advanced Script parameter
In the widget parameters editor, find the field labelled **Advanced Script** (mapped to the `advScript` parameter). This is a free-text field that accepts JavaScript.
The **Advanced Script** field accepts raw JavaScript. There is no syntax validation in the editor. A syntax error in your script will silently prevent the script from running. Check the browser console for errors if the board behaves unexpectedly after adding a script.
### 3. Write your script
Your script runs in the widget frame's JavaScript context. The Planningboard configuration object is accessible as `window.__pbConfig`. Modify properties on this object directly.
**Example: override the maximum number of work items**
```javascript theme={null}
if (window.__pbConfig) {
window.__pbConfig.maxItems = 500;
}
```
**Example: conditionally enable capacity load based on a URL parameter**
```javascript theme={null}
if (window.__pbConfig) {
var params = new URLSearchParams(window.location.search);
if (params.get('showCapacity') === 'true') {
window.__pbConfig.capacityLoad = true;
}
}
```
**Example: set the hours-per-day value for capacity calculations**
```javascript theme={null}
if (window.__pbConfig) {
window.__pbConfig.hoursPerDay = 6;
}
```
Always guard your script with `if (window.__pbConfig)`. If the board fails to initialize for any reason, `window.__pbConfig` may be undefined, and an unguarded access will throw a JavaScript error that can mask the real problem.
### 4. Save the widget parameters
Save the widget configuration. Reload the Planningboard page to verify the script takes effect.
## Configuration properties available in `window.__pbConfig`
The following properties are confirmed present in the configuration object. Use their exact names — incorrect casing or spelling will produce no effect (the property will be ignored silently).
| Property | Type | Default | Description |
| ------------------- | ------- | ------- | ------------------------------------------------------------------------------ |
| `maxItems` | number | `1000` | Maximum number of work items loaded onto the board |
| `capacityLoad` | boolean | `false` | Enables capacity loading calculations |
| `multiCapacityLoad` | boolean | `false` | Enables per-resource capacity loading across multiple plans |
| `userCapacityLoad` | boolean | `false` | Enables user-level capacity loading when using the Teams service |
| `hoursPerDay` | number | `8` | Working hours per day used in capacity calculations |
| `useTeamsService` | boolean | `false` | Enables integration with the Polarion Teams service |
| `capacityField` | string | `null` | Custom field ID containing capacity values (for example story points or hours) |
| `lastPlans` | number | `1` | Number of past plans to display as columns |
| `nextPlans` | number | `5` | Number of future plans to display as columns |
**Capacity parameters are whitespace-sensitive**
When setting `capacityField` or similar string-typed properties via a config script, ensure there are no leading or trailing spaces in the value. Whitespace in field IDs causes silent lookup failures.
## Common pitfalls
### Script does not run
Check the browser console for JavaScript syntax errors. A missing semicolon or unmatched bracket prevents the entire script from executing. Also confirm the script is saved in the `advScript` parameter, not in a different parameter field.
### Property change has no visible effect
Some properties are consumed during an initialization phase that has already passed by the time the script runs. If a property change does not take effect, the property may not be modifiable via config script — consult the [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) for the canonical way to set that value.
### Board shows wrong capacity after script change
Capacity configuration involves several interacting properties (`capacityLoad`, `multiCapacityLoad`, `userCapacityLoad`, `hoursPerDay`, `capacityField`). Setting one without the others may produce unexpected results. See [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration) for the full configuration sequence.
### Script conflicts with page parameters
If you are also using [Use Page Parameters](/planningboard/guides/configuration/page-parameters) or [Scripted Page Parameters](/planningboard/guides/advanced/scripted-page-parameters), be aware that page parameters are resolved server-side before the board widget is rendered, while the config script runs client-side. The config script runs after page parameter substitution, so it can read but not undo parameter-derived values.
## Verification
After saving your config script and reloading the board, you should see the board render with the modified behaviour. To confirm the script ran:
1. Open browser developer tools (F12).
2. In the Console, type `window.__pbConfig` and press Enter.
3. Inspect the configuration object — the properties you modified should reflect the values set in your script.
If the object shows the original values, the script did not execute. Check the Console for errors.
## See also
* [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) — all standard widget parameters and their defaults
* [Item Scripts](/planningboard/guides/advanced/item-scripts) — scripts that run per work-item card, for dynamic card content
* [Data Scripts](/planningboard/guides/advanced/data-scripts) — scripts for transforming the work item dataset before the board renders
* [Scripted Page Parameters](/planningboard/guides/advanced/scripted-page-parameters) — server-side parameter scripting complementary to config scripts
* [Dynamic Filtering with Page Parameters](/planningboard/guides/advanced/dynamic-filtering) — using URL parameters to drive board configuration
* [Script Errors](/planningboard/guides/troubleshooting/script-errors) — diagnosing and resolving script execution errors
**KB Articles**
* Planningboard Widget Parameters
* Planningboard: Customizable Statistics and Capacity Indicators
* Troubleshooting Script Errors in Planningboard
**Support Tickets**
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
**Source Code**
* `viewSetup.vm`
* `Config.java`
* `PlanningBoardWidgetRenderer.java`
* `Item.java`
* `planningboard.js`
# Custom Project Templates
Source: https://learn.nextedy.com/planningboard/guides/advanced/custom-templates
Install the Nextedy PLANNINGBOARD demo project template into your Polarion instance so you can spin up a fully configured Planningboard as a starting point for new projects.
## What This Guide Covers
This guide walks through installing the bundled `planningboard_template` into Polarion's project template registry, verifying the installation through the administration interface, and creating a new project from the installed template. It also covers the template's structure so you understand what gets provisioned.
## Prerequisites
* Planningboard is installed and licensed on your Polarion instance.
* You have administrator access to the Polarion server.
* You have access to **Administration > Nextedy PLANNINGBOARD** in the Polarion admin interface.
***
1. Log in to Polarion as a system administrator.
2. Navigate to **Administration > Nextedy PLANNINGBOARD**.
3. Select the **Setup** tab.
The setup page displays the currently installed plugin version and a **Template Installation** section showing whether the demo template is already present.
If the status already shows the template as installed, skip to [Step 3](#step-3-create-a-project-from-the-template). Re-installing an already-present template is safe — the installation is transaction-wrapped and rolls back on failure — but it is unnecessary.
***
1. On the Setup page, locate the **Install Demo Template** button.
2. Click the button to trigger installation.
The server installs the template ZIP bundled with the plugin into Polarion's template repository at `.polarion/projects/templates/planningboard_template`.
The page reloads and shows a status message:
* A message beginning with `OK:` confirms a successful installation.
* Any other message indicates a failure — the installation is automatically rolled back (no partial state is left).
If you see an error message after clicking Install, check that the Polarion server process has write access to `.polarion/projects/templates/`. A permission error on the templates directory is a common cause of installation failure.
```text theme={null}
Template Installation Flow
--------------------------
Plugin ZIP (bundled)
|
v
Scan for template.properties files
(each template.properties marks one template root)
|
v
Upload each discovered template into
.polarion/projects/templates/
(wrapped in a Polarion transaction)
|
/ \
/ \
Success Failure
| |
OK: msg Rollback
(no partial state)
```
The template ZIP may contain multiple project templates. All discovered templates (each identified by a `template.properties` file at its root) are installed in a single operation.
***
Once the template is installed it appears in Polarion's standard **New Project** wizard.
1. Navigate to **Administration > Projects > Create Project**.
2. In the template picker, select **planningboard\_template** (or the display name shown after installation).
3. Fill in your project ID, name, and other required fields.
4. Complete the wizard and wait for Polarion to provision the project.
The created project includes a pre-configured LiveReport page with the Planningboard widget already added, together with example Plans, swimlane configuration, and work item types that demonstrate the board's capabilities out of the box.
The E-Library template that ships with Polarion also works well as a base for evaluating Planningboard. After creating an E-Library project, add a LiveReport page in the Planning space and insert the **Plans - Planningboard** widget. This gives you a working board without using the bundled template. See [Setup into Existing Projects](/planningboard/getting-started/setup-existing-project) for the full walkthrough.
***
1. Open the newly created project in Polarion.
2. Navigate to **Documents & Pages > Planning** (or the space configured by the template).
3. Open the **Planningboard** LiveReport page.
The board should load and display the example Plans as columns and the example work items as cards distributed across swimlanes.
| What to check | Expected result |
| ---------------------------------- | ---------------------------------- |
| Board renders without errors | Cards and column headers visible |
| Plans appear as columns | At least one column shown |
| Work items appear as cards | Cards populated in swimlanes |
| Capacity bars visible (if enabled) | Bar shown below each column header |
**Plan Name Pattern and Plan ID Pattern are pre-set for Teams.** If your project does not use the Planningboard Teams feature, update these two widget parameters on the board page before creating your first new Plan from the board. Leaving them as-is when Teams are not configured causes new Plans to be created with unexpected IDs. See [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) for the `Plan Name Pattern` and `Plan ID Pattern` fields.
***
## Template Structure Reference
The installed template provisions the following configuration:
```text theme={null}
planningboard_template/
template.properties # Template identity (required — marks the template root)
.polarion/
polarion-project.xml # Project metadata
tracker/
fields/ # Work item type and field definitions
workflow/ # Work item workflow
pages/
Planning/ # Planning space
PlanningBoard/ # LiveReport page with the widget
modules/
Planning/ # Example planning documents
```
The widget on the provisioned page has sensible defaults for `plansMode`, `assignmentMode`, `query`, `lastPlans`, and `nextPlans`. You can adjust all of these as widget parameters after the project is created.
***
## Common Pitfalls
**Whitespace in capacity configuration parameters.** If you copy widget parameter values from the template and add or remove spaces around `=` signs, capacity calculations will silently fail. Capacity configuration parameters are whitespace-sensitive — copy them exactly.
**Template visible but project creation fails.** If the template appears in the wizard but the project fails to provision, verify that the Polarion server has sufficient disk space and that the templates repository is not locked by another operation.
***
## You Should Now See
After completing this guide, the Planningboard demo template appears in Polarion's project template picker, and any project created from it opens with a working Planningboard on its LiveReport page — Plans as columns, work items as cards in swimlanes, and the widget parameters pre-configured for immediate use.
***
## See Also
* [Setup into Existing Projects](/planningboard/getting-started/setup-existing-project) — add Planningboard to a project without using the template
* [Create Your First Planningboard](/planningboard/getting-started/first-planning-board) — step-by-step board creation from scratch
* [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) — full reference for all widget parameters
* [Configure Plans (Columns)](/planningboard/guides/configuration/plans-configuration) — customise which Plans appear as columns
* [Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration) — configure swimlane assignment type and sorting
* [Use Plan Templates](/planningboard/guides/planning/plan-templates) — configure the Template ID for new Plans created from the board
* [License Installation](/planningboard/getting-started/licensing) — if the setup page shows a license warning
**KB Articles**
* Planningboard: Customizable Statistics and Capacity Indicators
* Planningboard Widget Parameters
* How to setup Planningboard into existing projects (based on E-library template)
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
**Source Code**
* `PlanningBoardSetupService.java`
* `PlansMode.java`
* `Config.java`
* `viewSetup.vm`
* `viewLicense.vm`
# Data Scripts
Source: https://learn.nextedy.com/planningboard/guides/advanced/data-scripts
Use data scripts to customise how Nextedy PLANNINGBOARD loads, filters, and transforms work items and plans before they reach the board.
## Overview
Data scripts run server-side during the board rendering lifecycle. They let you intercept the data pipeline — adjusting queries, modifying assignment logic, or reshaping the items that appear in swimlanes and columns — without touching widget parameters.
```text theme={null}
Widget Parameters
|
v
+-------------------+ +-------------------+
| Plan Query | | Work Item Query |
| (plansQuery) | | (query) |
+-------------------+ +-------------------+
| |
v v
+---------------------------------------------------+
| Data Script Hook |
| (runs before data reaches the board renderer) |
+---------------------------------------------------+
|
v
+---------------------------------------------------+
| Board Renderer — swimlanes, cards, capacity bars |
+---------------------------------------------------+
```
## Before You Begin
* You need access to the Planningboard widget configuration on a Polarion LiveDoc or Wiki page.
* Data scripts are Groovy/Velocity expressions evaluated on the Polarion server. Syntax errors surface as board-level error messages; see [Script Errors](/planningboard/guides/troubleshooting/script-errors) for how to diagnose them.
* Review the widget parameters your board already uses — data scripts augment, not replace, them. See [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters).
1. Open the Polarion page containing the Planningboard widget.
2. Enter edit mode and open the widget's parameter panel.
3. Scroll to the **Advanced** section. The script fields are listed there.
**Verify in application**
The exact field label for data scripts in the widget parameter panel — confirm it against the live product before relying on the label shown here.
The following properties from the board configuration control how data is loaded. Data scripts operate within the bounds these properties establish.
| Property | Default | Description |
| ---------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `query` | `NOT *:*` | Lucene query filtering the work items displayed on the board. |
| `plansQuery` | *(none)* | Lucene query filtering which Plans are shown as columns. |
| `plansMode` | `PROJECT_PLANS` | How plans are generated — project plans, SAFe sprints, SAFe program increments, or custom stemming. |
| `assignmentMode` | `ASSIGNEE` | How work items map to swimlanes — `ASSIGNEE`, `ENUM`, `PARENT`, `PROJECT`, `SAFE_TEAM`, `SAFE_TRAIN_TEAM`, `SAFE_PROGRAMS`, or `none`. |
| `resourceField` | *(none)* | Custom field ID used when `assignmentMode` is `ENUM`. |
| `maxItems` | `1000` | Maximum work items loaded per render. |
| `wiType` | *(none)* | Work item type filter (e.g. `task`, `story`, `feature`). |
| `lastPlans` | `1` | Number of past plans to show. |
| `nextPlans` | `5` | Number of upcoming plans to show. |
**Whitespace sensitivity**
Capacity-related configuration properties are whitespace-sensitive. Trailing spaces in property values cause silent miscalculations. Always copy property names exactly as shown — do not add spaces before or after `=` separators.
Data scripts can reference the above properties to apply runtime logic. A typical pattern adjusts the work item query based on context — for example, restricting items to a specific type or excluding resolved items.
**Example: restrict the board to unresolved stories**
```text theme={null}
type:story AND NOT status:resolved
```
Place this expression in the work item **Query** field. This is a Lucene query — not a script — but the same field accepts scripted expressions when page parameters are involved. For dynamic filtering using page parameters, see [Dynamic Filtering with Page Parameters](/planningboard/guides/advanced/dynamic-filtering).
**Example: filter Plans by a date-range expression**
```text theme={null}
template.id:iteration AND dueDate:[NOW-90DAYS TO NOW+90DAYS]
```
Set this in the **Plans** query field. The Plans Type must be set to **Project Plans** (`PROJECT_PLANS`) for a plain Lucene `plansQuery` to take effect; SAFe modes auto-set their own plan filters.
When the Assignment Type is set to **Enumeration Field** (`ENUM`), the board groups cards by an enumeration field. To restrict which enum values appear as swimlanes, use the swimlane filtering options rather than a data script — see [Enumeration Field Swimlanes](/planningboard/guides/swimlanes/enum-swimlanes).
When the Assignment Type is set to **Parent Item** (`PARENT`), the board groups cards under parent work items matched by a Lucene query. Supply that query in the parent-query field.
**Parent Item mode does not support normalization**
`assignmentMode = PARENT` is incompatible with `planCellsMode`. Enabling both produces undefined layout behavior. Use the **Users (Assignee)** (`ASSIGNEE`) or **Enumeration Field** (`ENUM`) mode if you need capacity normalization across swimlanes.
Capacity-aware data loading is controlled by three boolean properties. Set them in the widget parameters panel:
| Property | Default | When to enable |
| ------------------- | ------- | --------------------------------------------------------------------------------------------------- |
| `capacityLoad` | `false` | Enable per-swimlane capacity bars (uses `remainingEstimate` / `initialEstimate` or a custom field). |
| `multiCapacityLoad` | `false` | Enable per-resource capacity across multiple plans simultaneously. |
| `userCapacityLoad` | `false` | Enable user-level capacity when Teams Service is active. |
To use a custom effort field instead of Polarion time-tracking fields, set `capacityField` to the custom field ID (for example, `storyPoints`). The `hoursPerDay` property (default `8`) converts time-based estimates to day units for the capacity bar.
**Teams Service unlocks richer capacity data**
Setting `useTeamsService = true` activates the Teams Service integration, which provides team member lists, per-user capacity, and vacation data. This overrides `plan.capacity` values with team-sourced figures. See [Set Up Teams Service](/planningboard/guides/capacity/teams-service-setup) for the prerequisite configuration.
If the board renders slowly, lower `maxItems` (default `1000`). A tighter `query` or `wiType` filter reduces the working set more precisely than `maxItems` alone.
```text theme={null}
Board load time factors:
maxItems (1000 default)
+
Breadth of query
+
Number of plans (lastPlans + nextPlans)
+
capacityLoad / multiCapacityLoad (extra aggregation)
---> Total render time
```
Reducing `nextPlans` from `5` to `3` — or narrowing `lastPlans` to `0` — noticeably cuts the plan-loading step.
## Verification
After saving the widget with your data script changes:
1. Exit edit mode and let the board reload.
2. Check that the swimlanes and columns show only the expected items.
3. If the board shows an error banner instead of cards, open browser developer tools and look for the script-error message, then consult [Script Errors](/planningboard/guides/troubleshooting/script-errors).
You should now see the board rendering only the work items and Plans that match your query and assignment configuration, with capacity bars (if enabled) reflecting the correct effort totals per swimlane.
**SAFe modes override plansQuery**
When the Plans Type is set to a SAFe value — **SAFe Sprints in Program** (`SAFE_SPRINTS`), **SAFe Sprints in Portfolio** (`SAFE_PFL_SPRINTS`), **SAFe Program Increments in Program** (`SAFE_PIS`), or **SAFe Program Increments in Solution** (`SAFE_SOLUTION`) — the plan filter is determined automatically from the SAFe Solution structure. A manually entered `plansQuery` value is ignored in these modes.
## See Also
* [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) — full property reference
* [Config Scripts](/planningboard/guides/advanced/config-scripts) — board-level configuration scripting
* [Item Scripts](/planningboard/guides/advanced/item-scripts) — per-card scripting for appearance and content
* [Dynamic Filtering with Page Parameters](/planningboard/guides/advanced/dynamic-filtering) — pass runtime values into queries via URL parameters
* [Scripted Page Parameters](/planningboard/guides/advanced/scripted-page-parameters) — derive page parameter values programmatically
* [Configure Plans (Columns)](/planningboard/guides/configuration/plans-configuration) — plan query and column setup
* [Configure Work Items Dataset](/planningboard/guides/configuration/work-items-configuration) — query and type filter options
* [Script Errors](/planningboard/guides/troubleshooting/script-errors) — diagnosing and fixing script failures
**KB Articles**
* Planningboard: Customizable Statistics and Capacity Indicators
* Planningboard Widget Parameters
**Support Tickets**
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
**Source Code**
* `Config.java`
* `viewSetup.vm`
* `PlanningBoardWidgetRenderer.java`
* `PlanningBoardWidget.java`
* `PlanningBoardDataService.java`
# Dynamic Filtering with Page Parameters
Source: https://learn.nextedy.com/planningboard/guides/advanced/dynamic-filtering
Configure a single Nextedy PLANNINGBOARD page that adapts its swimlane filter dynamically based on a page parameter, so different teams or roles can use the same board without maintaining separate per-team pages.
## What you will achieve
By the end of this guide you will have a Planningboard widget that reads a team or role identifier from a Polarion page parameter and applies it as a swimlane filter at load time. Users who need a different team view change the parameter value in the page URL or the page parameter widget — no widget reconfiguration required.
## Prerequisites
* A Planningboard widget already embedded in a Polarion LiveDoc or Wiki page.
* The swimlane **Assignment Mode** set to `ASSIGNEE` or `ENUM` on that widget (page parameters for swimlane filtering apply to these modes).
* If you plan to filter by Nextedy Team work items: the Team work item type ID in your Polarion project must be exactly `team` (hard-coded constraint — see [Common pitfalls](#common-pitfalls)).
***
## How page parameters work with Planningboard
Polarion pages support **page parameters**: named string values passed to every widget on the page. Planningboard reads these values from the page context and can use them to control the swimlane filter (`selectedTeam` or a resource field filter) at render time.
The parameter value is a **string** entered manually (a dropdown enum picker for page parameters is under investigation by the support team — see the note at the end of this page). Plan your parameter names and values to be human-readable, since users will type or copy them.
***
1. Open the LiveDoc or Wiki page that contains the Planningboard widget in **Edit** mode.
2. Insert a **Page Parameters** widget (Polarion built-in) somewhere on the page — typically above the board.
3. Define a parameter. For team-based filtering, a sensible name is `teamId`. Set a default value if you have a primary team.
The page parameter widget stores the name-value pair and exposes it to all other widgets on the same page.
***
Open the Planningboard widget's configuration panel.
### For ASSIGNEE mode — filtering by selected team
Set the **Selected Team** field (`selectedTeam` property) to reference your page parameter using the Polarion page-parameter expression syntax:
```properties theme={null}
selectedTeam = ${pageParam.teamId}
```
Replace `teamId` with the exact parameter name you defined in Step 1.
When `useTeamsService = true` is also enabled, the `selectedTeam` value is matched against the Teams Service team IDs. Ensure the parameter value your users supply matches the team ID exactly (case-sensitive).
### For ENUM mode — filtering by a resource field value
If your swimlanes are driven by an enum field (for example a `team` custom field on work items), set the resource field and then constrain which enum values appear as swimlanes by referencing the page parameter in the **Rows Filter** field:
```properties theme={null}
resourceField = team
rowsFilter = ${pageParam.teamId}
```
**String matching is exact and case-sensitive**
The value entered into the page parameter must match the enum option ID exactly, including casing. A value of `Alpha` will not match an option with ID `alpha`. Communicate the exact expected values to your users.
***
1. Save the page.
2. With the default parameter value in place, the board should load showing only the swimlanes that match.
3. Change the parameter value in the Page Parameters widget to a different team ID and reload — the swimlanes should update to reflect the new value.
**Use a URL parameter to share a pre-filtered view**
Polarion page parameters can also be supplied via the page URL (the exact syntax depends on your Polarion version). This means you can share a URL like `?teamId=beta` with a colleague and they will land directly on the filtered board view.
***
If you want the board to default to a team based on the current user's Polarion role — without the user having to enter anything — add a **Scripted Page Parameter** widget instead of (or alongside) the plain page parameter.
The script reads the current user's roles from the Polarion context and maps them to a team ID:
```javascript theme={null}
// Example: map Polarion role to a team ID
var roleToTeam = {
"team_alpha_member": "alpha",
"team_beta_member": "beta"
};
var roles = $user.getRoles($project.id);
var teamId = "all"; // default when no role matches
for (var i = 0; i < roles.length; i++) {
var mapped = roleToTeam[roles[i]];
if (mapped) { teamId = mapped; break; }
}
teamId; // last expression is the parameter value returned
```
Set the **Output Parameter Name** on the scripted widget to `teamId` so it feeds the same parameter name that the Planningboard widget reads.
See [Scripted Page Parameters](/planningboard/guides/advanced/scripted-page-parameters) for the full scripted widget API and additional examples.
***
## Configuration reference
| Property | Type | Default | Purpose in this guide |
| ----------------- | ------- | ---------- | ------------------------------------------------------------------------ |
| `selectedTeam` | string | `None` | ID of the team to filter swimlanes; accepts `${pageParam.*}` expressions |
| `useTeamsService` | boolean | `false` | Must be `true` when `selectedTeam` refers to a Teams Service team |
| `assignmentMode` | string | `ASSIGNEE` | Set to `ASSIGNEE` for user swimlanes or `ENUM` for field-based swimlanes |
| `resourceField` | string | `None` | Custom field ID used for ENUM-mode swimlane grouping |
***
## Common pitfalls
**Team work item type ID must be exactly `team`**
When using the Nextedy Teams Service integration, the work item type ID for your Team work items must be the literal string `team`. This is a hard-coded constraint in the product. If your project uses a different type ID (e.g. `agile_team`), the Teams Service integration will not locate your team work items correctly. Rename the type or contact support.
**Page parameter type is string — no dropdown picker yet**
Page parameters for swimlane filtering accept only a manually entered string value. An enum picker (dropdown) for page parameters is under investigation by the product team. Until it ships, users must type or paste the exact team or enum ID. Document the valid values prominently on the page (for example, in a text block above the board) to reduce entry errors.
**Parameter expression syntax requires exact casing**
The expression `${pageParam.teamId}` is case-sensitive. If you define the parameter as `TeamId` in Step 1 but reference it as `${pageParam.teamId}`, the value will not be substituted and the filter will be empty or use the literal string. Keep parameter names lowercase and consistent.
***
## You should now see...
After completing these steps:
* The Planningboard loads with swimlanes filtered to the team or resource identified by the current page parameter value.
* Changing the page parameter value (either in the Page Parameters widget or via URL) causes the board to reload showing only the matching swimlanes.
* If you added a scripted parameter, the board defaults automatically to the team matching the current user's role, with no manual entry required.
If swimlanes are not filtering as expected, check: (1) the parameter name in the Page Parameters widget matches exactly the name used in `${pageParam.*}`; (2) the parameter value matches the team ID or enum option ID exactly; (3) `useTeamsService` is set correctly for your assignment mode.
***
## See also
* [Use Page Parameters](/planningboard/guides/configuration/page-parameters) — full reference for Polarion page parameters and Planningboard integration
* [Scripted Page Parameters](/planningboard/guides/advanced/scripted-page-parameters) — role-aware and computed parameter values via Velocity scripts
* [User and Assignee Swimlanes](/planningboard/guides/swimlanes/user-swimlanes) — configuring ASSIGNEE mode swimlanes
* [Enumeration Field Swimlanes](/planningboard/guides/swimlanes/enum-swimlanes) — configuring ENUM mode swimlanes
* [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) — complete widget parameter reference
**KB Articles**
* Planningboard Widget Parameters
* Planningboard: Customizable Statistics and Capacity Indicators
**Support Tickets**
* [#6509](https://support.nextedy.com/helpdesk/tickets/6509)
* [#6309](https://support.nextedy.com/helpdesk/tickets/6309)
**Source Code**
* `Config.java`
* `PlanningBoardViewServlet.java`
* `PlanningBoardWidget.java`
* `PlanningBoardWidgetRenderer.java`
* `PlanningBoardWidgetDependenciesProcessor.java`
# Advanced Configuration
Source: https://learn.nextedy.com/planningboard/guides/advanced/index
Nextedy PLANNINGBOARD exposes a scripting and configuration API that lets you extend the board beyond its built-in widget parameters.
**Before using advanced features**
Familiarity with widget parameters and swimlane configuration is assumed. If you are new to Planningboard, start with [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) and [Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration) before working through this section.
## Topics in This Section
**[Item Scripts](/planningboard/guides/advanced/item-scripts)** — Write JavaScript expressions that run per card to control labels, colors, and field values rendered on each work item card.
**[Config Scripts](/planningboard/guides/advanced/config-scripts)** — Write server-side scripts that dynamically compute widget configuration at load time, allowing board layout to adapt to context, user, or project state.
**[Data Scripts](/planningboard/guides/advanced/data-scripts)** — Write server-side scripts that shape the work item dataset the board loads, enabling custom filtering, sorting, or data enrichment beyond the standard Plan query.
**[Template Functions](/planningboard/guides/advanced/template-functions)** — Use the built-in template function library available inside item scripts and config scripts to format field values, resolve enumerations, and compose card content.
**[Dynamic Filtering with Page Parameters](/planningboard/guides/advanced/dynamic-filtering)** — Pass Polarion page parameters into the board widget at runtime to drive swimlane filters, Plan queries, or dataset scope without hardcoding values in the widget configuration.
**[Read-Only Mode](/planningboard/guides/advanced/read-only-mode)** — Configure the board for viewing without drag-and-drop or edit permissions, suitable for stakeholder dashboards and embedded reporting pages.
**[Custom Project Templates](/planningboard/guides/advanced/custom-templates)** — Package a Planningboard widget configuration as a reusable project template so new projects start with a consistent board setup.
**[Scripted Page Parameters](/planningboard/guides/advanced/scripted-page-parameters)** — Generate page parameter values programmatically using scripts, extending the dynamic filtering pattern to computed or user-context-derived inputs.
## Script Execution Overview
## Related Troubleshooting
Script errors surface as board-level warnings or empty boards. See [Script Errors](/planningboard/guides/troubleshooting/script-errors) for diagnosis steps.
**KB Articles**
* Planningboard Widget Parameters
* Planningboard: Customizable Statistics and Capacity Indicators
* Planningboard interface & basic interactions
**Support Tickets**
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
**Source Code**
* `Config.java`
* `viewSetup.vm`
* `Item.java`
* `PlanningBoardWidgetRenderer.java`
* `widget.vm`
# Item Scripts
Source: https://learn.nextedy.com/planningboard/guides/advanced/item-scripts
Use item scripts to apply dynamic logic to individual work item cards on the Nextedy PLANNINGBOARD — controlling appearance, filtering, or computed values based on card data at render time.
## What Item Scripts Do
Item scripts run against each card as the board renders. They let you express per-card logic that goes beyond static widget parameters — for example, highlighting cards based on field combinations, computing derived labels, or conditionally hiding cards that match a specific state.
Item scripts operate at the card level. For board-wide configuration logic (selecting Plans, adjusting swimlane rules, or loading alternate data sets), see [Config Scripts](/planningboard/guides/advanced/config-scripts) and [Data Scripts](/planningboard/guides/advanced/data-scripts) instead.
## Prerequisites
Before writing an item script:
* The Planningboard widget must already be embedded in a Polarion LiveDoc or Wiki page.
* You must have edit access to the page containing the widget.
* Confirm the widget parameter that accepts the script is available in your installed version.
## How Item Scripts Are Applied
The board evaluates the item script once per card, passing the work item as the script's input context. The script can return values that modify how the card is displayed — for example, a CSS class name or a computed label.
```text theme={null}
Board renders
|
v
For each card (work item):
|
+---> Item script runs with work item context
|
+---> Script returns value (class, label, flag)
|
v
Card rendered with script result applied
```
This per-card evaluation means item scripts must be efficient — they run for every card in the visible board, not once globally.
1. Navigate to the LiveDoc or Wiki page containing the Planningboard widget.
2. Switch the page to **Edit** mode.
3. Click the widget to select it, then open its parameter editor (the gear or edit icon shown in the widget toolbar).
In the widget parameter editor, look for the parameter that accepts JavaScript expressions or script content for item-level logic.
**Parameter name casing is exact**
Widget parameter names are case-sensitive. Use the exact parameter name as it appears in the editor. Incorrect casing silently produces no effect — the parameter is ignored rather than raising an error.
Item scripts are written as JavaScript expressions. The work item is available as a context object. Access its fields using the field IDs defined in your Polarion project.
**Example — apply a CSS class based on priority:**
```javascript theme={null}
if (item.fields.priority && item.fields.priority.id === 'high') {
return 'highlight-high-priority';
}
return '';
```
**Example — flag items planned past their due date:**
```javascript theme={null}
var due = item.fields.dueDate;
var planned = item.fields.plannedEnd;
if (due && planned && planned > due) {
return 'overdue-card';
}
return '';
```
**Use exact field IDs**
Field IDs in scripts must match the IDs configured in your Polarion project — for example, `priority`, `dueDate`, `plannedEnd`. Wrong field IDs return `undefined` silently. Verify field IDs in **Administration > Work Items > Custom Fields** or in the work item form layout.
The value your script returns is applied to the card. How it is used depends on what the script parameter controls:
| Return value type | Typical use |
| ------------------------ | ----------------------------------------------------------- |
| CSS class name string | Applied to the card element for styling via custom CSS |
| Boolean (`true`/`false`) | Show or hide the card, or toggle a visual state |
| String label | Displayed as an overlay, badge, or tooltip text on the card |
| Empty string `''` | No modification — card renders with default appearance |
**Returning undefined stops rendering**
If your script throws an error or returns `undefined`, the card may render without the expected modification — or may not render at all, depending on how the parameter is used. Always return a default value (such as `''`) from all code paths.
1. Save the widget parameter editor.
2. Save the page.
3. Reload the board.
You should now see cards that match your script condition rendered differently from the rest — for example, highlighted with the CSS class you returned, or filtered from the board.
**Test with a single condition first**
When writing a new item script, start with a condition that matches exactly one card you can visually identify. Confirm the expected card is affected before adding more complex logic.
## Common Pitfalls
**Whitespace in parameter values**
Configuration parameters in Planningboard are whitespace-sensitive. If you paste a script with leading or trailing whitespace into a parameter field, the parameter may not parse correctly. Trim the script content before saving.
**Script errors are silent by default**
If an item script throws a JavaScript runtime error, the board may silently fall back to the default card appearance without surfacing the error in the UI. Check your browser's developer console for JavaScript errors if a script produces no visible effect.
**Swimlane sort order is coupled to item sort order**
Item scripts that modify card appearance do not affect swimlane sort order. Swimlane ordering is governed by the board's sort configuration, not by per-card script results. If you need to reorder swimlanes, adjust the sort parameters in the widget configuration instead. See [Sort Swimlanes](/planningboard/guides/swimlanes/sorting-swimlanes).
## Configuration Example
The following shows a complete item script parameter scenario: a board scoped to a project's stories, where cards in `Open` status that have no assignee should be visually flagged.
```javascript theme={null}
// Flag unassigned open items
var status = item.fields.status && item.fields.status.id;
var assignee = item.fields.assignee;
if (status === 'open' && !assignee) {
return 'unassigned-open';
}
return '';
```
Pair this with a custom CSS rule in your Polarion page or skin to apply a visible border or background tint to cards that receive the `unassigned-open` class.
## Verification
After saving the widget and reloading the board:
* Cards matching your condition should render with the visual change your script produces (class applied, label shown, or card hidden).
* Cards not matching the condition should render exactly as before.
* Open the browser developer console — there should be no JavaScript errors related to the item script.
If the script has no visible effect and there are no console errors, double-check the exact parameter name in the widget editor and confirm the field IDs used in the script match those in your Polarion project.
## See Also
* [Config Scripts](/planningboard/guides/advanced/config-scripts) — board-level scripted configuration
* [Data Scripts](/planningboard/guides/advanced/data-scripts) — scripted data loading and transformation
* [Template Functions](/planningboard/guides/advanced/template-functions) — reusable functions for card templates
* [Highlight Work Items by Rules](/planningboard/guides/customization/highlighting-rules) — rule-based highlighting without scripting
* [Customize Card Appearance](/planningboard/guides/customization/card-appearance) — static card appearance options
* [Script Errors](/planningboard/guides/troubleshooting/script-errors) — diagnosing and resolving script issues
* [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) — full list of configurable widget parameters
**KB Articles**
* Planningboard: Customizable Statistics and Capacity Indicators
* Planningboard Widget Parameters
**Support Tickets**
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
**Source Code**
* `Config.java`
* `viewSetup.vm`
* `PlanningBoardWidgetRenderer.java`
* `PlanningBoardDataService.java`
* `PlanningBoardWidget.java`
# Read-Only Mode
Source: https://learn.nextedy.com/planningboard/guides/advanced/read-only-mode
Enable read-only mode on a Nextedy PLANNINGBOARD instance so stakeholders and unlicensed users can view the board without being able to modify plans or move cards.
## How read-only mode works
Planningboard enforces read-only access automatically for users who do not hold a Planningboard license. When a user without a license opens a board, the following restrictions apply:
* **Drag and drop is blocked** — cards cannot be dragged between swimlanes or into plans; any drag attempt leaves the card in its original position and no change is persisted.
* **Create New Plan button is hidden** — the toolbar button that creates a new plan (`#btnCreateNewPlan`) is not shown.
* **Show Unplanned button is hidden** — the toggle that opens the unplanned sidebar (`#btnShowUnplanned`) is not shown.
* **Sidebar panel is hidden** — the editing sidebar (`#sidebar`) is not accessible.
Read-only users retain full **visibility** of the board: they can see all cards, swimlanes, capacity bars, and calendar data exactly as licensed planners see them.
Read-only access is license-driven, not a widget parameter. Determine which users in your Polarion instance should view-only:
1. Open **Administration > Nextedy PLANNINGBOARD > License**.
2. Review the list of assigned license seats.
3. Users not assigned a seat will automatically see the board in read-only mode.
**Share board links with stakeholders**
You can share the direct URL of a Planningboard Wiki page or LiveDoc with stakeholders who do not need a license. They will see the full board view — all swimlanes, cards, and capacity bars — without any risk of accidental edits.
Read-only users must be able to open the page where the board widget is embedded. Check that:
* The Polarion project is accessible to the user (project visibility and role).
* The Wiki page or LiveDoc containing the widget is readable by the user.
* No Polarion Document or Space ACL blocks the user from viewing the page.
**Polarion ACLs are separate from license seats**
A user without a Planningboard license can still be blocked from viewing the board entirely if Polarion's Document ACL or Space ACL denies read access to the page. Ensure the page and its space grant at least **Read** access to the intended audience. The SVN Repository ACL (Administration > Repositories) is an independent layer and must also permit read access.
After a read-only user opens the board:
1. Ask them (or test with a non-licensed account) to attempt dragging a card to a different swimlane or plan column.
2. The card should return to its original position and no change should be saved.
3. The **Create New Plan** and **Show Unplanned** toolbar buttons should not be visible.
4. The sidebar should not appear when clicking a card.
**Board refresh is always available**
Even in read-only mode, the **Refresh** button (↺) remains visible. Read-only users can use it to reload the current board state from the server at any time.
If a licensed user makes changes while a read-only user is viewing the board, the read-only user will not see those changes automatically. They must click the **Refresh** button to reload the board state from the server.
## Decision matrix — read-only vs. licensed access
| Capability | Read-only user | Licensed user |
| ---------------------------- | -------------- | ------------- |
| View swimlanes and cards | Yes | Yes |
| View capacity bars | Yes | Yes |
| View calendar / plan columns | Yes | Yes |
| Drag cards between swimlanes | No | Yes |
| Open unplanned sidebar | No | Yes |
| Create a new plan | No | Yes |
| Use the editing sidebar | No | Yes |
| Refresh board state | Yes | Yes |
## Limitations
* Read-only mode is enforced at the **license level only** — there is no widget parameter to force read-only mode for licensed users. If you need to lock down editing for a licensed user, manage access at the Polarion role or page ACL level.
* There is no visual indicator on the board that tells a read-only user they are in read-only mode beyond the absence of the edit controls.
## You should now see...
After following these steps, unlicensed users who open the board should see all planning data — swimlanes, cards, capacity bars, and plan columns — but find that the **Create New Plan** and **Show Unplanned** buttons are absent from the toolbar, the sidebar does not open, and any drag attempt leaves cards in their original positions.
## See also
* [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) — full list of widget parameters for controlling board behavior
* [Basic Board Interactions](/planningboard/getting-started/basic-interactions) — overview of board interactions available to all users
* [License Installation](/planningboard/getting-started/licensing) — how to install and manage Planningboard license seats
* [Drag and Drop Issues](/planningboard/guides/troubleshooting/drag-and-drop-issues) — troubleshoot cases where drag and drop is unexpectedly blocked
**KB Articles**
* Planningboard Widget Parameters
* Planningboard: Customizable Statistics and Capacity Indicators
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
**Source Code**
* `planningboard.js`
* `Config.java`
* `viewSetup.vm`
* `PlansMode.java`
* `licenseReadonly.cy.ts`
# Scripted Page Parameters
Source: https://learn.nextedy.com/planningboard/guides/advanced/scripted-page-parameters
Use Polarion Scripted Page Parameters to drive Nextedy PLANNINGBOARD widget properties dynamically — eliminating hardcoded values and letting a single board page adapt to the current user, role, or team.
## What this guide covers
Polarion's Scripted Page Parameters (documented in the Polarion Widget SDK, section 7.2) let a Wiki page compute parameter values at render time using a server-side script. When combined with Planningboard's widget parameters — such as `selectedTeam`, `assignmentMode`, or swimlane filters — this means one board page can serve multiple teams or roles without duplicating the page for every audience.
A common scenario: your project has several teams and you want each team member who opens the board to see only their own swimlane, without an administrator manually maintaining ten near-identical pages.
## Prerequisites
* Planningboard is installed and a board widget is already embedded on a Polarion Wiki page.
* You have Wiki page edit permissions in Polarion.
* You understand the basic Planningboard widget parameters. See [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) and [Use Page Parameters](/planningboard/guides/configuration/page-parameters).
***
A Scripted Page Parameter is a page-level script block that Polarion evaluates before rendering the page. The script produces a map of key/value pairs. Those values are then available to any widget on the page as named parameters — exactly as if a user had typed them into the widget's parameter editor.
The script has access to the Polarion server context, including the current user object and their roles and group memberships. This is what enables role-aware or team-aware board filtering.
***
Open the Wiki page that contains your Planningboard widget for editing. In the page source, add a Scripted Page Parameters block **before** the widget macro. In Polarion Wiki markup, this is a `module-scriptedparams` macro or an equivalent script block — refer to your Polarion version's Widget SDK for the exact syntax.
The script block returns a `Map`. Each key becomes a named parameter you can reference in widget configuration.
Example: mapping the current user's role to a team ID:
```javascript theme={null}
// Scripted Page Parameters script — runs server-side at page load
def user = polarionContext.user
def teamId = "unassigned"
if (user.hasRole("team-alpha")) {
teamId = "alpha"
} else if (user.hasRole("team-beta")) {
teamId = "beta"
} else if (user.hasRole("team-gamma")) {
teamId = "gamma"
}
return ["boardTeam": teamId]
```
This produces the parameter `boardTeam` with a value derived from the current user's Polarion role — no role IDs are exposed to end users.
**Role ID casing is exact**
Polarion role IDs are case-sensitive. Use the exact role ID string as it appears in **Administration > Roles**, not the display label. A mismatch produces no error — the condition simply never matches, and the parameter falls back to your default value.
***
Once the script produces a named parameter, reference it inside the Planningboard widget configuration using Polarion's standard `${paramName}` substitution syntax.
For example, to pass `boardTeam` into the `selectedTeam` widget property:
| Widget property | Value |
| --------------- | -------------- |
| `selectedTeam` | `${boardTeam}` |
You can use the same parameter in multiple widget properties. For instance, you could drive both the `selectedTeam` and a plan query filter from the same scripted value.
**Use a safe default in the script**
Always initialise the output variable before the conditional logic (as shown in Step 2). If no role condition matches, the widget receives the default value rather than an empty or null string, which could cause unexpected board behaviour.
***
The `plansQuery` property accepts a Lucene query string and also supports `${param}` substitution. This lets the script constrain which Plans appear as columns for the current user.
Example: show only plans belonging to the user's team prefix:
```javascript theme={null}
// Script
def user = polarionContext.user
def planPrefix = "all"
if (user.hasRole("team-alpha")) {
planPrefix = "alpha"
} else if (user.hasRole("team-beta")) {
planPrefix = "beta"
}
return ["teamPlanPrefix": planPrefix]
```
Widget configuration:
| Widget property | Value |
| --------------- | ----------------------- |
| `plansQuery` | `id:${teamPlanPrefix}*` |
When `teamPlanPrefix` resolves to `alpha`, the board loads only Plans whose ID starts with `alpha`.
**Whitespace in query values breaks Lucene**
If your scripted value might contain spaces (e.g. a team name used directly in a query), wrap it in quotes inside the query string: `id:"${teamPlanPrefix}"`. Unquoted spaces split the Lucene term and produce unexpected results. Capacity configuration parameters are also whitespace-sensitive — test with values that include spaces before deploying.
***
When your board uses the Teams Service (`useTeamsService = true`), the `selectedTeam` property determines which team's capacity is loaded. Driving this from a scripted parameter means the capacity bar automatically reflects the current user's team without them selecting it manually.
| Widget property | Value |
| ----------------- | -------------- |
| `useTeamsService` | `true` |
| `selectedTeam` | `${boardTeam}` |
For background on the Teams Service and capacity configuration, see [Set Up Teams Service](/planningboard/guides/capacity/teams-service-setup) and [Track Team Capacity](/planningboard/guides/capacity/team-capacity).
***
## Configuration example — single board, three teams
The following shows the complete setup for a project with three teams (`alpha`, `beta`, `gamma`), each with a matching Polarion role:
**Scripted Page Parameters script:**
```javascript theme={null}
def user = polarionContext.user
def teamId = "all"
def planPrefix = "all"
if (user.hasRole("team-alpha")) {
teamId = "alpha"
planPrefix = "alpha"
} else if (user.hasRole("team-beta")) {
teamId = "beta"
planPrefix = "beta"
} else if (user.hasRole("team-gamma")) {
teamId = "gamma"
planPrefix = "gamma"
}
return [
"boardTeam": teamId,
"teamPlanPrefix": planPrefix
]
```
**Planningboard widget properties (relevant excerpt):**
| Property | Value |
| ----------------- | ----------------------- |
| `useTeamsService` | `true` |
| `selectedTeam` | `${boardTeam}` |
| `plansQuery` | `id:${teamPlanPrefix}*` |
| `assignmentMode` | `ASSIGNEE` |
With this configuration, a user holding the `team-alpha` role sees only `alpha*` Plans as columns and the capacity bar reflects the alpha team's capacity. Users with no matching role see all Plans (`id:all*`) — adjust the fallback to your project's needs.
***
## Common pitfalls
**Parameter not defined results in literal `${paramName}` on the board**
If the scripted parameter block fails to execute or the key is misspelled, Polarion passes the raw `${boardTeam}` string to the widget. The board may load with an unresolved query. Check the page script for syntax errors and confirm the parameter name matches exactly (case-sensitive) between the script return map and the widget property value.
**Script errors are silent to end users**
A runtime error in the script block may silently return an empty map, leaving all widget properties that depend on scripted values unresolved. Enable Polarion server logging during setup, or add a fallback default before every return statement.
**Test with a fixed parameter first**
Before wiring up the full role-to-value logic, hardcode a known-good value in the script and confirm the widget responds correctly. Once the widget reads the parameter as expected, replace the hardcoded value with the conditional logic.
***
## Verification
After saving the page and refreshing in a browser:
1. Open the board as a user who holds one of the mapped roles.
2. Confirm the columns show only the Plans matching that team's prefix.
3. If `useTeamsService` is enabled, confirm the capacity bar reflects that team's capacity.
4. Open the board as a second user with a different role and verify the board shows a different set of Plans.
You should now see the board adapting its content to each user's role without any manual filter selection.
***
## See also
* [Use Page Parameters](/planningboard/guides/configuration/page-parameters) — static page parameters without scripting
* [Dynamic Filtering with Page Parameters](/planningboard/guides/advanced/dynamic-filtering) — URL-driven parameter patterns
* [Configure Plans (Columns)](/planningboard/guides/configuration/plans-configuration) — `plansQuery` and Plans Mode options
* [Set Up Teams Service](/planningboard/guides/capacity/teams-service-setup) — prerequisite for `selectedTeam` and capacity filtering
* [Config Scripts](/planningboard/guides/advanced/config-scripts) — server-side scripts that modify the full board configuration object
* [Script Errors](/planningboard/guides/troubleshooting/script-errors) — diagnosing failures in scripted page parameter blocks
**KB Articles**
* Planningboard Widget Parameters
* Planningboard: Customizable Statistics and Capacity Indicators
**Support Tickets**
* [#6509](https://support.nextedy.com/helpdesk/tickets/6509)
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
**Source Code**
* `Config.java`
* `viewSetup.vm`
* `PlanningBoardViewServlet.java`
* `PlanningService.java`
* `PlanningBoardWidget.java`
# Template Functions
Source: https://learn.nextedy.com/planningboard/guides/advanced/template-functions
Use Nextedy PLANNINGBOARD's built-in template variables to generate dynamic URLs for plan column headers and swimlane labels, enabling direct navigation to related reports, plans, and resources from the board.
## What You Can Parametrize
Planningboard exposes two report-link parameters — one for Plan columns and one for swimlane rows. Both accept a URL string with embedded template variables that are resolved at render time.
| Parameter | Scope | Template variables available |
| ------------ | ------------------- | ------------------------------------------------------- |
| `planLink` | Plan column headers | `${plan.objectId.projectId}`, `${plan.objectId.itemId}` |
| `reportLink` | Swimlane row labels | `${r.objectId.itemId}` |
The resolved URL is opened when a user clicks the column label or swimlane label on the board.
1. Open the Planningboard widget parameter editor (click **Edit Parameters** in the board toolbar or edit the page in Polarion).
2. Scroll to the **Parameters for Plans (Columns)** section.
3. Locate the **Report Link** field.
4. Enter a URL template using `${plan.objectId.projectId}` and `${plan.objectId.itemId}` to reference the plan bound to that column.
**Example** — link each plan column to its Polarion plan detail page:
```
/polarion/#/project/${plan.objectId.projectId}/plan?id=${plan.objectId.itemId}
```
**Example** — link each plan column to a Wiki report page filtered by plan:
```
/polarion/#/project/${plan.objectId.projectId}/wiki/SOME_REPORT?plan=${plan.objectId.itemId}
```
The variable `${plan.objectId.projectId}` resolves to the Polarion project ID (e.g. `MyProject`). The variable `${plan.objectId.itemId}` resolves to the Plan ID (e.g. `Iteration_4`).
Use this link to open a sprint burndown or velocity report that is pre-filtered to the plan in that column — users can navigate directly from the board without manually setting filters.
1. In the widget parameter editor, scroll to the **Swimlanes (Rows)** section.
2. Locate the **Report Link** field under swimlane configuration.
3. Enter a URL template using `${r.objectId.itemId}` to reference the resource (user, team, or enum value) bound to that swimlane.
**Example** — link each user swimlane to a wiki report filtered by user:
```
/polarion/#/project/PlanningBoard/wiki/SOME_REPORT?user=${r.objectId.itemId}
```
The variable `${r.objectId.itemId}` resolves to the resource identifier for the swimlane — typically a Polarion user ID when the swimlane assignment type is user/assignee-based.
The `${r.objectId.itemId}` variable resolves to the resource identifier for the current swimlane assignment type. If you switch assignment type (for example from **Users (Assignee)** to **Enumeration Field**), the resolved value changes accordingly — verify the link target is still meaningful for the new assignment type.
1. Save the widget parameters and reload the board page.
2. Click a **column header** (plan label) — the browser should open the URL you configured, with the `${plan.*}` variables replaced by the actual plan's project ID and item ID.
3. Click a **swimlane label** — the browser should open the URL with `${r.objectId.itemId}` replaced by the resource identifier for that row.
You should now see the report or target page open with the correct plan or user filter already applied, with no manual parameter entry needed.
## Reference: Template Variable Summary
## Common Pitfalls
**Hardcoded project ID breaks cross-project boards.** If you hard-code a project ID in the URL instead of using `${plan.objectId.projectId}`, the link will navigate to the wrong project when the board is used in a different project context. Always use the template variable.
**URL must be an absolute Polarion path.** The Report Link value is rendered as an `href` directly. Relative paths (without a leading `/polarion/`) may not resolve correctly depending on the browser's current path. Start links with `/polarion/#/project/...`.
When building the link URL, test the target page first by navigating to it manually in Polarion, then copy the URL and replace the static plan/user IDs with the corresponding template variables.
## See Also
* [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) — full reference for all widget parameters including Report Link fields
* [Configure Plans (Columns)](/planningboard/guides/configuration/plans-configuration) — set up which Plans appear as columns
* [Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration) — set up swimlane assignment type and row configuration
* [Use Page Parameters](/planningboard/guides/configuration/page-parameters) — pass dynamic values into the board from the Polarion page URL
* [Dynamic Filtering with Page Parameters](/planningboard/guides/advanced/dynamic-filtering) — filter the board using URL-level parameters
**KB Articles**
* Planningboard Widget Parameters
* Planningboard: Customizable Statistics and Capacity Indicators
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
**Source Code**
* `viewSetup.vm`
* `Config.java`
* `viewLicense.vm`
* `PlanningBoardWidgetRenderer.java`
* `PlanningBoardSetupService.java`
# Normalize Capacity Across Swimlanes
Source: https://learn.nextedy.com/planningboard/guides/capacity/capacity-normalization
Enable capacity normalization so each swimlane's capacity bar reflects the actual availability of its assigned users rather than a flat plan-level value.
## What you will achieve
After completing this guide, each swimlane on your Nextedy PLANNINGBOARD will display a capacity bar that accurately accounts for individual user availability within the plan's date range. Over-allocated users will be flagged visually, and users with no capacity in the current plan window will be suppressed from the board.
## Prerequisites
* Planningboard is installed and a board is already configured on a Polarion Wiki page or LiveDoc.
* Swimlane assignment type is set to **Users (Assignee)**. Capacity normalization works at the per-user level; it requires user-based swimlanes.
* Teams Service is set up with at least one team, team members, and a calendar. See [Set Up Teams Service](/planningboard/guides/capacity/teams-service-setup).
* At least one Polarion Plan with a start date and due date is visible on the board.
For swimlane-based normalization, your Polarion Plan IDs must follow a consistent pattern such as `Iteration_{planNum}-{teamName}` (e.g. `Iteration_5-alpha`). This naming convention is what allows Planningboard to group plans by iteration number across teams:
Work items must also have an enumeration custom field that identifies the team (for example, a field named `team`). Planningboard uses this field to map each work item to its swimlane:
**Limitations — read before proceeding**
Planningboard capacity tracking has the following confirmed limitations compared to Nextedy GANTT:
* **No multi-assignee support.** If a work item has multiple assignees, capacity is not distributed across them. Only the primary assignee is counted.
* **No sub-item effort distribution.** Effort from child work items is not rolled up to the parent for capacity calculations. Configure `capacityLoad` at the work-item level that holds the estimates.
* **Whitespace-sensitive configuration.** Configuration property values must have no leading or trailing whitespace. A single extra space will silently prevent the feature from activating.
***
Capacity normalization depends on data from the Teams Service. Before configuring normalization, confirm that user capacity is flowing through correctly.
Open the board and inspect the capacity bar in any swimlane. If the bar shows `0 / 0` for all users, the Teams Service is either not configured or not returning calendar data for the current plan range.
Refer to [Track User Capacity](/planningboard/guides/capacity/user-capacity) and [Track Team Capacity](/planningboard/guides/capacity/team-capacity) to confirm the prerequisite setup is in place.
***
In the Widget Parameters panel, locate **Capacity** and confirm the `useTeamsService` parameter is enabled. This parameter connects the board to the Teams Service, which supplies `totalCapacity`, `allocatedCapacity`, and `availableCapacity` per user per plan.
```text theme={null}
Capacity
└─ Use Teams Service: ✓ (enabled)
```
When `useTeamsService` is active, the plan's flat `capacity` value is replaced by per-user capacity values derived from the team calendar and the percentage assignment for each user.
In the same Widget Parameters panel, also confirm that the **Swimlanes (Rows)** section is set to use the team enumeration field. Set Assignment Type to **Enumeration Field** and enter the field ID (for example, `team`):
Finally, enable the **Normalization** option in the widget parameters. Under the **Normalization** section, set **Use Normalization by Swimlane** to **Yes**:
Users who have no team calendar entry for the plan's date range will default to `totalCapacity = 0.0`. Their swimlane will show zero available capacity but will still appear on the board unless you also enable Plan Range filtering (see Step 4).
***
In the Widget Parameters panel, set the **Capacity Load** mode. Planningboard derives effort from `remainingEstimate` / `initialEstimate` time-tracking fields by default. If your team uses a custom field for effort points, specify it here.
```text theme={null}
Capacity
└─ Capacity Load: remainingEstimate (or your custom field ID)
```
The `setEffort` calculation produces three values per work item:
| Value | Meaning |
| ------------ | -------------------------------------------------------------------------- |
| `effort` | Total estimate (initial or custom field value) |
| `effortDone` | For resolved items, equals `effort`; for open items, 0 |
| `effortTodo` | Remaining work (`remainingEstimate` or custom field; 0 for resolved items) |
Effort values are rounded to one decimal place. Ensure the field you reference holds numeric values in the same unit as your team calendar (hours or story points, whichever the Teams Service is configured to use).
**Whitespace in field IDs**
Configuration parameters are whitespace-sensitive. Do not include spaces around the field ID value. `remainingEstimate ` (trailing space) will not resolve to the correct field.
***
When a plan covers a short iteration and some team members have assignments only outside that window, their swimlanes contribute noise. Enable Plan Range filtering to show only users with active capacity in the currently displayed plans.
Go to **Polarion Administration → Configuration Properties** and add:
```properties theme={null}
nextedy.planningboard.activeTeamAssignmentsInPlanRangeOnly=true
```
Once applied:
* Users with team assignments overlapping the displayed plan range are shown.
* Users with assignments entirely outside the plan range are hidden.
* Work items previously assigned to hidden users are moved to the **Not Assigned / Other** swimlane.
**Property not taking effect?**
If the property appears not to apply after saving, make a trivial edit to any other Configuration Property (add and remove a space) and save again. This forces Polarion to flush and re-read the configuration.
**Deprecated alternative**
An earlier property `nextedy.planningboard.activeTeamAssignmentsOnly=true` (introduced in version 25.3.0) hid only *past* assignments and was independent of the displayed plan scope. It was deprecated in version 25.12.0. Use `activeTeamAssignmentsInPlanRangeOnly` instead.
***
After the configuration above is in place, each swimlane capacity bar reflects:
```text theme={null}
availableCapacity = totalCapacity − allocatedCapacity
```
Where:
* **`totalCapacity`** — hours derived from the team calendar for the plan's start-to-due-date window, multiplied by the user's percentage assignment.
* **`allocatedCapacity`** — sum of `remainingEstimate` (or custom field) for all work items assigned to the user within the plan.
* **`availableCapacity`** — the remaining headroom. A **negative value indicates overallocation**.
The board displays this as a progress bar inside each swimlane header. An overallocated swimlane will appear filled beyond 100%.
***
## Capacity flow at a glance
***
## Common pitfalls
**User shows `0 / 0` capacity**
The user has no team calendar entry covering the plan's date range. Either add a calendar record in the Teams Service for that period, or enable `activeTeamAssignmentsInPlanRangeOnly=true` to hide such users automatically.
**Capacity bar does not update after reassigning a work item**
Refresh the board using the **Refresh** button to reload capacity totals from the server. Capacity is calculated server-side and is not recalculated live on drag-and-drop.
**All swimlanes show identical capacity**
If `useTeamsService` is disabled or misconfigured, Planningboard falls back to the plan's flat `capacity` value, applying it uniformly to all swimlanes. Verify the Teams Service integration and confirm the parameter is saved correctly with no whitespace.
**Multi-dimensional capacity**
If your team tracks capacity across multiple dimensions (for example, separate front-end and back-end budgets per plan), see [Configure Multi-Dimensional Capacity](/planningboard/guides/capacity/multi-capacity) for the `multiCapacityLoad` parameter, which provides per-swimlane capacity breakdowns using a keyed capacity map.
***
## Verification
You should now see:
1. Each user swimlane displays a capacity bar with distinct values — not identical values across all swimlanes.
2. Users without team assignments in the current plan range are absent from the board (if `activeTeamAssignmentsInPlanRangeOnly=true` is set).
3. Overallocated swimlanes show a filled or overflowing capacity bar.
4. The **Not Assigned / Other** swimlane contains any work items that belonged to now-hidden users.
If capacity bars still show identical values or zeros, review [Capacity Calculation Issues](/planningboard/guides/troubleshooting/capacity-issues) for diagnostic steps.
***
## See also
* [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration)
* [Track Team Capacity](/planningboard/guides/capacity/team-capacity)
* [Track User Capacity](/planningboard/guides/capacity/user-capacity)
* [Visualize Capacity Load](/planningboard/guides/capacity/capacity-visualization)
* [Configure Multi-Dimensional Capacity](/planningboard/guides/capacity/multi-capacity)
* [Set Up Teams Service](/planningboard/guides/capacity/teams-service-setup)
* [Filter Swimlanes by Plan Range](/planningboard/guides/swimlanes/filtering-by-plan-range)
* [Capacity Calculation Issues](/planningboard/guides/troubleshooting/capacity-issues)
**KB Articles**
* What is 'Normalization'
* Swimlane Assignment Types
* Filter user swimlanes by Plan range
**Support Tickets**
* [#6777](https://support.nextedy.com/helpdesk/tickets/6777)
* [#6605](https://support.nextedy.com/helpdesk/tickets/6605)
* [#4714](https://support.nextedy.com/helpdesk/tickets/4714)
**Source Code**
* `PlanningBoardDataService.java`
* `PlanningBoardWidget.java`
* `planningboard.js`
* `capacityHelperData.cy.ts`
* `AssignmentMode.java`
# Visualize Capacity Load
Source: https://learn.nextedy.com/planningboard/guides/capacity/capacity-visualization
Learn how to display capacity bars and per-user load indicators on the Nextedy PLANNINGBOARD so your team can spot overallocation at a glance during sprint and release planning.
## Prerequisites
Before enabling capacity visualization, ensure the following are in place:
* The Teams Service is configured and your project has at least one team with members and a calendar. See [Set Up Teams Service](/planningboard/guides/capacity/teams-service-setup).
* Team members have remaining estimates on their assigned work items.
* You have access to edit the widget parameters on your Planningboard page.
## How Capacity Is Calculated
Planningboard computes capacity from two sources:
| Source | What it provides |
| ----------------------------- | ----------------------------------------------------------------------------------- |
| Team calendar | Total available hours per user for the Plan period (`totalCapacity`) |
| Work item remaining estimates | Sum of remaining estimates assigned to a user within the Plan (`allocatedCapacity`) |
The formula applied per user:
```text theme={null}
availableCapacity = totalCapacity - allocatedCapacity
```
Negative `availableCapacity` means the user is overallocated. Users without a team calendar entry default to `totalCapacity = 0.0`, which causes them to appear immediately overallocated if any work is assigned.
## Capacity Visualization Modes
Planningboard supports three capacity visualization modes, controlled by widget parameters:
| Parameter | Type | Default | Purpose |
| ------------------- | ------- | ------- | ----------------------------------------------------------------- |
| `capacityLoad` | boolean | `false` | Shows aggregate capacity progress bar per Plan column |
| `userCapacityLoad` | boolean | `false` | Shows per-user capacity in summary cells (requires Teams Service) |
| `multiCapacityLoad` | boolean | `false` | Shows per-resource capacity in each swimlane cell |
You can enable these modes individually or in combination. Note that `multiCapacityLoad` requires `capacityLoad` to also be `true` — it does not take effect on its own.
Column-level capacity bars show the aggregate load across all users for each Plan column. This is the simplest mode and requires no Teams Service.
1. Open the Polarion page that contains your Planningboard widget.
2. Click **Edit** to enter page editing mode.
3. Open the widget parameters editor for your Planningboard widget.
4. Set the `capacityLoad` parameter to `true`.
5. Set the `capacityField` parameter if your team tracks effort in a custom field (for example, story points). Leave it blank to use Polarion's built-in `remainingEstimate` / `initialEstimate` fields.
6. Set `hoursPerDay` to the number of working hours per day used in calculations (default: `8`).
7. Save the page.
**Custom effort fields**
If your work items carry story points in a custom field (for example `storyPoints`), set `capacityField = storyPoints`. Planningboard will sum that field instead of time estimates. Combine with a matching `hoursPerDay` conversion only when mixing time-based and point-based effort.
Per-user capacity shows each team member's individual allocation and remaining capacity in summary cells on the board. This mode requires the Teams Service and `assignmentMode = ASSIGNEE`.
1. Confirm that `useTeamsService` is set to `true` in your widget parameters.
2. Set `selectedTeam` to the ID of the team you want to display capacity for.
3. Set `userCapacityLoad` to `true`.
4. Save the page.
When configured, the board displays a summary cell per user row. Each summary cell shows:
* **Allocated** — sum of remaining estimates for tasks assigned to that user in the Plan
* **Total** — user's total available hours from the team calendar
* **Available** — total minus allocated (shown in red if negative)
**Users without calendar entries show zero total capacity**
If a team member has no calendar entry in the Teams Service, their `totalCapacity` defaults to `0.0`. Any assigned work immediately flags them as overallocated. Verify calendar coverage in the Teams Service before relying on per-user capacity numbers.
Multi-capacity mode shows a capacity progress bar in each individual swimlane cell — useful when different resources have significantly different capacities.
1. Ensure `capacityLoad` is set to `true` — `multiCapacityLoad` takes effect only when `capacityLoad` is also enabled.
2. Set `multiCapacityLoad` to `true` in the widget parameters.
3. Ensure `useTeamsService` is `true` (multi-capacity reads per-resource capacity from the Teams Service data).
4. Save the page.
By default, capacity bars show a tooltip with aggregate **Capacity / Done / Todo / Available** values. You can customize this tooltip to show a per-user allocation breakdown using the `columnTooltipTemplate` parameter.
Set `columnTooltipTemplate` to a template string or a JavaScript function that receives the column and row objects. When no custom template is configured, the default aggregate tooltip is used automatically.
**Per-user tooltip with overallocation highlighting**
A custom `columnTooltipTemplate` can highlight overallocated users in red. The format typically shows `Available (Overallocated) / Allocated / Total` per team member, making resource bottlenecks easy to spot during planning sessions.
## Known Limitations
**Capacity feature gaps compared to Gantt**
Planningboard capacity visualization has the following confirmed gaps relative to Nextedy GANTT:
* **No multi-assignee support** — capacity is calculated from a single assignee per work item. Work items with multiple assignees are not distributed across those users.
* **No sub-item effort distribution** — capacity is calculated from the work items loaded directly onto the board. Effort in child tasks below the displayed level is not rolled up into capacity calculations.
If your planning workflow depends on either of these behaviors, evaluate whether Nextedy GANTT's capacity view better fits your needs.
**Whitespace sensitivity in capacity parameters**
Capacity configuration parameters are whitespace-sensitive. Ensure there are no leading or trailing spaces in parameter values such as `capacityField`, `selectedTeam`, or `hoursPerDay`. Whitespace errors cause capacity calculations to silently fall back to zero or produce incorrect totals. See [Capacity Calculation Issues](/planningboard/guides/troubleshooting/capacity-issues) if you see unexpected zeros.
## Verification
After saving your widget configuration, reload the Planningboard page. You should now see:
* **Column-level mode (`capacityLoad`):** A progress bar appears at the top of each Plan column, showing aggregate load as a percentage and total hours.
* **Per-user mode (`userCapacityLoad`):** Each assignee swimlane row has a summary cell showing allocated, total, and available hours. Overallocated users appear with a red indicator.
* **Multi-capacity mode (`multiCapacityLoad`):** Individual swimlane cells display their own progress bars.
If capacity bars do not appear, verify that at least one work item in a Plan has a non-zero `remainingEstimate` (or the value of your `capacityField`), and that `useTeamsService` is enabled when required by the mode you selected.
## See Also
* [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration) — widget parameters for capacity configuration
* [Track Team Capacity](/planningboard/guides/capacity/team-capacity) — set up team-level capacity tracking
* [Track User Capacity](/planningboard/guides/capacity/user-capacity) — configure per-user capacity
* [Normalize Capacity Across Swimlanes](/planningboard/guides/capacity/capacity-normalization) — equalize capacity when swimlanes differ in size
* [Set Up Teams Service](/planningboard/guides/capacity/teams-service-setup) — prerequisite for per-user and multi-capacity modes
* [Capacity Calculation Issues](/planningboard/guides/troubleshooting/capacity-issues) — troubleshoot missing or incorrect capacity values
**KB Articles**
* Introduction to Planningboard
* Planningboard: Customizable Statistics and Capacity Indicators
* What is 'Normalization'
**Support Tickets**
* [#6605](https://support.nextedy.com/helpdesk/tickets/6605)
* [#4714](https://support.nextedy.com/helpdesk/tickets/4714)
* [#6777](https://support.nextedy.com/helpdesk/tickets/6777)
**Source Code**
* `PlanningBoardWidget.java`
* `planningboard.js`
* `PlanningBoardDataService.java`
* `perUserCapacity.cy.ts`
* `Config.java`
# Capacity Management
Source: https://learn.nextedy.com/planningboard/guides/capacity/index
Capacity management in Nextedy PLANNINGBOARD gives teams visibility into how much work is allocated per swimlane relative to available effort.
Use the pages in this section to set up capacity tracking, configure how capacity is displayed, and manage team availability including vacation time.
**Start here if you are new to capacity tracking**
Begin with [Track Team Capacity](/planningboard/guides/capacity/team-capacity) or [Track User Capacity](/planningboard/guides/capacity/user-capacity) to get capacity bars showing on your board, then explore normalization and visualization once the basics are in place.
## Capacity Setup
**[Track Team Capacity](/planningboard/guides/capacity/team-capacity)** — Configure capacity tracking per team, linking swimlanes to team definitions so the board reflects each team's available effort.
**[Track User Capacity](/planningboard/guides/capacity/user-capacity)** — Configure capacity tracking per individual user or assignee, with per-user effort limits shown in each swimlane.
**[Set Up Teams Service](/planningboard/guides/capacity/teams-service-setup)** — Set up the Teams Service integration that supplies team membership and capacity data to the board.
**[Track Vacation and Availability](/planningboard/guides/capacity/vacation-tracking)** — Account for time off and partial availability so capacity figures reflect realistic working time within a Plan's date range.
## Capacity Display and Analysis
**[Visualize Capacity Load](/planningboard/guides/capacity/capacity-visualization)** — Configure how capacity load is displayed on the board, including capacity bar appearance and load thresholds.
**[Normalize Capacity Across Swimlanes](/planningboard/guides/capacity/capacity-normalization)** — Apply normalization so capacity bars are comparable across swimlanes that differ in team size or sprint duration.
**[Configure Multi-Dimensional Capacity](/planningboard/guides/capacity/multi-capacity)** — Set up multiple capacity dimensions (for example, both story points and hours) tracked simultaneously per swimlane.
## Related
* [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration) — widget parameters that enable and control the capacity feature.
* [Customize Capacity Indicators](/planningboard/guides/customization/capacity-indicators) — visual customization of the capacity bar display.
* [Capacity Calculation Issues](/planningboard/guides/troubleshooting/capacity-issues) — troubleshoot incorrect or missing capacity values.
**Known limitations**
Planningboard capacity tracking does not distribute effort across multiple assignees on a single work item (multi-assignee capacity load). Each work item contributes its full effort value to the swimlane. Sub-item effort is also not automatically aggregated into parent-item swimlanes. See [Capacity Calculation Issues](/planningboard/guides/troubleshooting/capacity-issues) for details.
**KB Articles**
* Introduction to Planningboard
* Swimlane Assignment Types
* What is 'Normalization'
**Support Tickets**
* [#6605](https://support.nextedy.com/helpdesk/tickets/6605)
* [#6777](https://support.nextedy.com/helpdesk/tickets/6777)
* [#4714](https://support.nextedy.com/helpdesk/tickets/4714)
**Source Code**
* `PlanningBoardDataService.java`
* `PlanningBoardWidget.java`
* `planningboard.js`
* `capacityHelperData.cy.ts`
* `perUserCapacity.cy.ts`
# Configure Multi-Dimensional Capacity
Source: https://learn.nextedy.com/planningboard/guides/capacity/multi-capacity
Set up per-swimlane capacity tracking so each resource row shows its own capacity bar, giving your team an at-a-glance view of how load is distributed across assignees or teams.
***
## When to use multi-dimensional capacity
Standard capacity tracking (`capacityLoad`) shows a single capacity bar per Plan column — it aggregates effort across the whole column regardless of which swimlane a work item sits in. This works well for high-level sprint totals, but it does not tell you whether one assignee is overloaded while another is idle.
**Multi-dimensional capacity** (`multiCapacityLoad`) switches to per-swimlane capacity bars: every swimlane cell within a Plan column gets its own bar. Use it when:
* You want to track remaining capacity per user (assignee swimlanes)
* You have teams with different sprint commitments
* You need to spot overallocation in a single glance during planning
**Limitations before you start**
* Nextedy PLANNINGBOARD capacity load **does not support multiple assignees** on a single work item. Only the primary assignee is counted.
* Planningboard **does not calculate capacity from sub-item effort**. Only direct estimates on the work item itself are used.
* These are known gaps versus Nextedy GANTT's capacity model. Plan accordingly.
***
## Prerequisites
* Capacity tracking (`capacityLoad`) must already be working at the basic level. If it is not, set it up first: see [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration).
* The Teams Service must be configured and returning user capacity data. See [Set Up Teams Service](/planningboard/guides/capacity/teams-service-setup).
* Swimlanes must be set to **Users (Assignee)** assignment type so the per-user capacity map has matching rows to render into.
***
## How multi-dimensional capacity works
The board builds a `multiCapacity` map keyed by resource identifier. When `multiCapacityLoad` is enabled, each swimlane cell looks up its own entry in that map and renders its own progress bar. The formula per user is:
| Value | Calculation |
| ------------------- | ---------------------------------------------------------------------------------------------------------- |
| `allocatedCapacity` | Sum of `remainingEstimate` (or custom capacity field) for all work items assigned to the user in this Plan |
| `totalCapacity` | User's sprint capacity from the Teams Service calendar |
| `availableCapacity` | `totalCapacity − allocatedCapacity` (negative = overallocated) |
Both `allocatedCapacity` and `availableCapacity` are rounded to one decimal place.
**Users without a Teams Service entry**
If a user has no entry in the Teams Service calendar for a given Plan period, their `totalCapacity` defaults to `0.0`. Their swimlane shows a capacity bar with no available headroom. Add the user to the Teams Service to resolve this — see [Set Up Teams Service](/planningboard/guides/capacity/teams-service-setup).
***
Open your Planningboard widget parameters and confirm **Capacity Field** is set. This is the field used to calculate effort:
* Leave it blank to use Polarion's built-in `remainingEstimate` / `initialEstimate` time fields.
* Set it to a custom field ID if your team tracks effort on a custom field.
**Whitespace in capacity configuration is significant**
Capacity configuration parameters are whitespace-sensitive. Do not add leading or trailing spaces around field IDs or property values — they will silently fail to match.
***
In the **Widget Parameters** panel, locate **Capacity** settings and turn on **Multi-Capacity Load** (`multiCapacityLoad`). This switches the board from column-level capacity bars to per-swimlane cell capacity bars.
Keep **Capacity Load** (`capacityLoad`) also enabled — `multiCapacityLoad` requires it to be active.
**Using both modes together**
You can keep `capacityLoad` enabled alongside `multiCapacityLoad`. The column-level bar continues to show sprint totals, while each swimlane cell additionally shows its own bar.
***
Multi-dimensional capacity only produces meaningful bars when each swimlane corresponds to a distinct resource. Check that **Assignment Type** is set to **Users (Assignee)** in the **Swimlanes (Rows)** section of the widget parameters.
If you use a different assignment type (for example, **Enumeration Field**), the capacity map may not find matching keys for your swimlane rows.
***
The `useTeamsService` setting must be enabled. When active, the Teams Service provides:
* Per-user total sprint capacity (from the team calendar)
* Team membership (which users appear in the capacity calculation)
Without the Teams Service, `totalCapacity` for every user will be `0.0` and capacity bars will show only allocated effort with no baseline.
See [Track User Capacity](/planningboard/guides/capacity/user-capacity) and [Track Team Capacity](/planningboard/guides/capacity/team-capacity) for Teams Service configuration steps.
***
Reload the Planningboard. In each Plan column, each user swimlane now shows its own capacity bar.
```text theme={null}
Capacity bar states:
Under capacity ████████░░░░░░ (allocated < total, bar partially filled)
At capacity ██████████████ (allocated ≈ total, bar full)
Overallocated ████████████████████ (bar overflows, typically shown in red)
```
**You should now see** a separate capacity progress indicator inside each user swimlane cell for every Plan column. Hovering over a capacity bar displays the allocation breakdown: available (or overallocated), allocated, and total capacity for that user in that Plan.
**Customizing the capacity tooltip**
The column tooltip template (`columnTooltipTemplate`) can be customized to show a per-user allocation breakdown, including overallocation highlighted in a warning color. See [Customize Capacity Indicators](/planningboard/guides/customization/capacity-indicators).
***
## Troubleshooting
| Symptom | Likely cause | Action |
| ------------------------------------------------------------------ | -------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| Capacity bars show `0 / 0` for all users | Teams Service not connected or no calendar entries | Verify Teams Service setup — see [Set Up Teams Service](/planningboard/guides/capacity/teams-service-setup) |
| Some users have no capacity bar at all | User is not in the Teams Service for this Plan's date range | Add user to the team calendar for the relevant period |
| Bars show allocated effort but no total headroom | `useTeamsService` is off or the user has no calendar entry for this sprint | Enable Teams Service and add calendar data |
| Capacity bar is visible but higher than expected | Sub-item estimates are not included; only direct estimates count | This is a current limitation — Planningboard does not aggregate sub-item effort |
| Board shows a single column-level bar instead of per-swimlane bars | `multiCapacityLoad` is not enabled | Enable it in widget parameters alongside `capacityLoad` |
For additional capacity calculation issues, see [Capacity Calculation Issues](/planningboard/guides/troubleshooting/capacity-issues).
***
## See also
* [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration) — basic capacity setup
* [Track Team Capacity](/planningboard/guides/capacity/team-capacity) — configure team-level capacity
* [Track User Capacity](/planningboard/guides/capacity/user-capacity) — configure per-user capacity
* [Set Up Teams Service](/planningboard/guides/capacity/teams-service-setup) — prerequisites for capacity features
* [Normalize Capacity Across Swimlanes](/planningboard/guides/capacity/capacity-normalization) — adjust capacity display across swimlanes of different sizes
* [Visualize Capacity Load](/planningboard/guides/capacity/capacity-visualization) — understand capacity bar rendering
* [Customize Capacity Indicators](/planningboard/guides/customization/capacity-indicators) — change how capacity bars look and what tooltips show
**KB Articles**
* Swimlane Assignment Types
* Introduction to Planningboard
* What is 'Normalization'
**Support Tickets**
* [#6777](https://support.nextedy.com/helpdesk/tickets/6777)
* [#6605](https://support.nextedy.com/helpdesk/tickets/6605)
* [#4714](https://support.nextedy.com/helpdesk/tickets/4714)
**Source Code**
* `PlanningBoardDataService.java`
* `PlanningBoardWidget.java`
* `planningboard.js`
* `capacityHelperData.cy.ts`
* `Plan.java`
# Track Team Capacity
Source: https://learn.nextedy.com/planningboard/guides/capacity/team-capacity
Use Nextedy PLANNINGBOARD's capacity tracking to see how much work is allocated to each team member per sprint, spot overallocation before it becomes a problem, and balance workload across your team.
## Prerequisites
* Planningboard is installed and a board is configured on a Polarion Wiki page.
* A teams service is set up for your project. See [Set Up Teams Service](/planningboard/guides/capacity/teams-service-setup).
* Work items have remaining estimates (or a custom capacity field) populated.
* Team members are assigned to work items on the board.
**Single-assignee only**
Planningboard capacity tracking supports **one assignee per work item**. If a work item has multiple assignees, only the primary assignee is counted in capacity calculations. This is a known limitation compared to Nextedy GANTT. Additionally, capacity is calculated from direct task estimates only — effort on sub-items is **not** distributed upward to parent items.
***
Open the Widget Parameters panel for your Planningboard widget and set `useTeamsService` to `true`. This tells Planningboard to pull team membership and calendar data from the teams service rather than using a flat plan capacity value.
```properties theme={null}
useTeamsService = true
```
**Whitespace sensitivity**
Capacity configuration properties are whitespace-sensitive. Do not add leading or trailing spaces around the `=` sign or the value. Incorrect whitespace causes silent misconfiguration.
***
Set the `selectedTeam` widget parameter to the team whose capacity you want to track. This determines which users appear in per-user capacity calculations.
```properties theme={null}
selectedTeam =
```
Replace `` with the Polarion work item ID of your team (for example, `MYPROJECT-T-1`). Team IDs are automatically remapped if the team is defined in a supporting project.
***
Set the `capacityLoad` parameter to `true` to activate the capacity bar visualization in plan columns.
```properties theme={null}
capacityLoad = true
```
When enabled, each plan column shows a **capacity bar** indicating the ratio of allocated effort to total team capacity for that sprint.
***
For boards using user swimlanes, enable `multiCapacityLoad` to show a separate capacity bar per swimlane row rather than a single aggregate bar per column.
```properties theme={null}
multiCapacityLoad = true
```
With `multiCapacityLoad` enabled, each user's swimlane row displays its own capacity progress bar, making it straightforward to spot which team members are over- or under-allocated at a glance.
**Choose the right mode**
Use `capacityLoad = true` alone for a team-aggregate view per sprint column. Add `multiCapacityLoad = true` when your swimlanes are set to **Users (Assignee)** and you need per-person capacity visibility.
***
## How capacity is calculated
Planningboard derives capacity values from three sources:
| Value | Definition |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `totalCapacity` | Hours available from the user's working calendar for the sprint period, multiplied by their assignment percentage on the team. |
| `allocatedCapacity` | Sum of remaining estimates for all work items assigned to that user within the sprint. Rounded to one decimal place. |
| `availableCapacity` | `totalCapacity − allocatedCapacity`. Negative values indicate overallocation. |
**Users without a calendar default to zero capacity**
If a team member has no calendar defined and no fallback calendar is configured (`nextedy.gantt.calendarHolder`), their `totalCapacity` is `0.0`. They will always appear as overallocated regardless of assignment. Set up calendars for all team members, or configure a fallback calendar holder.
***
If some users lack individual calendars, set the `nextedy.gantt.calendarHolder` property in your project's administration properties to a base user whose calendar serves as the fallback.
```properties theme={null}
nextedy.gantt.calendarHolder = admin
```
This prevents zero-capacity fallback for users without their own calendar.
***
If your teams have planned capacity reductions — for example, a sprint where the team is partly allocated to a release — enable capacity modifiers:
```properties theme={null}
nextedy.gantt.useTeamCapacityModifiers = true
```
When enabled, Planningboard reads modifier percentages from the `capModA` field (default) on each team work item and reduces the calculated capacity accordingly. To use a different field name, set:
```properties theme={null}
nextedy.gantt.capacityModifierAField =
```
***
After saving the widget parameters, reload the board. You should now see:
* A **capacity bar** at the top of each plan column, showing total allocated effort vs. available team capacity for that sprint.
* If `multiCapacityLoad` is enabled: individual capacity bars in each user swimlane row.
* Hovering over a capacity bar shows a tooltip with per-user breakdown:
* **Available** (shown in red if negative / overallocated)
* **Allocated**
* **Total**
**Custom capacity tooltips**
You can customize the tooltip content using the `columnTooltipTemplate` configuration option. This accepts a string template or a function that receives the column and row objects. After updating the template programmatically, call `setCurrentView` to trigger a re-render.
***
## Example configuration
The following is a complete widget parameter snippet for a user-swimlane board with per-user capacity tracking:
```properties theme={null}
useTeamsService = true
selectedTeam = MYPROJECT-T-1
capacityLoad = true
multiCapacityLoad = true
```
This configuration activates team-aware capacity tracking, selects the team with ID `MYPROJECT-T-1`, and enables per-user capacity bars across all user swimlane rows.
***
## Limitations
* **No multi-assignee support.** Only one assignee per work item contributes to capacity load.
* **No sub-item effort distribution.** Parent item capacity is not aggregated from child task estimates; only direct estimates on assigned tasks are counted.
* Users without calendar entries default to `totalCapacity = 0.0` unless a fallback calendar holder is configured.
For troubleshooting capacity values that appear incorrect or zero, see [Capacity Calculation Issues](/planningboard/guides/troubleshooting/capacity-issues).
***
## See also
* [Set Up Teams Service](/planningboard/guides/capacity/teams-service-setup)
* [Track User Capacity](/planningboard/guides/capacity/user-capacity)
* [Visualize Capacity Load](/planningboard/guides/capacity/capacity-visualization)
* [Normalize Capacity Across Swimlanes](/planningboard/guides/capacity/capacity-normalization)
* [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration)
* [User and Assignee Swimlanes](/planningboard/guides/swimlanes/user-swimlanes)
* [Capacity Calculation Issues](/planningboard/guides/troubleshooting/capacity-issues)
**KB Articles**
* Swimlane Assignment Types
* What is 'Normalization'
* Introduction to Planningboard
**Support Tickets**
* [#6605](https://support.nextedy.com/helpdesk/tickets/6605)
* [#6777](https://support.nextedy.com/helpdesk/tickets/6777)
* [#4714](https://support.nextedy.com/helpdesk/tickets/4714)
**Source Code**
* `PlanningBoardDataService.java`
* `PlanningBoardWidget.java`
* `planningboard.js`
* `capacityHelperData.cy.ts`
* `perUserCapacity.cy.ts`
# Set Up Teams Service
Source: https://learn.nextedy.com/planningboard/guides/capacity/teams-service-setup
Enable the Teams Service to unlock per-user and per-team capacity tracking on the Nextedy PLANNINGBOARD capacity bar.
## Prerequisites
Before you begin:
* Planningboard is installed and a board widget is configured on a Polarion Wiki page.
* You have project-level administration access in Siemens Polarion ALM.
* Team work items exist in the project (or a supporting project). Each team work item must have team member assignment work items with `from` and `to` date fields so the service can filter members by active date range.
* Users are assigned to teams via team assignment work items with valid `from`/`to` date fields. Users whose IDs cannot be resolved are automatically excluded from capacity calculations.
***
The Teams Service queries for team work items in the current project and any supporting projects. Before enabling the service, confirm your team data is set up correctly.
1. Open your Polarion project.
2. Navigate to **Tracker** and search for work items of the type used to represent teams.
3. For each team work item, verify that member assignment child work items exist and include `from` and `to` date field values.
**Users without date fields are excluded**
If a team member assignment work item is missing the `from` or `to` date field, the service cannot apply date-range filtering. The member may appear in unfiltered queries but will not contribute to date-aware capacity calculations. Populate both fields on every assignment work item.
***
The Teams Service is activated via the `useTeamsService` widget parameter. When enabled, the service provides team member data, per-user capacity hours, and overrides any static `plan.capacity` values.
1. Open the Polarion Wiki page containing your Planningboard widget.
2. Enter edit mode and open the **Widget Parameters** panel.
3. In the **Capacity** section, locate the **Use Teams Service** parameter and set it to `true`.
```properties theme={null}
useTeamsService=true
```
4. Save the widget parameters and reload the page.
**Whitespace sensitivity**
Capacity configuration parameters are whitespace-sensitive. Do not add spaces around the `=` sign or trailing spaces in the value. A value of `useTeamsService = true` (with spaces) will not be recognized correctly.
***
By default, the Teams Service aggregates across all teams in the project. To focus capacity calculations on a single team, configure the `selectedTeam` parameter.
```properties theme={null}
selectedTeam=
```
Replace `` with the Polarion work item ID (e.g. `PROJ-42`) of the target team. When set, only users belonging to that team appear in capacity rows, and `userCapacities` reflects only those members.
***
If some users have no working calendar defined in Polarion, the service defaults to the system calendar, which may not reflect your organization's working hours. To set a named user as the calendar fallback, add the following property to the project's `context.properties`:
```properties theme={null}
nextedy.gantt.calendarHolder=
```
This property specifies a base user whose calendar is used as a fallback when a team member has no personal calendar. This is the same property used by Nextedy GANTT.
***
The Teams Service supports optional capacity modifier fields on team work items that reduce team capacity by a percentage. This feature is disabled by default.
To enable it, add to `context.properties`:
```properties theme={null}
nextedy.gantt.useTeamCapacityModifiers=true
```
When enabled, the service reads modifier percentages from fields on the team work item. The default field names are:
| Field | Default name | Description |
| ------------------ | ------------ | ------------------------------------------------- |
| Primary modifier | `capModA` | Integer (0–100) — percentage reduction to apply |
| Secondary modifier | `capModB` | Integer (0–100) — additional percentage reduction |
To use different field names:
```properties theme={null}
nextedy.gantt.capacityModifierAField=myCapModField
```
**Start without modifiers**
Leave `nextedy.gantt.useTeamCapacityModifiers` at its default (`false`) unless your teams have dedicated capacity-modifier fields already populated. Enabling it with empty fields will silently reduce all capacity values.
***
## How Capacity Is Calculated
Once the Teams Service is active, capacity on the board is calculated per user as follows:
```text theme={null}
totalCapacity = working hours in sprint × capacity percentage (from calendar + assignment)
allocatedCapacity = sum of remainingEstimate for all tasks assigned to the user in the plan
availableCapacity = totalCapacity − allocatedCapacity
```
Both `allocatedCapacity` and `availableCapacity` are rounded to one decimal place. Negative `availableCapacity` values indicate overallocation and are surfaced visually on the capacity bar.
Users without a team calendar entry or an unresolvable user ID default to `totalCapacity = 0.0`.
**Known limitations**
* **Multiple assignees not supported.** Planningboard capacity load tracks only a single assignee per work item. If a work item has multiple assignees, capacity is not distributed across them.
* **Sub-item effort not distributed.** Effort from child work items is not rolled up to parent items for capacity calculation purposes. Only direct remaining estimates on the assigned work item are counted.
* These are known gaps relative to Nextedy GANTT's capacity model. Plan accordingly when comparing board capacity figures to GANTT totals.
***
## Verification
After completing the steps above, reload the board. You should now see:
* Per-user swimlane rows populated with team members from the configured team (or all project teams if `selectedTeam` is not set).
* A capacity bar in each plan column showing allocated vs total capacity for the visible users.
* Summary cells displaying each user's `allocatedCapacity`, `totalCapacity`, and `availableCapacity`.
If capacity bars show `0 / 0`, revisit Step 1 to confirm team assignment work items exist with valid `from`/`to` dates, and verify `useTeamsService=true` is saved without extra whitespace.
***
## See Also
* [Track Team Capacity](/planningboard/guides/capacity/team-capacity)
* [Track User Capacity](/planningboard/guides/capacity/user-capacity)
* [Visualize Capacity Load](/planningboard/guides/capacity/capacity-visualization)
* [Normalize Capacity Across Swimlanes](/planningboard/guides/capacity/capacity-normalization)
* [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration)
* [Capacity Calculation Issues](/planningboard/guides/troubleshooting/capacity-issues)
**KB Articles**
* What is 'Normalization'
* Swimlane Assignment Types
* Introduction to Planningboard
**Support Tickets**
* [#6605](https://support.nextedy.com/helpdesk/tickets/6605)
* [#6777](https://support.nextedy.com/helpdesk/tickets/6777)
* [#4714](https://support.nextedy.com/helpdesk/tickets/4714)
**Source Code**
* `PlanningBoardDataService.java`
* `PlanningBoardWidget.java`
* `planningboard.js`
* `capacityHelperData.cy.ts`
* `PlanningBoardTeamsService.java`
# Track User Capacity
Source: https://learn.nextedy.com/planningboard/guides/capacity/user-capacity
Track how much work each team member has allocated versus available across sprint iterations to identify overallocation and balance workloads before finalizing a plan.
## Prerequisites
* The Teams Service must be configured for your project. See [Set Up Teams Service](/planningboard/guides/capacity/teams-service-setup).
* Your board must use the **Users (Assignee)** swimlane assignment type. See [User and Assignee Swimlanes](/planningboard/guides/swimlanes/user-swimlanes).
* Each team member must have a calendar entry in the Teams Service so total capacity can be derived from working hours.
* Work items must have `remainingEstimate` or `initialEstimate` values set (or a custom capacity field configured).
***
## How User Capacity Is Calculated
Nextedy PLANNINGBOARD tracks three values per user per plan column:
| Value | Source |
| ---------------------- | ------------------------------------------------------------------------------- |
| **Total capacity** | Derived from the user's team calendar for the plan's date range |
| **Allocated capacity** | Sum of `remainingEstimate` for all work items assigned to that user in the plan |
| **Available capacity** | `totalCapacity − allocatedCapacity` (auto-calculated; negative = overallocated) |
Both `allocatedCapacity` and `availableCapacity` are rounded to one decimal place.
**Users without a calendar entry default to 0.0 total capacity**
If a team member does not have a calendar entry in the Teams Service for the plan's date range, their `totalCapacity` is 0.0. They will appear permanently overallocated regardless of how much work is assigned. Verify calendar coverage before relying on capacity numbers.
**Single-assignee limitation**
Planningboard capacity load does **not** support multiple assignees per work item. If a work item has more than one assignee, its effort is not split or distributed — only the primary assignee is counted. This is a known gap compared to Nextedy GANTT. Plan assignments accordingly.
**Sub-item effort is not distributed**
Effort is read directly from the work item's own estimate fields. Capacity is **not** calculated from child or sub-item estimates rolled up to a parent. Ensure estimates are set at the level of items that appear on the board.
***
In your board's widget parameters, locate **Capacity** settings and enable the Teams Service integration by setting the `useTeamsService` flag. When enabled, Planningboard uses team calendar data to populate `totalCapacity` for each user rather than a static plan capacity value.
**Verify in application**
The exact widget parameter name for enabling the Teams Service integration should be confirmed against your installed version. See [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration) for the full parameter reference.
***
Enable per-user capacity tracking by setting the capacity parameters in your widget configuration. These are separate boolean parameters — not values of a single parameter.
For per-user capacity display (where each swimlane cell shows that user's own capacity progress), enable both `capacityLoad` and `userCapacityLoad`:
```properties theme={null}
capacityLoad=true
userCapacityLoad=true
```
**Whitespace sensitivity**
Capacity configuration parameters are whitespace-sensitive. Do not add spaces around the `=` sign or trailing spaces after the value. An incorrect entry silently disables capacity tracking.
If you need each swimlane row to show its own capacity bar independently (rather than an aggregate column bar), enable `multiCapacityLoad` alongside `capacityLoad`:
```properties theme={null}
capacityLoad=true
multiCapacityLoad=true
```
Use `userCapacityLoad=true` when the swimlane assignment type is **Users (Assignee)** and you want per-person total capacity drawn from the Teams Service. Use `multiCapacityLoad=true` when you want a separate capacity bar rendered inside each individual swimlane cell. Both require `capacityLoad=true` to be active.
***
User capacity tracking requires swimlanes grouped by individual users. In the widget parameters, confirm:
* **Swimlanes (Rows) > Assignment Type** is set to **Users (Assignee)**
* **User Role** is set to the Polarion role that identifies team members (for example, `project_user`)
Only users holding the specified role in the current project will appear as swimlane rows. Users outside the role are excluded from both the board view and capacity calculations.
***
Once configured, each user row on the board shows a **capacity bar** in the plan column summary cell. The bar visualizes:
* **Filled portion** — allocated capacity (hours assigned to this user in this plan)
* **Total bar width** — total capacity from the team calendar
* **Overallocation** — when allocated exceeds total, the bar overflows or changes state to signal the overallocation
Summary cells for user rows aggregate the user's load across all work items in that plan column. Available capacity values that go negative indicate overallocation and signal that work should be moved to another plan or reassigned.
***
With capacity visible per user per plan column:
1. Identify swimlane rows where allocated capacity exceeds total capacity (overallocated users).
2. Drag one or more cards from the overallocated user's row into a future plan column or into the unplanned sidebar.
3. Observe the capacity bar update as you move cards — allocated capacity recalculates on drop.
4. Repeat until all user rows show available capacity at or above zero.
**Use the unplanned sidebar as a holding area**
Items dragged off the board return to the unplanned sidebar with their estimates intact. This lets you stage work that cannot fit this iteration without losing the effort values.
***
## Verification
You should now see:
* Each user swimlane row displays a capacity bar in every plan column header.
* The bar shows allocated vs total hours derived from the team calendar.
* Moving cards between columns or between users updates the bars immediately.
* Users without calendar entries show 0.0 total capacity — address these in the Teams Service configuration.
If capacity bars are missing or all users show 0.0, see [Capacity Calculation Issues](/planningboard/guides/troubleshooting/capacity-issues) for diagnostic steps.
***
## Limitations
* **No multi-assignee support** — effort is not distributed across co-assignees.
* **No sub-item rollup** — capacity is not calculated from child work item estimates.
* Users not covered by the team calendar default to 0.0 total capacity.
***
## See also
* [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration)
* [Set Up Teams Service](/planningboard/guides/capacity/teams-service-setup)
* [Track Team Capacity](/planningboard/guides/capacity/team-capacity)
* [Visualize Capacity Load](/planningboard/guides/capacity/capacity-visualization)
* [Normalize Capacity Across Swimlanes](/planningboard/guides/capacity/capacity-normalization)
* [User and Assignee Swimlanes](/planningboard/guides/swimlanes/user-swimlanes)
* [Capacity Calculation Issues](/planningboard/guides/troubleshooting/capacity-issues)
**KB Articles**
* Swimlane Assignment Types
* Introduction to Planningboard
* What is 'Normalization'
**Support Tickets**
* [#6605](https://support.nextedy.com/helpdesk/tickets/6605)
* [#6777](https://support.nextedy.com/helpdesk/tickets/6777)
* [#4714](https://support.nextedy.com/helpdesk/tickets/4714)
**Source Code**
* `PlanningBoardDataService.java`
* `PlanningBoardWidget.java`
* `planningboard.js`
* `UserCapacityInfo.java`
* `capacityHelperData.cy.ts`
# Track Vacation and Availability
Source: https://learn.nextedy.com/planningboard/guides/capacity/vacation-tracking
Set up Nextedy PLANNINGBOARD to reflect each team member's actual available capacity, accounting for vacation days, part-time assignments, and calendar-based off days — so capacity bars show realistic sprint totals.
## Prerequisites
Before configuring vacation and availability tracking:
* The Teams Service must be enabled and configured. See [Set Up Teams Service](/planningboard/guides/capacity/teams-service-setup).
* Swimlanes must use the **Users (Assignee)** assignment type. See [User and Assignee Swimlanes](/planningboard/guides/swimlanes/user-swimlanes).
* Capacity tracking (`capacityLoad`) must be enabled on the board. See [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration).
## How availability is calculated
Planningboard calculates per-user capacity from the Teams Service, using each user's Polarion working calendar for the Plan's date range. The formula is:
```text theme={null}
totalCapacity = working hours in date range × assignment percentage
allocatedCapacity = sum of remainingEstimate for all tasks assigned to the user in the Plan
availableCapacity = totalCapacity − allocatedCapacity
```
A negative `availableCapacity` value indicates the user is overallocated.
Users who have no calendar defined and no team assignment entry default to a `totalCapacity` of `0.0`. They will always appear fully allocated regardless of actual workload.
The capacity values vary per Plan column because each Plan spans different dates — a user on vacation during one sprint has lower `totalCapacity` for that column automatically, without any manual adjustment.
Planningboard reads capacity from each user's Polarion working calendar. If a user has no calendar defined, the system falls back to the base calendar configured in `nextedy.gantt.calendarHolder`.
1. In Polarion, go to **Administration > Calendars**.
2. Confirm each team member has a calendar assigned.
3. Mark vacation or unavailability as off days on the user's calendar for the relevant date ranges.
If most team members share the same calendar, configure `nextedy.gantt.calendarHolder` with the ID of a base user whose calendar serves as the default fallback. This reduces per-user calendar setup overhead.
The Teams Service reads capacity percentage from team assignment work items. Each assignment work item must have:
* A `from` date field — when the team membership starts
* A `to` date field — when the team membership ends
* A capacity percentage (the field name depends on your team work item type setup)
Assignments outside the Plan's date range are excluded automatically from capacity calculations. This means a user who joins or leaves mid-sprint will have their capacity prorated to the actual overlap.
```text theme={null}
Team assignment work item
from: 2025-10-01
to: 2025-10-31
capacity: 80% ← user is 80% allocated to this team
```
If your team work items include capacity modifier fields to account for ceremonies, overhead, or other availability reductions, enable this in your Polarion system configuration:
```properties theme={null}
nextedy.gantt.useTeamCapacityModifiers=true
nextedy.gantt.capacityModifierAField=capModA
```
When enabled, the modifier percentage is read from the `capModA` field on the team work item and applied as a reduction to the calculated capacity. The default value of `nextedy.gantt.useTeamCapacityModifiers` is `false`.
Configuration properties are whitespace-sensitive. Ensure there are no leading or trailing spaces around property names or values, or the setting will be silently ignored.
To show per-user capacity bars in swimlane summary cells, the board must use `useTeamsService` together with per-user capacity load:
1. Open the widget parameters for your Planningboard.
2. Under **Capacity**, confirm that the Teams Service integration is active.
3. For per-user capacity bars, ensure `multiCapacityLoad` is configured — this shows each user swimlane's own capacity progress rather than an aggregate column total.
See [Track User Capacity](/planningboard/guides/capacity/user-capacity) for the full widget parameter configuration steps.
## How vacation days appear on the board
When Alice has vacation days marked in Sprint 4, her `totalCapacity` for that column is reduced proportionally. The capacity bar automatically reflects the shorter available window — no manual column adjustments are needed.
## Verification
After completing the steps above, open your Planningboard. In each Plan column, expand a user swimlane and check its summary cell. You should now see:
* A capacity bar showing load relative to the user's **actual** available hours for that sprint
* Overallocated users showing a full or overflowing bar (negative `availableCapacity`)
* Users on vacation in a given sprint showing a reduced total capacity for that column compared to adjacent sprints
If a user's capacity bar shows `0%` even though they have work assigned, check that their team assignment work item has both a `from` and `to` date, and that those dates overlap with the Plan's date range. Assignments without date boundaries are filtered out of capacity calculations.
## Known limitations
**Multiple assignees not supported**
Planningboard capacity load does not support work items with multiple assignees. If a work item has more than one assignee, capacity is not distributed across them — only a single primary assignee is used for capacity calculation. For multi-assignee planning, refer to [Nextedy GANTT](/planningboard/index).
**Sub-item effort not distributed**
Capacity calculation uses `remainingEstimate` from the work items directly on the board. Effort tracked on child tasks nested below the board's query scope is not rolled up into the parent's allocated capacity. This is a known gap compared to GANTT's capacity model.
## See also
* [Set Up Teams Service](/planningboard/guides/capacity/teams-service-setup)
* [Track User Capacity](/planningboard/guides/capacity/user-capacity)
* [Track Team Capacity](/planningboard/guides/capacity/team-capacity)
* [Visualize Capacity Load](/planningboard/guides/capacity/capacity-visualization)
* [Capacity Calculation Issues](/planningboard/guides/troubleshooting/capacity-issues)
* [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration)
**KB Articles**
* Swimlane Assignment Types
* Introduction to Planningboard
* What is 'Normalization'
**Support Tickets**
* [#6777](https://support.nextedy.com/helpdesk/tickets/6777)
* [#6605](https://support.nextedy.com/helpdesk/tickets/6605)
* [#4714](https://support.nextedy.com/helpdesk/tickets/4714)
**Source Code**
* `PlanningBoardDataService.java`
* `PlanningBoardWidget.java`
* `planningboard.js`
* `capacityHelperData.cy.ts`
* `UserCapacityInfo.java`
# Configure Capacity Tracking
Source: https://learn.nextedy.com/planningboard/guides/configuration/capacity-configuration
Enable and configure capacity bars in Nextedy PLANNINGBOARD to track how much work is planned against available capacity in each swimlane and Plan column.
## Before you begin
* The board must already be configured with Plans (columns) and swimlanes (rows). See [Configure Plans (Columns)](/planningboard/guides/configuration/plans-configuration) and [Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration).
* Capacity tracking works with time-based effort fields (`remainingEstimate`, `initialEstimate`) or a custom numeric field on work items. Decide which approach your team uses before proceeding.
Open the widget parameters for your Planningboard widget.
Under **Parameters for Plans (Columns)**, locate the **Show Capacity Load** toggle and enable it. This activates the `capacityLoad` property, which defaults to `false`.
```properties theme={null}
capacityLoad = true
```
Once enabled, a **capacity bar** appears at the top of each Plan column, showing the aggregate planned effort versus capacity for that Plan.
**Toggling capacity bars at runtime**
Users can show or hide the capacity visualization at any time using the **Toggle Resource Load visualization** button in the board toolbar (the bar-chart icon). This does not change the widget configuration — it is a per-session display toggle.
By default, Planningboard reads effort from Polarion's built-in time-tracking fields (`remainingEstimate` and `initialEstimate`). If your team uses a custom numeric field instead (for example, story points stored in a custom field), set the `capacityField` property to that field's ID.
```properties theme={null}
capacityField = storyPoints
```
Leave `capacityField` empty to use the default time-based fields.
**Whitespace sensitivity**
Capacity configuration property values are whitespace-sensitive. Do not include leading or trailing spaces around the field ID. A value such as `capacityField = storyPoints ` (with extra spaces) will not resolve correctly.
If you are using time-based effort fields, Planningboard converts effort values using the `hoursPerDay` property. The default is `8` hours per day.
```properties theme={null}
hoursPerDay = 8
```
Adjust this value to match your team's working day (for example, `6` for a 6-hour working day). This affects how the capacity bar computes load when effort is stored in hours.
Planningboard supports two capacity modes:
| Mode | Property | When to use |
| ----------------------------------- | -------------------------- | -------------------------------------------------------------------------------------------------------- |
| Single capacity | `capacityLoad = true` | One capacity bar per Plan column aggregated across all swimlanes |
| Multi-dimensional capacity | `multiCapacityLoad = true` | Each swimlane cell shows its own capacity bar, useful when different resources have different capacities |
| User-level capacity (Teams service) | `userCapacityLoad = true` | Per-user capacity drawn from the Teams service integration |
These modes build on each other — `multiCapacityLoad` requires `capacityLoad = true` to take effect:
```properties theme={null}
# Option A — column-level capacity only
capacityLoad = true
multiCapacityLoad = false
userCapacityLoad = false
# Option B — per-swimlane capacity (multiCapacityLoad requires capacityLoad = true)
capacityLoad = true
multiCapacityLoad = true
userCapacityLoad = false
```
**User-level capacity requires Teams service**
`userCapacityLoad = true` depends on the Teams service integration (`useTeamsService = true`). Without the Teams service configured, this property has no effect. See [Set Up Teams Service](/planningboard/guides/capacity/teams-service-setup) and [Track User Capacity](/planningboard/guides/capacity/user-capacity).
If your project uses the Polarion Teams service, enable it to supply accurate per-team and per-user capacity values that override the default plan capacity:
```properties theme={null}
useTeamsService = true
selectedTeam = team-alpha
```
`selectedTeam` filters the board to a specific team ID. Leave it empty to show all teams.
After saving the widget parameters, open or refresh the Planningboard. You should now see:
* A **capacity bar** at the top of each Plan column (if `capacityLoad = true`).
* The bar fills proportionally as work items are planned into the column.
* Hovering over a capacity bar shows a **tooltip** with detailed capacity information: total planned effort, available capacity, and the load percentage.
**Capacity tooltip**
The detailed capacity tooltip only appears if capacity tracking is enabled in the widget parameters. If hovering over the bar shows nothing, verify that `capacityLoad` is set to `true` and the widget has been saved and reloaded.
## Known limitations
* **No multi-assignee effort distribution.** When a work item has multiple assignees, Planningboard does not split the effort across them — the full effort is attributed to the primary resource. This differs from Nextedy GANTT's behavior.
* **No sub-item effort roll-up.** Effort from child work items is not automatically aggregated into parent items for capacity calculation purposes.
* **Swimlane sort order is coupled to item sort order.** Sorting items affects swimlane display order; these cannot be independently configured.
For troubleshooting capacity bars that do not appear or show unexpected values, see [Capacity Calculation Issues](/planningboard/guides/troubleshooting/capacity-issues).
## See also
* [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters)
* [Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration)
* [Configure Plans (Columns)](/planningboard/guides/configuration/plans-configuration)
* [Track Team Capacity](/planningboard/guides/capacity/team-capacity)
* [Track User Capacity](/planningboard/guides/capacity/user-capacity)
* [Normalize Capacity Across Swimlanes](/planningboard/guides/capacity/capacity-normalization)
* [Configure Multi-Dimensional Capacity](/planningboard/guides/capacity/multi-capacity)
* [Visualize Capacity Load](/planningboard/guides/capacity/capacity-visualization)
* [Capacity Calculation Issues](/planningboard/guides/troubleshooting/capacity-issues)
**KB Articles**
* Planningboard Widget Parameters
* Planningboard: Customizable Statistics and Capacity Indicators
* Planningboard interface & basic interactions
**Support Tickets**
* [#4714](https://support.nextedy.com/helpdesk/tickets/4714)
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
* [#6777](https://support.nextedy.com/helpdesk/tickets/6777)
**Source Code**
* `PlanningBoardWidget.java`
* `Config.java`
* `planningboard.js`
* `widget.vm`
* `PlanningBoardDataService.java`
# Configure Dependencies Display
Source: https://learn.nextedy.com/planningboard/guides/configuration/dependencies-configuration
Enable dependency visualization on the Nextedy PLANNINGBOARD so that link relationships between cards are drawn as arrows, making scheduling conflicts and blockers immediately visible.
## Prerequisites
* A Planningboard widget is already embedded in a Polarion LiveDoc or Wiki page.
* The Polarion work item link roles you want to visualize already exist in the project (for example, `depends_on`, `blocks`, or a custom link role).
* You have permission to edit widget parameters on the page.
1. Navigate to the Polarion page containing the Planningboard widget.
2. Click **Edit** to enter page editing mode.
3. Open the widget's parameter editor (click the widget configuration icon or choose **Edit Widget Parameters** from the widget context menu).
In the **Parameters for Work Items** section, locate the **Dependency Roles** field.
Enter one or more work item link role IDs that should be treated as dependencies. Separate multiple roles with a comma.
```text theme={null}
Dependency Roles: depends_on
```
Or for multiple roles:
```text theme={null}
Dependency Roles: depends_on, blocks
```
**Use exact link role IDs**
Enter the internal link role ID exactly as defined in the Polarion project configuration — not the display label. Wrong IDs are silently ignored: no dependency arrows will appear, and no error is shown. Check **Administration > Work Items > Link Roles** to confirm the exact ID.
**Check available link roles**
In Polarion, go to **Administration > Work Items > Link Roles** to see all defined roles and their IDs. Common defaults include `depends_on` and `parent`. Custom project roles vary.
Save the widget parameters and reload the page to apply the change.
With `Dependency Roles` configured, the **Show Dependencies** button in the Planningboard toolbar becomes functional.
Click **Show Dependencies** to toggle dependency arrows on for all cards currently visible on the board. Clicking it again hides the arrows.
**Toolbar vs. card-level Show Links**
The toolbar **Show Dependencies** button reveals all dependency arrows for the entire board at once. The per-card **Show Links** quick action (hover over a card) shows only links for that specific card and dims all others. Both use the same `Dependency Roles` configuration.
When you need to trace a single card's dependencies without visual clutter:
1. Hover over the card whose dependencies you want to inspect.
2. Click the **Show Links** icon (chain link icon) that appears in the card's upper-right corner.
3. All other cards are dimmed; only the selected card and its directly linked cards remain highlighted.
4. Click the icon again or click elsewhere to return to the full board.
To create a new dependency link between two cards directly on the board:
1. Hover over the source card and click the **Add Link** icon (also in the upper-right corner).
2. The same icon appears on all other cards. A red icon means a link already exists.
3. Click the target card to establish the link. Click a card with a red icon to remove that link.
## How dependency arrows are visualized
The diagram below shows how dependencies flow between cards across columns (Plans):
Cards with unresolved predecessors in earlier columns indicate scheduling risks: the dependent card may be planned before its dependency is complete.
## Configuration example
The following widget parameter snippet shows a typical dependency configuration alongside related work item parameters:
```properties theme={null}
# Work Items parameters
query = type:story
sortBy = priority
dependencyRoles = depends_on,blocks
sidebarFields = title,status,plannedIn
```
**Dependency arrows require cards to be loaded**
Dependency arrows are only drawn between cards that are currently loaded on the board. If a predecessor card is outside the current plan range (filtered out by **Show # of last plans** / **Show # of next plans**), its arrow will not appear even if the link exists in Polarion. Increase the plan window if you need to trace cross-sprint dependencies.
## Verification
After completing these steps you should see:
* A **Show Dependencies** button is active in the toolbar (it was previously greyed out or had no effect without `Dependency Roles` configured).
* Clicking **Show Dependencies** draws arrow lines between cards that have links of the configured role types.
* Hovering over a card and clicking **Show Links** highlights only that card's direct links.
* Clicking **Add Link** on a card, then clicking another card, creates a new Polarion link of the configured role between the two work items.
If no arrows appear after enabling **Show Dependencies**, verify the link role IDs are correct (Step 2) and that linked cards are both within the loaded plan range.
## See also
* [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) — full reference for all widget parameters including `Dependency Roles` and `Sidebar Fields`
* [Visualize and Manage Dependencies](/planningboard/guides/planning/dependencies) — planning workflow for working with dependencies day-to-day
* [Basic Board Interactions](/planningboard/getting-started/basic-interactions) — card quick actions including Show Links and Add Link
* [Configure Plans (Columns)](/planningboard/guides/configuration/plans-configuration) — controlling which Plans (and therefore which cards) are visible on the board
**KB Articles**
* Planningboard Widget Parameters
* Planningboard: Customizable Statistics and Capacity Indicators
* Planningboard interface & basic interactions
**Support Tickets**
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#5796](https://support.nextedy.com/helpdesk/tickets/5796)
**Source Code**
* `PlanningBoardWidget.java`
* `widget.vm`
* `Config.java`
* `viewSetup.vm`
* `planningboard.js`
# Configuration
Source: https://learn.nextedy.com/planningboard/guides/configuration/index
Configure Nextedy PLANNINGBOARD by setting widget parameters on each board instance embedded in a Polarion LiveDoc or Wiki page.
## Configuration Topics
[**Widget Parameters Overview**](/planningboard/guides/configuration/widget-parameters) — Reference for all widget parameters accepted by the Nextedy PLANNINGBOARD widget. Start here to understand the parameter model before diving into specific areas.
[**Configure Plans (Columns)**](/planningboard/guides/configuration/plans-configuration) — Control which Polarion Plans appear as columns on the board using Plan queries, date-range filtering, and Plan ordering.
[**Configure Swimlanes (Rows)**](/planningboard/guides/configuration/swimlanes-configuration) — Set the swimlane assignment type that groups work item cards into rows: by assignee, parent item, enumeration field, project, or no swimlanes. Covers sort order and filtering.
[**Configure Work Items Dataset**](/planningboard/guides/configuration/work-items-configuration) — Define which work items load onto the board: the Lucene query, work item types, and dataset scope.
[**Configure Unplanned Sidebar**](/planningboard/guides/configuration/unplanned-sidebar) — Set up the unplanned backlog sidebar so items not yet assigned to a Plan are accessible for drag-and-drop scheduling directly from the board.
[**Configure Capacity Tracking**](/planningboard/guides/configuration/capacity-configuration) — Enable capacity bars per swimlane, select the capacity field, and configure capacity normalization. Includes notes on whitespace-sensitive parameter values.
[**Configure Dependencies Display**](/planningboard/guides/configuration/dependencies-configuration) — Enable and configure the display of work item dependencies (link roles) as visual connectors on the board.
[**Use Page Parameters**](/planningboard/guides/configuration/page-parameters) — Bind Polarion page parameters to widget parameters so that a single board widget responds dynamically to user-selected filters on the page.
***
If you are configuring a Planningboard widget for the first time, begin with [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) to understand how parameters are set on a widget, then proceed to [Configure Plans (Columns)](/planningboard/guides/configuration/plans-configuration) and [Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration) to define the board's structure.
**KB Articles**
* Planningboard Widget Parameters
* Planningboard interface & basic interactions
* Planningboard: Customizable Statistics and Capacity Indicators
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#5796](https://support.nextedy.com/helpdesk/tickets/5796)
* [#6546](https://support.nextedy.com/helpdesk/tickets/6546)
**Source Code**
* `PlanningBoardWidget.java`
* `widget.vm`
* `viewSetup.vm`
* `Config.java`
* `PlanningBoardWidgetRenderer.java`
# Use Page Parameters
Source: https://learn.nextedy.com/planningboard/guides/configuration/page-parameters
Configure a Nextedy PLANNINGBOARD widget to respond to Polarion page parameters so the same board page can display different Plans, swimlanes, or queries depending on run-time context (for example, switching between Program Increments via URL).
**Page parameters in swimlane row configuration accept string type only**
Polarion page parameters (`$pageParameters.xxx`) are accepted in swimlane row configuration as **string values only** — manual text entry is required; an enum picker dropdown is not currently available. If string-entry is not sufficient for your use case, create a separate Planningboard page per team and configure row assignment statically. See [Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration) for the available assignment types.
## Before you start
* You have a Planningboard widget already embedded in a Polarion Wiki page or LiveDoc.
* You have edit rights to that page.
* You know the Polarion page parameter name(s) you want to use (e.g. `planId`, `programIncrement`).
***
Open the widget's configuration panel (**expand tools → click the edit button** on the Planningboard widget). The parameters that accept dynamic values are:
| Widget parameter | What it controls | Accepts page parameter? |
| --------------------------------- | --------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `Plans` (Plans Query) | Which Plans appear as columns | Yes — pass a Lucene query referencing the parameter |
| `Program Increment Parameter ID` | SAFe: which PI drives the board columns | Yes — reference the page parameter ID here |
| `Query` (Work Items) | Which work items load onto the board | Yes — embed the parameter in a Lucene query |
| `Scope` | Project scope for the board | |
| Swimlane `Assignment Type` / rows | How rows are formed | String-entry only — no enum picker; see [Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration) |
**SAFe Program Increment configuration**
For SAFe boards, the **Program Increment Parameter ID** field is the primary hook for page parameters. Set it to the name of the Polarion page parameter that carries the PI identifier, then the board columns update automatically when the parameter changes.
***
1. In the Polarion page editor, open the **Page Parameters** section (this is a standard Polarion feature, not Planningboard-specific).
2. Add a parameter with the name you intend to use (e.g. `pi`).
3. Give it a default value so the board renders without an explicit parameter in the URL (e.g. the ID of your current PI).
4. Save the page.
***
If you are driving which Plans appear as columns, use the Lucene `plansQuery` in the widget to embed the parameter.
**Example — filter columns to a specific Program Increment by ID:**
```text theme={null}
template.id:iterationPlan AND plannedIn.KEY:${pageParameters.pi}
```
Replace `pi` with your actual parameter name and adjust the field name to match your Polarion configuration.
**Example — Report Link template for column headers** (links each column label to the plan's own Polarion page):
```text theme={null}
/polarion/#/project/${plan.objectId.projectId}/plan?id=${plan.objectId.itemId}
```
**Whitespace sensitivity**
Capacity configuration parameters are whitespace-sensitive. Ensure there are no leading or trailing spaces around values you paste into the widget configuration panel. A stray space can cause the board to load no plans or miscalculate capacity.
***
If you also want to filter the work items dataset dynamically, reference the same or a different page parameter in the **Query** field.
**Example — show only items planned in the selected PI:**
```text theme={null}
plannedIn.KEY:${pageParameters.pi} AND type:story
```
The `query` property defaults to `NOT *:*` (no items), so a missing or malformed parameter reference will silently show an empty board. Always define a default value for the page parameter (Step 2) to avoid a blank board on first load.
**One Planningboard per page**
Each Polarion Wiki page or LiveDoc supports only **one** Planningboard widget. If you need side-by-side boards (for example, two teams on the same dashboard), create separate pages — one per board — and link them from a hub page. Each page then uses the same parameter name but different default values.
***
When using page parameters to select a PI, you typically want to show all sprints within that PI. Adjust **Show # of last plans** and **Show # of next plans** accordingly.
From `Config.java` defaults:
| Property | Default | Recommended for PI-driven board |
| ----------- | ------- | ------------------------------- |
| `lastPlans` | `1` | `0` (hide past PIs) |
| `nextPlans` | `5` | Match your sprint count per PI |
**Performance with large plan counts**
Loading more plans increases the number of work items fetched. The default `maxItems` limit is `1000`. If your board shows blank columns or truncated swimlanes, you may be hitting this limit. Reduce the work items query scope or lower the number of visible plans.
***
## Configuration Example
A SAFe Program level board that switches between Program Increments via URL:
```text theme={null}
Page URL: /polarion/#/project/MyProject/wiki/ProgramBoard?pi=PI_3_0
```
**Widget — Plans section:**
| Field | Value |
| ------------------------------ | ----------------------- |
| Plans Type | SAFe Program Increments |
| Program Increment Parameter ID | `pi` |
| Show # of last plans | `0` |
| Show # of next plans | `6` |
| Show Capacity Load | enabled |
**Widget — Work Items section:**
| Field | Value |
| ------- | -------------- |
| Query | `type:feature` |
| Sort by | Priority |
**Widget — Swimlanes section:**
| Field | Value |
| --------------- | ------------------------------------------------------------------------------------ |
| Assignment Type | Program / Solution Teams (SAFe) (`SAFE_TEAM`) — static, not driven by page parameter |
***
## Verification
After saving the page with the parameter configured:
1. Load the page without a `?pi=` parameter in the URL — the board should render using the **default value** you set in Step 2.
2. Append `?pi=` to the URL and reload — the board columns should update to the sprints of that PI.
3. Hover over a capacity bar — if **Show Capacity Load** is enabled, a tooltip with load detail should appear.
You should now see the board columns change dynamically as you switch the page parameter value in the URL, with swimlane rows remaining stable.
**Custom Team work item types are not supported**
Planningboard does not support custom Team work item types for swimlane configuration. The product requires Nextedy's standard Team work item with specific custom fields. If your project uses a custom Team WI type, use Nextedy GANTT (which supports custom team types as of version 25.5.0+) as the primary planning tool, or create a separate static Planningboard page per team using link-role-based rows.
***
## See also
* [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters)
* [Configure Plans (Columns)](/planningboard/guides/configuration/plans-configuration)
* [Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration)
* [Dynamic Filtering with Page Parameters](/planningboard/guides/advanced/dynamic-filtering)
* [Scripted Page Parameters](/planningboard/guides/advanced/scripted-page-parameters)
* [SAFe Planning Workflows](/planningboard/guides/planning/safe-planning)
* [SAFe Plan Naming Conventions](/planningboard/guides/planning/safe-naming-conventions)
**KB Articles**
* Planningboard Widget Parameters
* Planningboard interface & basic interactions
* Planningboard: Customizable Statistics and Capacity Indicators
**Support Tickets**
* [#6546](https://support.nextedy.com/helpdesk/tickets/6546)
* [#5796](https://support.nextedy.com/helpdesk/tickets/5796)
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
**Source Code**
* `PlanningBoardWidget.java`
* `widget.vm`
* `Config.java`
* `PlanningBoardWidgetRenderer.java`
* `planningboard.js`
# Configure Plans (Columns)
Source: https://learn.nextedy.com/planningboard/guides/configuration/plans-configuration
Configure which Polarion Plans appear as columns on the board, how many past and future Plans load, and whether capacity load is displayed per Plan.
## Before you start
Open the widget parameters editor for your Nextedy PLANNINGBOARD widget. In Polarion, edit the LiveDoc or Wiki page containing the widget, then click the widget's parameter icon to open the **Parameters for Plans (Columns)** section.
***
The **Plans Type** parameter (`plansMode`) determines which type of Plans are loaded as columns. Select the value that matches your project setup:
| Plans Type value | Use when |
| ------------------------- | --------------------------------------------------------------------------- |
| `PROJECT_PLANS` (default) | Standard Polarion project Plans — iterations, releases, versions |
| `SAFE_SPRINTS` | SAFe iterations (sprints) within a Program; requires Polarion SAFe Solution |
| `SAFE_PFL_SPRINTS` | SAFe sprints at Portfolio level; requires Polarion SAFe Solution |
| `SAFE_PIS` | SAFe Program Increments within a Program; requires Polarion SAFe Solution |
| `SAFE_SIS` | SAFe Program Increments at Solution level; requires Polarion SAFe Solution |
**SAFe Plans types require additional configuration**
Selecting any SAFe Plans Type changes the configuration fields available in the widget parameters panel — the **Plans** query field is replaced by SAFe-specific fields. SAFe modes also require a Polarion SAFe Solution license. If you need a SAFe configuration, contact support for guided setup.
**Configuration fields change by Plans Type**
The **Plan items** section (Scope, Query, Type) and the **Sync to parent** option are only available when **Project Plans** (`PROJECT_PLANS`) is selected. These sections are hidden for SAFe modes because Plans are auto-discovered from the SAFe structure.
***
When using **Project Plans** mode (`PROJECT_PLANS`), use the **Plans** field (`plansQuery`) to specify a Lucene query that filters which Plans appear as columns.
Leave the field empty to load Plans automatically, or enter a query to restrict the set. Example: to show only Plans of a specific type:
```
type:iteration
```
To show Plans matching a custom field value:
```
customFields.team:TeamA
```
**Use Last / Next plan counts to limit the board width**
Instead of writing a query that enumerates specific Plans by ID, use **Show # of last plans** and **Show # of next plans** (see Step 3) to keep the board focused on the current planning window. This approach requires no query maintenance as Plans are created.
***
Two parameters control how many Plans are displayed:
* **Show # of last plans** (`lastPlans`, default `1`) — how many completed or past Plans to include to the left of the current Plan.
* **Show # of next plans** (`nextPlans`, default `5`) — how many upcoming Plans to include to the right.
**Example scenario:** A team currently in *Iteration 6* with `lastPlans = 2` and `nextPlans = 3` will see Iterations 4, 5, 6, 7, 8, and 9 on the board.
**High plan counts affect load time**
Loading many Plans at once increases the number of work items fetched. Keep the window to a practical range (typically 1–2 past, 3–6 future) to avoid slow board rendering on large projects.
***
Turn on the **Show Capacity Load** toggle (`capacityLoad`, default `false`) to display a capacity bar at the top of each Plan column. The capacity bar shows how much of the swimlane's capacity has been consumed by planned work items.
When enabled, hovering over a Plan column's capacity bar opens a tooltip with a detailed capacity breakdown per swimlane.
See [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration) for how to configure the capacity calculation (field, hours per day, normalization, and multi-capacity modes).
***
The **Assign to Parent Plan** toggle controls whether a work item dropped onto a Plan column is also automatically planned into that Plan's parent Plan.
* **Disabled (default):** The work item is planned only in the target Plan (e.g., *Iteration 4*).
* **Enabled:** The work item is planned in both the target Plan and its parent Plan (e.g., *Iteration 4* and *Version 1.0*).
Use this when your project hierarchy requires work items to appear at both iteration and release levels.
***
The **Report Link** field (`planLink`, default: `/polarion/#/project/${plan.objectId.projectId}/plan?id=${plan.objectId.itemId}`) defines a URL that opens when a user clicks a Plan column label. The URL supports template variables resolved per Plan:
| Variable | Resolves to |
| ---------------------------- | ------------------------------------------- |
| `${plan.objectId.projectId}` | The Polarion project ID containing the Plan |
| `${plan.objectId.itemId}` | The Plan's item ID |
**Example — link to a custom Wiki report parameterized by Plan:**
```
/polarion/#/project/${plan.objectId.projectId}/wiki/SPRINT_REPORT?plan=${plan.objectId.itemId}
```
**Leave Report Link at its default to link directly to the Plan**
The built-in default opens the Plan detail page in Polarion. Only change this if you want column clicks to open a custom report or dashboard instead.
***
## Configuration example
The following shows a complete Plans (Columns) configuration for a Scrum team using standard Polarion iterations, displaying one past iteration and four upcoming ones, with capacity load enabled:
| Widget parameter | Value |
| --------------------- | ---------------------------------- |
| `plansMode` | `PROJECT_PLANS` |
| `plansQuery` | `type:iteration` |
| `lastPlans` | `1` |
| `nextPlans` | `4` |
| `capacityLoad` | `true` |
| Assign to Parent Plan | enabled |
| Report Link | *(default — links to Plan detail)* |
***
## Verification
After saving the widget parameters, reload the board. You should now see:
* Plan columns matching your query and count settings, ordered chronologically from past (left) to future (right).
* Capacity bars visible at the top of each column if **Show Capacity Load** is enabled.
* Clicking a Plan column header navigates to the configured report link (or the Plan detail page if using the default).
If columns do not appear, check the [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) to confirm the parameter values were saved, and see [Troubleshooting Common Errors](/planningboard/guides/troubleshooting/common-errors) if Plans remain empty.
***
## See also
* [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) — full widget parameter reference
* [Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration) — configure how work items are grouped into rows
* [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration) — set up capacity fields, hours per day, and normalization
* [Configure Work Items Dataset](/planningboard/guides/configuration/work-items-configuration) — control which work items appear on the board
* [SAFe Planning Workflows](/planningboard/guides/planning/safe-planning) — end-to-end SAFe configuration guidance
**KB Articles**
* Planningboard Widget Parameters
* Planningboard interface & basic interactions
* Planningboard: Customizable Statistics and Capacity Indicators
**Support Tickets**
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#6546](https://support.nextedy.com/helpdesk/tickets/6546)
**Source Code**
* `PlanningBoardWidget.java`
* `Config.java`
* `widget.vm`
* `Item.java`
* `viewSetup.vm`
# Configure Swimlanes (Rows)
Source: https://learn.nextedy.com/planningboard/guides/configuration/swimlanes-configuration
Configure how Nextedy PLANNINGBOARD groups work item cards into horizontal rows by selecting a swimlane assignment type and adjusting supporting options in the widget parameters panel.
## Before you start
* You have an existing Planningboard widget embedded in a Polarion LiveDoc or Wiki page.
* You have edit rights on the page and an active Planningboard license.
* You know which Polarion field or hierarchy you want to use as the grouping dimension (assignee, parent item, enumeration field, project, or SAFe resource).
***
1. Open the page containing your Planningboard widget in Polarion.
2. Switch the page to edit mode (**Edit** button in the Polarion toolbar).
3. Expand the **Tools** panel next to the widget.
4. Click the **Edit** (pencil) button to open the widget parameters panel.
The panel opens on the right side of the page. The **Swimlanes (Rows)** section is roughly halfway down.
***
In the **Swimlanes (Rows)** section, open the **Assignment Type** dropdown. The available options are described below.
### Users (Assignee)
Each swimlane represents one user who holds a specified role in the project. Use this for workload and capacity planning at the individual level.
| Field | Required | Description |
| --------------- | -------- | ------------------------------------------------------------------------------------------------------------------ |
| **User Role** | Yes | Polarion role ID whose members become swimlane rows (e.g. `project_user`) |
| **Report Link** | No | URL template for a report opened when clicking the swimlane label; use `${r.objectId.itemId}` as the user variable |
**Example report link:**
```
/polarion/#/project/PlanningBoard/wiki/SOME_REPORT?user=${r.objectId.itemId}
```
### Parent Item
Each swimlane represents a parent work item (for example, a Feature or Epic). Child items can only be placed in the swimlane of their actual parent — dragging to a different row automatically snaps the card back to its correct parent.
| Field | Required | Description |
| ------------------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| **Sort By** | No | Property used to order parent swimlane rows (e.g. `priority`). Sorting parent swimlanes by a custom property is supported from version 25.9.0. |
| **Parent Role** | No | Link role that defines the parent–child relationship (e.g. `implements`) |
| **Parent Query** | No | Lucene query to restrict which parent items appear as swimlane rows |
| **Filter Parents** | No | Yes / No — whether to limit rows to the parents returned by the query |
| **Report Link** | No | URL template for a report opened when clicking the swimlane label |
**Drag behavior with parent swimlanes**
When **Parent Item** is active you cannot freely assign items to any row. Planningboard enforces the parent–child relationship: dropping a card in the wrong parent swimlane will snap it back to its actual parent's row.
### Enumeration Field
Each swimlane represents one value from a Polarion enumeration custom field. Use this for team, component, priority, or any other enumeration-typed attribute.
| Field | Required | Description |
| --------------- | -------- | ------------------------------------------------------------------------------------- |
| **Field ID** | Yes | The Polarion field identifier (e.g. `team`, `severity`) |
| **Rows Filter** | No | Limits the visible rows to a subset of enum values. An empty filter shows all values. |
| **Report Link** | No | URL template for a report, parameterised by the field value |
**Rows Filter default behavior**
Leaving the **Rows Filter** empty displays every enum value as a swimlane row. Select specific values in the multi-value selector dialog to show only those rows.
**Multi-value enumeration fields**
Support for swimlanes based on **multi-valued** enumeration fields (where a single work item can hold multiple values) is **not yet available**. The product team has committed to implementing this capability. Until then, use single-value enumeration fields for swimlane grouping. If your field validation returns a "field is not enumeration" error, verify that the field is registered as an enumeration type in the Polarion project configuration and rebuild the widget configuration.
### Project
Each swimlane represents one Polarion project. Use this for cross-project planning views where multiple projects share a single board.
| Field | Required | Description |
| --------------- | -------- | ------------------------------------------ |
| **Report Link** | No | URL template for a project-specific report |
### SAFe Assignment Types
Swimlane types designed for Scaled Agile Framework environments — **Program / Solution Teams (SAFe)**, **Agile Release Train Teams (SAFe)**, and **Programs (SAFe)** — are available but require additional configuration. Contact Nextedy support for setup guidance.
### No Swimlanes
Disables row grouping entirely. All cards appear in a single flat view. Use this for high-level planning overviews where swimlane separation is not needed.
***
Two additional options in the **Swimlanes (Rows)** section affect how rows are displayed:
| Property | Default | Description |
| ---------------------- | -------------- | ---------------------------------------------------------------------------------------------------------- |
| `swimlaneSort` | `alphabetical` | Order in which swimlanes are listed. Applies to all assignment types except `none`. |
| `showEmptySwimlanes` | `false` | When `true`, swimlane rows with no cards are still shown on the board. |
| `collapsibleSwimlanes` | `true` | Allows users to collapse or expand individual swimlane rows from the toolbar or by clicking the row label. |
***
1. Click **Save** (or **Apply**) in the widget parameters panel.
2. Reload the page — the board reloads automatically after a parameter save.
3. Verify the swimlane rows appear as expected.
You should now see the board divided into labeled horizontal rows that match the assignment type you configured. Cards are grouped by the chosen criterion, and the toolbar **Collapse all / Expand all** controls work per row.
***
## Configuration example
The following widget parameter scenario configures swimlanes by user assignee, limiting rows to members of the `project_user` role and linking each swimlane label to a per-user capacity report:
```text theme={null}
Swimlanes (Rows)
Assignment Type : Users (Assignee)
User Role : project_user
Report Link : /polarion/#/project/MyProject/wiki/CapacityReport?user=${r.objectId.itemId}
```
To switch to an enumeration field (for example, a `team` field):
```text theme={null}
Swimlanes (Rows)
Assignment Type : Enumeration Field
Field ID : team
Rows Filter : (leave empty to show all teams)
```
***
## Limitations
* **Page parameters in swimlane configuration accept string type only.** Polarion page parameters (`$pageParameters.xxx`) are accepted in swimlane configuration as string values requiring manual text entry. An enum picker dropdown is not currently available. For multi-team deployments where string-entry is not sufficient, create a separate Planningboard page per team and configure swimlanes statically using link roles.
* **Custom Team work item types not supported.** Planningboard's swimlane configuration does not recognise custom Team work item types. Only Nextedy's standard Team work item with its specific custom fields is supported. This differs from Gantt 25.5.0+, which added support for custom team types.
* **Swimlane sort order is coupled to item sort order.** Changing the swimlane sort setting also affects how cards within each swimlane are ordered.
***
## See also
* [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters)
* [User and Assignee Swimlanes](/planningboard/guides/swimlanes/user-swimlanes)
* [Parent Item Swimlanes](/planningboard/guides/swimlanes/parent-item-swimlanes)
* [Enumeration Field Swimlanes](/planningboard/guides/swimlanes/enum-swimlanes)
* [Project Swimlanes](/planningboard/guides/swimlanes/project-swimlanes)
* [SAFe Swimlanes](/planningboard/guides/swimlanes/safe-swimlanes)
* [Sort Swimlanes](/planningboard/guides/swimlanes/sorting-swimlanes)
* [Filter Swimlanes by Plan Range](/planningboard/guides/swimlanes/filtering-by-plan-range)
* [Filter Swimlanes by Team](/planningboard/guides/swimlanes/filtering-by-team)
* [No Swimlanes Mode](/planningboard/guides/swimlanes/no-swimlanes-mode)
* [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration)
**KB Articles**
* Planningboard Widget Parameters
* Swimlane Assignment Types
* Planningboard interface & basic interactions
**Support Tickets**
* [#6681](https://support.nextedy.com/helpdesk/tickets/6681)
* [#6546](https://support.nextedy.com/helpdesk/tickets/6546)
* [#6777](https://support.nextedy.com/helpdesk/tickets/6777)
**Source Code**
* `PlanningBoardWidget.java`
* `licenseReadonly.cy.ts`
* `enum-rows-filter.cy.ts`
* `widget.vm`
* `planningboard.js`
# Configure Unplanned Sidebar
Source: https://learn.nextedy.com/planningboard/guides/configuration/unplanned-sidebar
Set up and control the unplanned sidebar — the backlog panel on the right of the board where cards wait to be dragged into a Plan.
## What the unplanned sidebar does
The Nextedy PLANNINGBOARD layout is split into two sections: the **Planningboard Area** (columns and swimlanes) on the left and the **Unplanned Section** on the right. The unplanned sidebar holds cards that have not yet been assigned to a Plan. You drag cards from the sidebar onto the board to schedule them.
## Prerequisites
* A Planningboard widget already embedded in a Polarion LiveDoc or Wiki page.
* Access to the widget parameters editor (expand the widget's tools menu and click **Edit**).
The unplanned sidebar can be toggled with the **Show Unplanned** toolbar button (the panel icon). If the sidebar is not visible:
1. Locate the toolbar in the upper-left corner of the Planningboard.
2. Click **Show Unplanned** to toggle the sidebar on.
The sidebar appears on the right. Your preference is saved between sessions.
The sidebar can group cards under their parent work items, showing a tree structure. The depth is controlled by the `PARAMETER_US_DEPTH` widget parameter, which sets how many levels of parent work items are loaded.
1. Open the widget parameters editor (expand tools → click **Edit**).
2. Find the **Unplanned Sidebar** section.
3. Set the depth value:
| Depth value | Effect |
| ----------- | ---------------------------------------------------- |
| `0` | No parent grouping — all cards appear as a flat list |
| `1` | Cards grouped under their immediate parent |
| `2` | Two levels of parent hierarchy shown |
**Performance with deep hierarchies**
Loading more levels of parent hierarchy means more work items fetched from Polarion. For large backlogs, keep the depth at `1` or `2`. Deep hierarchies on large projects can slow sidebar loading noticeably.
The parent-child relationships are determined by the `PARAMETER_PARENTS_LINK_ROLE` parameter, which specifies which Polarion link role defines the parent relationship. Set this to the link role ID used in your project for parent-child links (for example, `parent`).
**Example widget parameter configuration:**
```properties theme={null}
PARAMETER_US_DEPTH=1
PARAMETER_PARENTS_LINK_ROLE=parent
```
With these settings, the sidebar groups each card under its direct parent, and uses the `parent` link role to resolve the hierarchy.
You can predefine Polarion queries that users can activate from the sidebar filter, making it easy to surface specific subsets of unplanned cards without typing a query each time.
1. In the widget parameters editor, locate the **Queries** section.
2. Add one or more named queries. Each query has a display name and a Lucene query string.
**Example:** Create a query named `Reviewed` with the Lucene query `status:reviewed`. When a user clicks the funnel icon in the sidebar and selects **Reviewed**, the sidebar shows only cards with status `reviewed`.
**Use queries for sprint preparation**
Define a query for your sprint-ready states (for example, `status:approved`) so the planning team can quickly see which backlog items are ready to drag into the next iteration — without scrolling through unrelated cards.
When a user clicks a card in the unplanned sidebar, the **Work Item Properties** sidebar opens showing configurable fields. These are set via the `PARAMETER_SIDEBAR_FIELDS` widget parameter (defaults to `title`, `status`, `plannedIn`).
1. In the widget parameters editor, find **Sidebar Fields**.
2. Add the field IDs you want users to see when clicking a card.
```properties theme={null}
PARAMETER_SIDEBAR_FIELDS=title,status,plannedIn,assignee
```
Users can also personalize their sidebar view using the **Select Fields** (gear icon) button in the sidebar. Fields added this way apply only to that user and affect all work items of the same type.
## Using sidebar filters at runtime
Once configured, users interact with the sidebar filters in several ways:
**Filter by assignee or team**
Click the funnel icon to filter cards by assignee or team. If custom queries are defined, they appear here as selectable filters.
**Hide verified work items**
Click the upper-right button in the sidebar to filter out cards with the `Verified` status.
**Filter out already-planned verified items**
The **Filter columns** option hides verified cards that are already assigned to a Plan.
**Verified cards cannot be moved**
Once a card with the `Verified` status has been placed on the board, it is locked — it cannot be dragged or unplanned. If you need to reschedule a verified item, change its status first in Polarion.
**Resource filter and query filter are mutually exclusive**
Filtering by resource and filtering by query cannot be active simultaneously. Activating one clears the other. Use **Clear filter** to remove all active filters (this does not clear the search text or the verified toggle).
**Search**
The search box performs real-time, case-insensitive text search across card content and parent names. Search combines with other active filters.
## Verification
After saving the widget parameters, reload the Planningboard page. You should now see:
* The unplanned sidebar showing cards grouped under parent items (if `PARAMETER_US_DEPTH` is `1` or higher).
* The funnel icon in the sidebar, with your custom queries listed when clicked.
* The sidebar header showing an item count in the format `X out of Y work items`.
* Dragging a card from the sidebar onto a Plan column assigns it and removes it from the sidebar.
**Toggle sidebar during planning sessions**
Use the **Show Unplanned** toolbar button to hide the sidebar when you need more horizontal space to review the board, then show it again when you need to drag in more cards.
## See also
* [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters)
* [Configure Work Items Dataset](/planningboard/guides/configuration/work-items-configuration)
* [Manage Unplanned Backlog](/planningboard/guides/planning/unplanned-backlog)
* [Drag and Drop Planning](/planningboard/guides/planning/drag-and-drop)
* [Basic Board Interactions](/planningboard/getting-started/basic-interactions)
**KB Articles**
* Planningboard Widget Parameters
* Planningboard interface & basic interactions
* Planningboard: Customizable Statistics and Capacity Indicators
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#5796](https://support.nextedy.com/helpdesk/tickets/5796)
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
**Source Code**
* `PlanningBoardWidget.java`
* `widget.vm`
* `Config.java`
* `viewSetup.vm`
* `PlanningBoardWidgetRenderer.java`
# Widget Parameters Overview
Source: https://learn.nextedy.com/planningboard/guides/configuration/widget-parameters
Configure the Nextedy PLANNINGBOARD widget parameters to control which work items and Plans appear on your board, how swimlanes are structured, and what capacity data is displayed.
## Before you start
* You must be in **edit mode** on the Polarion LiveDoc or Wiki page that contains the Planningboard widget.
* Expand the **Tools** panel in the Polarion rich page editor, then click the **Edit** button on the widget to open the configuration dialog.
Planningboard supports only one widget instance per Polarion page. Multi-team dashboard layouts that require multiple independent boards must use separate pages — one Planningboard per page.
***
## Parameter groups
The configuration dialog is organized into five groups. The sections below cover each in turn.
***
## 1. Work Items
These parameters define **which work items are loaded** onto the board and how they appear.
| Parameter | What it does |
| -------------------- | ------------------------------------------------------------------------------------------------------------------ |
| **Scope** | Project scope for this board instance (from which projects items will appear) |
| **Query type** | Type of the query |
| **Query** | Query to filter work items shown on the board. |
| **Add Planned** | When enabled, loads all already-planned items in addition to those matched by Type and Query |
| **Sort by** | Defines card sort order within swimlane cells |
| **Dependency Roles** | Link roles to visualize as dependency arrows between cards |
| **Sidebar Fields** | Fields shown in the Work Item Properties sidebar when a card is clicked. Defaults: `Title`, `Status`, `Planned In` |
Users can further personalize sidebar fields using the **gear icon** (Select Fields button) in the sidebar. Those additions apply only to that user and to all work items of the same type — they do not affect the widget's `Sidebar Fields` default.
### Configuration example
A Scrum team tracking Stories and Tasks with effort estimates:
* **Query**: `type:story OR type:task`
* **Sort by**: priority
* **Dependency Roles**: `depends on`
* **Sidebar Fields**: `Title`, `Status`, `Planned In`, `Estimate`
***
## 2. Plans (Columns)
These parameters control **which Polarion Plans appear as columns** and how capacity is displayed.
| Parameter | What it does |
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| **Plans Type** | Plan type / mode for column generation. Options include project plans and SAFe plan types (see note below) |
| **Plans** | Query selecting which Plans to load as columns (`plansQuery`) |
| **Normalization** | Enables capacity normalization across swimlanes. See [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration) |
| **Show # of last plans** | Number of past/completed plans to display (`lastPlans`, default: `1`) |
| **Show # of next plans** | Number of upcoming plans to display (`nextPlans`, default: `5`) |
| **Show Capacity Load** | Enables the capacity bar visualization per Plan column (`capacityLoad`) |
| **Assign to Parent Plan** | When enabled, dropping a card into a Plan also plans it in that Plan's parent Plan |
| **Report Link** | URL template for the link opened when clicking a column label. Supports `${plan.objectId.projectId}` and `${plan.objectId.itemId}` variables |
If you need a SAFe plan type (SAFe Sprints, Program Increments), contact Nextedy support to assist with the configuration — these modes require Polarion SAFe Solution to be present.
With **Assign to Parent Plan** disabled: dragging a card into *Iteration 4* plans it only in Iteration 4. With it enabled: the card is also planned in *Version 1.0* (Iteration 4's parent Plan) automatically.
### Report Link example
```text theme={null}
/polarion/#/project/${plan.objectId.projectId}/wiki/SPRINT_REPORT?plan=${plan.objectId.itemId}
```
***
## 3. Queries (Unplanned Sidebar Filters)
The **Queries** group lets you define named filters that appear in the unplanned section's filter menu.
| Parameter | What it does |
| ----------- | ------------------------------------------------------------------------------------ |
| **Queries** | List of named Lucene queries accessible via the funnel icon in the unplanned section |
Use this to give planners fast access to subsets of the backlog — for example, items with a specific status, type, or component — without changing the main board query.
**Example**: Create a query named `Reviewed` with value `status:reviewed`. It surfaces all reviewed cards under the unplanned section when the filter is enabled.
***
## 4. Swimlanes (Rows)
These parameters control **how work items are grouped into horizontal rows**.
| Parameter | What it does |
| ------------------- | ---------------------------------------------------------------------------------------------------------- |
| **Assignment Type** | The swimlane assignment mode — determines what each row represents |
| **User Role** | (Visible when Assignment Type is user-based) Filters which users appear as swimlane rows |
| **Report Link** | URL template opened when clicking a swimlane label. Supports `${r.objectId.itemId}` for the row's resource |
### Assignment modes
| Mode | Swimlane rows represent | Notes |
| ---------------------------------- | --------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| `Users (Assignee)` | Individual users (assignees) | Supports role filtering and Teams Service integration |
| `Enumeration Field` | Enum field values (e.g., component, priority, team) | Single and multi-value enum fields supported; `status`, `resolution`, and `type` fields are not supported |
| `Parent Item` | Parent work items (via Lucene query) | Does not support plan normalization |
| `Program / Solution TEams (SAFe)` | SAFe teams in the current program | Requires Polarion SAFe Solution |
| `Agile Release Train Teams (SAFe)` | Teams within a specific Agile Release Train | Requires ART ID parameter |
| `Programs (SAFe)` | SAFe programs in a solution train | Requires Polarion SAFe Solution at portfolio level |
| `Project` | Projects within the current project group | Opens a Project Query option below |
Polarion page parameters (`$pageParameters.xxx`) are accepted in swimlane configuration as **string values only** — manual text entry is required; no enum picker dropdown is available. For multi-team deployments where string-entry is not sufficient, create a separate Planningboard page per team and configure swimlanes statically using link roles.
Planningboard swimlane configuration requires Nextedy's standard Team work item type (with its specific custom fields). Custom team work item types are not supported. If your project uses a custom team structure, consider using Nextedy GANTT (25.5.0+), which added support for custom team types.
### Report Link example
```text theme={null}
/polarion/#/project/PlanningBoard/wiki/TEAM_REPORT?user=${r.objectId.itemId}
```
***
## 5. New Plan
When enabled, adds a **plus (+) button** to the board toolbar so users can create new Plans directly from the board.
| Parameter | What it does |
| --------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| **Template ID** | Polarion plan template ID for newly created plans (e.g., `iteration`, `release`) |
| **Parent ID** | If set, new plans are always created under this specific parent Plan |
| **Plan Name Pattern** | Display name pattern for the new Plan's column header |
| **Plan ID Pattern** | ID pattern new Plans should follow |
| **New Plan Duration** | Duration of newly created plans |
| **Enable Teams** | Enables team-based plan creation (creates one plan per team) |
| **Teams** | Name and ID of each Team (when Enable Teams is on) |
| **Last Plan Query** | Lucene query to find the "last plan". Default (empty): finds the latest plan in the same project with the same template type |
| **Last Plan Sort** | How to determine which plan from the query is "last". Default (empty): sorts by `dueDate` descending |
When **Enable Teams** is on, the Plan Name Pattern and Plan ID Pattern fields are pre-populated for team-based naming. If you are **not** using Teams, remember to update these patterns to match your project's naming conventions — the pre-filled defaults assume Teams are present.
During Planningboard setup, you may encounter a template zip file in the plugin distribution. This file does **not** need to be imported via the Polarion Administration UI. Follow the standard installation steps instead; importing the zip is not part of the setup process.
### Example: New Plan without Teams
Configure new iteration plans under a specific parent version:
* **Template ID**: `iteration`
* **Parent ID**: `Version_3_0`
* **Plan Name Pattern**: `Iteration ${lastPlan.counter + 1}`
* **Plan ID Pattern**: `iteration_${lastPlan.counter + 1}`
* **New Plan Duration**: `14d`
* **Enable Teams**: disabled
When the **+** button is clicked, a confirmation window shows the resolved values before the Plan is created.
***
## Verification
After saving the widget configuration, **refresh the page**. You should now see:
* Cards matching your **Query** loaded into the board
* Columns corresponding to the Plans selected by your **Plans** query and count settings
* Swimlane rows reflecting the chosen **Assignment Type**
* The capacity bar visible in each Plan column header (if **Show Capacity Load** is enabled)
* The unplanned section populated with cards not yet assigned to any Plan
If the board appears empty, check that your **Query** is not `NOT *:*` (the default — intentionally loads nothing) and that at least one Plan exists in the selected project scope.
Hover over the capacity bar in any Plan column header to see a detailed tooltip with capacity figures. This is only available when **Show Capacity Load** is enabled in the Plans parameters.
***
## See also
* [Configure Plans (Columns)](/planningboard/guides/configuration/plans-configuration) — detailed Plans query and mode options
* [Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration) — swimlane assignment type setup
* [Configure Work Items Dataset](/planningboard/guides/configuration/work-items-configuration) — query and type filtering
* [Configure Unplanned Sidebar](/planningboard/guides/configuration/unplanned-sidebar) — unplanned section and query filters
* [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration) — capacity load and normalization
* [Configure Dependencies Display](/planningboard/guides/configuration/dependencies-configuration) — dependency link role setup
* [Use Page Parameters](/planningboard/guides/configuration/page-parameters) — parameterizing board configuration per page
# Configure Work Items Dataset
Source: https://learn.nextedy.com/planningboard/guides/configuration/work-items-configuration
Configure which work items appear on your Nextedy PLANNINGBOARD, how they are sorted, what dependency links are visualized, and which fields show in the sidebar preview.
## Before you start
* You have an existing Planningboard widget embedded in a Polarion LiveDoc or Wiki page.
* You can open the widget's configuration panel (expand the widget tools, then click **Edit**).
* You know the Lucene query syntax used in Polarion for filtering work items.
***
1. Navigate to the Polarion page that contains your Planningboard widget.
2. Expand the widget toolbar and click the **Edit** (pencil) icon to open the configuration panel.
3. In the configuration panel, locate the **Parameters for Work Items** section.
***
The **Scope** field defines which Polarion project (or project group) provides work items for this board instance.
* Set **Scope** to the project ID you want the board to draw work items from.
* Leave blank to use the project the page lives in.
When you embed the same board template in multiple projects, leaving **Scope** blank lets each instance automatically draw from its own project.
***
The **Query** field contains a Lucene query that filters which work items are loaded onto the board. The default value in the configuration is `NOT *:*`, which matches nothing — you must set an explicit query.
**Query type** controls how the query string is interpreted:
| Query Type | Use when |
| ---------- | ------------------------------------------------------ |
| Lucene | You want full Lucene query syntax (recommended) |
| SQL-like | You prefer a simplified SQL-like Polarion query format |
**Example queries:**
```text theme={null}
# All user stories and tasks not yet closed
(type:story OR type:task) AND NOT status:closed
# All items in a specific severity category
severity:must_have AND NOT status:done
# Items assigned to a specific user
assignee.id:jsmith AND NOT status:verified
```
**Add Planned** — enable this option to load all work items that are already planned into any Plan, in addition to items matching the **Type** and **Query** fields. Use this when you want the board to show a complete picture of both backlog and already-scheduled items.
The `maxItems` configuration property defaults to `1000`. If your query matches more than 1000 work items, only the first 1000 are loaded. Narrow your query or request a `maxItems` increase from your Polarion administrator if you need more items.
The default query `NOT *:*` intentionally returns no results. After creating a new widget, the board will appear empty until you set a valid query.
***
Use the **Work Item Type** field (`wiType`) to restrict the board to a single work item type, such as `story`, `task`, or `feature`. This is equivalent to adding `type:` to your query but is applied as a separate filter.
* Leave blank to show all types matching the query.
* Set to a single type ID (e.g. `story`) to narrow the dataset.
When using enum-based swimlanes, the available enum values in the rows filter change based on the selected work item type. Different types may have different enumeration configurations — set **Work Item Type** explicitly to ensure the swimlane options match your dataset.
***
The **Sort by** field defines the initial ordering of cards on the board. Cards are sorted within each swimlane according to this setting.
In the current version of Planningboard, the swimlane sort order is coupled to the item sort order. Changing **Sort by** affects how items appear within each swimlane row, not just globally. There is no independent swimlane sort separate from item sort.
***
The **Dependency Roles** field specifies which Polarion work item link roles are visualized as dependency arrows between cards on the board.
* Enter one or more link role IDs (as configured in your Polarion project).
* Dependencies are only shown visually when the **Show Dependencies** toolbar button is toggled on.
**Example:** If your project uses `depends_on` as a link role ID:
```text theme={null}
depends_on
```
The **Show Dependencies** toolbar button must be enabled for arrows to appear. Dependency roles must already exist in your Polarion project's link role configuration — Planningboard does not create link roles.
***
When a user clicks on a card, the **Work Item Properties** sidebar opens. The **Sidebar Fields** parameter controls which fields appear by default in that sidebar.
* Default fields: `title`, `status`, `plannedIn`
* Enter additional field IDs separated by the configured delimiter.
**Example sidebar fields configuration:**
```text theme={null}
title, status, plannedIn, severity, assignee
```
Users can further customize their own sidebar view using the **Select Fields** (gear icon) button in the sidebar. Personal field selections apply only to that user and affect all work items of the same type.
***
1. Save the widget configuration.
2. Reload the Planningboard page.
You should now see cards populating the board according to your query and filters. The sidebar of any clicked card should show the fields you configured.
If you see no cards after saving, check:
* The **Query** field is not still set to `NOT *:*` (the default).
* The **Scope** project contains work items matching your query.
* The **Work Item Type** filter is not excluding all items.
* The `maxItems` limit (default: 1000) has not been silently hit.
***
## Configuration example
The following widget parameter values set up a board for a sprint team working with user stories:
| Parameter | Example value |
| ---------------- | ---------------------------------------------- |
| Scope | `MyProject` |
| Query type | Lucene |
| Query | `type:story AND NOT status:closed` |
| Work Item Type | `story` |
| Add Planned | enabled |
| Sort by | `priority` |
| Dependency Roles | `depends_on` |
| Sidebar Fields | `title, status, plannedIn, assignee, severity` |
***
## Known limitations
* **Custom Team work item types** are not supported for swimlane configuration in Planningboard. If your project uses a custom Team work item type (rather than the standard Nextedy Team work item with required custom fields), swimlane assignment by team is not available. Use Nextedy GANTT (version 25.5.0 and later) if you need custom Team work item type support.
* **Page parameters in work item queries** — dynamic filtering via Polarion page parameters (e.g., `$pageParameters.xxx`) in the swimlane row configuration is not supported. As a workaround, configure a separate Planningboard page per team using static link roles.
* **Multi-assignee capacity** — Planningboard assigns each work item to a single resource for capacity purposes. Multi-assignee capacity distribution (as available in Nextedy GANTT) is not currently supported.
***
## See also
* [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters)
* [Configure Plans (Columns)](/planningboard/guides/configuration/plans-configuration)
* [Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration)
* [Configure Unplanned Sidebar](/planningboard/guides/configuration/unplanned-sidebar)
* [Configure Dependencies Display](/planningboard/guides/configuration/dependencies-configuration)
* [Use Page Parameters](/planningboard/guides/configuration/page-parameters)
* [Dynamic Filtering with Page Parameters](/planningboard/guides/advanced/dynamic-filtering)
**KB Articles**
* Planningboard Widget Parameters
* Planningboard: Customizable Statistics and Capacity Indicators
* Planningboard interface & basic interactions
**Support Tickets**
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
* [#6496](https://support.nextedy.com/helpdesk/tickets/6496)
* [#6546](https://support.nextedy.com/helpdesk/tickets/6546)
**Source Code**
* `PlanningBoardWidget.java`
* `widget.vm`
* `Config.java`
* `viewSetup.vm`
* `PlanningBoardWidgetRenderer.java`
# Customize Board Appearance
Source: https://learn.nextedy.com/planningboard/guides/customization/board-appearance
Adjust the overall visual layout, card sizing, column and swimlane display, and toolbar visibility of your Nextedy PLANNINGBOARD to match your team's planning workflow.
## Overview of appearance controls
Planningboard appearance is shaped by three complementary mechanisms:
| Mechanism | What it controls | Where to configure |
| ----------------- | ------------------------------------------------ | --------------------------------------- |
| Widget parameters | Plans shown, swimlane mode, capacity display | Widget **Advanced Properties** |
| Item Script | Per-card color, label, fields line, height | **Advanced Properties > Item Script** |
| Config Script | Global CSS overrides (card height, title height) | **Advanced Properties > Config Script** |
The sections below address each in turn.
***
The number of Plans (columns) displayed on the board is governed by two widget parameters:
* `lastPlans` — number of past or completed Plans to show (default: `1`)
* `nextPlans` — number of upcoming Plans to show (default: `5`)
Open the widget's **Advanced Properties** panel and set these values to narrow or widen the column range. Showing fewer columns reduces visual noise on large boards; showing more gives teams an extended planning horizon.
**Example — show one past Plan and three upcoming Plans:**
```properties theme={null}
lastPlans=1
nextPlans=3
```
To restrict which Plans appear at all, set `plansQuery` to a Lucene query that matches only the Plans you want:
```properties theme={null}
plansQuery=title:"Sprint*" AND NOT status:closed
```
Reducing `nextPlans` to the number of active sprints keeps the board focused and reduces the time to load capacity data. Very large values (>10) can noticeably slow board rendering.
### Plan header date display
Each column header shows the plan name and its date range on a single line. The year is not repeated if both dates fall within the same year:
If neither a Start nor a Due Date is defined, no value is shown below the plan name:
Start date only: an infinity symbol (∞) is displayed instead of the missing Due date:
Due date only: only the Due date is displayed:
***
Swimlanes (rows) are controlled by the `assignmentMode` widget parameter. The board supports these modes:
| `assignmentMode` value | Groups rows by |
| ---------------------- | -------------------------------------------------- |
| `ASSIGNEE` (default) | Individual users / assignees |
| `ENUM` | An enumeration custom field (e.g. team, component) |
| `PARENT` | Parent work items (matched by a Lucene query) |
| `PROJECT` | Sub-projects within the current project group |
| `SAFE_TEAM` | SAFe teams within the current program |
| `SAFE_TRAIN_TEAM` | Teams within a specific Agile Release Train |
| `SAFE_PROGRAMS` | SAFe programs within a solution train |
Set the mode in **Advanced Properties**:
```properties theme={null}
assignmentMode=ASSIGNEE
```
For the **Enumeration Field** (`ENUM`) mode, also set `enumFieldId` to the custom field ID you want to group by:
```properties theme={null}
assignmentMode=ENUM
enumFieldId=team
```
The **Enumeration Field** (`ENUM`) mode does not support the `status`, `resolution`, or `type` built-in fields. If you specify one of these as `enumFieldId`, swimlanes will not render correctly. Use a custom enumeration field instead.
See [Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration) for the full swimlane configuration reference.
***
Card-level appearance — background color, border color, the fields shown below the title, and optional labels — is controlled by an **Item Script** in the widget's Advanced Properties. The script runs per work item and sets properties on the `cli` object.
### Available `cli` properties
| Property | Type | Effect |
| ---------------- | ------- | -------------------------------------------------- |
| `cli.cardColor` | String | Card background color (HEX or named color) |
| `cli.color` | String | Card frame (border) color |
| `cli.label` | String | Short text label displayed on the card |
| `cli.fieldsLine` | String | HTML rendered below the card title |
| `cli.tooltip` | String | HTML shown on card hover |
| `cli.resolved` | Boolean | Visual resolved state |
| `cli.readonly` | Boolean | Prevent drag-and-drop modification from the script |
### Example — color cards by workflow status
```javascript theme={null}
var status = wi.getStatus().getId();
if (status === "open") {
cli.cardColor = "#e3edff";
} else if (status === "inProgress") {
cli.cardColor = "#fff8e1";
} else if (status === "done") {
cli.cardColor = "#e8f5e9";
}
```
Planningboard card coloring is driven by workflow status values or by explicit scripted logic. **Custom enumeration-based card coloring (as available in Scrumboard) is not supported.** If you need cards colored by a custom enumeration field (e.g. topic category, component), you must implement this manually in the Item Script — there is no built-in enum-to-color mapping. Users migrating from Scrumboard should be aware of this difference.
### Example — color cards by parent item (inherit parent's color)
When child items should share the visual grouping of their parent, define a `pbColor` custom field (type: String) on the parent work item type, populate it with a color name per parent, and use this Item Script:
```javascript theme={null}
cli.readonly = false;
var i = wi.getLinkedWorkItemsStructsDirect().iterator();
var parentItem = null;
while (i.hasNext()) {
var link = i.next();
if (link.getLinkRole() && link.getLinkRole().getId() === "implements") {
parentItem = link.getLinkedItem();
}
}
if (parentItem != null) {
var pbColor = parentItem.getValue("pbColor");
if (pbColor && pbColor.trim() !== "") {
pbColor = pbColor.toLowerCase().trim();
if (pbColor === "blue") cli.cardColor = "#00c3ff";
else if (pbColor === "red") cli.cardColor = "#ff4d4d";
else if (pbColor === "green") cli.cardColor = "#00f57f";
else if (pbColor === "yellow") cli.cardColor = "#ffd700";
}
}
```
Replace `"implements"` with the link role your project uses to connect child items to their parent. You can extend the color list with any HEX code. This pattern works best when each child item has a single parent in the hierarchy.
### Example — customizing the fields line
Show story points, priority, and assignee under the card title:
```javascript theme={null}
cli.fieldsLine =
workitem.fields().get("storyPoints").render().htmlFor().forFrame() +
" sp, " +
workitem.fields().priority().render().withText(true).withIcon(false).htmlFor().forFrame() +
", " +
workitem.fields().assignee().render().htmlFor().forFrame();
```
***
If card titles are long, the default card height may truncate them. Use a **Config Script** to inject a CSS override that increases the title area:
```javascript theme={null}
var style = document.createElement('style');
style.innerHTML = ".eventitem .title { height: 87px; }";
document.head.appendChild(style);
```
Set the `height` value to slightly less than the total card height you intend (set card height in the widget parameters). To find the right value, right-click a card in your browser and choose **Inspect** — the Elements panel shows the live rendered height, which you can override until the content fits cleanly.
The title height set in the Config Script must be smaller than the card's total height, or content will overflow. Always test by inspecting the card in your browser's developer tools after applying the script.
***
The Planningboard toolbar (upper-left) provides toggles for swimlane collapse, data refresh, capacity/resource load visualization, the Unplanned section, prioritization mode, and dependency display. These are runtime controls — no widget parameter is required to show the toolbar.
To control the **Unplanned Sidebar** (the right-hand backlog panel), use the widget parameter `PARAMETER_US_DEPTH` to set how many levels of parent hierarchy load for the unplanned items. Setting a lower depth reduces load time on projects with deep item trees.
Dependencies overlay (the **Show Dependencies** toolbar button) must be explicitly enabled via the `dependencyLinkRole` widget parameter — it is off by default.
```properties theme={null}
dependencyLinkRole=depends_on
```
See [Configure Dependencies Display](/planningboard/guides/configuration/dependencies-configuration) for details.
***
## Board layout reference diagram
Columns = Plans (controlled by `lastPlans` / `nextPlans` / `plansQuery`).
Rows = swimlanes (controlled by `assignmentMode`).
Cards = work items (appearance controlled by Item Script and Config Script).
***
## Verification
After applying your changes, reload the Planningboard page. You should now see:
* The correct number of Plan columns based on your `lastPlans` and `nextPlans` values
* Swimlane rows grouped according to your chosen `assignmentMode`
* Card background colors and field lines reflecting your Item Script logic
* Card title areas tall enough to display full titles without truncation
If cards still appear with default styling after saving the Item Script, check that the script contains no syntax errors — open your browser's developer console (F12) while the board loads to see any JavaScript errors from the script execution.
***
## See also
* [Customize Card Content](/planningboard/guides/customization/card-content) — add or remove fields from card bodies
* [Customize Card Appearance](/planningboard/guides/customization/card-appearance) — card-level styling options
* [Customize Card Colors](/planningboard/guides/customization/card-colors) — color configuration patterns
* [Highlight Work Items by Rules](/planningboard/guides/customization/highlighting-rules) — rule-based card highlighting
* [Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration) — full swimlane configuration
* [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) — complete widget parameter reference
* [Item Scripts](/planningboard/guides/advanced/item-scripts) — scripting API reference
* [Config Scripts](/planningboard/guides/advanced/config-scripts) — global CSS and config scripting
**KB Articles**
* Planningboard: Customizable Statistics and Capacity Indicators
* Planningboard interface & basic interactions
* Customize the content of the card
**Support Tickets**
* [#6612](https://support.nextedy.com/helpdesk/tickets/6612)
* [#6679](https://support.nextedy.com/helpdesk/tickets/6679)
* [#6523](https://support.nextedy.com/helpdesk/tickets/6523)
**Source Code**
* `Config.java`
* `viewLicense.vm`
* `PlanningBoardWidgetRenderer.java`
* `perUserCapacity.cy.ts`
* `capacityHelperData.cy.ts`
# Customize Capacity Indicators
Source: https://learn.nextedy.com/planningboard/guides/customization/capacity-indicators
Adjust how capacity bars and capacity tooltips appear on the Nextedy PLANNINGBOARD so your team can quickly assess load at a glance.
## Prerequisites
Before customizing capacity indicators, ensure you have:
* Capacity tracking enabled on the widget (set `capacityLoad = true` in widget parameters — see [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration))
* At least one Plan with work items assigned to swimlanes
* Widget editor access to the Polarion page hosting the Planningboard
***
## How capacity indicators work
Each column (Plan) on the Planningboard displays a **capacity bar** in the column header when `capacityLoad` is enabled. The bar shows the ratio of allocated effort to the Plan's total capacity. When you hover over the bar, a tooltip shows the breakdown.
***
Planningboard supports three capacity modes, controlled by widget parameters:
| Parameter | Type | Default | Effect |
| ------------------- | ------- | -------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `capacityLoad` | boolean | `false` | Enables column-level capacity bars |
| `multiCapacityLoad` | boolean | `false` | Enables per-swimlane (per-resource) capacity bars |
| `userCapacityLoad` | boolean | `false` | Enables per-user capacity when the Teams service is active |
| `capacityField` | string | *(none)* | Custom field ID supplying capacity values (e.g. story points); falls back to `remainingEstimate`/`initialEstimate` when unset |
| `hoursPerDay` | number | `8` | Conversion factor for time-based effort to daily hours |
Enable the mode that fits your planning context:
* **Column-level only** — set `capacityLoad = true`. A single bar per Plan column shows total load.
* **Per-resource bars** — set both `capacityLoad = true` and `multiCapacityLoad = true`. Each swimlane cell shows its own bar.
* **Per-user capacity with Teams service** — set `capacityLoad = true` and `userCapacityLoad = true` (requires `useTeamsService = true`).
**Whitespace sensitivity**
Capacity configuration parameter values are whitespace-sensitive. Do not add trailing spaces after boolean values such as `true` or `false` in widget parameter fields — they may silently disable the feature.
***
By default, Planningboard derives effort from the work item's `remainingEstimate` and `initialEstimate` time-tracking fields, converting them using `hoursPerDay`.
To use a custom numeric field (for example, story points stored in a field called `storyPoints`):
1. Open the widget parameters for your Planningboard.
2. Set `capacityField = storyPoints` (use the exact Polarion field ID, matching case).
3. Ensure the field is populated on your work items before opening the board.
**Story points vs hours**
When using `capacityField`, the `hoursPerDay` conversion is applied to translate the field value into hours for capacity calculations. If your field already stores hours, set `hoursPerDay = 1` to avoid double conversion.
***
By default, hovering over a capacity bar shows aggregate values: **Capacity**, **Done**, **Todo**, and **Available**.
You can replace this with a custom tooltip template using the `columnTooltipTemplate` configuration option. This is configured via a **Config Script** in the widget's Advanced Properties section.
### Default tooltip (no template configured)
```text theme={null}
Capacity: 40 h
Done: 10 h
Todo: 22 h
Available: 8 h
```
### Custom tooltip with per-user breakdown
The `columnTooltipTemplate` accepts either a static string template or a JavaScript function receiving the column and row objects. The following example adds a per-user allocation breakdown with overallocation highlighting:
```javascript theme={null}
scheduler.columnTooltipTemplate = function(column, row) {
var lines = "" + column.text + " ";
if (column.users) {
column.users.forEach(function(user) {
var available = user.capacity - user.allocated;
var style = available < 0 ? "color:red;" : "";
lines += user.name + ": "
+ "" + available + " "
+ " / " + user.allocated
+ " / " + user.capacity + " h ";
});
}
return lines;
};
scheduler.setCurrentView();
```
**Calling setCurrentView**
After setting or changing `columnTooltipTemplate` programmatically, call `scheduler.setCurrentView()` to trigger a re-render. Without it, the board continues to show the previous tooltip until the next natural refresh.
The tooltip is attached to the `.capacityLoad` element on each Plan column (`.plan[data-col-id]`). The HTML rendered by your template is stored in the `data-html` attribute of that element and shown on hover.
***
Beyond column capacity bars, Planningboard has a **Toggle Resource Load visualization** control in the toolbar. When active, it shows the current load of each assignee directly in the swimlanes.
To enable it:
1. Open the board.
2. Click the **Toggle Resource Load visualization** button in the upper-left toolbar.
This is a per-session toggle — it does not require widget parameter changes.
***
## Capacity indicator layout reference
***
## Common pitfalls
**Capacity bar does not appear**
If no capacity bar is shown despite `capacityLoad = true`, verify that:
* The Plans on the board have a capacity value set in Polarion.
* The `capacityField` value (if set) matches an existing, populated field ID exactly — field IDs are case-sensitive.
* There are no trailing spaces in parameter values (whitespace sensitivity applies).
**multiCapacityLoad shows no per-resource bars**
`multiCapacityLoad` requires `capacityLoad` to also be `true`. Setting only `multiCapacityLoad = true` without the base `capacityLoad` flag does not activate capacity bars.
**Custom tooltip not updating**
If you change `columnTooltipTemplate` in a Config Script, you must call `scheduler.setCurrentView()` at the end of the script. Without this call, the board re-renders on the next data refresh, not immediately.
**Identifying overallocated swimlanes**
In a custom tooltip template, available capacity is negative when a resource is overallocated. Display it in red (e.g. `style={{color: "red"}}`) to make overallocation visible at a glance — this mirrors the built-in overallocation visualization behavior.
***
## Limitations
* **No multi-assignee effort distribution:** When a work item has multiple assignees, Planningboard does not split its effort across them. The full effort is attributed to the primary resource. This is a known gap relative to Nextedy GANTT.
* **No sub-item effort rollup:** Effort on child work items is not automatically aggregated into a parent's capacity contribution on the board.
* **Swimlane sort order is coupled to item sort order:** You cannot sort swimlane rows by capacity independently of the item sort order.
***
## Verification
After applying your changes, refresh the Planningboard. You should now see:
* A colored bar in each Plan column header when `capacityLoad` is enabled.
* Per-swimlane bars in each cell when `multiCapacityLoad` is also enabled.
* The customized tooltip content when hovering over any capacity bar.
If the bars are missing, review the pitfalls above and check [Capacity Calculation Issues](/planningboard/guides/troubleshooting/capacity-issues).
***
## See also
* [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration) — enable and wire up capacity parameters
* [Visualize Capacity Load](/planningboard/guides/capacity/capacity-visualization) — understand what the capacity bar values represent
* [Normalize Capacity Across Swimlanes](/planningboard/guides/capacity/capacity-normalization) — balance capacity display across uneven swimlanes
* [Track Team Capacity](/planningboard/guides/capacity/team-capacity) — team-level capacity with the Teams service
* [Configure Multi-Dimensional Capacity](/planningboard/guides/capacity/multi-capacity) — advanced multi-capacity setup
* [Troubleshoot Capacity Calculation Issues](/planningboard/guides/troubleshooting/capacity-issues)
**KB Articles**
* Planningboard: Customizable Statistics and Capacity Indicators
* Customize the content of the card
* Planningboard interface & basic interactions
**Support Tickets**
* [#6679](https://support.nextedy.com/helpdesk/tickets/6679)
* [#6612](https://support.nextedy.com/helpdesk/tickets/6612)
* [#6523](https://support.nextedy.com/helpdesk/tickets/6523)
**Source Code**
* `Config.java`
* `viewLicense.vm`
* `capacityTooltipRendering.cy.ts`
* `PlanningBoardDataService.java`
* `planningboard.js`
# Customize Card Appearance
Source: https://learn.nextedy.com/planningboard/guides/customization/card-appearance
Control the visual look of cards on your Nextedy PLANNINGBOARD — background color, border color, field layout, and card height — using the Item Script and Config Script in the widget's Advanced Properties.
## What you can change
The following appearance properties are available through the `cli` object in the Item Script:
| Property | Type | Effect |
| ---------------- | ------- | ------------------------------------------------------------------------ |
| `cli.cardColor` | String | Card background color (HEX or named color, e.g. `"#e3edff"` or `"blue"`) |
| `cli.color` | String | Card frame (border) color |
| `cli.label` | String | Short text label shown on the card |
| `cli.fieldsLine` | String | HTML displayed under the card title |
| `cli.tooltip` | String | Text shown when hovering over the card (supports HTML) |
| `cli.resolved` | Boolean | Marks the item as resolved — can trigger visual cues |
| `cli.readonly` | Boolean | When `true`, prevents script-driven card modifications |
Card height is controlled separately via a CSS rule in the Config Script (see [Adjust card height](#adjust-card-height) below).
1. Open the Polarion Wiki page or LiveDoc that contains your Planningboard widget.
2. Switch to **Edit** mode for the page.
3. Click the widget to select it, then open its **Widget Parameters**.
4. Scroll to the **Advanced Properties** section. You will find two script fields:
* **Item Script** — runs once per card, controls per-item appearance.
* **Config Script** — runs once when the board loads, used for board-wide CSS overrides.
Add the following to the **Item Script** to apply a fixed background color to every card:
```javascript theme={null}
cli.cardColor = "#e3edff";
```
To apply color conditionally based on a work item field value (for example, a custom `crType` enumeration field):
```javascript theme={null}
var crType = wi.getValue("crType");
if (crType != null && crType.getId() === "parentCR") {
cli.cardColor = "#e3edff";
}
```
**Use HEX codes for precise colors**
Named colors such as `"blue"` are supported, but HEX codes give you full control over shade and contrast. Pick values that remain legible against white card text.
The `cli.fieldsLine` property controls what appears under the card title. You can combine multiple rendered fields using the `workitem.fields()` rendering API:
```javascript theme={null}
cli.fieldsLine =
workitem.fields().get("initialStoryPoints").render().htmlFor().forFrame() +
" sp, " +
workitem.fields().priority().render().withText(true).withIcon(false).htmlFor().forFrame() +
", " +
workitem.fields().status().render().withText(false).htmlFor().forFrame() +
" " +
workitem.fields().assignee().render().htmlFor().forFrame();
```
**Custom fields must exist and be populated in Polarion**
If a custom field referenced with `workitem.fields().get("fieldId")` does not exist on the work item type, or has no value, the rendered output will be empty — and no error is shown. Verify field IDs match those configured in your Polarion project.
A common pattern is to color child cards based on a color value set on their parent item. This groups related cards visually without manual per-item configuration.
**Prerequisites:**
* Create a custom field named `pbColor` (type: String) on the parent work item type (for example, on your System Requirement type).
* Enter a color value (`blue`, `red`, `green`, `yellow`, or a HEX code) in this field for each parent item.
**Item Script:**
```javascript theme={null}
// Allow editing of card attributes
cli.readonly = false;
// Get all direct links for this work item
var i = wi.getLinkedWorkItemsStructsDirect().iterator();
var systemrequirement = null;
// Identify linked parent System Requirement
while (i.hasNext()) {
var link = i.next();
if (link.getLinkRole() && link.getLinkRole().getId() === "implements") {
systemrequirement = link.getLinkedItem();
}
}
// Apply the parent's color if defined
if (systemrequirement != null) {
var pbColor = systemrequirement.getValue("pbColor");
if (pbColor && pbColor.trim() !== "") {
pbColor = pbColor.toLowerCase().trim();
if (pbColor === "blue") cli.cardColor = "#00c3ff";
else if (pbColor === "red") cli.cardColor = "#ff4d4d";
else if (pbColor === "green") cli.cardColor = "#00f57f";
else if (pbColor === "yellow") cli.cardColor = "#ffd700";
}
}
```
**Replace the link role to match your project**
The script above uses the `"implements"` link role. If your project uses a different relationship name (for example `"refines"` or `"derives"`), replace `"implements"` with the correct link role ID. Wrong link role IDs cause no error — the color simply will not apply.
**Extend to HEX codes**
You can expand the color list to include arbitrary HEX values. Just add more `else if` branches or check `pbColor.startsWith("#")` to pass the value through directly.
If your card titles are long, or if your `cli.fieldsLine` spans multiple lines, increase the card height using the **Config Script**:
```javascript theme={null}
var style = document.createElement('style');
style.innerHTML = ".eventitem .title { height: 87px; }";
document.head.appendChild(style);
```
**Title height must be smaller than the card height widget parameter**
Set the title height slightly smaller than the **Card Height** widget parameter value to prevent content overflow. Use your browser's developer tools (right-click a card → **Inspect**) to test height values in real time before committing a value.
## Scripting API reference
The Item Script has access to three main objects:
| Object | Description |
| ---------- | ----------------------------------------------------------------------------------------------------------------------- |
| `wi` | The current work item via the classic Polarion API (`IWorkItem`). Use `wi.getValue("fieldId")` to read field values. |
| `workitem` | The same item via the rendering API. Use `workitem.fields()` to access field rendering helpers. |
| `cli` | The card's client-side configuration object. Setting properties here controls what is displayed and how the card looks. |
## Card appearance flow
```text theme={null}
Item Script runs (per card)
|
+---> wi.getValue("fieldId") Read raw field values from Polarion
|
+---> workitem.fields()... Build rendered HTML for fieldsLine
|
+---> cli.cardColor = "..." Set background color
+---> cli.color = "..." Set border color
+---> cli.fieldsLine = "..." Set subtitle HTML
+---> cli.label = "..." Set short label text
|
v
Card renders with updated appearance
Config Script runs (once, on board load)
|
+---> inject CSS via document.createElement('style')
|
v
Board-wide style overrides applied (e.g. card height)
```
## Limitation: color by custom enumeration is not supported
Planningboard card coloring through the standard widget configuration is based on workflow status only. **Coloring cards based on a custom enumeration field** (such as a topic category or priority field) via point-and-click configuration is not currently supported.
If you need enumeration-based coloring, use the Item Script approach described above: read the enum field with `wi.getValue("fieldId")`, then map the enum ID to a HEX color and assign it to `cli.cardColor`.
**Parity gap with Scrumboard**
Users migrating from Nextedy Scrumboard may expect custom-enum card coloring to be available as a built-in configuration option. In Planningboard this requires an Item Script workaround. The built-in color configuration applies workflow status colors only.
## Verification
Save the widget parameters and reload the board. You should now see:
* Cards with the background color you configured (solid color or conditionally per item).
* The fields line showing the fields you specified under each card title.
* Cards with adjusted height if you added a Config Script CSS rule.
If colors or fields are not appearing, check: the Item Script for syntax errors (open the browser console), that all referenced field IDs exist on the work item type, and that the `pbColor` custom field is populated on parent items if you are using color inheritance.
## See also
* [Customize Card Content](/planningboard/guides/customization/card-content) — control which fields appear on the card
* [Customize Card Colors](/planningboard/guides/customization/card-colors) — color rules and status-based coloring
* [Highlight Work Items by Rules](/planningboard/guides/customization/highlighting-rules) — rule-based visual highlighting
* [Item Scripts](/planningboard/guides/advanced/item-scripts) — full Item Script API reference
* [Config Scripts](/planningboard/guides/advanced/config-scripts) — board-wide scripting
* [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) — all widget parameters including Card Height
**KB Articles**
* Customize the content of the card
* Planningboard interface & basic interactions
* Planningboard: Customizable Statistics and Capacity Indicators
**Support Tickets**
* [#6679](https://support.nextedy.com/helpdesk/tickets/6679)
* [#6612](https://support.nextedy.com/helpdesk/tickets/6612)
* [#6523](https://support.nextedy.com/helpdesk/tickets/6523)
**Source Code**
* `PlanningBoardWidget.java`
* `licenseReadonly.cy.ts`
* `Config.java`
* `viewLicense.vm`
* `PlanningBoardWidgetRenderer.java`
# Customize Card Colors
Source: https://learn.nextedy.com/planningboard/guides/customization/card-colors
Color-code cards on the Nextedy PLANNINGBOARD to communicate status, priority, or team ownership at a glance using the Item Script.
## Overview
Card colors in Planningboard are set via the **Item Script** in the widget's Advanced Properties. The `cli.cardColor` property accepts any CSS HEX or named color value and can be set conditionally based on any work item field — including workflow status, custom fields, or parent-item relationships.
**Limitation: no built-in custom enumeration coloring**
Planningboard does not support automatic card coloring based on custom enumeration fields (such as topic category or component). This differs from Nextedy SCRUMBOARD, which supports enum-based card coloring out of the box. In Planningboard, all conditional coloring must be implemented via an Item Script.
***
## How to set a card color
### Step 1: Open widget parameters
1. Navigate to the Polarion LiveDoc or Wiki page that contains your Planningboard widget.
2. Enter edit mode and open the widget's **Advanced Properties** section.
3. Locate the **Item Script** field.
### Step 2: Set `cli.cardColor` in the script
Add a JavaScript expression that sets `cli.cardColor` to a color value. The color is applied as the card's background.
**Simplest form — fixed color for all cards:**
```javascript theme={null}
cli.cardColor = "#e3edff";
```
**Conditional color based on a work item field:**
```javascript theme={null}
var crType = wi.getValue("crType");
if (crType != null && crType.getId() === "parentCR") {
cli.cardColor = "#e3edff";
}
```
In this example, `wi` is the current work item (Polarion `IWorkItem`) and `wi.getValue("crType")` reads the `crType` custom field. Replace `"crType"` and `"parentCR"` with your actual field ID and enum ID.
### Step 3: Save and reload
Save the widget configuration and reload the page. Cards matching the condition will display with the new background color.
**Use the browser Inspector to check colors**
Right-click a card and choose **Inspect** to preview the applied background color in real time. This helps you confirm the script is working and lets you fine-tune HEX values visually before committing.
***
## Color cards by parent item
A common pattern is to let child items inherit a color from their parent — for example, all items belonging to the same System Requirement share a color. This makes it easy to trace hierarchy on a dense board.
### Step 1: Create a custom string field on the parent type
In Polarion Administration, add a custom field to your parent work item type:
* **Field ID:** `pbColor` (or any name you choose)
* **Type:** String
### Step 2: Populate the field on parent items
On each parent work item, enter a color name into the `pbColor` field: `blue`, `red`, `green`, or `yellow`.
### Step 3: Add the Item Script
Paste the following into the **Item Script** field in the widget's Advanced Properties:
```javascript theme={null}
// Allow card attributes to be modified by this script
cli.readonly = false;
// Walk direct links to find the parent System Requirement
var i = wi.getLinkedWorkItemsStructsDirect().iterator();
var systemrequirement = null;
while (i.hasNext()) {
var link = i.next();
if (link.getLinkRole() && link.getLinkRole().getId() === "implements") {
systemrequirement = link.getLinkedItem();
}
}
// Apply the parent's color to this card
if (systemrequirement != null) {
var pbColor = systemrequirement.getValue("pbColor");
if (pbColor && pbColor.trim() !== "") {
pbColor = pbColor.toLowerCase().trim();
if (pbColor === "blue") cli.cardColor = "#00c3ff";
else if (pbColor === "red") cli.cardColor = "#ff4d4d";
else if (pbColor === "green") cli.cardColor = "#00f57f";
else if (pbColor === "yellow") cli.cardColor = "#ffd700";
}
}
```
**Adjust the link role for your project**
The script uses the `"implements"` link role to identify the parent. If your project uses a different link role (e.g. `"is_part_of"` or a custom role), replace `"implements"` with that role's ID — use the exact ID as configured in Polarion, not the display label.
**Extend the color list with HEX codes**
You are not limited to named colors. Replace or extend the `if/else` block with any HEX values:
```javascript theme={null}
if (pbColor === "teal") cli.cardColor = "#009688";
```
***
## Item Script API reference
The table below lists the `cli` properties relevant to card color customization. These are the confirmed properties available inside an Item Script.
| Property | Type | Description |
| ---------------- | ------- | ----------------------------------------------------------------------------------- |
| `cli.cardColor` | String | Background color of the card. Accepts CSS HEX (`#e3edff`) or named colors (`blue`). |
| `cli.color` | String | Frame (border) color of the card. |
| `cli.readonly` | Boolean | Set to `false` to allow the script to write card attributes. |
| `cli.fieldsLine` | String | HTML text displayed below the card title. |
| `cli.label` | String | Short text label shown on the card. |
| `cli.tooltip` | String | Text shown when hovering over the card (supports HTML). |
The main objects available in every Item Script:
| Object | Description |
| ---------- | --------------------------------------------------------------------------------------------------------------------- |
| `wi` | The current work item via the classic Polarion API (`IWorkItem`). Use `wi.getValue("fieldId")` to read custom fields. |
| `workitem` | The same item via the rendering API. Use `workitem.fields()` to access field renderers. |
| `cli` | The client-side card configuration object. Properties set here control what the card displays and how it looks. |
***
## Decision guide: which approach to use
***
## Verification
After saving the Item Script and reloading the page, you should now see:
* Cards that match your condition displaying the assigned background color.
* Cards that do not match the condition retaining the default (uncolored) appearance.
* If you implemented parent-color inheritance, all child items linked to the same parent appear with the same color.
If cards show no color change, verify that:
1. The `cli.readonly = false;` line is present if needed.
2. The field ID and enum ID strings match exactly what is configured in Polarion (IDs are case-sensitive).
3. The `pbColor` field (or equivalent) is populated on the parent items.
4. The correct link role ID is used in `getLinkRole().getId()`.
***
## See also
* [Customize Card Content](/planningboard/guides/customization/card-content) — control which fields and HTML appear on card faces
* [Customize Card Appearance](/planningboard/guides/customization/card-appearance) — adjust card height, layout, and overall style
* [Highlight Work Items by Rules](/planningboard/guides/customization/highlighting-rules) — rule-based highlighting for items such as those planned after their due date
* [Item Scripts](/planningboard/guides/advanced/item-scripts) — full reference for the Item Script API and scripting patterns
* [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) — all widget parameters including the Advanced Properties section where Item Script is configured
**KB Articles**
* Customize the content of the card
* Planningboard: Customizable Statistics and Capacity Indicators
* Planningboard interface & basic interactions
**Support Tickets**
* [#6679](https://support.nextedy.com/helpdesk/tickets/6679)
* [#6612](https://support.nextedy.com/helpdesk/tickets/6612)
* [#6523](https://support.nextedy.com/helpdesk/tickets/6523)
**Source Code**
* `PlanningBoardWidget.java`
* `licenseReadonly.cy.ts`
* `Item.java`
* `Plan.java`
* `Config.java`
# Customize Card Content
Source: https://learn.nextedy.com/planningboard/guides/customization/card-content
Configure what information appears on each card using the Item Script in the Nextedy PLANNINGBOARD widget's Advanced Properties.
Cards in Planningboard display work item data by default, but you can tailor the visible fields, layout, and colors to match your team's planning workflow. Customization is done through a JavaScript-based **Item Script** that runs for each card as the board renders.
## Prerequisites
* The Planningboard widget is embedded in a Polarion LiveDoc or Wiki page
* You have editor access to the widget's Advanced Properties
***
1. Open the Polarion page containing your Planningboard widget.
2. Switch to **Edit** mode on the page.
3. Click the widget to select it, then open its properties.
4. Navigate to **Advanced Properties** and locate the **Item Script** field.
This script runs once per card and has access to three objects:
| Object | Description |
| ---------- | ------------------------------------------------------------------------------------------------------------ |
| `wi` | The current work item via the classic Polarion API (`IWorkItem`). Use for reading field values and links. |
| `workitem` | The same item through the rendering API. Use for building rendered HTML output (`workitem.fields()`, etc.). |
| `cli` | The card's client-side configuration. Set properties on this object to control display, color, and behavior. |
***
Assign an HTML string to `cli.fieldsLine` to control what appears under the card title. You can render multiple fields and separate them with commas, spaces, or ` ` line breaks.
```javascript theme={null}
cli.fieldsLine =
workitem.fields().get("initialStoryPoints").render().htmlFor().forFrame() +
" sp, " +
workitem.fields().priority().render().withText(true).withIcon(false).htmlFor().forFrame() +
", " +
workitem.fields().status().render().withText(false).htmlFor().forFrame() +
" " +
workitem.fields().assignee().render().htmlFor().forFrame();
```
The `workitem.fields().get("fieldId")` pattern accesses any standard or custom field by its Polarion field ID. Chain `.render().htmlFor().forFrame()` to produce the formatted HTML fragment.
***
You can branch on any field value to render different content for different item types. The following example reads a custom enumeration field (`crType`) and applies a distinct fields line and card color for a specific value:
```javascript theme={null}
var crType = wi.getValue("crType");
if (crType != null && crType.getId() === "parentCR") {
cli.fieldsLine =
workitem.fields().get("swagEstimate").render().htmlFor().forFrame() +
", " +
workitem.fields().priority().render().withText(true).withIcon(false).htmlFor().forFrame() +
", " +
workitem.fields().status().render().withText(false).htmlFor().forFrame() +
" " +
workitem.fields().assignee().render().htmlFor().forFrame() +
" [" +
workitem.fields().get("vendorTeam").render().htmlFor().forFrame() +
"]";
cli.cardColor = "#e3edff";
} else {
cli.fieldsLine =
workitem.fields().get("initialStoryPoints").render().htmlFor().forFrame() +
" sp, " +
workitem.fields().priority().render().withText(true).withIcon(false).htmlFor().forFrame() +
", " +
workitem.fields().status().render().withText(false).htmlFor().forFrame() +
" " +
workitem.fields().assignee().render().htmlFor().forFrame() +
" [" +
workitem.fields().get("solutionTeam").render().htmlFor().forFrame() +
"]";
}
```
***
A common pattern is to color child cards based on a color value stored on their parent. This makes it easy to visually group items that belong to the same parent work item.
**Set up the custom field on the parent type:**
1. In Polarion Administration, add a custom field of type `String` to the parent work item type. Name it `pbColor` (or any ID you choose).
2. For each parent item, enter a color value in this field: `blue`, `red`, `green`, `yellow`, or any valid CSS hex code.
**Add the following to the Item Script:**
```javascript theme={null}
// Allow the script to modify card attributes
cli.readonly = false;
// Traverse direct links to find the parent
var i = wi.getLinkedWorkItemsStructsDirect().iterator();
var systemrequirement = null;
while (i.hasNext()) {
var link = i.next();
if (link.getLinkRole() && link.getLinkRole().getId() === "implements") {
systemrequirement = link.getLinkedItem();
}
}
// Apply parent color if set
if (systemrequirement != null) {
var pbColor = systemrequirement.getValue("pbColor");
if (pbColor && pbColor.trim() !== "") {
pbColor = pbColor.toLowerCase().trim();
if (pbColor === "blue") cli.cardColor = "#00c3ff";
else if (pbColor === "red") cli.cardColor = "#ff4d4d";
else if (pbColor === "green") cli.cardColor = "#00f57f";
else if (pbColor === "yellow") cli.cardColor = "#ffd700";
}
}
```
**Replace the link role if needed**
The script uses the `implements` link role to traverse to the parent. Replace `"implements"` with whichever link role your project uses to represent the parent-child relationship. Using the wrong role means no parent is found and no color is applied — with no error shown on the card.
**Extend the color palette**
You can add additional `else if` branches for any named colors, or skip the name-mapping entirely and write hex codes directly into the `pbColor` field (e.g. `#e3edff`). Apply the value directly: `cli.cardColor = pbColor;`
***
If your work item titles are long, they may be clipped at the default card height. You can increase the title area by injecting a CSS rule through the **Config Script** (a separate field in the same Advanced Properties section).
```javascript theme={null}
var style = document.createElement('style');
style.innerHTML = ".eventitem .title { height: 87px; }";
document.head.appendChild(style);
```
**Keep title height smaller than card height**
Set the title height to a value slightly smaller than the overall card height you have configured. If the title height equals or exceeds the card height, content below the title will be hidden or overflow. Use your browser's **Inspect** tool (right-click a card → **Inspect**) to preview height values in real time before finalizing.
***
## Available `cli` properties reference
The table below lists all `cli` properties available in the Item Script.
| Property | Type | Description |
| ---------------- | ------- | ------------------------------------------------------------------------------------------------------ |
| `cli.fieldsLine` | String | HTML displayed under the card title. Supports multi-line via ` `. |
| `cli.cardColor` | String | Card background color. Accepts HEX (`#e3edff`) or CSS named colors. |
| `cli.color` | String | Card frame (border) color. |
| `cli.label` | String | Short text label displayed on the card. |
| `cli.tooltip` | String | Text shown on card hover. Supports HTML. |
| `cli.text` | String | General additional text content on the card. |
| `cli.effort` | Float | Numeric effort value; can be used in calculations or display. |
| `cli.resolved` | Boolean | Whether the item is resolved. Can drive visual cues. |
| `cli.readonly` | Boolean | When `true`, prevents script-driven card modifications. Set to `false` to allow changes in the script. |
***
## Card content flow
```text theme={null}
Polarion work item (wi / workitem)
|
v
+---------------------------+
| Item Script |
| reads fields via wi / |
| workitem rendering API |
+---------------------------+
|
v
cli object properties set
(fieldsLine, cardColor, label…)
|
v
+---------------------------+
| Card rendered on board |
| title + fieldsLine HTML |
| background = cardColor |
+---------------------------+
```
***
## Limitations
**Card coloring is status-based by default**
Out of the box, Planningboard colors cards by workflow status. Custom enumeration-based coloring (as available in Nextedy SCRUMBOARD) is not natively supported — it requires an Item Script like the ones above. If you need coloring based on an arbitrary custom enum field, you must implement the mapping manually in the script.
***
## Verification
Save the widget, exit Edit mode, and reload the board. You should now see:
* The fields you specified in `cli.fieldsLine` appearing under each card's title
* Any conditional background colors applied to matching cards
* Parent-color inheritance visible across child cards that have a populated `pbColor` field on the parent
If cards look unchanged, confirm the Item Script was saved (re-open Advanced Properties and check the field is not empty) and that any custom fields referenced in the script exist and are populated in Polarion.
***
## See also
* [Customize Card Appearance](/planningboard/guides/customization/card-appearance)
* [Customize Card Colors](/planningboard/guides/customization/card-colors)
* [Highlight Work Items by Rules](/planningboard/guides/customization/highlighting-rules)
* [Item Scripts](/planningboard/guides/advanced/item-scripts)
* [Config Scripts](/planningboard/guides/advanced/config-scripts)
* [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters)
**KB Articles**
* Customize the content of the card
* Planningboard interface & basic interactions
* Planningboard: Customizable Statistics and Capacity Indicators
**Support Tickets**
* [#6612](https://support.nextedy.com/helpdesk/tickets/6612)
* [#6679](https://support.nextedy.com/helpdesk/tickets/6679)
* [#6523](https://support.nextedy.com/helpdesk/tickets/6523)
**Source Code**
* `PlanningBoardWidget.java`
* `licenseReadonly.cy.ts`
* `viewLicense.vm`
* `Config.java`
* `PlanningBoardWidgetRenderer.java`
# Highlight Work Items by Rules
Source: https://learn.nextedy.com/planningboard/guides/customization/highlighting-rules
Use highlighting rules to visually flag work items that need attention — for example, cards planned after their due date — so planners can spot scheduling problems at a glance.
## How the default highlight works
Since version **25.10.0**, Nextedy PLANNINGBOARD automatically highlights work items that are placed in a Plan whose end date falls after the work item's own **Due Date** field. These cards receive a red frame to signal the scheduling conflict.
The comparison logic is:
* Planningboard reads the **Due Date** field of each work item.
* It compares that date against the **end date of the Plan column** the card occupies.
* If the work item's due date is earlier than the plan's end date, the card is highlighted in red.
For example: a Plan ends on September 7, but a work item's due date is August 5. Because August 5 is earlier than September 7, Planningboard flags the card automatically.
No widget parameter is required to enable this — the behavior is on by default from version 25.10.0 onward.
***
## Customize the highlight with an Item Script
The default red frame can be replaced or extended using an **Item Script**. The script runs for each card and lets you change the frame color, background color, or both.
### Step 1 — Open widget parameters
Open the Polarion page that contains your Planningboard widget. Enter edit mode and open the widget configuration panel.
### Step 2 — Navigate to the Item Script field
Go to **Widget Parameters → Advanced → Item Script**.
### Step 3 — Enter your highlighting script
Paste a script that checks the due date condition and sets the visual properties you want. The example below changes the default red frame to orange and adds a soft orange card background:
```javascript theme={null}
if (wi.getDueDate() != null && cli.planEndDate != null
&& wi.getDueDate().getDate().getTime() < cli.planEndDate.getTime()) {
cli.color = "orange";
cli.cardColor = "#f3e2c2";
}
```
### Step 4 — Save and reload the board
Save the widget parameters and reload the page. Cards meeting the condition will now display with the orange frame and background instead of the default red frame.
***
## Item Script properties for highlighting
The following properties are available when writing a highlight rule in the Item Script:
| Property | Type | Purpose |
| ----------------- | ------ | ------------------------------------------------------------------------------ |
| `wi.getDueDate()` | Method | Returns the work item's Due Date field value, or `null` if unset |
| `cli.planEndDate` | Date | The end date of the Plan column where the card is placed |
| `cli.color` | String | Sets the **frame (border) color** of the card (CSS color value or named color) |
| `cli.cardColor` | String | Sets the **background color** of the card (CSS color value or hex code) |
**Null checks are required**
Always guard against `null` before comparing dates. If `wi.getDueDate()` is `null` (the work item has no due date set) or `cli.planEndDate` is `null`, the comparison will throw an error and the script will fail silently for that card.
***
## Example: color by priority
You can extend the same pattern to apply different highlights based on other work item fields. For example, to use a stronger color for high-priority overdue items:
```javascript theme={null}
if (wi.getDueDate() != null && cli.planEndDate != null
&& wi.getDueDate().getDate().getTime() < cli.planEndDate.getTime()) {
if (wi.getPriority() != null && wi.getPriority().getId() === "high") {
cli.color = "red";
cli.cardColor = "#fce4e4";
} else {
cli.color = "orange";
cli.cardColor = "#f3e2c2";
}
}
```
**Use Item Scripts for multiple conditions**
A single Item Script can apply multiple highlight rules sequentially. Each condition block can set `cli.color` and `cli.cardColor` independently. The last block to match wins, so order conditions from lowest to highest priority.
***
## Diagram: how highlighting is evaluated
```text theme={null}
For each card on the board
|
v
wi.getDueDate() present?
| |
No Yes
| |
(no highlight) v
cli.planEndDate present?
| |
No Yes
| |
(no highlight) v
dueDate < planEndDate?
| |
No Yes
| |
(no highlight) Apply cli.color
and cli.cardColor
from Item Script
(default: red frame)
```
***
## Pitfalls and limitations
**Default highlight requires version 25.10.0 or later**
The automatic red-frame highlight for overdue items was introduced in version **25.10.0**. On earlier versions, no default highlight appears. To check your version, go to **Administration > Nextedy PLANNINGBOARD** and look at the installed version number.
**Item Script errors suppress the highlight silently**
A syntax error or uncaught exception in the Item Script will prevent the highlighting logic from running for affected cards. If your customized highlight stops appearing, check the browser console for script errors. See [Script Errors](/planningboard/guides/troubleshooting/script-errors) for diagnosis steps.
**Card coloring is not enumeration-based**
Planningboard card coloring (including highlights set via `cli.color` and `cli.cardColor`) is driven by Item Scripts, not by custom enumeration fields. Unlike Scrumboard, Planningboard does not support custom-enum-based card coloring out of the box. If you need color to reflect an enumeration value, read the field in the Item Script and map it to a color manually.
***
## Verification
After saving the widget parameters and reloading the board, scan for cards that are placed in Plans whose end date is later than each card's due date. Those cards should display with the frame color defined in your script (or the default red if no script is set). Cards without a due date, or cards placed in Plans that end before their due date, should remain unhighlighted.
***
## See also
* [Customize Card Appearance](/planningboard/guides/customization/card-appearance) — change card layout and visual style beyond highlighting
* [Customize Card Colors](/planningboard/guides/customization/card-colors) — set card colors based on status or other rules
* [Item Scripts](/planningboard/guides/advanced/item-scripts) — full reference for the Item Script API
* [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) — where to find the Advanced → Item Script field
* [Script Errors](/planningboard/guides/troubleshooting/script-errors) — diagnose Item Script failures
**KB Articles**
* Planningboard: Customizable Statistics and Capacity Indicators
* Planningboard interface & basic interactions
* Highlight Work Items planned after their due date
**Support Tickets**
* [#6679](https://support.nextedy.com/helpdesk/tickets/6679)
* [#6612](https://support.nextedy.com/helpdesk/tickets/6612)
* [#6496](https://support.nextedy.com/helpdesk/tickets/6496)
**Source Code**
* `unplanned_sidebar.js`
* `PlanningBoardWidget.java`
* `Item.java`
* `customProgressTooltip.cy.ts`
* `perUserCapacity.cy.ts`
# Customization
Source: https://learn.nextedy.com/planningboard/guides/customization/index
Nextedy PLANNINGBOARD gives you fine-grained control over how work items appear on the board — from the fields shown on each card to the colors, progress bars, and capacity indicators that make planning infor
## Card Appearance and Content
**[Customize Card Content](/planningboard/guides/customization/card-content)** — Choose which work-item fields appear on each card: title, assignee, estimate, custom fields, and more.
**[Customize Card Appearance](/planningboard/guides/customization/card-appearance)** — Control the size, layout, and visual style of cards on the board.
**[Customize Card Colors](/planningboard/guides/customization/card-colors)** — Assign colors to cards based on work-item field values or enumeration types to make item categories visually distinct.
## Highlighting and Rules
**[Highlight Work Items by Rules](/planningboard/guides/customization/highlighting-rules)** — Define rules that highlight cards meeting specific conditions, such as items planned after their due date or items exceeding capacity.
## Indicators and Bars
**[Customize Progress Bars](/planningboard/guides/customization/progress-bars)** — Configure the progress bar shown on each card to reflect estimate consumption, child-item completion, or other metrics.
**[Customize Capacity Indicators](/planningboard/guides/customization/capacity-indicators)** — Tailor how the capacity bar and load indicators are displayed per swimlane.
## Additional Visual Elements
**[Customize Tooltips](/planningboard/guides/customization/tooltips)** — Define the content shown in the hover tooltip for cards, including additional fields not visible on the card face.
**[Customize Board Appearance](/planningboard/guides/customization/board-appearance)** — Adjust board-level visual settings such as column widths and overall layout options.
***
**Start with card content**
If you are new to Planningboard customization, begin with [Customize Card Content](/planningboard/guides/customization/card-content) — the fields you surface on the card face have the most impact on planning readability. Color coding and highlighting rules build naturally on top of that.
**KB Articles**
* Customize the content of the card
* Planningboard: Customizable Statistics and Capacity Indicators
* Planningboard interface & basic interactions
**Support Tickets**
* [#6612](https://support.nextedy.com/helpdesk/tickets/6612)
* [#6679](https://support.nextedy.com/helpdesk/tickets/6679)
* [#6523](https://support.nextedy.com/helpdesk/tickets/6523)
**Source Code**
* `Config.java`
* `PlanningBoardWidget.java`
* `PlanningBoardWidgetRenderer.java`
* `viewLicense.vm`
* `licenseReadonly.cy.ts`
# Customize Progress Bars
Source: https://learn.nextedy.com/planningboard/guides/customization/progress-bars
Configure how Nextedy PLANNINGBOARD displays progress bars in Plan columns and swimlane cells so your team can read capacity and work-item status at a glance.
## What progress bars show
Planningboard renders two levels of progress bar when capacity load visualization is enabled:
* **Column header bars** — appear in the calendar header above each Plan column and aggregate all work items in that time period across every swimlane.
* **Cell bars** — appear inside individual Planningboard cells and show progress for a specific swimlane–Plan intersection.
Each bar is divided into up to four colored segments, one per status category:
| Segment color | Status category |
| ------------- | ------------------------------- |
| Green | Done |
| Blue | Todo |
| Red | Invalid |
| Orange | Rejected |
| Gray | Mixed / multiple other statuses |
Each segment displays a numeric count label showing exactly how many work items belong to that category. When all status counts are zero, Planningboard automatically falls back to the default four-segment bar to prevent an empty or confusing visualization.
Hovering over a progress bar shows a tooltip with the full status breakdown — this is useful when segments are too narrow to read the count labels clearly.
***
Progress bars are only rendered when capacity load is turned on for the widget. Open the widget parameters for your Planningboard and set `capacityLoad` to `true`:
```properties theme={null}
capacityLoad = true
```
**Default value:** `false`
Save the widget and reload the page. Column header bars will now appear above each Plan column.
**All Plans must use a consistent calculation type**
If your Plans use mixed calculation types (for example, some using remaining estimate and others using time-spent), the totals shown in progress bars will be incorrect. This is a non-obvious requirement — configure all Plans in the project to use the same calculation type before enabling capacity load visualization. See [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration) for details.
***
Planningboard supports three capacity modes that affect how progress bars are calculated and where they appear.
### Single (column-level) capacity
The default when `capacityLoad = true`. A single progress bar appears in each Plan column header. All swimlane cells share the same column total.
```properties theme={null}
capacityLoad = true
multiCapacityLoad = false
userCapacityLoad = false
```
### Per-resource (cell-level) capacity
Set `multiCapacityLoad = true` to render a separate progress bar inside each swimlane cell. Each cell shows its own capacity progress independently of other cells in the same column.
```properties theme={null}
capacityLoad = true
multiCapacityLoad = true
```
Use this mode when different swimlanes (for example, different assignees or teams) have different capacity allocations and you want per-cell visibility.
### User capacity
Set `userCapacityLoad = true` together with Teams Service integration to load per-user capacity values from the Teams Service:
```properties theme={null}
capacityLoad = true
userCapacityLoad = true
useTeamsService = true
```
**Enable Teams Service for per-swimlane capacity visualization**
The `useTeamsService = true` property unlocks per-swimlane capacity visualization when combined with `userCapacityLoad`. Without it, individual user capacity data is not available to the board. See [Set Up Teams Service](/planningboard/guides/capacity/teams-service-setup) for the Teams Service prerequisite setup.
***
Tell the board which work-item field holds the effort value used to calculate how full each progress bar segment is:
```properties theme={null}
capacityField = storyPoints
```
Replace `storyPoints` with your project's field ID (for example, `estimate`, `timeSpent`, or a custom field ID). If `capacityField` is not set, Planningboard uses the default effort field.
Also confirm the number of working hours per day used in capacity math:
```properties theme={null}
hoursPerDay = 8
```
**Default:** `8`
***
After saving all widget parameters, reload the board. You should now see:
* Colored progress bars appearing in the calendar header above each Plan column.
* Numeric labels inside each segment showing the item count for that status category.
* (If `multiCapacityLoad = true`) Individual progress bars inside each swimlane–Plan cell.
* A detailed status breakdown tooltip when hovering over any bar.
If bars appear but all segments are gray, check that your work items have recognized status values that map to the Done / Todo / Invalid / Rejected categories. If all segments read zero and the bar reverts to the default four-segment display, there are no work items in the queried Plans — verify your Plan query and work-item query parameters.
***
## Configuration example
The following widget parameter block shows a complete capacity-enabled configuration for a team board where each assignee swimlane needs its own capacity bar:
```properties theme={null}
capacityLoad = true
multiCapacityLoad = true
userCapacityLoad = false
capacityField = storyPoints
hoursPerDay = 8
useTeamsService = false
```
For a Teams Service-integrated board with per-user capacity:
```properties theme={null}
capacityLoad = true
multiCapacityLoad = false
userCapacityLoad = true
useTeamsService = true
capacityField = estimate
hoursPerDay = 8
```
**Whitespace in capacity parameters**
Capacity configuration parameters are whitespace-sensitive. Do not add leading or trailing spaces around the `=` sign or the values. A value like `capacityLoad = true ` (trailing space) may not be parsed correctly and will silently produce no progress bars.
***
## Known limitations
* Progress bar coloring is based on work-item **workflow status categories** only. Custom enumeration fields cannot be used to color-code progress bar segments. This is a current product limitation — users migrating from Nextedy SCRUMBOARD should be aware that SCRUMBOARD's custom-enum coloring is not available in Planningboard.
* Multi-assignee work items and sub-item effort distribution are not reflected in capacity bars. Each work item's effort is counted once under its primary assignee. See [Capacity Calculation Issues](/planningboard/guides/troubleshooting/capacity-issues) if totals look unexpected.
* The `PARENT` swimlane assignment mode does not support `planCellsMode`; cell-level bars are not available in that configuration.
***
## See also
* [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration)
* [Visualize Capacity Load](/planningboard/guides/capacity/capacity-visualization)
* [Track Team Capacity](/planningboard/guides/capacity/team-capacity)
* [Set Up Teams Service](/planningboard/guides/capacity/teams-service-setup)
* [Customize Capacity Indicators](/planningboard/guides/customization/capacity-indicators)
* [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters)
* [Capacity Calculation Issues](/planningboard/guides/troubleshooting/capacity-issues)
**KB Articles**
* Planningboard: Customizable Statistics and Capacity Indicators
* Planningboard interface & basic interactions
* Customize the content of the card
**Support Tickets**
* [#6612](https://support.nextedy.com/helpdesk/tickets/6612)
* [#6496](https://support.nextedy.com/helpdesk/tickets/6496)
* [#6679](https://support.nextedy.com/helpdesk/tickets/6679)
**Source Code**
* `customProgressBar.cy.ts`
* `customProgressTooltip.cy.ts`
* `viewLicense.vm`
* `PlanningBoardWidgetRenderer.java`
* `planningboard.js`
# Customize Tooltips
Source: https://learn.nextedy.com/planningboard/guides/customization/tooltips
Configure what appears when users hover over cards and capacity bars on the Nextedy PLANNINGBOARD.
Planningboard surfaces two distinct tooltip types:
* **Card tooltips** — shown when hovering over a work item card on the board
* **Capacity tooltips** — shown when hovering over the capacity bar of a Plan column
Both are configurable through scripting. Card tooltips use the `cli.tooltip` property in an Item Script; capacity column tooltips use the `columnTooltipTemplate` configuration option.
***
## Before you begin
* You need edit access to the Planningboard widget parameters on the LiveDoc or Wiki page.
* Familiarity with the `wi` and `cli` scripting objects helps — see [Customize Card Content](/planningboard/guides/customization/card-content) for an introduction to Item Script.
* Capacity tooltips require capacity loading to be enabled (`capacityLoad = true`). See [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration).
***
## Customize card tooltips
Card tooltips appear when a user hovers over any work item card on the board. By default, no custom tooltip is set. You define the tooltip content using the `cli.tooltip` property inside the **Item Script**.
### Step 1: Open the widget parameters
Open the page containing the Planningboard widget in edit mode and open the **Advanced Properties** section of the widget.
### Step 2: Add an Item Script
In the **Item Script** field, set `cli.tooltip` to any string. The value supports HTML for richer formatting.
**Example — show the work item ID and description on hover:**
```javascript theme={null}
cli.tooltip = "" + wi.getId() + " " + wi.getDescription();
```
**Example — show a custom field value in the tooltip:**
```javascript theme={null}
var riskLevel = wi.getValue("riskLevel");
if (riskLevel != null) {
cli.tooltip = "Risk: " + riskLevel.getName();
} else {
cli.tooltip = wi.getTitle();
}
```
**Example — show assignee and status together:**
```javascript theme={null}
cli.tooltip =
workitem.fields().assignee().render().htmlFor().forFrame() +
" — " +
workitem.fields().status().render().withText(true).htmlFor().forFrame();
```
### Step 3: Save and verify
Save the widget. Hover over any card on the board. The tooltip should appear with the content you defined.
`cli.tooltip` accepts HTML strings. You can use ` `, ``, ``, and inline styles to format multi-line or highlighted tooltips. Keep the content concise — long tooltip text is hard to read at small sizes.
If `cli.tooltip` is set to `null` or an empty string, no tooltip appears. Ensure the field or value you are reading from `wi` is populated in Polarion before testing — custom field data must exist on the work item for it to appear in the tooltip.
***
## Customize capacity tooltips
Capacity tooltips appear when hovering over the **capacity bar** of a Plan column in the calendar header. They are only active when capacity loading is enabled on the board.
### Default capacity tooltip
When no custom template is configured, the default tooltip shows aggregate values:
```text theme={null}
Capacity / Done / Todo / Available
```
This is the fallback shown automatically when `columnTooltipTemplate` is not set.
### Configure a custom capacity tooltip
The `columnTooltipTemplate` option accepts either a string template or a JavaScript function that receives `column` and `row` objects. You set this through the **Config Script** in the widget's Advanced Properties.
**Example — per-user allocation breakdown:**
```javascript theme={null}
scheduler.columnTooltipTemplate = function(column, row) {
var html = "" + column.text + " ";
if (column.users) {
column.users.forEach(function(user) {
var avail = user.available;
var color = avail < 0 ? "color:red;" : "";
html +=
"" +
user.name + ": " +
avail + " / " + user.allocated + " / " + user.total +
" ";
});
}
return html;
};
scheduler.setCurrentView();
```
The `setCurrentView()` call is required after programmatically changing the tooltip template — it triggers a re-render so the new template takes effect immediately.
Overallocated users are best indicated with red text (`color: red`) on negative available values. This is the pattern used in standard Nextedy capacity reports and is immediately recognizable to planning teams.
`setCurrentView()` must be called after any programmatic change to `columnTooltipTemplate`. Without it, the old tooltip format remains until the next natural board refresh.
***
## Tooltip data flow
The diagram below shows how the two tooltip types relate to their data sources and configuration points:
***
## Available scripting objects
| Object | Description |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `wi` | The current work item (classic Polarion IWorkItem API). Access field values with `wi.getValue("fieldId")`, IDs with `wi.getId()`, titles with `wi.getTitle()`. |
| `workitem` | The same item through the rendering API. Use `workitem.fields().fieldName().render().htmlFor().forFrame()` to render fields as HTML. |
| `cli` | Client-side card configuration. Set `cli.tooltip` to a string (HTML supported). |
| `cli.tooltip` | String. Defines the text shown when hovering over the card. Supports HTML. |
| `columnTooltipTemplate` | Config Script property. A string template or function returning HTML for the capacity bar tooltip. |
***
## Common pitfalls
**Capacity tooltip not appearing**
Capacity tooltips only appear when `capacityLoad` is enabled in the widget parameters. If the capacity bar is not visible on the board, the tooltip will not appear either. See [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration) to enable it.
**Tooltip shows raw object text**
If `cli.tooltip` is set to a Polarion enum option without calling `.getName()`, the tooltip displays the raw `EnumOption[...]` object string instead of the label. Always call `.getName()` on enum-typed fields:
```javascript theme={null}
var status = wi.getValue("status");
cli.tooltip = status != null ? status.getName() : "";
```
**Custom field returns null**
If a custom field has no value on the work item, `wi.getValue("fieldId")` returns `null`. Always guard with a null check before using the value in a tooltip string to avoid rendering `null` as text.
***
## You should now see
* Hovering over any work item card shows the tooltip content defined in your Item Script.
* Hovering over a Plan column's capacity bar shows either the default aggregate values or your custom per-user breakdown.
* Overallocated users (negative available hours) appear in red in a custom capacity tooltip.
***
## See also
* [Customize Card Content](/planningboard/guides/customization/card-content) — configure `cli.fieldsLine`, `cli.cardColor`, and other card properties alongside tooltips
* [Customize Card Appearance](/planningboard/guides/customization/card-appearance) — adjust card height, colors, and layout
* [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration) — enable the capacity bar that drives capacity tooltips
* [Visualize Capacity Load](/planningboard/guides/capacity/capacity-visualization) — understand what the capacity bar displays
* [Item Scripts](/planningboard/guides/advanced/item-scripts) — full reference for the Item Script execution environment
* [Config Scripts](/planningboard/guides/advanced/config-scripts) — full reference for the Config Script execution environment
**KB Articles**
* Planningboard: Customizable Statistics and Capacity Indicators
* Customize the content of the card
* Planningboard interface & basic interactions
**Support Tickets**
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
* [#6523](https://support.nextedy.com/helpdesk/tickets/6523)
* [#6612](https://support.nextedy.com/helpdesk/tickets/6612)
**Source Code**
* `capacityTooltipRendering.cy.ts`
* `customProgressTooltip.cy.ts`
* `viewLicense.vm`
* `PlanningBoardWidget.java`
* `PlanningBoardWidgetRenderer.java`
# Guides
Source: https://learn.nextedy.com/planningboard/guides/index
These guides cover task-oriented configuration and day-to-day use of Nextedy PLANNINGBOARD.
**New to Planningboard?**
Start with the [Getting Started](/planningboard/getting-started/index) section for installation and your first board, then return here when you need to configure specific features.
## Configuration
Set up the board widget and its core behaviour.
**[Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters)** — All widget parameters and their accepted values\
**[Configure Plans (Columns)](/planningboard/guides/configuration/plans-configuration)** — Control which Plans appear as columns on the board\
**[Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration)** — Define how work items are grouped into swimlanes\
**[Configure Work Items Dataset](/planningboard/guides/configuration/work-items-configuration)** — Filter and scope the work items shown on the board\
**[Configure Unplanned Sidebar](/planningboard/guides/configuration/unplanned-sidebar)** — Show a sidebar of unplanned backlog items\
**[Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration)** — Enable and tune capacity bars per swimlane\
**[Configure Dependencies Display](/planningboard/guides/configuration/dependencies-configuration)** — Show dependency links between cards\
**[Use Page Parameters](/planningboard/guides/configuration/page-parameters)** — Pass runtime values into the widget from the Polarion page URL
## Swimlanes
Group work items into rows using different swimlane assignment types.
**[User and Assignee Swimlanes](/planningboard/guides/swimlanes/user-swimlanes)** — One swimlane per assignee\
**[Parent Item Swimlanes](/planningboard/guides/swimlanes/parent-item-swimlanes)** — Group by parent work item (e.g. Feature, Epic)\
**[Enumeration Field Swimlanes](/planningboard/guides/swimlanes/enum-swimlanes)** — Group by any enumeration-typed field\
**[Project Swimlanes](/planningboard/guides/swimlanes/project-swimlanes)** — Separate rows per Polarion project\
**[SAFe Swimlanes](/planningboard/guides/swimlanes/safe-swimlanes)** — Swimlane layout for SAFe team/ART structures\
**[Sort Swimlanes](/planningboard/guides/swimlanes/sorting-swimlanes)** — Control the order swimlanes appear on the board\
**[Filter Swimlanes by Plan Range](/planningboard/guides/swimlanes/filtering-by-plan-range)** — Restrict swimlanes to a Plan date range\
**[Filter Swimlanes by Team](/planningboard/guides/swimlanes/filtering-by-team)** — Show only swimlanes belonging to a given team\
**[Multi-Valued Field Swimlanes](/planningboard/guides/swimlanes/multi-valued-swimlanes)** — Handle fields that carry more than one value\
**[No Swimlanes Mode](/planningboard/guides/swimlanes/no-swimlanes-mode)** — Display the board as a flat list without row grouping
## Customization
Control what appears on cards and how the board looks.
**[Customize Card Content](/planningboard/guides/customization/card-content)** — Choose which work item fields appear on each card\
**[Customize Card Appearance](/planningboard/guides/customization/card-appearance)** — Adjust card size, layout, and visual weight\
**[Customize Card Colors](/planningboard/guides/customization/card-colors)** — Apply color rules based on field values\
**[Highlight Work Items by Rules](/planningboard/guides/customization/highlighting-rules)** — Flag cards that match conditions (e.g. planned after due date)\
**[Customize Progress Bars](/planningboard/guides/customization/progress-bars)** — Configure the progress indicator shown on cards\
**[Customize Capacity Indicators](/planningboard/guides/customization/capacity-indicators)** — Style the capacity bar displayed per swimlane\
**[Customize Tooltips](/planningboard/guides/customization/tooltips)** — Configure the information shown in card hover tooltips\
**[Customize Board Appearance](/planningboard/guides/customization/board-appearance)** — Global board layout and styling options
## Capacity Management
Track team and individual capacity across the board.
**[Track Team Capacity](/planningboard/guides/capacity/team-capacity)** — Configure capacity bars at the team level\
**[Track User Capacity](/planningboard/guides/capacity/user-capacity)** — Configure per-user capacity in assignee swimlanes\
**[Visualize Capacity Load](/planningboard/guides/capacity/capacity-visualization)** — Interpret the capacity bar and load indicators\
**[Normalize Capacity Across Swimlanes](/planningboard/guides/capacity/capacity-normalization)** — Scale capacity values for consistent comparison\
**[Set Up Teams Service](/planningboard/guides/capacity/teams-service-setup)** — Connect Planningboard to the Polarion Teams service\
**[Track Vacation and Availability](/planningboard/guides/capacity/vacation-tracking)** — Account for time off in capacity calculations\
**[Configure Multi-Dimensional Capacity](/planningboard/guides/capacity/multi-capacity)** — Track more than one capacity dimension simultaneously
## Planning Workflows
Move cards, manage backlogs, and run planning sessions.
**[Drag and Drop Planning](/planningboard/guides/planning/drag-and-drop)** — Assign work items to Plans by dragging cards between columns\
**[Prioritize Work Items](/planningboard/guides/planning/prioritization)** — Reorder cards within a swimlane to set priority\
**[Create Plans](/planningboard/guides/planning/creating-plans)** — Add new Plans directly from the board\
**[Bulk Plan Creation](/planningboard/guides/planning/bulk-plan-creation)** — Create multiple Plans at once\
**[Use Plan Templates](/planningboard/guides/planning/plan-templates)** — Apply a template when creating Plans\
**[Visualize and Manage Dependencies](/planningboard/guides/planning/dependencies)** — Display and navigate dependency relationships between cards\
**[SAFe Planning Workflows](/planningboard/guides/planning/safe-planning)** — Run PI Planning and iteration planning with SAFe structures\
**[SAFe Plan Naming Conventions](/planningboard/guides/planning/safe-naming-conventions)** — Naming patterns for SAFe Plans recognized by the board\
**[Cross-Project Planning](/planningboard/guides/planning/cross-project-planning)** — Combine work items from multiple Polarion projects on one board\
**[Manage Unplanned Backlog](/planningboard/guides/planning/unplanned-backlog)** — Work with unassigned items in the sidebar
## Advanced Configuration
Scripting and dynamic behaviour for complex setups.
**[Item Scripts](/planningboard/guides/advanced/item-scripts)** — JavaScript scripts that run per card to compute values\
**[Config Scripts](/planningboard/guides/advanced/config-scripts)** — Scripts that generate widget configuration dynamically\
**[Data Scripts](/planningboard/guides/advanced/data-scripts)** — Scripts that transform or augment the work item dataset\
**[Template Functions](/planningboard/guides/advanced/template-functions)** — Functions available inside card and tooltip templates\
**[Dynamic Filtering with Page Parameters](/planningboard/guides/advanced/dynamic-filtering)** — Drive board filters from URL parameters at runtime\
**[Read-Only Mode](/planningboard/guides/advanced/read-only-mode)** — Lock the board to prevent drag-and-drop changes\
**[Custom Project Templates](/planningboard/guides/advanced/custom-templates)** — Package board configurations as reusable project templates\
**[Scripted Page Parameters](/planningboard/guides/advanced/scripted-page-parameters)** — Generate page parameter values programmatically
## Troubleshooting
**[Troubleshooting](/planningboard/guides/troubleshooting/index)** — Full troubleshooting index
**KB Articles**
* Swimlane Assignment Types
* Planningboard Widget Parameters
**Support Tickets**
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
**Source Code**
* `viewSetup.vm`
* `Config.java`
# Bulk Plan Creation
Source: https://learn.nextedy.com/planningboard/guides/planning/bulk-plan-creation
Create multiple Polarion Plans at once from the Nextedy PLANNINGBOARD toolbar using pattern-based naming and automatic date sequencing — without leaving the board.
## Prerequisites
* The **New Plan** feature must be enabled in your widget parameters (see [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters)).
* You need write access to the Polarion project where Plans will be created.
* Decide on a `Template ID` matching an existing Polarion plan template in your project (for example, `iteration` or `release`).
***
In your widget parameters, navigate to the **New Plan** section. Enable the feature. The toolbar on your board will show a **plus (+) button** once the board reloads.
The following fields control how bulk Plans are generated:
| Parameter | Purpose | Example |
| ------------------- | ----------------------------------------------------------------- | ------------------ |
| `Template ID` | Polarion plan template to use | `iteration` |
| `Parent ID` | Optional parent Plan under which new Plans are created | `Version_3_0` |
| `Plan Name Pattern` | Display name template using `{planNum}` and `{teamName}` | `Sprint {planNum}` |
| `Plan ID Pattern` | Unique ID template using `{planNum}` and `{teamId}` | `Sprint_{planNum}` |
| `New Plan Duration` | Duration of each newly created Plan | `14` (days) |
| `Last Plan Query` | Lucene query to find the "last plan" for auto-numbering | `type:iteration` |
| `Last Plan Sort` | Sort field to determine which plan is "last" (default: `dueDate`) | `dueDate` |
**Predefined patterns include Teams placeholders**
The default `Plan Name Pattern` and `Plan ID Pattern` values include `{teamName}` and `{teamId}` respectively. If you are **not** using Teams, change these patterns before creating Plans — otherwise the placeholders will appear literally in the Plan name and ID.
***
Patterns use two placeholders:
* **`{planNum}`** — replaced with an auto-incremented integer. Required for auto-numbering to work. The system scans plans matching your `Template ID` in the project, extracts the number from the last plan's ID, and increments by 1. If no prior plans are found, numbering starts at 1.
* **`{teamName}`** — replaced with the team's display name (for multi-team creation).
* **`{teamId}`** — replaced with the team's identifier (for multi-team ID uniqueness).
**Example — single-team iteration setup:**
```text theme={null}
Plan Name Pattern: Sprint {planNum}
Plan ID Pattern: Sprint_{planNum}
```
This produces Plans named `Sprint 4`, `Sprint 5`, etc., with IDs `Sprint_4`, `Sprint_5`.
**Example — multi-team setup:**
```text theme={null}
Plan Name Pattern: PI {planNum} - {teamName}
Plan ID Pattern: PI_{planNum}_{teamId}
```
This produces `PI 3 - Team Alpha` / `PI_3_TeamAlpha` for each configured team.
**Override auto-numbering with `nextNumber`**
If the auto-detected starting number is wrong (for example, after renaming old Plans), you can specify `nextNumber` explicitly in the widget parameters to force a specific starting value.
***
By default, Planningboard calculates start and end dates automatically:
* If a `nextStartDate` is **not** specified, the system determines the start date from the tail (most recent) plan matching your template and parent configuration, or from the parent Plan's dates.
* If you specify `nextStartDate` (in `YYYY-MM-DD` format), that value takes precedence over all automatic date logic.
* Each subsequent plan's start date is calculated by adding `New Plan Duration` to the previous plan's start date.
**Date format is strict**
`nextStartDate` must be in `YYYY-MM-DD` format. Any other format is not parsed correctly and the system falls back to automatic date calculation.
***
If your project uses Teams, enable **Enable Teams** and configure one or more teams with their name and ID:
```text theme={null}
Enable Teams: true
Teams:
- name: Team Alpha
id: TeamAlpha
- name: Team Beta
id: TeamBeta
```
When Teams are enabled, clicking the **plus (+)** button creates one Plan per team in a single transaction. All Plans are created or none are created — if any Plan fails to create, the entire batch is rolled back automatically.
**One Plan at a time without Teams**
When Teams are disabled, clicking **+** creates exactly one Plan using the `{planNum}` placeholder only. This is the simpler setup for projects with a single team or no team segmentation.
***
Once configured:
1. Open the Planningboard page in Polarion.
2. Click the **plus (+) button** in the toolbar.
3. A confirmation dialog appears showing the resolved values — review the Plan name, ID, start date, end date, and parent.
4. Confirm to create.
The board refreshes and the new column(s) appear immediately.
***
## How the Process Flows
***
## Common Pitfalls
**Parent ID scopes all new Plans**
If you set `Parent ID`, every new Plan is created under that parent regardless of which Plans are currently visible on the board. Verify the parent ID matches the correct Version or PI before bulk-creating.
**Plan ID must be unique across the project**
The `Plan ID Pattern` generates the Polarion plan ID. If a plan with that ID already exists in the project (even in a different space), creation fails for that plan and the entire batch is rolled back.
**Capacity whitespace sensitivity**
Capacity configuration parameters are whitespace-sensitive. A stray space in a capacity field value can cause unexpected behavior in capacity bars after Plans are created. Double-check values in the widget parameters before confirming creation.
***
## Verification
After clicking **Confirm** in the creation dialog, you should now see:
* New column(s) appear on the right side of the board, each labeled with the resolved Plan name.
* The new Plan(s) exist in Polarion's Plans section with IDs matching your `Plan ID Pattern`.
* Capacity bars (if enabled via `Show Capacity Load`) display for the new columns.
* If `Assign to Parent Plan` is enabled, work items you drag into the new Plan are also automatically planned into its parent Plan.
If columns do not appear after creation, use the **Refresh data** toolbar button to reload the board.
***
## See Also
* [Create Plans](/planningboard/guides/planning/creating-plans) — create a single Plan interactively
* [Use Plan Templates](/planningboard/guides/planning/plan-templates) — reuse Plan structures across projects
* [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) — full parameter reference including New Plan fields
* [Configure Plans (Columns)](/planningboard/guides/configuration/plans-configuration) — control which Plans appear as columns
* [Track Team Capacity](/planningboard/guides/capacity/team-capacity) — set up capacity tracking for newly created Plans
* [SAFe Planning Workflows](/planningboard/guides/planning/safe-planning) — bulk Plan creation in a SAFe hierarchy
**KB Articles**
* Planningboard Widget Parameters
* Introduction to Planningboard
* Planningboard interface & basic interactions
**Support Tickets**
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#4711](https://support.nextedy.com/helpdesk/tickets/4711)
**Source Code**
* `Config.java`
* `PlanningService.java`
* `Item.java`
* `PlanningBoardWidgetRenderer.java`
* `PlansMode.java`
# Create Plans
Source: https://learn.nextedy.com/planningboard/guides/planning/creating-plans
Create new Polarion Plans directly from the Nextedy PLANNINGBOARD toolbar without leaving your planning session.
## Overview
Planningboard lets you add Plans (sprint iterations, releases, or other plan types) to your board on the fly. The **New Plan** feature must be enabled and configured via widget parameters before the toolbar button appears. Once enabled, a single click opens a confirmation dialog, auto-numbers the new Plan, and appends it as a new column — with optional team expansion for multi-team setups.
## Prerequisites
* Planningboard is embedded in a Polarion LiveDoc or Wiki page.
* You have write permission to create Plans in the target project.
* The **New Plan** section is configured in the widget parameters (see Step 1 below).
Open the widget parameters for your Planningboard instance and locate the **New Plan** section. Set the following fields:
| Parameter | Description | Example |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------- |
| `Template ID` | Plan template type to use when creating the Plan (e.g. `iteration`, `release`) | `iteration` |
| `Parent ID` | Optional. ID of the parent Plan under which new Plans are created. Useful when a project has multiple versions and you want new iterations under only one of them. | `Version_3_0` |
| `Plan Name Pattern` | Display name template. Use `{planNum}` for auto-incrementing numbers and `{teamName}` for the team's display name. | `Iteration {planNum}` |
| `Plan ID Pattern` | Internal ID template. Use `{planNum}` for the sequence number and `{teamId}` for the team identifier. Must be unique across the project. | `Iter_{planNum}` |
| `New Plan Duration` | Duration of each new Plan in days. | `14` |
| `Enable Teams` | Toggle on if you want one Plan created per team in a single click. | enabled / disabled |
| `Teams` | When **Enable Teams** is on: specify team names and IDs. | see below |
| `Last Plan Query` | Optional Lucene query that identifies the "last plan" for auto-numbering. If empty, Planningboard searches for the latest plan in the same project with the same template type. | *(leave empty for default)* |
| `Last Plan Sort` | Optional sort field for the last-plan lookup. If empty, sorts by `dueDate` (latest due date = last plan). | *(leave empty for default)* |
**Pattern placeholders are required for auto-numbering**
If `{planNum}` is not present in both the `Plan Name Pattern` and `Plan ID Pattern`, auto-numbering cannot extract the sequence from existing plan IDs. Planningboard defaults to `1` when no existing plans match the pattern, which can create duplicate IDs. Always include `{planNum}` in both fields.
**Predefined patterns assume Teams — change them if you are not using Teams**
The default patterns ship predefined for Teams usage (`{teamName}` / `{teamId}`). If **Enable Teams** is disabled, remove `{teamName}` and `{teamId}` from the patterns or new plans will have literal placeholder text in their names and IDs.
**Whitespace matters in capacity configuration**
Capacity configuration parameters are whitespace-sensitive. Avoid leading or trailing spaces in field values — unexpected spaces cause silent parsing failures.
Save the widget parameters. The **plus (+) button** now appears in the Planningboard toolbar.
This workflow creates one Plan at a time.
1. Ensure **Enable Teams** is off in the widget parameters.
2. On the Planningboard, click the **plus (+) button** in the toolbar.
3. A confirmation dialog appears showing the resolved values — name, ID, start date, and due date.
4. Review the values, then confirm.
5. Planningboard creates the Plan and refreshes the board. The new Plan appears as a new column.
**Date calculation**
If `nextStartDate` is not set, Planningboard calculates the start date automatically based on the due date of the last plan found by the `Last Plan Query`. If no tail plan is found, it falls back to the parent plan's start date.
When **Enable Teams** is on, clicking the **plus (+) button** creates one Plan per configured team in a single transaction. All Plans are created or none are created — the operation rolls back automatically on failure.
1. Enable **Enable Teams** in the widget parameters.
2. Configure the `Teams` list with each team's name and ID.
3. Verify `Plan Name Pattern` includes `{teamName}` and `Plan ID Pattern` includes `{teamId}`.
4. Click the **plus (+) button** in the toolbar.
5. The confirmation dialog shows the full set of Plans that will be created (one per team).
6. Confirm. Planningboard creates all Plans and refreshes the board.
**Example Teams configuration:**
```
Teams:
- Name: Alpha Team ID: alpha
- Name: Beta Team ID: beta
```
With `Plan Name Pattern = PI-{planNum} {teamName}` and `Plan ID Pattern = PI-{planNum}-{teamId}`, clicking the button creates:
| Plan Name | Plan ID |
| --------------- | ---------- |
| PI-4 Alpha Team | PI-4-alpha |
| PI-4 Beta Team | PI-4-beta |
**Auto-numbering with Teams**
The `{planNum}` sequence is shared across all teams. Planningboard extracts the current number from the last plan matching the ID pattern, increments it by one, and applies that number to all teams' plans in the same batch. If no existing plans match, it starts from `1`.
After creation, the board refreshes automatically. You should now see:
* The new Plan column(s) appearing in the board header.
* Cards can be dragged into the new column from the Unplanned section or from other Plan columns.
* If capacity tracking is enabled, the capacity bar for the new Plan is visible when hovering over the column header.
If the new column does not appear, click the **Refresh data** button in the toolbar (circular arrow icon) to force a reload.
## Auto-numbering logic
Planningboard determines the next plan number using this sequence:
1. If `nextNumber` is set explicitly in the configuration, use it.
2. Otherwise, query for existing plans matching `Template ID` + project ID (+ `Last Plan Query` if set).
3. Sort results by `Last Plan Sort` (default: `dueDate` descending).
4. Extract `{planNum}` from the last matching plan's ID using the `Plan ID Pattern` as the extraction template.
5. Increment by one. If no plans match, start from `1`.
## Assign to Parent Plan
When the **Assign to Parent Plan** widget parameter is enabled, planning a work item into a new Plan also automatically plans it into that Plan's parent. For example, dragging a work item into `Iteration 4` (child of `Version 1.0`) also assigns it to `Version 1.0`.
**SAFe plan name compatibility**
If you use SAFe naming conventions with dashes (e.g. `PI-2401`, `I-2401-1`), ensure you are running **version 25.3.0 or later**. Earlier versions (including the partial fix in 23.8.0) incorrectly parsed dashes in plan names, causing column spans to render incorrectly, capacity to show zero, and plan shortcuts to disappear. Upgrade before adopting dash-containing plan name patterns.
## Common pitfalls
**SAFe Plans Type changes the configuration UI**
When `Plans Type` is set to **SAFe Program Increments**, the widget parameter UI changes — different fields are shown compared to **Project Plans** mode. If you switch Plans Type, review all plan-related parameters because some fields (such as `Scope` and `Query`) are not shown for SAFe modes and different fields become relevant.
**Parent ID is project-specific**
The `Parent ID` must be the exact Polarion plan ID within the current project. If the board spans multiple projects or you have recently renamed plans, confirm the parent plan ID is still valid before creating plans.
**Use Last Plan Query to target the correct sequence**
In projects with multiple plan hierarchies (e.g. multiple versions each containing iterations), set `Last Plan Query` to a Lucene expression that narrows the search to only the relevant parent — for example `parentId:Version_3_0`. This prevents Planningboard from picking up the highest-numbered iteration from a different version when calculating the next number.
## See also
* [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) — full reference for all widget parameters
* [Configure Plans (Columns)](/planningboard/guides/configuration/plans-configuration) — configure which Plans appear as columns
* [Bulk Plan Creation](/planningboard/guides/planning/bulk-plan-creation) — create multiple Plans in one operation via scripting
* [Use Plan Templates](/planningboard/guides/planning/plan-templates) — pre-defined plan structures for consistent setup
* [Drag and Drop Planning](/planningboard/guides/planning/drag-and-drop) — assign work items to Plans after creating them
* [SAFe Planning Workflows](/planningboard/guides/planning/safe-planning) — configure Planningboard for SAFe hierarchies
* [SAFe Plan Naming Conventions](/planningboard/guides/planning/safe-naming-conventions) — naming patterns for SAFe Plans and version requirements
**KB Articles**
* Introduction to Planningboard
* Planningboard interface & basic interactions
* Planningboard Widget Parameters
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
* [#4711](https://support.nextedy.com/helpdesk/tickets/4711)
**Source Code**
* `Item.java`
* `PlanningBoardWidgetRenderer.java`
* `Config.java`
* `PlansMode.java`
* `PlanningBoardDataService.java`
# Cross-Project Planning
Source: https://learn.nextedy.com/planningboard/guides/planning/cross-project-planning
Plan and schedule work items from multiple Polarion projects on a single Nextedy PLANNINGBOARD using project swimlanes and cross-project plan queries.
***
## Overview
Cross-project planning lets you bring work items from several sub-projects onto one board, giving program managers and Scrum masters a unified view of capacity and scheduling across teams. The board uses the **Project** (`PROJECT`) assignment mode to split swimlanes by sub-project, while a shared Plan query selects which Plans appear as columns.
**Sub-projects only**
The **Project** (`PROJECT`) assignment mode includes only **readable sub-projects** within the current project group. It does not include the current project itself, and it cannot reach projects outside the group hierarchy.
***
## Prerequisites
* Planningboard is installed and licensed in your Polarion instance.
* Your Planningboard page lives inside a **project group** that contains the sub-projects you want to plan across.
* You have permission to read work items in each sub-project.
* You are familiar with adding a Planningboard widget to a LiveDoc page. See [Create Your First Planningboard](/planningboard/getting-started/first-planning-board) if not.
***
1. Navigate to the LiveDoc or Wiki page that hosts your Planningboard widget.
2. Expand the widget tools and click **Edit** to open the widget configuration panel.
***
In the **Plans (Columns)** section of the widget configuration:
1. Set **Plans Mode** to **Project Plans** (`PROJECT_PLANS`).
```properties theme={null}
plansMode = PROJECT_PLANS
```
This is the default mode. It loads Plans from the current project using a Lucene query and organizes them chronologically as columns.
2. Adjust how many past and future Plans appear on the board using the **Last Plans** and **Next Plans** counters:
```properties theme={null}
lastPlans = 1
nextPlans = 5
```
The defaults show one completed Plan and five upcoming Plans. Increase `nextPlans` if your planning horizon spans more sprints.
3. Optionally, add a **Plans Query** to restrict which Plans appear as columns. For example, to show only sprint Plans:
```properties theme={null}
plansQuery = type:sprint
```
**Plan items configuration is only available in Project Plans mode**
The plan items section in the configuration panel appears only when `plansMode` is set to `PROJECT_PLANS`. If you switch to a SAFe mode, those options are hidden.
***
In the **Swimlanes (Rows)** section:
1. Set **Assignment Mode** to **Project** (`PROJECT`).
```properties theme={null}
assignmentMode = PROJECT
```
The board will create one swimlane per readable sub-project within the current project group. The current project itself is excluded.
**Project mode does not support capacity normalization**
When using **Project** (`PROJECT`) assignment mode with `planCellsMode`, verify your setup against the live product — normalization behavior in cross-project configurations is not confirmed in the source context.
***
In the **Work Items Dataset** section, set a Lucene query that targets the work item types you want to plan across all sub-projects:
```properties theme={null}
query = type:story AND NOT status:done
```
Adjust the type and status filters to match your project's work item type IDs. The `maxItems` parameter (default: `1000`) limits the total number of work items loaded across all sub-projects:
```properties theme={null}
maxItems = 1000
```
**Large project groups can hit the item limit quickly**
If you have many sub-projects, the combined result set may reach `maxItems` before all sub-projects are fully represented. Tighten your query (for example, restrict by iteration date or status) or increase `maxItems` to compensate.
***
There is a known Polarion issue where selecting a plan template from another project causes the page to become unresponsive. If you encounter this symptom, apply the following workaround at the **global Polarion administration level** (not at the project level):
```properties theme={null}
nextedy.planningboard.workaround_siemens_issue_global_plans=false
```
**Apply this property at global administration level**
This configuration property must be added in the global Polarion administration settings — not inside a project's `context.properties`. Applying it at the project level has no effect.
***
1. Save the widget configuration.
2. The board reloads. You should now see:
* One **column per Plan** that matches your `plansQuery`, ordered chronologically.
* One **swimlane per sub-project** within the project group.
* Work items distributed into the cell that corresponds to their assigned Plan and their source sub-project.
3. Verify that all expected sub-projects appear as swimlanes. If a project is missing, confirm that your Polarion user account has read access to that sub-project.
***
## Configuration example
The following widget parameter set configures a cross-project Planningboard showing the last sprint and the next four sprints, grouped by sub-project, displaying only Stories that are not yet done:
```properties theme={null}
plansMode = PROJECT_PLANS
assignmentMode = PROJECT
plansQuery = type:sprint
lastPlans = 1
nextPlans = 4
query = type:story AND NOT status:done
maxItems = 1000
```
***
## Drag-and-drop across projects
Once the board is set up, drag-and-drop works as on a single-project board:
* Drag a card from the **Unplanned** sidebar onto a Plan column to assign it to that sprint.
* The card stays in its sub-project swimlane — dragging horizontally changes the Plan assignment; dragging vertically changes the swimlane (resource) assignment, which in **Project** (`PROJECT`) mode is not applicable for cross-project moves.
**Items with status Verified cannot be moved**
Cards with the **Verified** status are locked on the board and cannot be dragged or unplanned, regardless of which project they belong to.
See [Drag and Drop Planning](/planningboard/guides/planning/drag-and-drop) for full drag-and-drop reference.
***
## Limitations
* **Project (`PROJECT`) assignment mode excludes the current project.** Only sub-projects within the group are shown.
* **No multi-assignee swimlane split in Project mode.** Unlike the **Users (Assignee)** (`ASSIGNEE`) mode, the **Project** (`PROJECT`) mode shows one swimlane per project — it does not further subdivide by assignee within each project.
* **Capacity bars require additional setup.** Capacity tracking across multiple projects is not automatically configured; see [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration) for setup steps.
* **Cross-project plan template selection** may trigger a Polarion responsiveness issue — apply the `nextedy.planningboard.workaround_siemens_issue_global_plans=false` property as described in Step 5.
***
## See also
* [Project Swimlanes](/planningboard/guides/swimlanes/project-swimlanes) — detailed reference for the **Project** (`PROJECT`) assignment mode
* [Configure Plans (Columns)](/planningboard/guides/configuration/plans-configuration) — Plans query and column configuration
* [Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration) — all assignment modes
* [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) — full parameter reference
* [Drag and Drop Planning](/planningboard/guides/planning/drag-and-drop) — moving cards between Plans
* [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration) — capacity bars and load visualization
**KB Articles**
* Introduction to Planningboard
* Planningboard interface & basic interactions
* How to setup Planningboard into existing projects (based on E-library template)
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
* [#6661](https://support.nextedy.com/helpdesk/tickets/6661)
**Source Code**
* `PlansMode.java`
* `PlanningBoardDataService.java`
* `Item.java`
* `Config.java`
* `PlanningBoardWidgetRenderer.java`
# Visualize and Manage Dependencies
Source: https://learn.nextedy.com/planningboard/guides/planning/dependencies
Enable dependency visualization on the Nextedy PLANNINGBOARD so you can see, create, and manage links between work item cards directly on the board.
## Before you begin
Dependency visualization requires the **Dependency Roles** widget parameter to be configured. Without it, the **Show Dependencies** toolbar button has no effect. Confirm you have edit access to the widget parameters for your Planningboard page.
Open the widget parameters for your Planningboard page and locate the **Dependency Roles** field under the **Parameters for Work Items** section.
Enter one or more Polarion link role IDs that represent dependency relationships in your project — for example, `depends_on` or `blocks`. Separate multiple roles with a comma.
```text theme={null}
Dependency Roles: depends_on, blocks
```
**Use exact link role IDs**
The **Dependency Roles** field requires the exact Polarion link role ID, not its display label. Using the display label (e.g. "Depends On" instead of `depends_on`) will silently produce no arrows on the board. Check **Administration > Work Items > Link Roles** in Polarion to confirm the correct IDs.
Save the widget parameters. The board will reload with dependency tracking active.
Once dependency roles are configured, use the toolbar to reveal all dependency arrows at once.
1. Open your Planningboard page.
2. In the toolbar (upper-left corner), click the **Show Dependencies** button.
All links matching the configured dependency roles are drawn as arrows connecting the relevant cards across columns and swimlanes.
**Show Dependencies vs Show Links**
**Show Dependencies** (toolbar) reveals all dependency arrows across the entire board in one click. **Show Links** (card hover action) focuses on a single card — it hides all other cards and shows only that card and its directly linked cards. Use Show Links when investigating one item's relationships; use Show Dependencies for a board-wide view.
To examine one card's dependencies without the noise of the full board:
1. Hover over the card you want to inspect.
2. Click the **Show Links** icon (chain-link icon) that appears in the upper-right corner of the card.
All other cards are hidden. Only the selected card and its linked cards remain visible, making it easy to trace the dependency chain for that item.
To return to the full board, click the **Show Links** icon again or click away.
You can create a link between two cards without leaving the Planningboard:
1. Hover over the source card.
2. Click the **Add Link** icon (appears alongside Show Links in the card's upper-right corner).
3. The same icon appears on all other cards. Click the target card to establish the connection.
A red icon on a card during this mode indicates a link already exists between the source and that card. Clicking a red icon removes the link.
```text theme={null}
Workflow diagram:
Hover source card → Click Add Link → Click target card → Link created
(Red icon on target = link exists; click to delete)
```
**Verified work items cannot be moved or re-linked**
Cards with the **Verified** status are locked on the board. They cannot be dragged, unplanned, or have their plan assignment changed. This constraint applies to all card interactions, including dependency management.
## Dependency relationship on the board
Dependencies are drawn edge-to-edge as directional arrows. Cross-column and cross-swimlane dependencies are both supported and visible when Show Dependencies is active.
## Common pitfalls
**Dependency arrows not appearing after enabling Show Dependencies**
If no arrows appear after clicking Show Dependencies, check:
1. **Dependency Roles is empty or incorrect** — open widget parameters and confirm a valid link role ID is set.
2. **No links exist yet** — the board only draws arrows for links that already exist in Polarion. Create links using Add Link on the board, or add them in the Polarion work item form.
3. **Link role not present in Polarion** — if you entered a role ID that does not exist in the project, the board silently ignores it. Verify the role exists under **Administration > Work Items > Link Roles**.
**Dependency Roles field is not shown in widget parameters**
The **Dependency Roles** field appears in the **Parameters for Work Items** section. If you do not see it, confirm you are editing the Planningboard widget parameters, not a different widget on the same page.
## You should now see
After completing this guide:
* The **Show Dependencies** toolbar button reveals directional arrows between all linked cards on the board, following the link roles you configured.
* Hovering a card and clicking **Show Links** isolates that card and its linked neighbours.
* Clicking **Add Link** on a card lets you draw a new dependency to any other card on the board; a red icon flags existing links, which you can remove by clicking them.
## See also
* [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) — full reference for all widget parameters including Dependency Roles
* [Configure Dependencies Display](/planningboard/guides/configuration/dependencies-configuration) — additional configuration options for dependency visualization
* [Basic Board Interactions](/planningboard/getting-started/basic-interactions) — overview of card actions, toolbar controls, and the Show Links feature
* [Prioritize Work Items](/planningboard/guides/planning/prioritization) — ordering cards on the board alongside dependency management
**KB Articles**
* Introduction to Planningboard
* Planningboard interface & basic interactions
* Planningboard Widget Parameters
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
* [#4711](https://support.nextedy.com/helpdesk/tickets/4711)
**Source Code**
* `PlansMode.java`
* `Item.java`
* `Config.java`
* `PlanningBoardDataService.java`
* `PlanningBoardWidgetRenderer.java`
# Drag and Drop Planning
Source: https://learn.nextedy.com/planningboard/guides/planning/drag-and-drop
Move work items from the unplanned backlog onto Plans and between swimlanes using Nextedy PLANNINGBOARD's drag-and-drop interface.
***
## Before you start
* The Planningboard widget is embedded and configured on a Polarion LiveDoc or Wiki page.
* Plans are already set up as columns and swimlanes are configured. See [Configure Plans (Columns)](/planningboard/guides/configuration/plans-configuration) and [Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration) if needed.
* You have write access to the work items you want to plan.
***
## Board layout at a glance
The **Unplanned section** (right) holds all cards not yet assigned to a Plan. The **board area** (left) is a grid of columns (Plans) and rows (swimlanes). Drag cards from right to left to plan them, or between cells to reschedule or reassign them.
***
If the Unplanned section is not visible, click the **Show Unplanned** button in the toolbar (the panel icon). The section slides open on the right side of the board.
The Unplanned section has its own filter controls. Click the **funnel icon** to filter cards by assignee, team, or a saved query. Use the upper-right toggle to **filter out Verified work items** from the list, and **Filter columns** to hide already-planned Verified items from the board.
***
Scroll or filter the Unplanned section to find the work item you want to assign. Each card in the Unplanned section represents a single Polarion work item.
Predefined **Queries** let you surface specific subsets of unplanned work (for example, all items with status `reviewed`). Configure them in the widget's **Queries** parameters. Once configured, enable them from the funnel icon in the Unplanned section.
***
Click and hold the card, then drag it into the target cell — the intersection of the Plan column and swimlane row where you want to schedule it.
A **visual highlight** marks the drop target as you drag over valid cells. Release the card to confirm the assignment.
What happens when you drop a card:
* The work item is **added to the Plan** that corresponds to the column. Internally, Planningboard assigns the item based on the Plan's date range (`start_date` / `end_date`).
* If swimlanes are set to **Users (Assignee)** mode, dropping into a swimlane also **reassigns the work item** to that user.
* If swimlanes use an **Enumeration Field** mode (for example, a team or component field), dropping into a swimlane updates that enumeration field on the work item.
* If **Assign to Parent Plan** is enabled in the widget parameters, the work item is also planned into the parent Plan of the target column automatically.
Work items with status **Verified** are **locked** — they cannot be dragged or unplanned. If you need to move a Verified item, change its status first in Polarion.
***
You can also drag cards already on the board:
* **Between columns** — reschedules the work item into a different Plan.
* **Between swimlanes** — reassigns the work item to a different resource or changes its enum field value, depending on the swimlane assignment type.
* **Back to the Unplanned section** — hover over the card to reveal the **Unplan item** quick action (the arrow icon in the upper-right corner of the card), then click it. This removes the item from its current Plan.
Dropping a card into a swimlane in **Parent Item** assignment mode does not change the parent link — items are grouped by their parent work item, and the parent relationship is not modified by drag-and-drop. Rearranging parent associations must be done in Polarion directly.
***
After dropping cards, watch the **capacity bar** at the top of each column or swimlane (if capacity display is enabled). The bar shows how much capacity has been consumed relative to the Plan's total.
Hover over a capacity bar to see a detailed tooltip with capacity breakdown. This feature requires **Show Capacity Load** to be enabled in the widget's Plans parameters.
If capacity bars are not visible, see [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration).
***
After dropping, the card appears in the target cell. The board preserves your **swimlane position and scroll location** — it does not jump back to the top, so you can keep planning without losing your place.
Click the card to open the **Work Item Properties** sidebar and confirm the Plan assignment and assignee fields are set as expected.
**You should now see** the card in the correct Plan column and swimlane row, the capacity bar updated to reflect the new load, and the work item removed from the Unplanned section.
***
## Common pitfalls
**Card does not move — no drop target highlighted**
If no cell highlights when dragging, the board may be in **read-only mode** or the work item type may not match the widget's work item type filter (`wiType`). Confirm you have edit permissions in Polarion and that the work item type is included in the board's query.
**Capacity shows zero after planning**
Capacity calculations require the work items to have effort values (`remainingEstimate` or `initialEstimate`, or the field set in `capacityField`). Items with no effort data count as zero. Also verify that **Show Capacity Load** is enabled and the `hoursPerDay` parameter is set correctly (default: `8`).
**Known limitation**
If your Plan names contain dashes (for example, SAFe naming patterns like `PI-2401` or `I-2401-1`), capacity display may show zero on versions earlier than 25.3.0. Upgrade to 25.3.0 or later to resolve this.
**Item reappears in Unplanned after drop**
If the server rejects the assignment (for example, due to a validation rule or a permissions error), the board rolls back the card to its previous position and displays an error alert. Check the error message and resolve the underlying Polarion constraint before retrying.
**Swimlane assignment does not update after drop**
In **Enumeration Field** swimlane mode, multi-value enum fields are updated by adding the target value. If the field has restrictions (for example, `status`, `resolution`, or `type` fields are not supported as swimlane assignment fields), the drop will not change the field. Use a supported custom enum field for swimlane assignment. See [Enumeration Field Swimlanes](/planningboard/guides/swimlanes/enum-swimlanes).
***
## Tips
**Collapsed swimlanes persist across sessions**
Planningboard saves which swimlanes you have collapsed to your browser's local storage. They are automatically restored the next time you open the board — no need to re-collapse large swimlanes on every visit.
**Use dependencies to guide planning order**
Enable **Show Dependencies** in the toolbar to display all dependency links between cards as arrows. This helps you spot blocked items before moving them to earlier sprints. Dependencies must be configured via the `PARAMETER_DEPENDENCY_LINK_ROLE` widget parameter. See [Visualize and Manage Dependencies](/planningboard/guides/planning/dependencies).
**Prioritize within a cell after planning**
Once items are in a Plan, use the **Prioritize** button in the toolbar to enter prioritization mode and reorder cards within their swimlane cells. See [Prioritize Work Items](/planningboard/guides/planning/prioritization).
***
## See also
* [Basic Board Interactions](/planningboard/getting-started/basic-interactions)
* [Configure Plans (Columns)](/planningboard/guides/configuration/plans-configuration)
* [Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration)
* [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration)
* [Manage Unplanned Backlog](/planningboard/guides/planning/unplanned-backlog)
* [Prioritize Work Items](/planningboard/guides/planning/prioritization)
* [Visualize and Manage Dependencies](/planningboard/guides/planning/dependencies)
* [Drag and Drop Issues](/planningboard/guides/troubleshooting/drag-and-drop-issues)
**KB Articles**
* Planningboard interface & basic interactions
* Introduction to Planningboard
* Planningboard Widget Parameters
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
* [#4711](https://support.nextedy.com/helpdesk/tickets/4711)
**Source Code**
* `Item.java`
* `PlanningBoardWidgetRenderer.java`
* `PlansMode.java`
* `Config.java`
* `PlanningBoardDataService.java`
# Planning Workflows
Source: https://learn.nextedy.com/planningboard/guides/planning/index
Nextedy PLANNINGBOARD turns Polarion Plans and work items into draggable cards so teams can schedule, prioritize, and replan directly on the board.
## Drag and Drop
**[Drag and Drop Planning](/planningboard/guides/planning/drag-and-drop)** — Move cards between Plans and swimlanes interactively; covers scheduling, rescheduling, and move behaviour.
## Prioritization
**[Prioritize Work Items](/planningboard/guides/planning/prioritization)** — Reorder cards within a Plan column to reflect delivery priority.
## Creating and Managing Plans
**[Create Plans](/planningboard/guides/planning/creating-plans)** — Add new Polarion Plans to the board directly from the widget.
**[Bulk Plan Creation](/planningboard/guides/planning/bulk-plan-creation)** — Generate multiple Plans at once using a template-driven approach.
**[Use Plan Templates](/planningboard/guides/planning/plan-templates)** — Define and apply reusable Plan templates to standardise sprint or release setup.
## Dependencies
**[Visualize and Manage Dependencies](/planningboard/guides/planning/dependencies)** — Display dependency links between work items across Plans and act on blockers.
## SAFe Planning
**[SAFe Planning Workflows](/planningboard/guides/planning/safe-planning)** — Organise Program Increments and iterations using SAFe swimlane and Plan conventions.
**[SAFe Plan Naming Conventions](/planningboard/guides/planning/safe-naming-conventions)** — Name Plans consistently so the board groups and filters them correctly in SAFe contexts.
## Backlog and Cross-Project Work
**[Manage Unplanned Backlog](/planningboard/guides/planning/unplanned-backlog)** — Work with the unplanned sidebar to hold and triage items not yet assigned to a Plan.
**[Cross-Project Planning](/planningboard/guides/planning/cross-project-planning)** — Display work items from multiple Polarion projects on a single board.
**Starting out**
If you are new to planning on Planningboard, begin with [Drag and Drop Planning](/planningboard/guides/planning/drag-and-drop) and [Prioritize Work Items](/planningboard/guides/planning/prioritization) to get comfortable with the core interaction model, then explore Plan creation and SAFe workflows as your process matures.
**KB Articles**
* Planningboard interface & basic interactions
* Introduction to Planningboard
* Planningboard Widget Parameters
**Support Tickets**
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#4711](https://support.nextedy.com/helpdesk/tickets/4711)
**Source Code**
* `Item.java`
* `Config.java`
* `PlansMode.java`
* `PlanningBoardDataService.java`
* `PlanningBoardWidgetRenderer.java`
# Use Plan Templates
Source: https://learn.nextedy.com/planningboard/guides/planning/plan-templates
Configure name and ID patterns so Nextedy PLANNINGBOARD creates consistently structured Plans from a single click — no manual naming required.
## What this guide covers
When you enable the **New Plan** feature in widget parameters, Planningboard generates new Plans from a template. This guide shows you how to configure the template parameters — name pattern, ID pattern, duration, parent, and optional team expansion — so every new Plan follows your project's naming conventions.
## Prerequisites
* Planningboard widget already embedded in a Polarion LiveDoc or Wiki page
* Widget parameters accessible (page editor or administration)
* At least one existing Plan in the project (auto-numbering extracts the sequence start from the last matching Plan)
***
1. Open the page containing your Planningboard widget and enter edit mode.
2. Open the widget parameters panel.
3. Locate the **New Plan** section and enable it.
Once enabled, a **plus (+) button** appears in the board toolbar. Until you configure the template parameters (steps below), clicking it creates Plans with default values — proceed to the next steps to control naming and structure.
***
The `Template ID` parameter tells Polarion which plan template to use (for example `iteration` or `release`). This controls the Plan type that gets created.
```properties theme={null}
Template ID: iteration
```
**Match your project's plan template IDs**
The value must match an existing Polarion plan template ID in your project, not a display name. Using an incorrect ID silently creates a Plan of the wrong type or causes creation to fail.
***
Two pattern parameters control what the new Plan is called and what identifier it receives:
| Parameter | Purpose | Available placeholders |
| ------------------- | ------------------------------------ | ------------------------- |
| `Plan Name Pattern` | Display name shown in column headers | `{planNum}`, `{teamName}` |
| `Plan ID Pattern` | Unique identifier in Polarion | `{planNum}`, `{teamId}` |
The `{planNum}` placeholder is replaced by an auto-incremented integer. Planningboard determines the next number by:
1. Querying for existing Plans matching the same template ID and project.
2. Extracting `{planNum}` from the last matching Plan's ID.
3. Incrementing by 1.
4. Defaulting to `1` if no matching Plans are found.
### Example — single-team iterations
```properties theme={null}
Plan Name Pattern: Iteration {planNum}
Plan ID Pattern: iteration_{planNum}
```
This produces Plans named **Iteration 4**, **Iteration 5**, etc., with IDs `iteration_4`, `iteration_5`.
### Example — SAFe-style naming with dashes
```properties theme={null}
Plan Name Pattern: I-{planNum}
Plan ID Pattern: I-{planNum}
```
**Dash characters in plan names require version 25.3.0 or later**
A parsing bug in earlier versions caused column spans to render incorrectly, capacity to show zero, and plan shortcuts to disappear when plan names contained dashes (for example `I-2401-1` or `PI-2401`). If you use dash-containing naming patterns, confirm you are running version 25.3.0 or later before relying on this feature in production.
***
If your project contains multiple release versions and you want new iterations created under a specific parent, set the `Parent ID` parameter:
```properties theme={null}
Parent ID: Version_3_0
```
Leave this blank to place new Plans at the root level of the project.
**Use Parent ID when multiple versions exist**
Without a Parent ID, Planningboard looks for the most recent Plan of the same template type anywhere in the project. If multiple versions are active, new Plans may be placed under the wrong parent. Specifying Parent ID ensures consistent placement.
***
`New Plan Duration` defines how long each generated Plan spans. Enter the duration in days:
```properties theme={null}
New Plan Duration: 14
```
Planningboard calculates the start date of the next Plan by looking for the last Plan matching your template and project (using `Last Plan Query` and `Last Plan Sort` if configured), then placing the new Plan immediately after it.
**Date calculation fallback sequence:**
```text theme={null}
1. Use nextStartDate if explicitly provided (YYYY-MM-DD)
|
v
2. Find last plan via Last Plan Query + Last Plan Sort
(default sort: latest dueDate)
|
v
3. Calculate new start = last plan's end date + 1 day
|
v
4. Calculate new end = new start + New Plan Duration
```
If no previous Plan is found, the system falls back to the parent Plan's start date, then today's date.
***
By default, Planningboard finds the "last plan" by querying all Plans in the project with the same template ID, sorted by due date (latest first). You can override this with a custom Lucene query:
```properties theme={null}
Last Plan Query: projectId:MyProject AND type.id:iteration
Last Plan Sort: dueDate
```
Leave both blank to use the default behavior.
***
If your board uses multiple teams, enable the **Enable Teams** option and define team name/ID pairs. When Teams are enabled, clicking the plus (+) button creates one new Plan per team in a single operation.
```properties theme={null}
Enable Teams: true
Teams:
- name: Alpha Team
id: alpha
- name: Beta Team
id: beta
Plan Name Pattern: {teamName} - Iteration {planNum}
Plan ID Pattern: {teamId}_iteration_{planNum}
```
This produces Plans named **Alpha Team - Iteration 4** and **Beta Team - Iteration 4** simultaneously.
**Predefined patterns include / by default**
When you enable Teams, the widget pre-populates the name and ID patterns with `{teamName}` and `{teamId}` placeholders. If your project does not use teams, remove these placeholders — otherwise `{teamName}` and `{teamId}` appear as literal text in your Plan names.
***
1. Save the widget parameters.
2. Return to the board view and click the **plus (+) button** in the toolbar.
3. A confirmation dialog appears showing the calculated values (name, ID, dates, parent).
4. Review the values and confirm.
The new Plan appears as a column on the board immediately after the page refreshes.
**Review values in the confirmation dialog before creating**
The confirmation dialog shows what Planningboard calculated for name, ID, start date, and end date. If the values look wrong (wrong sequence number, unexpected parent), cancel and check your pattern configuration before proceeding.
***
## Verification
You should now see:
* The new Plan column in the board with the name matching your `Plan Name Pattern`.
* The Plan ID in Polarion matching your `Plan ID Pattern` with the correct sequence number.
* The Plan's start and end dates consistent with the previous Plan's end date plus the configured duration.
* If Teams are enabled, one column per team created in a single operation.
If the column does not appear, use the **Refresh data** toolbar button to reload the board without a full page reload.
***
## Configuration summary
| Parameter | Required | Example | Notes |
| ------------------- | -------- | --------------------- | -------------------------------------------------------- |
| `Template ID` | Yes | `iteration` | Must match an existing Polarion plan template ID |
| `Plan Name Pattern` | Yes | `Iteration {planNum}` | Uses `{planNum}`, `{teamName}` |
| `Plan ID Pattern` | Yes | `iteration_{planNum}` | Uses `{planNum}`, `{teamId}` |
| `Parent ID` | No | `Version_3_0` | Scopes new Plans under a specific parent |
| `New Plan Duration` | Yes | `14` | Duration in days |
| `Last Plan Query` | No | `type.id:iteration` | Lucene query to find the anchor Plan |
| `Last Plan Sort` | No | `dueDate` | Field used to pick the "last" Plan; default is `dueDate` |
| `Enable Teams` | No | `true` | Creates one Plan per team on each click |
***
## See also
* [Bulk Plan Creation](/planningboard/guides/planning/bulk-plan-creation) — create multiple Plans at once via script
* [Create Plans](/planningboard/guides/planning/creating-plans) — manually create and manage Plans on the board
* [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) — full reference for all widget parameters
* [Configure Plans (Columns)](/planningboard/guides/configuration/plans-configuration) — control which Plans appear as columns
* [SAFe Plan Naming Conventions](/planningboard/guides/planning/safe-naming-conventions) — naming patterns for SAFe hierarchies
* [SAFe Planning Workflows](/planningboard/guides/planning/safe-planning) — end-to-end SAFe configuration guide
**KB Articles**
* Introduction to Planningboard
* Planningboard interface & basic interactions
* Planningboard Widget Parameters
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
* [#4711](https://support.nextedy.com/helpdesk/tickets/4711)
**Source Code**
* `PlanningBoardWidgetRenderer.java`
* `Item.java`
* `PlansMode.java`
* `Config.java`
* `PlanningBoardDataService.java`
# Prioritize Work Items
Source: https://learn.nextedy.com/planningboard/guides/planning/prioritization
Enable the Prioritization feature on the board to reorder work item cards within a swimlane, establishing a ranked order that persists in Polarion.
***
## Before You Begin
* You need edit permissions on the work items in the board scope.
* The board must be displaying work items as cards (not in read-only mode). See [Read-Only Mode](/planningboard/guides/advanced/read-only-mode) if the **Prioritize** button is not shown.
* Familiarize yourself with the board layout if needed: [Basic Board Interactions](/planningboard/getting-started/basic-interactions).
***
1. Navigate to the Polarion page that contains your Nextedy PLANNINGBOARD widget.
2. In the toolbar in the upper-left corner of the board, click the **Prioritize** button ( icon).
Prioritization mode is now active. A visual indicator shows that the board is in priority-editing state.
**Toolbar reference**
The **Prioritize** button is one of several toolbar controls. If you cannot see the toolbar, check that the board has loaded fully. Use the **Refresh data** button to reload if cards are missing.
***
Within each swimlane, drag cards up or down to reflect their priority. The card at the top of a swimlane column is treated as the highest priority.
When Prioritize mode is active, each card shows its current priority value in brackets next to its priority field. Here are three cards before any reordering — PB-138 at 61.0, PB-136 at 55.0, and PB-122 at 46.0:
After dragging PB-122 above PB-136, its priority value updates to reflect its new position (58.000 — the average between 61 and 55):
Dragging PB-122 further to the top position assigns it a value of 71.000 (10 points above the previous top card):
Each drop is saved immediately — you do not need to confirm or submit changes.
**Sort order is shared with swimlane sort**
The card sort order within a swimlane is coupled to the overall item sort order configured via the **Sort by** widget parameter. Changing priority order in Prioritization mode rewrites the item rank in Polarion. If your board is configured to sort by a field such as due date or severity, enabling prioritization overrides that display order for subsequent loads. Verify your **Sort by** setting before using prioritization in boards that rely on field-based sorting.
***
Repeat the drag-and-drop reordering for each swimlane that needs priority adjustments. Each swimlane maintains its own card order independently.
**Scroll position is preserved**
When you drag a card and Planningboard saves the change, the board preserves your current swimlane and scroll position. You will not be jumped back to the top of the board, which makes it practical to work through a long list of items in a large board.
***
Click the **Prioritize** button again in the toolbar to turn off prioritization mode. The board returns to its standard drag-and-drop planning state.
***
## Configure the Sort Order Used for Prioritization
The **Sort by** widget parameter controls the initial ordering of cards when the board loads, and it interacts directly with prioritization. To configure it:
1. Open the widget configuration (expand tools → click the edit button on the widget).
2. Locate the **Parameters for Work Items** section.
3. Set **Sort by** to the field or criterion that should establish the default order before manual prioritization is applied.
| Sort by value | Effect on board |
| ---------------------- | ------------------------------------------------------------------------------ |
| Priority field | Cards load in Polarion priority rank order; drag reorders that rank |
| Due date | Cards load by due date; drag overrides the date-based order with a manual rank |
| Severity / custom enum | Cards load by enum value order; drag overrides with manual rank |
**Consistency required across Plans**
All Plans on the board must use consistent calculation types. Mixing Plans with different calculation configurations causes summation issues in capacity and effort totals, and can affect how items sort relative to each other across columns. If items appear in unexpected positions after prioritization, verify that all Plans in your project use the same calculation type.
***
## Verified Items Cannot Be Moved
Work items with the **Verified** status are locked on the board. Cards in Verified status cannot be dragged in either standard planning mode or prioritization mode. This applies both to moving them between Plans and to reordering them within a swimlane.
This is expected behaviour. Verified items have completed their planning lifecycle. If you need to reorder a Verified item, change its status first via the work item sidebar.
***
## Interaction with the Unplanned Section
Items in the **Unplanned** section (the right-hand backlog sidebar) are not part of the prioritization order. Prioritization applies only to cards already placed on the board (i.e., assigned to a Plan column). Plan items from the Unplanned section first, then use Prioritization mode to rank them within their swimlane.
Attempting to drag a card from one column (Plan) to another while Prioritization mode is active is blocked. The board displays an error message:
See [Manage Unplanned Backlog](/planningboard/guides/planning/unplanned-backlog) for guidance on moving items from the backlog onto the board.
***
## Prioritization and Card Filtering
When the board has active card filters (for example, filtered by assignee or by a custom query via the funnel icon), Prioritization mode operates on the currently visible cards only. Hidden cards retain their position in the full order. Reordering filtered-view cards may produce gaps in the overall rank sequence.
**Filter before prioritizing**
If you only want to prioritize a subset of items — for example, only stories assigned to a specific user — apply that filter before entering Prioritization mode. This limits the drag targets to the relevant cards and makes the relative order easier to reason about.
***
## Verification
After reordering cards and exiting Prioritization mode, you should now see:
* Cards in each swimlane column appear in the order you set.
* Refreshing the board (using the **Refresh data** toolbar button) reloads the board with the updated order intact — confirming the priority was saved to Polarion.
* If another user opens the same board, they see the same ranked order.
After exiting prioritization mode the priority brackets disappear from the cards. The card positions are preserved but the values are no longer shown:
Use the **Refresh data** button to confirm the new order persists:
After refreshing, the cards reload with the updated priority values visible:
If cards revert to a different order after refresh, check whether the **Sort by** widget parameter is set to a field value that overrides the manual rank on load.
***
## See Also
* [Drag and Drop Planning](/planningboard/guides/planning/drag-and-drop) — standard planning interactions before using prioritization
* [Configure Work Items Dataset](/planningboard/guides/configuration/work-items-configuration) — set the **Sort by** parameter and work item query
* [Sort Swimlanes](/planningboard/guides/swimlanes/sorting-swimlanes) — configure how swimlane rows themselves are ordered
* [Basic Board Interactions](/planningboard/getting-started/basic-interactions) — toolbar controls and card quick actions overview
* [Manage Unplanned Backlog](/planningboard/guides/planning/unplanned-backlog) — move backlog items onto the board before prioritizing
**KB Articles**
* Introduction to Planningboard
* Planningboard interface & basic interactions
* Planningboard Widget Parameters
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
* [#6496](https://support.nextedy.com/helpdesk/tickets/6496)
**Source Code**
* `Item.java`
* `PlansMode.java`
* `Config.java`
* `PlanningBoardDataService.java`
* `PlanningBoardWidgetRenderer.java`
# SAFe Plan Naming Conventions
Source: https://learn.nextedy.com/planningboard/guides/planning/safe-naming-conventions
Apply consistent SAFe naming patterns to Plans so that Nextedy PLANNINGBOARD correctly parses hierarchy, renders columns, and displays capacity.
**Version requirement for dash characters**
Plan names containing dashes (e.g. `PI-2401`, `I-2401-1`) caused column spans to render incorrectly, capacity to show zero, and plan shortcuts to disappear in versions before 25.3.0. A partial fix shipped in 23.8.0; full support for dashes in plan names requires **version 25.3.0 or later**. Verify your installed version before adopting dash-based naming.
***
## SAFe hierarchy overview
Planningboard models SAFe planning across four levels. Each level maps to a `plansMode` value and a corresponding Plan ID pattern:
The Plan **ID** (not just the display name) is what Planningboard uses when loading and cross-referencing plans. Using a predictable, level-consistent pattern across all Plans prevents silent mismatches.
***
Adopt one naming pattern per level and apply it uniformly. The examples below match the patterns used in support tickets for enterprise SAFe deployments:
| Level | Example Plan ID | Example Plan Name |
| ---------------------- | --------------- | ----------------- |
| Program Increment (PI) | `PI-2401` | PI 2401 |
| Team Iteration | `I-2401-1` | Iteration 2401.1 |
| Program Iteration | `PI-2401-IP` | IP Sprint 2401 |
Rules:
* Use only alphanumeric characters, dashes (`-`), and underscores (`_`) in Plan IDs.
* Dashes are safe from version 25.3.0 onward — do not use them on earlier versions.
* Keep the delimiter consistent within each level (all dashes or all underscores — do not mix).
* The Plan ID must be unique within the project; the Plan Name is the display label shown in column headers.
**PI date codes**
Encoding the year and quarter in the PI name (e.g. `PI-2401` = 2024 Q1) makes boards self-documenting and simplifies the `Last Plan Query` when creating new plans from the board.
***
When creating Plans manually in Polarion, set both the **ID** and the **Name** fields:
* **ID** — enter the pattern ID exactly (e.g. `PI-2401`). This is the value Planningboard stores internally and uses when syncing SAFe parent plans.
* **Name** — enter the human-readable label (e.g. `PI 2401`). This appears in the board column header.
If you are using Planningboard's **New Plan** feature to create Plans from the board, configure the `Plan ID Pattern` and `Plan Name Pattern` widget parameters to match your chosen scheme. See [Configure Plans (Columns)](/planningboard/guides/configuration/plans-configuration) for parameter details.
***
Open the widget parameters for your Planningboard widget and locate the **New Plan** section:
| Parameter | Value for PI level | Value for Iteration level |
| ------------------- | ------------------------ | -------------------------------------- |
| `Plan ID Pattern` | `PI-${year}${quarter}` | `I-${year}${quarter}-${index}` |
| `Plan Name Pattern` | `PI ${year}${quarter}` | `Iteration ${year}${quarter}.${index}` |
| `Template ID` | your PI plan template ID | your iteration plan template ID |
**Default patterns assume Teams**
The `Plan ID Pattern` and `Plan Name Pattern` fields are pre-filled with Team-aware placeholders when Teams are enabled. If you are not using Teams, replace the defaults with your SAFe pattern — otherwise newly created plans will not match your naming scheme and the `Last Plan Query` will not find them.
***
The `plansMode` widget parameter controls which Plans Planningboard loads and how it groups them. Set it to the value that matches the board's level in the SAFe hierarchy:
| Board scope | `plansMode` value |
| ------------------------------------ | ----------------- |
| Team-level sprints within a program | `safeSprints` |
| Sprints across the portfolio | `safePflSprints` |
| Program Increments within an ART | `safePIs` |
| Program Increments at solution level | `safeSIs` |
**Plans Type selector**
In the widget configuration UI, `plansMode` appears as the **Plans Type** dropdown. Selecting a SAFe type changes which configuration fields are shown — for example, the **Program Increment Parameter ID** field appears only for the **SAFe Sprints in Program** (`safeSprints`) and **SAFe Sprints in Portfolio** (`safePflSprints`) modes, and the plan items section is hidden for SAFe modes (it is available only in **Project Plans** (`PROJECT_PLANS`) mode).
***
When Planningboard creates a new plan, it finds the "last plan" to calculate the next plan's date range using the `Last Plan Query` (defaults to the latest plan of the same template type if left empty) and `Last Plan Sort` (defaults to `dueDate` descending).
If your IDs contain dates or sequence numbers, confirm that the query can still find the correct last plan after renaming. For example, if you use `PI-2401`, `PI-2402`, `PI-2403`, the default sort by `dueDate` finds the last PI correctly without a custom query.
If you add PIs out of chronological order, or your template has mixed types, provide an explicit `Last Plan Query` to pin the lookup.
***
After applying your naming scheme:
1. Open the Planningboard page in Polarion.
2. Check that the expected Plans appear as **columns** and that column headers show the display names (not the IDs).
3. Hover over a **capacity bar** to confirm the capacity tooltip shows a non-zero value. A zero capacity value is a symptom of Planningboard failing to parse the plan name — upgrade to 25.3.0 if this occurs on a plan with dashes in the name.
4. Confirm that **plan shortcuts** (the links in column headers) open the correct Polarion Plan pages.
**Refreshing the board after renaming**
If you rename existing Plans in Polarion and the board still shows old column headers, use the **Refresh data** toolbar button (circular arrow icon) to force a reload. The board does not auto-detect Plan renames.
***
## ASCII diagram — SAFe Plan ID hierarchy
Each level's Plan IDs must be unique within their Polarion project. Cross-level references (parent plan assignment, `syncSAFEParentsFromChildren`) rely on the ID patterns being parseable — consistent dash placement ensures correct parsing.
***
## Common pitfalls
**Mixed delimiters break parsing**
Using `PI_2401` in one sprint and `PI-2401` in another causes Planningboard to treat them as different hierarchy branches. Pick one delimiter per level and do not mix.
**Capacity showing zero after PI rename**
If you rename a PI plan after the board has been used, existing capacity values stored against the old ID will not transfer automatically. Re-enter capacity values via the capacity bar tooltip or the `POST /capacity` API endpoint after any rename.
**SAFe configuration UI differs by Plans Type**
Selecting **SAFe Sprints in Program** (`safeSprints`) or **SAFe Sprints in Portfolio** (`safePflSprints`) shows a **Program Increment Parameter ID** field that is absent in **Project Plans** (`PROJECT_PLANS`) mode. Page Parameters must be explicitly created in the widget configuration and referenced here — they are not created automatically. Missing Page Parameter setup is the most common reason SAFe boards show no columns after configuration.
***
## You should now see
* All Plans appear as columns with the correct display names from your naming scheme.
* Hovering over a capacity bar shows a non-zero capacity tooltip (assuming capacity is configured).
* Plan shortcut links in column headers navigate to the correct Polarion Plan pages.
* The **New Plan** button (if enabled) creates plans whose IDs follow your chosen pattern.
***
## See also
* [SAFe Planning Workflows](/planningboard/guides/planning/safe-planning) — end-to-end SAFe board configuration by hierarchy level
* [Configure Plans (Columns)](/planningboard/guides/configuration/plans-configuration) — `Plan ID Pattern`, `Plan Name Pattern`, `Last Plan Query`, and other column parameters
* [Bulk Plan Creation](/planningboard/guides/planning/bulk-plan-creation) — scripted creation of multiple Plans with consistent naming
* [Use Plan Templates](/planningboard/guides/planning/plan-templates) — template IDs and how they interact with plan creation
* [Capacity Calculation Issues](/planningboard/guides/troubleshooting/capacity-issues) — diagnosing zero capacity after naming changes
**KB Articles**
* Introduction to Planningboard
* Planningboard interface & basic interactions
* Planningboard Widget Parameters
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#4711](https://support.nextedy.com/helpdesk/tickets/4711)
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
**Source Code**
* `PlanningBoardDataService.java`
* `Config.java`
* `PlansMode.java`
* `Item.java`
* `PlanningBoardWidgetDependenciesProcessor.java`
# SAFe Planning Workflows
Source: https://learn.nextedy.com/planningboard/guides/planning/safe-planning
Configure Planningboard for Scaled Agile Framework (SAFe) planning across Portfolio, Program, and Team hierarchy levels.
***
## Before you start
* Nextedy PLANNINGBOARD is installed and licensed in your Polarion project
* Your Polarion project uses the SAFe solution template with SAFe Plan types configured
* You have widget editor access on the Wiki or LiveDoc page hosting the board
* Plan names follow SAFe conventions (see the warning on dash-containing names below)
**Dash characters in plan names require version 25.3.0 or later**
SAFe naming conventions commonly use dashes — for example `PI-2401` or `I-2401-1`.
A parsing bug caused column spans to render incorrectly, capacity to display as zero, and plan shortcuts to disappear when plan names contained dashes. This was partially fixed in 23.8.0 and **fully resolved in 25.3.0**. If your plan names contain dashes, upgrade to 25.3.0 or later before proceeding.
***
## How SAFe planning modes map to hierarchy levels
Planningboard exposes five `plansMode` values. For SAFe deployments, four are relevant:
The `assignmentMode` you pair with each level determines the swimlane grouping:
| Level | Recommended `plansMode` | Recommended `assignmentMode` |
| ------------------------ | ----------------------- | ---------------------------- |
| Team (Sprint board) | `SAFE_SPRINTS` | `SAFE_TEAM` or `ASSIGNEE` |
| Program (PI board) | `SAFE_PIS` | `SAFE_TRAIN_TEAM` |
| Portfolio (solution PIs) | `SAFE_SOLUTION` | `SAFE_PROGRAMS` |
| Portfolio (sprint view) | `SAFE_PFL_SPRINTS` | `SAFE_PROGRAMS` |
**Plans Type selection changes the configuration UI**
When you switch **Plans Type** in the widget parameters, the visible configuration fields change. Fields like **Scope**, **Query**, and **Type** appear for **Project Plans** (`PROJECT_PLANS`) mode; SAFe modes show different fields including the **Program Increment Parameter ID** field. This is expected — each mode surfaces only the fields relevant to its hierarchy level.
***
1. Open the Polarion Wiki or LiveDoc page containing your Planningboard widget.
2. Click **Edit** on the page, then open the widget parameters panel.
3. Under **Parameters for Plans (Columns)**, set **Plans Type** to the SAFe mode for your hierarchy level (for example, **SAFe Program Increments in Program** (`SAFE_PIS`) for a Program-level PI board).
4. Save the widget parameters.
The board will now load SAFe Plans as columns instead of standard project plans.
***
1. In the same widget parameters panel, open **Swimlanes (Rows)**.
2. Set **Assignment Type** to the mode matching your hierarchy level:
* **Program / Solution Teams (SAFe)** (`SAFE_TEAM`) — swimlanes for SAFe teams within the current program (sourced from Polarion SAFe Solution data)
* **Agile Release Train Teams (SAFe)** (`SAFE_TRAIN_TEAM`) — swimlanes for teams within a specific Agile Release Train, filtered by ART ID
* **Programs (SAFe)** (`SAFE_PROGRAMS`) — swimlanes for SAFe programs within a solution train (portfolio-level)
* **Users (Assignee)** (`ASSIGNEE`) — standard assignee swimlanes (also valid at Team level)
3. If you selected **Agile Release Train Teams (SAFe)** (`SAFE_TRAIN_TEAM`), enter the ART ID in the **ART ID** field that appears.
4. Save the widget parameters.
**SAFe Team field and Program field**
Planningboard reads SAFe team assignments from the `safeTeam` custom field on work items (default for **Program / Solution Teams (SAFe)** (`SAFE_TEAM`) and **Agile Release Train Teams (SAFe)** (`SAFE_TRAIN_TEAM`) modes), and SAFe program assignments from the `safeProgram` field (default for **Programs (SAFe)** (`SAFE_PROGRAMS`) mode). If your project uses different field IDs, set `safeTeamField` or `safeProgramField` to match your actual field IDs.
***
When using **SAFe Sprints in Program** (`SAFE_SPRINTS`) or **SAFe Sprints in Portfolio** (`SAFE_PFL_SPRINTS`), the board needs to know which Program Increment to load sprints from. This is driven by a **Page Parameter**.
1. In the widget parameters panel, locate the **Program Increment Parameter ID** field (visible only in **SAFe Sprints in Program** (`SAFE_SPRINTS`) and **SAFe Sprints in Portfolio** (`SAFE_PFL_SPRINTS`) modes).
2. Enter the name of the Page Parameter you will create — for example, `pi`.
3. On the Wiki or LiveDoc page, create a Page Parameter named `pi` and set its default value to the ID of the current Program Increment plan.
4. The board now loads only the sprints belonging to that PI. Users can switch PIs by changing the page parameter value.
**Page Parameters must be explicitly created**
The Program Increment Parameter ID field only references the parameter by name — the Page Parameter itself must be created separately on the page. If the parameter does not exist, the board will fail to load sprints correctly. See [Use Page Parameters](/planningboard/guides/configuration/page-parameters) for setup steps.
***
When a work item is dragged into a sprint column, Planningboard can automatically assign it to the parent Program Increment as well.
1. In the widget parameters, under **Parameters for Plans (Columns)**, enable **Assign to Parent Plan**.
2. Save.
With this enabled: dragging a Story into `I-2401-1` also plans it under `PI-2401`. Without it, the Story is planned only in the iteration.
For SAFe modes, Planningboard also runs `syncSAFEParentsFromChildren` automatically — when a team assignment changes on a work item, the item is remapped to the correct Team Program Increment plan for that team.
***
Capacity bars in SAFe boards work the same as in standard mode. To enable them:
1. Under **Parameters for Plans (Columns)**, enable **Show Capacity Load**.
2. Optionally set **capacityField** to a custom field (such as story points) if you are not using time-tracking fields.
3. Set **hoursPerDay** if your team uses a value other than the default of `8`.
**Capacity configuration is whitespace-sensitive**
Widget parameter values for capacity (for example, `capacityField`) must not contain leading or trailing whitespace. A space before or after the field ID will silently break capacity calculations and show zero on the capacity bar.
See [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration) for full details.
***
After saving all widget parameters, reload the page. You should now see:
* SAFe Plans (PIs or sprints) displayed as columns, ordered chronologically
* Swimlanes showing SAFe teams, ART teams, programs, or assignees depending on your assignment mode
* Capacity bars per swimlane (if capacity load is enabled)
* Work items as cards, draggable between plan columns and swimlanes
**Use the toolbar to verify dependency and load visibility**
Use **Toggle Resource Load visualization** in the toolbar to confirm that capacity bars are rendering correctly. Use **Show Dependencies** to verify that dependency arrows appear between cards (requires `dependencyLinkRoles` to be configured — see [Configure Dependencies Display](/planningboard/guides/configuration/dependencies-configuration)).
***
## SAFe plan naming conventions
Plan IDs generated via bulk creation use `{planNum}` and `{teamId}` placeholders. For SAFe naming, align your **Plan ID Pattern** and **Plan Name Pattern** to the conventions above. See [SAFe Plan Naming Conventions](/planningboard/guides/planning/safe-naming-conventions) for the full pattern reference.
***
## Configuration overview diagram
***
## Common pitfalls
**Configuration UI changes by Plans Type — this is not a bug**
Users often report that the widget parameter form looks different from screenshots in other guides. The form is dynamic: selecting **SAFe Program Increments in Program** (`SAFE_PIS`) hides the **Scope** and **Query** fields that are only relevant in **Project Plans** (`PROJECT_PLANS`) mode. If you do not see an expected field, verify that your **Plans Type** selection matches the level you are configuring.
**Program / Solution Teams (SAFe) requires a Polarion SAFe Solution**
The **Program / Solution Teams (SAFe)** (`SAFE_TEAM`) and **Programs (SAFe)** (`SAFE_PROGRAMS`) assignment modes read team and program data from Polarion's SAFe Solution structure. If your project does not have a SAFe Solution configured in Polarion, these modes will render an empty board or fail silently. Use **Users (Assignee)** (`ASSIGNEE`) or **Enumeration Field** (`ENUM`) mode as an alternative if the SAFe Solution is not set up.
**Start with a single level before adding hierarchy**
SAFe configuration is context-dependent and the interactions between `plansMode`, `assignmentMode`, and Page Parameters are easy to misconfigure. Configure and verify one hierarchy level (for example, the Team sprint board) before setting up the Program or Portfolio boards.
***
## See also
* [SAFe Plan Naming Conventions](/planningboard/guides/planning/safe-naming-conventions) — naming patterns for PIs, iterations, and team plans
* [SAFe Swimlanes](/planningboard/guides/swimlanes/safe-swimlanes) — detailed swimlane configuration for SAFe team and program modes
* [Use Page Parameters](/planningboard/guides/configuration/page-parameters) — how to create and reference Page Parameters for dynamic PI selection
* [Configure Plans (Columns)](/planningboard/guides/configuration/plans-configuration) — full Plans configuration reference
* [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration) — capacity bar setup and normalization
* [Bulk Plan Creation](/planningboard/guides/planning/bulk-plan-creation) — create PI and iteration plans in bulk with naming patterns
**KB Articles**
* Planningboard interface & basic interactions
* Introduction to Planningboard
* Planningboard Widget Parameters
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#4711](https://support.nextedy.com/helpdesk/tickets/4711)
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
**Source Code**
* `PlanningBoardDataService.java`
* `PlansMode.java`
* `Config.java`
* `Item.java`
* `PlanningBoardWidgetRenderer.java`
# Manage Unplanned Backlog
Source: https://learn.nextedy.com/planningboard/guides/planning/unplanned-backlog
Use the Unplanned section to review, filter, and assign backlog work items onto Plans directly from the Nextedy PLANNINGBOARD — without leaving Polarion.
## What the Unplanned section is
The Planningboard layout has two main areas: the **Planningboard Area** on the left (cards arranged in columns by Plan and rows by swimlane) and the **Unplanned Section** on the right. The Unplanned section acts as a backlog holding all work items that have not yet been assigned to a Plan. Cards sit here until you drag them onto the board.
## Toggle the Unplanned section
The Unplanned section can be shown or hidden using the **Show Unplanned** toolbar button in the upper-left corner. Click it to toggle visibility without leaving the board.
## Filter cards in the Unplanned section
The Unplanned section provides several filtering controls to narrow the backlog to the cards you want to plan.
### Filter by assignee or team
1. Click the **funnel icon** at the bottom of the Unplanned section.
2. Select one or more assignees or teams from the list.
3. The section updates immediately to show only matching cards.
If you have predefined **Queries** configured in the widget parameters, those also appear in the filter panel and can be enabled here. See [Configure Unplanned Sidebar](/planningboard/guides/configuration/unplanned-sidebar) for how to set up custom queries.
### Hide Verified work items
Click the **upper-right button** in the Unplanned section header to filter out work items with the status **Verified**. This keeps the backlog focused on actionable items.
Use the Verified filter when your team has a habit of leaving resolved items in the backlog query. It removes noise from the view without changing the underlying query.
### Filter out already-planned Verified work items
The **Filter columns** option hides Verified work items that are already planned on the board. This is useful when your query includes planned items (for example when **Add Planned** is enabled in the widget parameters) and you want to remove the clutter of done work.
## Plan cards from the Unplanned section
### Drag and drop onto a Plan
1. Find the card you want to plan in the Unplanned section.
2. Drag it to the target cell on the board — the intersection of the Plan column and the appropriate swimlane row.
3. Release to assign the work item to that Plan.
The assignment writes back to Polarion immediately. There is no separate save step for drag-and-drop operations.
Cards with the status **Verified** that have already been placed on the board cannot be moved or returned to the Unplanned section. This lock prevents accidental re-opening of completed work.
### Use the Unplan action to return a card to backlog
To move a planned card back to the Unplanned section:
1. Hover over the card on the board.
2. Click the **Unplan item** quick-action icon that appears in the upper-right corner of the card.
The card moves back to the Unplanned section and is removed from the Plan.
## Configure what appears in the Unplanned section
The Unplanned section renders work items based on the widget's work-item query and optional Queries configuration. To control which backlog items appear:
| Widget parameter | What it does |
| ---------------- | -------------------------------------------------------------------------------- |
| `query` | Lucene query selecting which work items load onto the board (default: `NOT *:*`) |
| `wiType` | Restricts displayed items to a specific work item type (e.g., `story`, `task`) |
| `maxItems` | Maximum number of work items loaded (default: `1000`) |
| `addPlanned` | When enabled, loads all planned items in addition to those matched by the query |
For the Unplanned sidebar specifically, two additional parameters control the parent hierarchy display:
| Widget parameter | What it does |
| ----------------------------- | ------------------------------------------------------------------ |
| `PARAMETER_US_DEPTH` | Number of parent levels loaded in the Unplanned sidebar hierarchy |
| `PARAMETER_PARENTS_LINK_ROLE` | Link roles used to build the parent-child hierarchy in the sidebar |
Deep parent hierarchies (high `PARAMETER_US_DEPTH` values) increase load time. Start with a depth of 1 or 2 and increase only if your planning workflow requires it.
See [Configure Unplanned Sidebar](/planningboard/guides/configuration/unplanned-sidebar) and [Configure Work Items Dataset](/planningboard/guides/configuration/work-items-configuration) for full parameter details.
## Set up named Queries for the Unplanned section
Named Queries let team members switch quickly between filtered backlog views — for example, showing only items with a specific status or assigned to a specific component.
1. Open the widget parameters for your Planningboard.
2. Navigate to the **Queries** section.
3. Add a query with a name and a Lucene filter expression (for example: `status:reviewed`).
4. Save the widget parameters.
On the board, open the funnel filter in the Unplanned section. Your named query appears in the list and can be toggled on or off.
Create a query named "Ready for Sprint" scoped to items with status `reviewed` or `approved`. Team members can activate it during sprint planning to instantly surface only the work that has been groomed and is ready to commit.
## Workflow: assign backlog items during sprint planning
Enable the **Toggle Resource Load visualization** toolbar button while dragging cards. The capacity bars update as you assign work, letting you track load in real time without switching to another view.
## Verify your results
After assigning cards from the Unplanned section, you should see:
* The cards you dragged now appear as cells in the correct Plan column and swimlane row on the board.
* The Unplanned section no longer contains those cards (unless **Add Planned** is enabled in the widget parameters, in which case they remain visible but can be hidden using the Filter columns option).
* The capacity bar for the affected swimlane reflects the updated load.
* In Polarion, the work items' `plannedIn` field is updated to the target Plan.
If a card still appears in the Unplanned section after dragging, refresh the board using the **Refresh data** toolbar button.
## See also
* [Configure Unplanned Sidebar](/planningboard/guides/configuration/unplanned-sidebar) — set up parent hierarchy depth, link roles, and named queries
* [Configure Work Items Dataset](/planningboard/guides/configuration/work-items-configuration) — control the backlog query, type filters, and `Add Planned` behavior
* [Drag and Drop Planning](/planningboard/guides/planning/drag-and-drop) — detailed guide to drag-and-drop interactions on the board
* [Basic Board Interactions](/planningboard/getting-started/basic-interactions) — overview of toolbar controls and card actions
* [Track Team Capacity](/planningboard/guides/capacity/team-capacity) — understand capacity bars and how they relate to the items you plan
**KB Articles**
* Planningboard interface & basic interactions
* Introduction to Planningboard
* Planningboard Widget Parameters
**Support Tickets**
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#6121](https://support.nextedy.com/helpdesk/tickets/6121)
**Source Code**
* `PlanningBoardDataService.java`
* `Item.java`
* `PlansMode.java`
* `Config.java`
* `PlanningBoardWidgetRenderer.java`
# Enumeration Field Swimlanes
Source: https://learn.nextedy.com/planningboard/guides/swimlanes/enum-swimlanes
Group your Nextedy PLANNINGBOARD rows by any enumeration custom field — such as team, severity, or priority — so every card lands in the swimlane that reflects its category value.
## Prerequisites
* A Planningboard widget is already embedded in a Polarion LiveDoc or Wiki page.
* The Polarion project has at least one custom field of enumeration type (or a list-type field whose items are enum values) defined for the work item type you plan to display.
* You have edit access to the page containing the widget.
**Status, resolution, and type fields are not supported**
The `status`, `resolution`, and `type` built-in Polarion fields cannot be used as the enumeration field for swimlane grouping. Use a custom enumeration field instead.
1. Open the Polarion page containing your Planningboard widget.
2. Switch the page to **Edit** mode (click the page-level **Edit** button in the Polarion rich-page editor toolbar).
3. Expand the **Tools** panel on the widget.
4. Click the widget **Edit** () button to open the Widget Parameters dialog.
1. In the Widget Parameters dialog, navigate to the **Swimlanes (Rows)** section.
2. Open the **Assignment Type** dropdown.
3. Select **Enumeration Field**.
In the **Field ID** input, enter the exact identifier of the enumeration custom field you want to use as the grouping criterion.
For example, if your project has a custom field whose ID is `team`, enter:
```
team
```
The field ID must match the identifier as it is defined in Polarion Administration — it is case-sensitive. Common choices include fields such as `team`, `severity`, or `priority` (when those are custom enum fields on your work item type).
**Finding the field ID**
Go to **Administration > Work Items > Custom Fields** in your Polarion project and locate the field. The value in the **ID** column is what you enter here — not the display label.
The **Rows Filter** (optional) limits which enumeration values appear as swimlane rows.
* **Leave empty** to display all enum values as rows (default — shows all).
* **Select specific values** to restrict the board to only those swimlanes.
To configure the filter:
1. Click the **Rows Filter** selector.
2. A multi-value selection dialog opens, listing all available enum values for the configured field and work item type.
3. Select the values you want displayed as swimlane rows.
4. Confirm the selection.
**Enum values are type-specific**
Available values in the Rows Filter depend on the **work item type** displayed on the board. If you change the work item type, the available enum options in the filter will update accordingly.
You can attach an optional **Report Link** to the swimlane configuration. This lets you navigate from a swimlane directly to a related Polarion report filtered by that field value. Enter the report URL or leave blank.
1. Click **Save** (or **OK**) in the Widget Parameters dialog.
2. Exit page edit mode.
3. The Planningboard reloads and displays one swimlane row per enum value present in the loaded work items (or per the filtered selection you configured).
Items with no value for the field appear in a **(none)** / unassigned swimlane row.
## Showing Empty Swimlanes
By default (`showEmptySwimlanes = false`), Planningboard hides swimlane rows that contain no work items. To show all enum values as rows even when they are empty, enable **Show Empty Swimlanes** in the widget parameters.
## Multi-Value Enum Fields
If the enumeration field on your work items allows multiple values (list-type with enum items), each card can appear in more than one swimlane — one row per value it holds.
**Multi-enum swimlane support — check your version**
Multi-value enumeration fields for swimlane grouping were committed for release by end of February 2026. If you configure a multi-value enum field and cards do not distribute across rows as expected, verify your installed Planningboard version supports this capability. Earlier versions may surface a field validation error (`field is not enumeration`) for certain multi-value field configurations. If you see that error, also try **clearing the widget configuration cache** and re-saving the widget parameters to trigger a config rebuild.
## Troubleshooting
### Cards all appear in a single row or in "(none)"
* Confirm the **Field ID** exactly matches the Polarion custom field identifier (case-sensitive).
* Confirm the field is of enumeration type (or a list-type whose items are enum values). Status, resolution, and type fields are not supported.
* Confirm work items in the board's query actually have values set for that field.
### The Rows Filter shows no values
* This usually means the field ID does not resolve to an enum field for the currently configured work item type. Verify the field ID and the work item type selection in the widget parameters.
### A swimlane row is missing for a value I expect
* The Rows Filter may be limiting visible rows — open it and check the selection.
* `showEmptySwimlanes` may be off: rows with no matching items are hidden by default.
**Capacity normalization and parent modes**
Enumeration field swimlanes are compatible with capacity tracking. However, capacity normalization (`planCellsMode`) is not supported when the assignment type is set to **Parent Item** — this limitation does not apply to enumeration field swimlanes.
## You Should Now See
Your Planningboard displays one horizontal swimlane row per enumeration value (filtered to your selection if a Rows Filter is set). Work items are grouped into rows by their field value, and dragging a card between rows updates that field's value on the underlying Polarion work item.
## See Also
* [Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration) — overview of all swimlane settings
* [User and Assignee Swimlanes](/planningboard/guides/swimlanes/user-swimlanes) — group rows by assignee instead of a custom field
* [Parent Item Swimlanes](/planningboard/guides/swimlanes/parent-item-swimlanes) — group rows by parent work item
* [Multi-Valued Field Swimlanes](/planningboard/guides/swimlanes/multi-valued-swimlanes) — details on multi-value enum behavior
* [Sort Swimlanes](/planningboard/guides/swimlanes/sorting-swimlanes) — control the vertical order of swimlane rows
* [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) — full parameter reference
**KB Articles**
* Swimlane Assignment Types
* Filter user swimlanes by Plan range
* Sorting of Swimlanes (Parent Item Assignment Type)
**Support Tickets**
* [#6000](https://support.nextedy.com/helpdesk/tickets/6000)
* [#6777](https://support.nextedy.com/helpdesk/tickets/6777)
* [#6681](https://support.nextedy.com/helpdesk/tickets/6681)
**Source Code**
* `PlanningBoardWidgetRenderer.java`
* `enum-rows-filter.cy.ts`
* `licenseReadonly.cy.ts`
* `AssignmentMode.java`
* `PlanningBoardWidget.java`
# Filter Swimlanes by Plan Range
Source: https://learn.nextedy.com/planningboard/guides/swimlanes/filtering-by-plan-range
Show only the team members who have active assignments within the time range covered by the Plans currently displayed on your board — hiding users who have no capacity in that window.
This guide applies when you are using **user-based swimlanes derived from Team Assignments** and want the board to automatically suppress rows for members whose assignments fall entirely outside the shown Plans.
***
## Prerequisites
Before you begin, confirm that your board meets the following requirements:
* The Nextedy PLANNINGBOARD is configured with **Teams Service** enabled (`useTeamsService = true`).
* Team Assignments are set up for the project (members have assignments with start and end dates).
* Swimlanes use the **Users (Assignee)** assignment type, with rows derived from Team Assignments.
* You are running **Planningboard version 25.12.0** or later.
**Deprecated property**
An earlier property, `nextedy.planningboard.activeTeamAssignmentsOnly=true`, was introduced in version 25.3.0 and **deprecated in version 25.12.0**. That version filtered only past assignments, without regard to the scope of the shown Plans. Do not use it for new setups — use `activeTeamAssignmentsInPlanRangeOnly` instead (documented below).
***
## How it works
When `activeTeamAssignmentsInPlanRangeOnly=true` is set, Planningboard calculates the combined date span of all Plans visible on the board and checks each team member's assignments. Members whose assignments have **no overlap** with that span are hidden. Any work items already assigned to a hidden member are moved automatically to the **Not Assigned / Other** swimlane.
***
## Steps
### 1. Open Polarion Administration Configuration Properties
In Polarion, navigate to:
**Administration > Configuration Properties**
### 2. Add the property
Add the following property to your configuration:
```properties theme={null}
nextedy.planningboard.activeTeamAssignmentsInPlanRangeOnly=true
```
### 3. Save and reload
Save the configuration. Planningboard will apply the filter on the next board load — no server restart is required.
**Property not taking effect?**
If the board does not reflect the change immediately, make a trivial edit in Configuration Properties (add a space, then remove it) and save again. This forces the configuration cache to refresh.
### 4. Verify the result
Reload the Planningboard. Users who have no Team Assignments overlapping the date range of the currently shown Plans should no longer appear as swimlane rows. Any cards that were in their rows will have moved to the **Not Assigned / Other** swimlane.
***
## Configuration example
A typical setup combining Teams Service with plan-range filtering:
```properties theme={null}
# Enable Teams Service integration
nextedy.planningboard.useTeamsService=true
# Show only members with assignments in the displayed Plan range
nextedy.planningboard.activeTeamAssignmentsInPlanRangeOnly=true
```
Widget parameters (set in the **Widget Parameters** panel of your board):
| Widget parameter | Value |
| ----------------- | ---------------- |
| Assignment Type | Users (Assignee) |
| Use Teams Service | enabled |
***
## Worked example
**Scenario:** Team Alpha is planning for three sprints (Sprint 10–12, covering January to mid-February). The board shows swimlanes for all team members. Mark Test left the team in December and has no assignment for this window.
**Before enabling the property:**
The board shows a swimlane for Mark Test even though he has no capacity in the planning window. Tasks that slip into his row are unlikely to be completed.
**After enabling `activeTeamAssignmentsInPlanRangeOnly=true`:**
Mark Test's swimlane disappears. Any tasks that were assigned to him move to **Not Assigned / Other**, making the capacity gap visible and prompting reassignment.
This ensures that capacity shown on the board reflects only members who can realistically take on work within the planning window.
***
## Limitations
* This feature requires **Planningboard 25.12.0 or later**. Earlier versions do not support plan-range-aware filtering.
* The filter is applied at board load time — it reflects the Plans currently shown. If you scroll the board to display a different Plan range, the visible swimlane rows update accordingly on the next load.
* Items assigned to a hidden member are surfaced in **Not Assigned / Other**, not silently dropped. Review that swimlane after enabling the filter to reassign any affected cards.
* This behavior applies only to swimlanes derived from **Team Assignments**. User swimlanes based on project role membership (not Teams Service) are not affected.
***
## Verification
After completing the steps above, reload the Planningboard. You should see:
* Swimlane rows only for team members whose Team Assignments overlap the date range of the Plans shown.
* A **Not Assigned / Other** swimlane at the bottom containing any cards previously belonging to hidden members.
* No swimlane row for members whose assignments fall entirely before or after the current Plan window.
***
## See also
* [User and Assignee Swimlanes](/planningboard/guides/swimlanes/user-swimlanes) — configure the Users (Assignee) assignment type
* [Filter Swimlanes by Team](/planningboard/guides/swimlanes/filtering-by-team) — restrict swimlane rows to a specific team
* [Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration) — full swimlane configuration reference
* [Set Up Teams Service](/planningboard/guides/capacity/teams-service-setup) — prerequisite for Team Assignment–based filtering
* [Track Team Capacity](/planningboard/guides/capacity/team-capacity) — use capacity bars alongside swimlane filtering
**KB Articles**
* Filter user swimlanes by Plan range
* Swimlane Assignment Types
* Sorting of Swimlanes (Parent Item Assignment Type)
**Support Tickets**
* [#5760](https://support.nextedy.com/helpdesk/tickets/5760)
* [#6681](https://support.nextedy.com/helpdesk/tickets/6681)
* [#5922](https://support.nextedy.com/helpdesk/tickets/5922)
**Source Code**
* `filterMultiSwimlaneRows.cy.ts`
* `PlanningBoardWidgetRenderer.java`
* `AssignmentMode.java`
* `licenseReadonly.cy.ts`
* `enum-rows-filter.cy.ts`
# Filter Swimlanes by Team
Source: https://learn.nextedy.com/planningboard/guides/swimlanes/filtering-by-team
Show only the users who have active Team Assignments within the date range of the Plans currently displayed on the board.
When your board uses user-based swimlanes derived from Team Assignments, Nextedy PLANNINGBOARD can automatically hide team members who have no capacity assigned in the current Plan range. This keeps the board focused on people who are actually available for the plans you are scheduling, and moves any items assigned to hidden users to the **Not Assigned/Other** swimlane.
**Version requirement**
This feature requires Planningboard **25.12.0** or later. An earlier property (`nextedy.planningboard.activeTeamAssignmentsOnly=true`) introduced in 25.3.0 is deprecated as of 25.12.0 — migrate to the new property described below.
***
## Prerequisites
Before enabling this filter, confirm that your board meets both of the following requirements:
* The Polarion project has **Teams and Team Assignments** configured (users are assigned to teams with specific date ranges).
* The Planningboard widget uses **Users (Assignee)** as the swimlane assignment type, with swimlane users derived from Team Assignments.
If your swimlanes are populated from a user role (not from Team Assignments), this filter has no effect.
***
## Steps
### 1. Open Polarion Administration Configuration Properties
In Polarion, navigate to **Administration > Configuration Properties** for the project (or at the global level if you want this behavior across all boards in the instance).
### 2. Add the property
Add the following line to Configuration Properties:
```properties theme={null}
nextedy.planningboard.activeTeamAssignmentsInPlanRangeOnly=true
```
Save the configuration.
**Property not taking effect?**
If the board does not reflect the change after saving, make a trivial edit to any other property in Configuration Properties and save again. This forces Planningboard to reload the configuration.
### 3. Reload the board
Refresh the Planningboard page. Users with no Team Assignment overlapping the date range of the currently displayed Plans will no longer appear as separate swimlane rows. Any work items previously assigned to those users are now grouped under the **Not Assigned/Other** swimlane row.
***
## How it works
The filter compares each user's Team Assignment date range against the date range spanned by the Plans currently shown on the board. Only users with at least one Team Assignment that overlaps this window remain as visible swimlane rows.
***
## Also filter the Plans shown (recommended)
Filtering swimlane rows by Team Assignment range is most effective when you also restrict the **Plans** (columns) shown on the board to the same team. Without this second step, the board may display iterations belonging to other teams alongside the filtered swimlanes, which can be confusing.
To filter iterations by team using a page parameter, pass a `team` page parameter in your Planningboard widget and configure a Plans query that references it. See [Dynamic Filtering with Page Parameters](/planningboard/guides/advanced/dynamic-filtering) for the full setup, and [Configure Plans (Columns)](/planningboard/guides/configuration/plans-configuration) for Plans query syntax.
**Incomplete setup**
A common support issue arises when only the swimlane filter is enabled but the Plans query is left unfiltered. The swimlane rows show only members of the selected team, but the columns still include iterations from other teams. Always coordinate both configurations for a clean team-scoped board.
***
## What happens to items assigned to hidden users
When a user is hidden because they have no Team Assignment in the current Plan range:
* Their swimlane row is **removed** from the board.
* Any work items assigned to them appear in the **Not Assigned/Other** row at the bottom of the board.
* This signals that those items are unlikely to be completed by that person within the shown Plans, and should be reassigned or rescheduled.
**Multi-assignee limitation**
Items with multiple assignees currently display under only **one** swimlane row, not all assigned users. If one of those assignees is hidden by this filter, the item's placement may not reflect the remaining active assignee. This is a known product limitation — an enhancement to display items under all assignees' swimlanes is tracked but not yet shipped.
***
## Reverting to the deprecated property
If you are on an older version of Planningboard (25.3.0–25.11.x) and cannot upgrade, the earlier property hides only users with Team Assignments entirely in the past, regardless of the shown Plan range:
```properties theme={null}
nextedy.planningboard.activeTeamAssignmentsOnly=true
```
This property is **deprecated as of 25.12.0**. Migrate to `nextedy.planningboard.activeTeamAssignmentsInPlanRangeOnly=true` when you upgrade.
***
## Verification
After saving and refreshing:
* The board should show **only** the swimlane rows for users whose Team Assignment date range overlaps the Plans currently displayed.
* Users outside that range should be absent from the row list.
* Any items that were assigned to now-hidden users should appear in the **Not Assigned/Other** swimlane at the bottom.
If a user you expect to see is missing, verify their Team Assignment dates in Polarion and confirm they overlap at least one of the displayed Plans.
***
## See also
* [User and Assignee Swimlanes](/planningboard/guides/swimlanes/user-swimlanes) — configure the swimlane assignment type that this filter applies to
* [Filter Swimlanes by Plan Range](/planningboard/guides/swimlanes/filtering-by-plan-range) — related Plan-range filtering approach
* [Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration) — full swimlane widget parameter reference
* [Dynamic Filtering with Page Parameters](/planningboard/guides/advanced/dynamic-filtering) — filter both swimlanes and Plans by team using page parameters
* [Set Up Teams Service](/planningboard/guides/capacity/teams-service-setup) — prerequisite: configuring Teams and Team Assignments in Polarion
**KB Articles**
* Filter user swimlanes by Plan range
* Swimlane Assignment Types
* Sorting of Swimlanes (Parent Item Assignment Type)
**Support Tickets**
* [#5760](https://support.nextedy.com/helpdesk/tickets/5760)
* [#6681](https://support.nextedy.com/helpdesk/tickets/6681)
* [#5922](https://support.nextedy.com/helpdesk/tickets/5922)
**Source Code**
* `filterMultiSwimlaneRows.cy.ts`
* `PlanningBoardWidgetRenderer.java`
* `licenseReadonly.cy.ts`
* `AssignmentMode.java`
* `PlanningBoardWidget.java`
# Swimlanes
Source: https://learn.nextedy.com/planningboard/guides/swimlanes/index
Swimlanes are the horizontal rows of a Nextedy PLANNINGBOARD. Each swimlane groups a set of work item cards and displays a capacity bar showing the planned load against the swimlane's available capacity.
**Swimlane assignment type**
The swimlane assignment type is the central configuration choice. It determines which field or relationship the board reads to place each card into a row. All other swimlane options — sorting, filtering, multi-value handling — build on top of this choice.
## Assignment Types
**[User and Assignee Swimlanes](/planningboard/guides/swimlanes/user-swimlanes)** — Group cards by the work item's assignee field. One swimlane appears per user who has assigned work in the selected Plans, making this the most common type for sprint planning and capacity tracking per team member.
**[Parent Item Swimlanes](/planningboard/guides/swimlanes/parent-item-swimlanes)** — Group cards by their parent work item (e.g. by Feature or Epic). Cards for child items cluster under the parent they belong to, giving a hierarchical view of planned work.
**[Enumeration Field Swimlanes](/planningboard/guides/swimlanes/enum-swimlanes)** — Group cards by any custom enumeration field on the work item (e.g. component, team, priority tier). One swimlane is created for each enum value present in the data.
**[Multi-Valued Field Swimlanes](/planningboard/guides/swimlanes/multi-valued-swimlanes)** — A variant of enumeration swimlanes for fields that can hold more than one value. A card appears in every swimlane that matches one of its field values.
**[Project Swimlanes](/planningboard/guides/swimlanes/project-swimlanes)** — Group cards by the Polarion project they belong to. Useful for cross-project boards where work from multiple projects shares the same set of Plans.
**[SAFe Swimlanes](/planningboard/guides/swimlanes/safe-swimlanes)** — A specialized assignment type for Scaled Agile Framework (SAFe) boards, grouping cards by Agile Release Train (ART) or team-level constructs according to SAFe naming conventions.
**[No Swimlanes Mode](/planningboard/guides/swimlanes/no-swimlanes-mode)** — Disables row grouping entirely. All cards appear in a single flat list per Plan column, which can be useful for simple boards or when swimlane grouping is not needed.
## Swimlane Behaviour
**[Sort Swimlanes](/planningboard/guides/swimlanes/sorting-swimlanes)** — Control the order in which swimlanes appear on the board. Sorting is coupled to the item sort order — the guide explains the relationship and the available options.
**[Filter Swimlanes by Plan Range](/planningboard/guides/swimlanes/filtering-by-plan-range)** — Restrict which swimlanes are shown based on the date range of the Plans displayed. Useful for hiding swimlanes that have no work in the visible time window.
**[Filter Swimlanes by Team](/planningboard/guides/swimlanes/filtering-by-team)** — Narrow the swimlane list to a specific team, drawing on the Teams Service configuration. Combine with user swimlanes for per-team capacity views.
**Capacity and swimlanes**
Capacity bars are displayed per swimlane when capacity tracking is enabled. See the [Capacity Management](/planningboard/guides/capacity/index) guides for how to configure swimlane capacity, normalization, and multi-dimensional capacity tracking.
**KB Articles**
* Swimlane Assignment Types
* Filter user swimlanes by Plan range
* Sorting of Swimlanes (Parent Item Assignment Type)
**Support Tickets**
* [#5922](https://support.nextedy.com/helpdesk/tickets/5922)
* [#6681](https://support.nextedy.com/helpdesk/tickets/6681)
* [#5760](https://support.nextedy.com/helpdesk/tickets/5760)
**Source Code**
* `PlanningBoardWidgetRenderer.java`
* `licenseReadonly.cy.ts`
* `filterMultiSwimlaneRows.cy.ts`
* `Config.java`
* `PlanningBoardWidget.java`
# Multi-Valued Field Swimlanes
Source: https://learn.nextedy.com/planningboard/guides/swimlanes/multi-valued-swimlanes
Configure Planningboard to display a single work item across multiple swimlane rows when it holds more than one value in a user or enumeration field — giving each assigned user or enum value its own row.
## Overview
When a work item has multiple values in its grouping field (for example, two assignees or two team tags), Nextedy PLANNINGBOARD can show that card in every relevant swimlane row simultaneously. This lets you plan across assignees or categories without losing visibility of shared items.
Multi-valued swimlane grouping works for two assignment modes:
| Assignment Mode | Supported Field Types |
| ----------------- | -------------------------------------------------------------------------- |
| Users (Assignee) | Multi-user custom fields |
| Enumeration Field | Multi-value enumeration custom fields (`IListType` with `IEnumType` items) |
**Current limitation — items with multiple assignees**
When using **Users (Assignee)** swimlanes, work items with multiple assignees currently display under only one swimlane row in some configurations — not duplicated across all assigned users as expected. This is a known product gap. If you need guaranteed multi-user display, use a dedicated multi-value user custom field as the grouping field rather than the built-in assignee field, and verify behavior in your version.
## Before You Start
* You have a Planningboard widget configured on a Polarion Wiki page or LiveDoc.
* Your work items have a custom field of type **multi-value enumeration** (e.g., a `team` field that can hold multiple values) or a **multi-user** field.
* The field is registered in Polarion and available for the work item type shown on the board.
1. Navigate to the Polarion page that contains your Planningboard widget.
2. Expand the **Tools** panel and click the **Edit** button to open the widget configuration.
3. Go to the **Swimlanes (Rows)** section.
For multi-valued **enumeration** fields:
1. Set **Assignment Type** to **Enumeration Field**.
2. In **Field ID**, enter the exact identifier of your multi-value enum field (for example, `team`).
For multi-valued **user** fields:
1. Set **Assignment Type** to **Users (Assignee)**.
2. Confirm that the field you intend to group by supports multiple user values in your Polarion project configuration.
**Field type validation**
Planningboard validates the field type at load time. If the field is not recognized as an enumeration type (`IEnumType` or `IListType` with `IEnumType` items), the board will report a field validation error. Common causes: using the `status`, `resolution`, or `type` built-in fields (these are **not supported** for swimlane grouping), or referencing a text field instead of an enum field. Double-check the field ID and its type in **Polarion Administration → Work Items → Custom Fields**.
If your enumeration has many values and you only want certain ones to appear as swimlane rows:
1. Click the **Rows Filter** field.
2. Select the enum values you want to display. Leaving the filter empty shows all values.
The **Multi-Value Selector Dialog** lists all enum options available for the selected work item type. Options vary by work item type — if you change the **Work Item Type** filter on the board, the available enum values in the dialog update accordingly.
1. Save the widget configuration.
2. If the board does not update immediately, click **Refresh** (the refresh button in the board toolbar) to reload data from the server.
## How Multi-Valued Rows Appear
Work item WI-101 carries two team values (`Team Alpha` and `Team Beta`), so it appears in both rows. WI-105 has no team value and appears in the special **Not Assigned/Other** row.
Each swimlane row receives a unique internal row ID even when the same work item appears in multiple rows — this prevents rendering conflicts.
## Removing a Value by Drag and Drop
You can remove a specific field value from a work item by dragging its card from that value's swimlane row into the **Not Assigned/Other** row:
* Dragging WI-101 from **Team Beta** to **Not Assigned/Other** removes `Team Beta` from its team field — but keeps `Team Alpha`.
* The card then disappears from the **Team Beta** row and remains in **Team Alpha**.
* The change persists after a board refresh.
**Removing one value, not all**
Dropping a card into the Not Assigned/Other row only removes the value that corresponds to the *source* row you dragged from — it does not clear the entire field. This lets you adjust multi-valued assignments precisely without losing the other values.
## Troubleshooting
**Board shows "field is not enumeration" error**
The field referenced in **Field ID** is not typed as an enumeration in Polarion. Verify the field type under **Administration → Work Items → Custom Fields**. Only `IEnumType` fields and `IListType` fields whose items are `IEnumType` are supported.
**Items appear in only one row despite multiple field values**
Check your Planningboard version. Multi-enum swimlane display requires the feature to be active in your installed version. If you are on an older release, contact Nextedy support to confirm availability.
**After changing Work Item Type, the Rows Filter shows different options**
This is expected behavior. Enum values are configured per work item type in Polarion, so the available filter options reflect the selected type's configuration.
**Config changes do not take effect**
If a configuration property change does not appear to apply, make a minor edit and save the Configuration Properties again to force a reload. This is a known quirk with some Polarion configuration caches.
**Verify in application**
Multi-enum swimlane support was committed as a planned feature for matrix-organization resource capacity forecasting. Confirm that your installed version includes this capability before building workflows that depend on it.
## Limitations
* The built-in `status`, `resolution`, and `type` fields are **not supported** as swimlane grouping fields.
* Swimlane sort order is tied to item sort order — independent sorting of swimlanes versus items within them is **not currently supported**. See [Sort Swimlanes](/planningboard/guides/swimlanes/sorting-swimlanes) for available options.
* Capacity bar calculations when a work item appears in multiple swimlanes simultaneously may not distribute effort across rows. Verify capacity totals in your setup.
* Read-only access (unlicensed users) preserves full board visibility including multi-valued rows, but drag-and-drop operations to reassign values are blocked.
## You Should Now See
After saving and refreshing, work items with multiple enum or user values appear in each corresponding swimlane row. The **Not Assigned/Other** row shows items with no value set for the grouping field. Dragging a card from a specific row to Not Assigned/Other removes only that row's value from the field.
## See Also
* [Enumeration Field Swimlanes](/planningboard/guides/swimlanes/enum-swimlanes) — single-value enum swimlane setup
* [User and Assignee Swimlanes](/planningboard/guides/swimlanes/user-swimlanes) — user-based swimlane configuration
* [Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration) — full swimlane widget parameters reference
* [Sort Swimlanes](/planningboard/guides/swimlanes/sorting-swimlanes) — controlling swimlane row order
* [Filter Swimlanes by Plan Range](/planningboard/guides/swimlanes/filtering-by-plan-range) — hide swimlanes outside active plan dates
**KB Articles**
* Swimlane Assignment Types
* Filter user swimlanes by Plan range
* Sorting of Swimlanes (Parent Item Assignment Type)
**Support Tickets**
* [#6777](https://support.nextedy.com/helpdesk/tickets/6777)
* [#5922](https://support.nextedy.com/helpdesk/tickets/5922)
* [#6000](https://support.nextedy.com/helpdesk/tickets/6000)
**Source Code**
* `PlanningBoardWidgetRenderer.java`
* `filterMultiSwimlaneRows.cy.ts`
* `licenseReadonly.cy.ts`
* `enum-rows-filter.cy.ts`
* `AssignmentMode.java`
# No Swimlanes Mode
Source: https://learn.nextedy.com/planningboard/guides/swimlanes/no-swimlanes-mode
Enable No Swimlanes mode to display all work item cards in a single unified view, removing row grouping entirely and focusing attention on columns and item order.
## When to use this mode
No Swimlanes mode is the right choice when:
* You want a high-level overview of work across Plans without the visual complexity of row groupings
* Swimlane separation by assignee, parent item, or field value adds noise rather than clarity
* You are running a quick planning pass focused only on which Plan (column) each item belongs to
* Your board has a small or mixed set of items where per-user or per-feature rows would create mostly empty space
No Swimlanes mode pairs well with boards that use detailed card content or color rules to distinguish items — the visual load from swimlane headers is removed, leaving more room for the cards themselves.
## Steps
### 1. Open the widget parameters
On the Polarion page containing your Nextedy PLANNINGBOARD widget, switch to edit mode and open the widget configuration panel.
Navigate to the **Swimlanes (Rows)** section.
### 2. Set the Assignment Type to No Swimlanes
In the **Assignment Type** dropdown, select **No Swimlanes**.
```text theme={null}
Swimlanes (Rows)
Assignment Type: No Swimlanes
```
When this option is selected, all row-related configuration fields (User Role, Field ID, Parent Role, and so on) are hidden — they are not applicable in this mode.
### 3. Save and refresh
Save the widget parameters and reload the board. All work items will now appear in a single row per Plan column, without any swimlane headers or row dividers.
## What changes on the board
All cards that were spread across multiple swimlane rows are now stacked together within each Plan column. The order of cards within a column follows the board's configured item sort order.
## Configuration example
The following widget parameter excerpt shows a board configured with no swimlane grouping:
```properties theme={null}
assignmentMode=none
```
The `assignmentMode` property accepts `NONE` as the value that corresponds to the No Swimlanes option. All other swimlane properties (`userRole`, `enumFieldId`, `parentWorkItemType`, and similar) are ignored when `assignmentMode` is `NONE`.
The `showEmptySwimlanes` property has no effect in No Swimlanes mode — there are no lanes to show or hide.
## Capacity bars in No Swimlanes mode
Capacity bars are calculated per swimlane. When No Swimlanes mode is active there is only one logical row per board, so capacity tracking across individual assignees or teams is not available in this configuration.
If your planning workflow requires per-user or per-team capacity visibility, you need a swimlane assignment type that creates a row per resource — such as Users (Assignee) or an Enumeration Field grouping. See [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration) for details.
Switching an existing board from a swimlane assignment type to No Swimlanes mode removes all row-level capacity bars. Work items remain assigned to their Plans (columns), but their swimlane assignment is no longer rendered. Switching back to a swimlane type restores the rows without data loss — items will reappear in the correct lanes based on their field values.
## Drag and drop in No Swimlanes mode
Drag and drop continues to work in No Swimlanes mode. Dragging a card between columns reassigns it to a different Plan. Because there are no rows, dropping a card anywhere within a column places it in that Plan — there is no swimlane constraint to satisfy.
In No Swimlanes mode, item order within a column is governed by the board's configured sort order. If you need manual prioritization (dragging items up or down within a column), check that your work items dataset configuration supports ordering. See [Prioritize Work Items](/planningboard/guides/planning/prioritization).
## Switching back to a swimlane type
To re-enable swimlane grouping at any time:
1. Open the widget parameters.
2. Go to **Swimlanes (Rows)**.
3. Select a different **Assignment Type** (for example, Users (Assignee), Enumeration Field, or Parent Item).
4. Configure the type-specific fields that appear.
5. Save and refresh.
The board will re-render with the selected grouping applied.
## Verification
After completing the steps above, you should see:
* No swimlane header rows on the board — only Plan column headers remain
* All work items displayed as cards stacked within their respective Plan columns
* No capacity bar indicators in the row area
* Drag and drop active for moving cards between Plan columns
***
## See also
* [Swimlanes overview](/planningboard/guides/swimlanes/index)
* [Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration)
* [User and Assignee Swimlanes](/planningboard/guides/swimlanes/user-swimlanes)
* [Parent Item Swimlanes](/planningboard/guides/swimlanes/parent-item-swimlanes)
* [Enumeration Field Swimlanes](/planningboard/guides/swimlanes/enum-swimlanes)
* [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration)
* [Prioritize Work Items](/planningboard/guides/planning/prioritization)
**KB Articles**
* Swimlane Assignment Types
* Filter user swimlanes by Plan range
* Sorting of Swimlanes (Parent Item Assignment Type)
**Support Tickets**
* [#6681](https://support.nextedy.com/helpdesk/tickets/6681)
* [#5760](https://support.nextedy.com/helpdesk/tickets/5760)
* [#5922](https://support.nextedy.com/helpdesk/tickets/5922)
**Source Code**
* `PlanningBoardWidgetDependenciesProcessor.java`
* `licenseReadonly.cy.ts`
* `PlanningBoardWidget.java`
* `AssignmentMode.java`
* `PlanningBoardWidgetRenderer.java`
# Parent Item Swimlanes
Source: https://learn.nextedy.com/planningboard/guides/swimlanes/parent-item-swimlanes
Configure Planningboard to group work items into swimlanes by their parent work item, giving you a visual breakdown of how child tasks are distributed across features, epics, or any other parent type.
## Before you begin
* You have a Nextedy PLANNINGBOARD widget already embedded in a Polarion Wiki page or LiveDoc.
* The work items you want to display have parent–child link relationships configured in Polarion (for example, tasks that *implement* a feature).
* You know the **link role** that connects child items to their parents (for example, `implements`, `is parent of`, or a custom role).
***
1. Open the page containing your Planningboard widget.
2. Expand the tools panel and click the **edit** (pencil) button to enter widget configuration mode.
3. In the configuration panel, navigate to **Swimlanes (Rows)**.
***
In the **Assignment Type** dropdown, select **Parent Item**.
The **Swimlanes (Rows)** section expands to show the fields specific to this mode:
| Field | Required | Description |
| ------------------ | -------- | -------------------------------------------------------------------------------------------- |
| **Parent Role** | Yes | The link role connecting child items to their parent (e.g. `implements`). |
| **Sort By** | No | Field(s) used to order parent swimlanes. See [Step 4](#step-4--sort-parent-swimlanes) below. |
| **Parent Query** | No | A Lucene query to restrict which parent items appear as swimlanes. |
| **Filter Parents** | No | `Yes` / `No` — whether to limit visible parents to those matching the Parent Query. |
| **Report Link** | No | A URL to a related report, attached to each parent swimlane for quick navigation. |
***
For parent swimlanes to display correctly, Planningboard must load the parent work items alongside the child items.
1. In the widget configuration panel, navigate to **Unplanned Sidebar**.
2. Set **Load Parents** to at least `1`.
3. Set **Parent Roles** to the same link role you chose in Step 2 (for example, `implements`).
***
The **Sort By** field controls the vertical order in which parent swimlanes appear. It is available since version **25.9.0**.
Enter one or more Polarion work item field IDs, separated by spaces:
```text theme={null}
priority
```
```text theme={null}
title
```
```text theme={null}
severity id
```
Use the **tilde operator (`~`)** to sort in descending order:
```text theme={null}
~title
```
```text theme={null}
priority ~id
```
Sorting examples:
| Sort By value | Result |
| -------------- | --------------------------------------------------- |
| `priority` | Swimlanes ordered by priority (ascending) |
| `~priority` | Swimlanes ordered by priority (descending) |
| `title` | Alphabetical order by title |
| `~title` | Reverse alphabetical |
| `priority ~id` | By priority ascending; ties broken by ID descending |
| *(empty)* | Default order returned by Polarion |
***
If you want only a subset of parent items to appear as swimlanes:
1. Enter a Lucene query in **Parent Query** — for example, `type:feature AND status:open`.
2. Set **Filter Parents** to **Yes**.
Leave both fields empty to show all parent items that have at least one matching child on the board.
***
Click **Save** in the widget configuration panel. The board reloads and displays one swimlane per parent work item.
***
## How drag and drop works in this mode
**Items snap to their actual parent**
When Parent Item is the swimlane assignment type, you **cannot freely move a card to any swimlane**. Planningboard enforces the parent–child link: if you drag a task to a swimlane that does not match its parent, the card automatically jumps back to the correct parent's row once dropped.
To move an item to a different parent swimlane, first update the parent link relationship on the work item in Polarion.
Cards can still be dragged **between columns** (Plans) within the same parent swimlane to change their planned sprint or release.
***
## Configuration example
The following widget parameter values configure a board grouped by parent features, sorted by priority descending, and filtered to open features only:
```properties theme={null}
# Swimlanes (Rows)
assignmentMode = PARENT
parentRole = implements
sortBy = ~priority
parentQuery = type:feature AND status:open
filterParents = Yes
```
***
## Limitations
**Swimlane sort order and item sort order are linked**
The swimlane sort order (parent row order) is currently coupled to the item sort order on the board. **Independent sorting of swimlanes versus items within them is not yet supported.** If you need different sort criteria for swimlane rows versus the cards inside them, this is a known gap — refer to the [sorting guide](/planningboard/guides/swimlanes/sorting-swimlanes) for any available workarounds.
**Plan normalization (planCellsMode) is not supported in this mode**
The Parent Item assignment mode does not support plan normalization (`planCellsMode`). If your board uses stemming or plan cells mode, switch to a different assignment type.
***
## Troubleshooting
**Parent swimlanes not appearing**
If parent swimlanes are missing after saving, check that **Load Parents** in the Unplanned Sidebar is set to at least `1` and that **Parent Roles** matches the link role configured in the Swimlanes section. Without this, Planningboard does not load parent data.
**Items appearing under '(No Parent)'**
Work items without a link matching the configured Parent Role are grouped in a catch-all swimlane. Verify that the correct link role is set in both the **Parent Role** field and the Polarion work item's links tab.
**Sort By field not taking effect**
The Sort By parameter for parent swimlanes requires version **25.9.0** or later. If your board shows parents in an unexpected order after entering a sort field, verify your installed version via **Administration > Nextedy PLANNINGBOARD > Version**.
***
## You should now see
A board with one horizontal swimlane per parent work item, ordered according to your Sort By field, with child work item cards distributed across the Plan columns (sprints or releases) within each parent's row.
***
## See also
* [Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration) — full overview of swimlane widget parameters
* [Sort Swimlanes](/planningboard/guides/swimlanes/sorting-swimlanes) — detailed sorting options across all swimlane types
* [User and Assignee Swimlanes](/planningboard/guides/swimlanes/user-swimlanes) — grouping rows by assignee instead of parent
* [Enumeration Field Swimlanes](/planningboard/guides/swimlanes/enum-swimlanes) — grouping rows by a custom enumeration field
* [Filter Swimlanes by Plan Range](/planningboard/guides/swimlanes/filtering-by-plan-range) — limit visible swimlanes to the active plan window
* [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) — full parameter reference
**KB Articles**
* Swimlane Assignment Types
* Sorting of Swimlanes (Parent Item Assignment Type)
* Filter user swimlanes by Plan range
**Support Tickets**
* [#6000](https://support.nextedy.com/helpdesk/tickets/6000)
* [#6681](https://support.nextedy.com/helpdesk/tickets/6681)
* [#5922](https://support.nextedy.com/helpdesk/tickets/5922)
**Source Code**
* `AssignmentMode.java`
* `PlanningBoardDataService.java`
* `licenseReadonly.cy.ts`
* `filterMultiSwimlaneRows.cy.ts`
* `Config.java`
# Project Swimlanes
Source: https://learn.nextedy.com/planningboard/guides/swimlanes/project-swimlanes
Group work items by project on your Nextedy PLANNINGBOARD to plan and track work across multiple Polarion projects in a single board view.
## Overview
The **Project** swimlane assignment type creates one horizontal row per sub-project in the current project group. Each row shows the work items belonging to that project, letting you compare workload, allocate tasks across projects, and drag cards between projects without switching contexts.
Only sub-projects that the current user can read are included. The current project itself is excluded from the swimlane list; only its sub-projects appear as rows.
***
## Prerequisites
* A Polarion project group with at least two readable sub-projects.
* A Planningboard widget already embedded on a LiveDoc or Wiki page.
* Widget edit permissions for your Polarion account.
***
1. Navigate to the LiveDoc or Wiki page containing your Planningboard widget.
2. Expand the widget toolbar and click the **Edit** (pencil) icon to open the widget configuration panel.
***
1. In the configuration panel, select **Swimlanes (Rows)**.
2. Open the **Assignment Type** dropdown.
3. Select **Project**.
***
The Project assignment type exposes one optional field:
| Field | Required | Description |
| --------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Report Link** | No | URL template for a project-specific report. The link appears next to the swimlane header, giving viewers quick access to detailed reporting for that project. |
Fill in **Report Link** if your team uses per-project reports and you want one-click access from the board row header.
***
1. Click **Save** (or **Apply**) in the widget configuration panel.
2. The Planningboard reloads. You should now see one swimlane row per readable sub-project in the group.
3. Verify that the expected projects appear and that cards are distributed correctly across rows.
If a sub-project row is missing, confirm that your Polarion user account has read access to that project. Projects the current user cannot read are silently excluded — there is no empty row placeholder for them.
***
With project swimlanes active, dragging a card from one row to another **reassigns the work item to the target project**. This is a data change — the work item's project field is updated in Polarion.
Dragging a card to a different project swimlane moves that work item into the target project. This operation is immediate and persists to Polarion. Verify that the work item type and required fields exist in the target project before dragging, otherwise the assignment may fail silently or produce validation errors.
***
## Controlling Which Swimlanes Appear
### Show or hide empty swimlanes
By default, swimlanes with no work items may still appear depending on the `showEmptySwimlanes` configuration. To show all sub-projects regardless of whether they have cards in the visible Plans, confirm the `showEmptySwimlanes` property is set to `true` in your widget configuration. Set it to `false` to hide projects that have no items in the currently visible Plan columns.
### Swimlane sort order
Use the `swimlaneSort` property to control the vertical order of project rows. The default value is `alphabetical`.
### Collapsing individual rows
Project swimlanes are collapsible by default (`collapsibleSwimlanes = true`). Click the row header to collapse a project's swimlane and reduce visual noise when focusing on other projects. Click again to expand.
***
## Configuration Example
The following widget parameter snippet enables project-based swimlanes with a report link template:
```properties theme={null}
assignmentMode = PROJECT
```
If you use the optional report link:
```properties theme={null}
assignmentMode = PROJECT
# reportLink = https://polarion.example.com/reports/project-summary?projectId=${project.id}
```
Widget parameter names are whitespace-sensitive. Ensure there are no leading or trailing spaces around property names or their values, or the configuration may not be applied correctly.
***
## Common Pitfalls
**Sub-projects not appearing**
If a project you expect is missing from the swimlanes, check two things:
1. **Read permission** — the current user must have read access to the sub-project. The Project swimlane type silently excludes inaccessible projects.
2. **Project group structure** — the Planningboard must be embedded in a parent project group. If it is embedded in a standalone project (not a group), there are no sub-projects to display and the swimlane list will be empty.
**Current project is not shown**
The project the Planningboard widget is embedded in is intentionally excluded from the swimlane rows. Only its sub-projects appear. This is expected behavior.
**Combining project swimlanes with a Plan query**
You can narrow which Plans (columns) appear on the board independently of the swimlane assignment type. Use the **Plans** section of the widget configuration to set a `plansQuery` — for example, filtering by date range or plan name — while keeping **Project** as the swimlane assignment type. The two settings are orthogonal.
***
## Verification
After saving, you should see:
* One swimlane row per readable sub-project in the project group.
* Work item cards placed in their respective project rows.
* The swimlane header showing the sub-project name (and a report link icon if configured).
* Drag-and-drop between rows moving cards to the target project.
If rows are missing or cards appear in the wrong row, review the read-permission and project-group-structure checks above.
***
## See also
* [Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration) — full reference for all swimlane parameters
* [User and Assignee Swimlanes](/planningboard/guides/swimlanes/user-swimlanes) — group rows by individual team members
* [Enumeration Field Swimlanes](/planningboard/guides/swimlanes/enum-swimlanes) — group rows by a custom enum field
* [Parent Item Swimlanes](/planningboard/guides/swimlanes/parent-item-swimlanes) — group rows by parent work item
* [Filter Swimlanes by Plan Range](/planningboard/guides/swimlanes/filtering-by-plan-range) — hide swimlanes outside the active Plan window
* [Cross-Project Planning](/planningboard/guides/planning/cross-project-planning) — broader cross-project planning workflows
**KB Articles**
* Swimlane Assignment Types
* Filter user swimlanes by Plan range
* Sorting of Swimlanes (Parent Item Assignment Type)
**Support Tickets**
* [#5760](https://support.nextedy.com/helpdesk/tickets/5760)
* [#5922](https://support.nextedy.com/helpdesk/tickets/5922)
* [#6681](https://support.nextedy.com/helpdesk/tickets/6681)
**Source Code**
* `filterMultiSwimlaneRows.cy.ts`
* `PlanningBoardWidgetRenderer.java`
* `licenseReadonly.cy.ts`
* `Config.java`
* `PlanningBoardWidget.java`
# SAFe Swimlanes
Source: https://learn.nextedy.com/planningboard/guides/swimlanes/safe-swimlanes
Configure Planningboard to group work items into swimlanes using SAFe (Scaled Agile Framework) assignment types — Program/Solution Teams, Agile Release Train Teams, or Programs.
**Verify in application**
SAFe swimlane assignment types require a **Polarion SAFe Solution** to be configured in your environment. Contact Nextedy support for setup guidance before attempting to configure these modes.
***
## SAFe assignment types overview
Nextedy PLANNINGBOARD supports three SAFe-specific **swimlane assignment types**, each suited to a different level of the SAFe hierarchy:
| Assignment Type | Widget parameter value | SAFe level | What each swimlane represents |
| -------------------------------- | ---------------------- | ------------------ | ---------------------------------------------- |
| Program / Solution Teams (SAFe) | `SAFE_TEAM` | Program / Solution | One team within the current SAFe program |
| Agile Release Train Teams (SAFe) | `SAFE_TRAIN_TEAM` | ART | One team within a specific Agile Release Train |
| Programs (SAFe) | `SAFE_PROGRAMS` | Portfolio | One SAFe program within a solution train |
All three types read team and program data from Polarion's SAFe Solution — they do not require you to maintain a separate enumeration field.
***
## Configure Program / Solution Teams swimlanes
Use **Program / Solution Teams (SAFe)** when your board shows a single SAFe program and you want one swimlane per team within that program.
**Steps:**
1. Open the Planningboard widget parameters panel.
2. Navigate to **Swimlanes (Rows)**.
3. Set **Assignment Type** to **Program / Solution Teams (SAFe)** (`SAFE_TEAM`).
4. Set the **SAFe Team Field** (`safeTeamField`) to the custom field ID that stores the SAFe team assignment on your work items. The default value is `safeTeam` — change this only if your Polarion project uses a different field ID.
5. Optionally set **Show Empty Swimlanes** (`showEmptySwimlanes`) to `true` if you want all teams to appear even when they have no planned work items.
6. Save and reload the board.
**Widget parameter example:**
```properties theme={null}
assignmentMode=SAFE_TEAM
safeTeamField=safeTeam
showEmptySwimlanes=false
```
**Plans mode for SAFe sprints**
When using SAFe team swimlanes, set **Plans Mode** (`plansMode`) to **SAFe Sprints in Program** (`SAFE_SPRINTS`) so the board columns show iteration plans automatically filtered by the SAFe Iteration Plan template — no manual plan query needed.
***
## Configure Agile Release Train Teams swimlanes
Use **Agile Release Train Teams (SAFe)** when you need to scope the board to teams within a specific ART rather than all teams in the program.
**Steps:**
1. Open the Planningboard widget parameters panel.
2. Navigate to **Swimlanes (Rows)**.
3. Set **Assignment Type** to **Agile Release Train Teams (SAFe)** (`SAFE_TRAIN_TEAM`).
4. Set the **SAFe Team Field** (`safeTeamField`) to the custom field ID that stores the SAFe team assignment on work items (default: `safeTeam`).
5. Enter the **ART ID** in the corresponding widget parameter to filter which Agile Release Train's teams appear as swimlanes. Only teams belonging to that ART will be shown.
6. Save and reload the board.
**Widget parameter example:**
```properties theme={null}
assignmentMode=SAFE_TRAIN_TEAM
safeTeamField=safeTeam
```
**ART ID required**
If you leave the ART ID parameter empty, the board may show teams from all ARTs or produce unexpected results. Always specify the ART ID when using **Agile Release Train Teams (SAFe)** (`SAFE_TRAIN_TEAM`).
***
## Configure Programs swimlanes (portfolio level)
Use **Programs (SAFe)** when planning at the portfolio level, where each swimlane represents a SAFe program within a solution train.
**Steps:**
1. Open the Planningboard widget parameters panel.
2. Navigate to **Swimlanes (Rows)**.
3. Set **Assignment Type** to **Programs (SAFe)** (`SAFE_PROGRAMS`).
4. Set the **SAFe Program Field** (`safeProgramField`) to the custom field ID that stores the SAFe program assignment on work items. The default value is `safeProgram`.
5. Configure the portfolio suffix in the corresponding parameter if your Polarion SAFe Solution uses a non-default solution train configuration.
6. Save and reload the board.
**Widget parameter example:**
```properties theme={null}
assignmentMode=SAFE_PROGRAMS
safeProgramField=safeProgram
```
***
## SAFe-specific planning features
### Automatic plan syncing for User Stories
When a work item's team assignment changes (for example, by dragging its card to a different swimlane), Planningboard can automatically sync the item to the correct Team Program Increment plan. This automation is triggered by `syncSAFEParentsFromChildren` — plan IDs are remapped based on the updated team assignment.
### Plans mode for SAFe Program Increments
For portfolio-level boards using **Programs (SAFe)** (`SAFE_PROGRAMS`), set **Plans Mode** to **SAFe Program Increments in Program** (`SAFE_PIS`) to load Program Increment plans as columns, or **SAFe Program Increments in Solution** (`SAFE_SOLUTION`) for solution-train-level planning.
```properties theme={null}
plansMode=SAFE_PIS
assignmentMode=SAFE_PROGRAMS
safeProgramField=safeProgram
```
***
## Swimlane sort order
Swimlanes are sorted according to the `swimlaneSort` parameter. The default is `alphabetical`. For SAFe assignment types, teams and programs are listed alphabetically by their Polarion display name unless you change this parameter.
```properties theme={null}
swimlaneSort=alphabetical
```
**Swimlane sort order is coupled to item sort order**
Changing the swimlane sort order also affects the item sort order within each lane. This is a known product limitation — independent control of swimlane order and item order is not currently supported.
***
## Collapsible swimlanes
All SAFe swimlane types support collapsing individual lanes. Collapsible swimlanes are enabled by default (`collapsibleSwimlanes=true`). Users can expand or collapse any team or program row to manage board complexity when many lanes are visible.
```properties theme={null}
collapsibleSwimlanes=true
```
***
## Common pitfalls
**SAFe Solution must be configured first**
SAFe assignment types — Program / Solution Teams (SAFe) (`SAFE_TEAM`), Agile Release Train Teams (SAFe) (`SAFE_TRAIN_TEAM`), and Programs (SAFe) (`SAFE_PROGRAMS`) — require Polarion SAFe Solution to be installed and configured in your Polarion instance. If the SAFe Solution is absent, these assignment modes produce empty boards with no swimlanes. Contact Nextedy support to enable SAFe swimlane options.
**Custom field IDs must match exactly**
The `safeTeamField` and `safeProgramField` parameters are whitespace-sensitive and must exactly match the field IDs defined in your Polarion project. Incorrect or mismatched field IDs cause work items to appear in the "Not Assigned/Other" swimlane instead of the correct team lane.
**Items with multiple assignees appear in one swimlane only**
Work items assigned to multiple users currently display under only one swimlane, not duplicated across all assigned users. This limitation applies to user-based assignment modes and SAFe team-based modes. An enhancement to display items under all assigned swimlanes is tracked as a known product improvement.
**Use showEmptySwimlanes during initial setup**
When first configuring SAFe swimlanes, set `showEmptySwimlanes=true` to confirm all expected teams appear. Once you have verified the setup, you can switch back to `false` to keep the board focused on active teams.
***
## Verification
After saving your widget parameters, reload the Planningboard. You should now see:
* One horizontal swimlane row per SAFe team (or program) as defined in your Polarion SAFe Solution
* Work items grouped into the swimlane matching their `safeTeam` (or `safeProgram`) field value
* Items with no SAFe assignment grouped in the "Not Assigned/Other" row at the bottom
* Collapsible rows with team or program labels on the left
If swimlanes are empty or missing, verify that your SAFe field IDs are correct and that Polarion SAFe Solution is active.
***
## See also
* [Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration) — general swimlane configuration and the Assignment Type dropdown
* [User and Assignee Swimlanes](/planningboard/guides/swimlanes/user-swimlanes) — standard user-based swimlane assignment
* [Enumeration Field Swimlanes](/planningboard/guides/swimlanes/enum-swimlanes) — swimlanes by custom enumeration field
* [Project Swimlanes](/planningboard/guides/swimlanes/project-swimlanes) — swimlanes for cross-project planning
* [Filter Swimlanes by Team](/planningboard/guides/swimlanes/filtering-by-team) — scope visible swimlanes to a specific team using page parameters
* [SAFe Planning Workflows](/planningboard/guides/planning/safe-planning) — broader SAFe planning configuration including Plans mode and PI planning
* [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) — full reference for all widget parameters
**KB Articles**
* Swimlane Assignment Types
* Filter user swimlanes by Plan range
* Sorting of Swimlanes (Parent Item Assignment Type)
**Support Tickets**
* [#5922](https://support.nextedy.com/helpdesk/tickets/5922)
* [#6681](https://support.nextedy.com/helpdesk/tickets/6681)
* [#5760](https://support.nextedy.com/helpdesk/tickets/5760)
**Source Code**
* `PlanningBoardWidgetRenderer.java`
* `filterMultiSwimlaneRows.cy.ts`
* `licenseReadonly.cy.ts`
* `Config.java`
* `PlanningBoardWidget.java`
# Sort Swimlanes
Source: https://learn.nextedy.com/planningboard/guides/swimlanes/sorting-swimlanes
Control the vertical order of swimlane rows on your Nextedy PLANNINGBOARD by configuring the **Sort by** parameter for Parent Item swimlanes or the `swimlaneSort` property for other assignment types.
***
## Before you begin
Swimlane sorting is available when using the **Parent Item** assignment type. This feature was introduced in version **25.9.0**. For other assignment types (Users/Assignee, Enumeration Field, Project), the `swimlaneSort` widget parameter controls ordering.
**Swimlane order is tied to item sort order**
When using Parent Item swimlanes, the swimlane sort order is currently coupled to the item sort order within swimlanes. Independent sorting of swimlane rows versus items inside them is not yet supported. Plan your sort fields accordingly.
***
## Sort Parent Item swimlanes
### Step 1 — Set up Parent Item swimlanes
If you have not already configured Parent Item swimlanes, open your Planningboard widget parameters and complete the following before configuring sort order:
1. Go to **Widget Parameters → Unplanned Sidebar**.
2. Set **Load Parents** to at least `1`.
3. Set **Parent Roles** to the link role connecting child items to their parent (for example, `implements`).
### Step 2 — Configure the Sort by parameter
1. Open **Widget Parameters → Swimlanes (Rows)**.
2. Set **Assignment Type** to **Parent Item**.
3. In **Parent Role**, select the link role that defines the parent–child relationship.
4. In **Sort by**, enter one or more work item field IDs.
### Step 3 — Save and verify
Save the widget parameters and refresh the Planningboard. The swimlane rows now appear in the order defined by your **Sort by** expression.
You should now see swimlane rows ordered according to the field you entered — for example, highest-priority parent items at the top when sorting by `priority`.
***
## Sort by syntax
The **Sort by** field accepts one or more work item field IDs, space-separated. Use the **tilde operator (`~`)** before a field name to sort in descending order.
If you leave **Sort by** empty, swimlanes appear in the default order returned by Polarion.
***
## Configuration overview
The table below summarises the key parameters involved in swimlane sorting.
| Parameter | Location | What it controls |
| ------------------------- | ------------------------------------ | -------------------------------------------------------------------- |
| `Sort by` | Widget Parameters → Swimlanes (Rows) | Field(s) used to order Parent Item swimlane rows |
| `Parent Role` | Widget Parameters → Swimlanes (Rows) | Link role connecting child items to parent items |
| `Parent Query` (optional) | Widget Parameters → Swimlanes (Rows) | Lucene query to restrict which parent items appear as swimlanes |
| `Filter Parents` | Widget Parameters → Swimlanes (Rows) | Whether to limit visible parent swimlanes (`Yes` / `No`) |
| `swimlaneSort` | Widget Parameters → Swimlanes (Rows) | Sort order for non-Parent assignment types (default: `alphabetical`) |
**Sorting by custom fields**
You can sort by any valid Polarion work item field ID, including custom fields. For example, if your project defines a custom `team` or `component` field on parent items, enter that field ID in **Sort by** to group swimlanes by that value.
***
## Sorting swimlanes with other assignment types
For assignment types other than **Parent Item** — such as **Users (Assignee)**, **Enumeration Field**, or **Project** — the `swimlaneSort` widget parameter controls the vertical ordering of rows.
The default value is `alphabetical`, which orders swimlane rows by their display label in ascending alphabetical order.
**Verify in application**
Additional `swimlaneSort` values beyond `alphabetical` are not confirmed in the current documentation sources. Check your installed version's widget parameter options for the full list of accepted values.
***
## Common pitfalls
**Field ID must be exact**
The **Sort by** field is case-sensitive and must match the exact Polarion field ID as defined in your project. A typo (for example, `Priority` instead of `priority`) will cause the sort to silently fall back to the default Polarion order. Verify field IDs in **Administration → Work Items → Custom Fields**.
**Sorting requires version 25.9.0 or later**
The **Sort by** parameter for Parent Item swimlanes was introduced in Planningboard 25.9.0. If your board does not show the **Sort by** field in the Widget Parameters panel, upgrade Planningboard before proceeding.
**Use tiebreaker fields for stable ordering**
When multiple parent items share the same value for your primary sort field (for example, equal priority), add a tiebreaker such as `id` to produce a stable, predictable swimlane sequence — for example: `priority id`.
***
## Verification
After saving your widget parameters and refreshing the board:
* Swimlane rows appear in the order specified by your **Sort by** expression.
* Changing the sort expression and saving immediately reorders the rows on the next board load.
* If rows appear in an unexpected order, confirm the field ID is correct and that all parent items have the field populated.
***
## See also
* [Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration) — full reference for all swimlane widget parameters
* [Parent Item Swimlanes](/planningboard/guides/swimlanes/parent-item-swimlanes) — how to set up parent-based swimlane grouping
* [Filter Swimlanes by Plan Range](/planningboard/guides/swimlanes/filtering-by-plan-range) — hide swimlane rows outside the visible Plan timeframe
* [User and Assignee Swimlanes](/planningboard/guides/swimlanes/user-swimlanes) — configure user-based swimlane rows
* [Enumeration Field Swimlanes](/planningboard/guides/swimlanes/enum-swimlanes) — use a custom enumeration field for swimlane grouping
**KB Articles**
* Swimlane Assignment Types
* Sorting of Swimlanes (Parent Item Assignment Type)
* Filter user swimlanes by Plan range
**Support Tickets**
* [#6681](https://support.nextedy.com/helpdesk/tickets/6681)
* [#6000](https://support.nextedy.com/helpdesk/tickets/6000)
* [#5922](https://support.nextedy.com/helpdesk/tickets/5922)
**Source Code**
* `Config.java`
* `licenseReadonly.cy.ts`
* `PlanningBoardWidgetRenderer.java`
* `AssignmentMode.java`
* `filterMultiSwimlaneRows.cy.ts`
# User and Assignee Swimlanes
Source: https://learn.nextedy.com/planningboard/guides/swimlanes/user-swimlanes
Configure your Nextedy PLANNINGBOARD to display one swimlane per team member, giving you a clear view of individual workloads and enabling drag-and-drop planning across assignees.
## What you will achieve
After following this guide, each row on your board represents one user who holds a specified role in the project. Cards appear in the swimlane of the work item's assignee, and you can drag cards between rows to reassign work.
## Prerequisites
* A Planningboard widget already embedded on a Polarion LiveDoc or Wiki page
* Users added to the project with a defined role (for example, `project_user`)
* Basic familiarity with the Widget Parameters panel
***
1. Navigate to the page containing your Planningboard widget.
2. Expand the **Tools** area and click the **Edit** button for the widget.
3. The Widget Parameters panel opens on the right side of the page.
***
1. In the Widget Parameters panel, locate the **Swimlanes (Rows)** section.
2. Open the **Assignment Type** dropdown.
3. Select **Users (Assignee)**.
Once selected, two new fields appear: **User Role** and **Report Link**.
***
The **User Role** field controls which project role determines who appears as a swimlane. Only users who hold this role in the current project are shown as rows on the board.
Set **User Role** to the role ID you want to use. For most projects the value is `project_user`. Check your Polarion project's role configuration under **Administration > User Management > Roles** to confirm the correct role ID.
**Use a narrower role to reduce noise**
If your project has many users, create or choose a role that is assigned only to active team members. A more targeted role keeps the board focused and avoids empty swimlanes for inactive users.
***
The **Report Link** field lets you attach a Polarion report URL to each swimlane. When set, a link icon appears next to each user's swimlane header, opening the report filtered for that user's work.
Leave this field empty if you do not need per-user report navigation.
***
Click **Save** in the Widget Parameters panel. The board reloads and now displays one swimlane per user who holds the configured role.
Work items whose assignee does not match any swimlane row (unassigned, or assigned to a user without the configured role) appear in a **Not Assigned / Other** swimlane at the bottom.
***
## Filtering swimlanes by Plan range (version 25.12.0+)
When user swimlanes are derived from Team Assignments, you can hide users who have no active Team Assignment within the date range of the currently displayed Plans. This keeps the board focused on team members who actually have capacity in the shown timeframe.
To enable this behavior, add the following property to **Administration > Configuration Properties**:
```properties theme={null}
nextedy.planningboard.activeTeamAssignmentsInPlanRangeOnly=true
```
Once enabled, users whose Team Assignments fall entirely outside the Plans shown on the board are hidden. Any work items previously assigned to those users move to the **Not Assigned / Other** swimlane.
**Property not applying after save?**
If the setting does not take effect immediately, make a minor edit to any Configuration Property and save again. This forces Planningboard to reload its configuration.
**Required setup for Plan-range filtering:**
| Requirement | Detail |
| --------------------------------- | ----------------------------------------------------- |
| Polarion Teams & Team Assignments | Configured for the project |
| Planningboard swimlanes | Set to Users (Assignee) derived from Team Assignments |
| Minimum version | 25.12.0 |
### Deprecated alternative
An earlier approach (`nextedy.planningboard.activeTeamAssignmentsOnly=true`) hid users with past-only assignments regardless of the Plans shown. This property was introduced in version 25.3.0 and **deprecated in version 25.12.0**. Use `activeTeamAssignmentsInPlanRangeOnly` instead.
***
## Filtering the board by team
If you want swimlanes to show only users from a specific team (rather than all users with the configured role), you must configure two things together:
1. **Team page parameter** — filters which users appear as swimlane rows
2. **Plans query** — filters which iterations (Plans) appear as columns, scoped to the same team
Configuring only one of the two leads to a mismatch: swimlanes show the team's users but columns still include all iterations, or vice versa.
See [Filter Swimlanes by Team](/planningboard/guides/swimlanes/filtering-by-team) for a step-by-step walkthrough of the coordinated setup.
***
## Known limitations
**Items with multiple assignees appear in only one swimlane**
When a work item has more than one assignee, Planningboard currently places the card in only one user's swimlane — it does not duplicate the card across all assignees' rows. If your team regularly co-assigns items, be aware that the other assignees' rows will not reflect those items. An enhancement to display items under all assigned users' swimlanes is being tracked.
**Swimlane sort order is coupled to item sort order**
The order in which user swimlanes appear is controlled by the swimlane sort setting (default: alphabetical). There is no independent sort order for swimlanes separate from item ordering — changing the item sort affects the overall board layout.
***
## Verification
After saving your Widget Parameters, you should now see:
* One labeled swimlane row per user who holds the configured role in the project
* Work item cards placed in the row matching their assignee
* A **Not Assigned / Other** row at the bottom for items with no matching assignee
* If Plan-range filtering is enabled: users with no Team Assignment in the displayed Plans' date range are no longer visible
If users you expect are missing, verify their role assignment under **Administration > User Management > Roles** and confirm the **User Role** field in the widget matches the role ID exactly.
***
## See also
* [Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration) — full reference for all swimlane widget parameters
* [Filter Swimlanes by Team](/planningboard/guides/swimlanes/filtering-by-team) — coordinate Team page parameters with a Plans query for team-scoped boards
* [Filter Swimlanes by Plan Range](/planningboard/guides/swimlanes/filtering-by-plan-range) — hide users outside the active plan window
* [Parent Item Swimlanes](/planningboard/guides/swimlanes/parent-item-swimlanes) — group rows by parent work item instead of assignee
* [Enumeration Field Swimlanes](/planningboard/guides/swimlanes/enum-swimlanes) — group rows by a custom field value such as team or component
* [Track User Capacity](/planningboard/guides/capacity/user-capacity) — add capacity bars to user swimlanes
* [Sort Swimlanes](/planningboard/guides/swimlanes/sorting-swimlanes) — control the vertical order of swimlane rows
**KB Articles**
* Swimlane Assignment Types
* Filter user swimlanes by Plan range
* Sorting of Swimlanes (Parent Item Assignment Type)
**Support Tickets**
* [#5922](https://support.nextedy.com/helpdesk/tickets/5922)
* [#6681](https://support.nextedy.com/helpdesk/tickets/6681)
* [#5760](https://support.nextedy.com/helpdesk/tickets/5760)
**Source Code**
* `PlanningBoardWidgetRenderer.java`
* `licenseReadonly.cy.ts`
* `PlanningBoardWidget.java`
* `filterMultiSwimlaneRows.cy.ts`
* `Config.java`
# Capacity Calculation Issues
Source: https://learn.nextedy.com/planningboard/guides/troubleshooting/capacity-issues
Diagnose and resolve common capacity calculation problems in Nextedy PLANNINGBOARD so your capacity bars reflect accurate effort data.
## How capacity is calculated
Before troubleshooting, it helps to know the two capacity modes:
* **`capacityLoad`** — tracks effort at the column (Plan) level using `remainingEstimate`, `initialEstimate`, or a custom `capacityField`. Capacity bars appear per Plan column.
* **`multiCapacityLoad`** — tracks effort per swimlane cell, so each resource row shows its own capacity bar. Uses a `multiCapacity` map keyed by capacity type name.
Resolved work items are handled specially: `effortDone` is set to the full effort value, and `effortTodo` is set to `0`.
***
## Symptom: capacity bar shows zero or is missing
**Likely causes:** `capacityLoad` is not enabled, the effort field is empty on work items, or the field name does not match what Planningboard expects.
**Steps:**
1. Open the widget parameters for your Planningboard page.
2. Confirm that `capacityLoad` is set to `true`.
3. Check that work items in the board have values in `remainingEstimate` or `initialEstimate` (whichever your configuration uses). Items with no estimate contribute zero effort.
4. If you are using a custom effort field, verify the `capacityField` parameter exactly matches the field ID as defined in Polarion — field IDs are case-sensitive and any mismatch silently produces zero.
5. Save the widget parameters and refresh the board using the refresh button.
**Whitespace sensitivity in capacity parameters**
Capacity configuration parameters are whitespace-sensitive. A trailing space in a field ID or parameter value will cause the capacity bar to show zero with no error message. Copy field IDs directly from the Polarion field configuration rather than typing them by hand.
**You should now see** the capacity bars populated with effort totals from the work items in each column or swimlane cell.
***
## Symptom: per-swimlane capacity not showing (multiCapacityLoad)
**Steps:**
1. Confirm `multiCapacityLoad` is enabled in the widget parameters.
2. Verify that each resource (swimlane) has capacity data available. `multiCapacityLoad` uses a `multiCapacity` map keyed by capacity type name — if the capacity type name does not match what the swimlane expects, that swimlane's bar will be empty.
3. Check the assignment mode. `multiCapacityLoad` is most effective with the **Users (Assignee)** (`ASSIGNEE`) or **Enumeration Field** (`ENUM`) assignment modes, where resource IDs are stable and well-defined.
4. If you use the Teams Service (`useTeamsService`), verify the Teams Service is configured and returning team member data — Teams Service data overrides plan capacity values.
**multiCapacityLoad vs capacityLoad**
Use `capacityLoad` when you want a single capacity bar per Plan column. Use `multiCapacityLoad` when different resources have different capacities and you need per-row visibility. Note that `multiCapacityLoad` takes effect only when `capacityLoad` is also set to `true` — both must be enabled together.
***
## Symptom: effort values look wrong or inconsistent
**Steps:**
1. Check whether the affected work items are in a resolved state. Resolved items always contribute their full effort to `effortDone` and zero to `effortTodo` — this is by design, not a bug.
2. If effort values appear rounded unexpectedly, note that Planningboard applies rounding to effort calculations. This is expected behavior.
3. Confirm the `hoursPerDay` conversion is set correctly if you are mixing time-based estimates with day-based capacity. A mismatch (for example, estimates in hours but capacity in days with the wrong conversion factor) produces misleading percentages.
**No multi-assignee effort distribution**
Planningboard does not split effort across multiple assignees. If a work item has multiple assignees, its full effort is counted once — not divided per resource. This is a known limitation compared to Nextedy GANTT. Plan your capacity expectations accordingly.
***
## Symptom: capacity shows correctly for some swimlanes but not others
**Likely cause:** The **Parent Item** assignment mode (`PARENT`) does not support plan normalization (`planCellsMode`). If you are using parent-item swimlanes, capacity normalization is unavailable for those swimlane rows.
**Steps:**
1. Check the assignment mode. If it is set to **Parent Item** (`PARENT`), capacity normalization is not supported — this is a product limitation, not a misconfiguration.
2. For **Users (Assignee)** (`ASSIGNEE`) or **Enumeration Field** (`ENUM`) assignment modes, verify that all swimlane rows have a matching resource entry in the capacity configuration.
3. If some swimlanes are new (recently added enum values or new users), the capacity map may not yet include them. Update the widget parameters to add capacity values for the new swimlane identifiers.
***
## Symptom: capacity changes when switching plans mode
The plans mode affects which Plans are loaded and how effort is aggregated:
| Plans mode | Capacity scope |
| ------------------ | -------------------------------------------------------------- |
| `PROJECT_PLANS` | Capacity per project plan column |
| `SAFE_SPRINTS` | Capacity per iteration plan (sprint) |
| `SAFE_PFL_SPRINTS` | Capacity per portfolio-level sprint (across multiple programs) |
| `SAFE_PIS` | Capacity per program increment |
| `SAFE_SOLUTION` | Capacity per solution train increment |
If capacity looks wrong after changing the plans mode, re-verify that the capacity configuration is appropriate for the new mode. SAFe modes use plan templates to discover plans automatically — if the template filter excludes a plan, its work items and effort are not counted.
***
## Symptom: board becomes unresponsive or hangs when loading capacity data
**Network and firewall issues can cause infinite loading**
If the board hangs indefinitely when capacity data is loading, the cause may be a network or firewall issue rather than a capacity misconfiguration. Corporate firewalls and proxies can block the requests that Planningboard makes to load plan and resource data. Open the browser console (F12) and check the Network tab for failed or stalled requests. See [Network and Firewall Requirements](/planningboard/guides/troubleshooting/network-requirements) for details on what to check.
***
## Known limitation: multi-enum swimlanes and capacity
When work items appear in multiple swimlanes (for example, when using multi-valued enumeration fields for swimlane assignment), capacity calculation behavior across those swimlanes is not yet fully defined. Multi-enum swimlanes were planned for release by end of February 2026 — check the current product version for availability.
**Verify in application**
Once multi-enum swimlane support ships, verify how effort is counted when a single work item appears in more than one swimlane row. Until confirmed, treat per-swimlane effort totals as approximate in multi-enum configurations.
***
## Known issue: cross-project plan loading and page unresponsiveness
If the board becomes unresponsive when selecting a project for a plan template in a cross-project planning scenario, this is caused by a known Polarion issue with cross-project plan loading.
**Workaround:** Add the following property at the **global** Polarion administration level (not at the project level):
```properties theme={null}
nextedy.planningboard.workaround_siemens_issue_global_plans=false
```
After adding the property, restart Polarion and reload the board.
**Where to add the global property**
This property must be set in global Polarion administration, not in a project's `context.properties`. Setting it at the project level has no effect on the cross-project plan loading behavior.
***
## Verification
After applying any of the fixes above:
1. Refresh the board using the refresh button.
2. Confirm that capacity bars appear in the expected swimlane cells or Plan columns.
3. Spot-check a work item with a known estimate — verify its contribution to the capacity bar matches the expected value.
4. If using the Teams Service, confirm that user capacity values come from the Teams Service data and not from the plan's default capacity value (Teams Service values take precedence).
**You should now see** accurate capacity bars reflecting the effort of work items in each Plan column or swimlane cell, with resolved items counted as fully done.
***
## See also
* [Configure Capacity Tracking](/planningboard/guides/configuration/capacity-configuration)
* [Track Team Capacity](/planningboard/guides/capacity/team-capacity)
* [Track User Capacity](/planningboard/guides/capacity/user-capacity)
* [Normalize Capacity Across Swimlanes](/planningboard/guides/capacity/capacity-normalization)
* [Set Up Teams Service](/planningboard/guides/capacity/teams-service-setup)
* [Configure Multi-Dimensional Capacity](/planningboard/guides/capacity/multi-capacity)
* [Network and Firewall Requirements](/planningboard/guides/troubleshooting/network-requirements)
* [Common Errors](/planningboard/guides/troubleshooting/common-errors)
**Support Tickets**
* [#6659](https://support.nextedy.com/helpdesk/tickets/6659)
* [#6777](https://support.nextedy.com/helpdesk/tickets/6777)
* [#6661](https://support.nextedy.com/helpdesk/tickets/6661)
**Source Code**
* `PlanningBoardDataService.java`
* `PlanningBoardWidget.java`
* `planningboard.js`
* `PlanningBoardWidgetDependenciesProcessor.java`
* `PlanningBoardWidgetRenderer.java`
# Common Errors
Source: https://learn.nextedy.com/planningboard/guides/troubleshooting/common-errors
Resolve the most frequent Nextedy PLANNINGBOARD errors — from infinite loading and swimlane mismatches to license restrictions and field validation failures.
***
## Board loads indefinitely (infinite spinner)
If the board never finishes loading and the spinner keeps running, the most likely cause is a network or firewall issue blocking Planningboard's requests, not a product defect.
**Steps to diagnose:**
1. Open your browser's developer tools (**F12**) and switch to the **Network** tab.
2. Reload the page containing the Planningboard widget.
3. Look for requests with status **ERR\_BLOCKED**, **ERR\_CONNECTION\_REFUSED**, **net::ERR\_FAILED**, or that hang without a response.
4. If blocked requests appear, escalate to your IT/network team — a corporate firewall or proxy is likely filtering the Polarion server's internal API calls.
5. If no blocked requests appear, check the **Console** tab for JavaScript errors (see [Script Errors](/planningboard/guides/troubleshooting/script-errors)).
**Corporate firewalls block Polarion API calls**
In evaluated or restricted environments, internal firewall rules can silently block the Polarion API endpoints that Planningboard uses to load plans and work items. The board renders its shell but waits indefinitely for data. This has been confirmed as the root cause in multiple support cases — the fix is on the network side, not the product configuration.
**Use Edge if Chrome is restricted**
Some proxy configurations intercept browser requests differently per browser. If Chrome shows blocked requests but Microsoft Edge does not, switching to Edge may be a working interim workaround while network access is resolved.
***
## Clicking a swimlane expands the wrong one
When you click to expand a swimlane, a different swimlane (often the last one in the list) expands instead.
**This is a known intermittent UI issue affecting Google Chrome.** Microsoft Edge handles this correctly.
**Workaround:**
1. Switch to **Microsoft Edge** for Planningboard sessions that require frequent swimlane interaction.
2. If you must use Chrome, try refreshing the board using the **Refresh** button before expanding swimlanes — this resets the board's internal state.
3. If the issue persists in Chrome, scroll the swimlane list so the target swimlane is fully visible before clicking.
**Chrome swimlane expansion bug**
Clicking a swimlane in Chrome intermittently expands a different swimlane (typically the last one). No fix has been shipped at time of writing. Use Microsoft Edge as the confirmed working browser for swimlane-heavy workflows.
See [Swimlane Expansion Issues](/planningboard/guides/troubleshooting/swimlane-expansion) for additional context.
***
## "Field is not enumeration" error on swimlane configuration
This error appears when configuring enumeration-based swimlanes and the selected field is not recognized as a valid enum type.
**Supported field types for ENUM assignment mode:**
* Fields of type `IEnumType`
* List fields (`IListType`) where list items are of type `IEnumType`
**Fields that are NOT supported as swimlane grouping fields:**
* `status`
* `resolution`
* `type` (work item type)
**Steps to resolve:**
1. In the widget configuration, locate the **Resource Field** selector (visible when **Assignment Mode** is set to `ENUM`).
2. Verify the selected field is a custom enumeration field — not `status`, `resolution`, or `type`.
3. If using a project-specific enum field, confirm it is registered at the **global** field level in Polarion administration. Project-local fields may not resolve correctly.
4. After correcting the field selection, save the widget configuration and **rebuild the board configuration** by reloading the page.
5. If the error persists after a field change, clear the Polarion server cache (**Administration > Maintenance > Clear Caches**) and reload.
**Status, resolution, and type fields are not supported**
These built-in Polarion fields use a different internal type and cannot be used as swimlane grouping fields in ENUM assignment mode. Attempting to use them produces a field validation error. Use a custom enumeration field instead.
**Global vs. project-specific enum fields**
Enum fields defined only at the project level may fail to resolve in cross-project or multi-project board configurations. Register enum fields at the global administration level when you need them to work reliably across projects.
***
## Multi-enum swimlane support
Grouping swimlanes by a **multi-valued enumeration field** (where a work item can belong to more than one enum value simultaneously) is **not yet fully supported**.
The feature gap was acknowledged by the product team and is planned for release. Until it ships, work items that have multiple values in the swimlane grouping field may not appear in all expected swimlanes, or the configuration may produce a validation error.
**Current workaround:**
* Use a single-value enumeration field for swimlane grouping.
* For resource capacity management across multiple teams or components, consider [User and Assignee Swimlanes](/planningboard/guides/swimlanes/user-swimlanes) as an interim approach.
See [Enumeration Field Swimlanes](/planningboard/guides/swimlanes/enum-swimlanes) for supported configuration steps.
***
## Plan creation and unplanned sidebar not visible
If the **Create New Plan** button or the **Show Unplanned** button is missing from the board toolbar, the most likely cause is that your Polarion user account does not have a Planningboard license assigned.
**Planningboard enforces license-based access control:**
| Feature | Licensed users | Unlicensed users |
| ---------------------- | -------------- | ---------------------- |
| View board content | Yes | Yes |
| Drag and drop cards | Yes | No (changes not saved) |
| Create New Plan button | Visible | Hidden |
| Show Unplanned button | Visible | Hidden |
| Sidebar panel | Visible | Hidden |
**Steps to resolve:**
1. Ask your Polarion administrator to check whether your account has a Planningboard license assigned (**Administration > Nextedy PLANNINGBOARD > Licenses**).
2. If you are an administrator, see [License Count and Warnings](/planningboard/guides/troubleshooting/license-issues) for license assignment steps.
3. If you have a license but these controls are still hidden, reload the page using the browser refresh (not the board Refresh button) to pick up the updated license state from the server.
**Unlicensed users retain full read access**
Unlicensed users can still view all board content — plan columns, swimlanes, cards, and capacity bars. Dragging a card appears to work but changes are not saved to the server. This is intentional: it allows stakeholders and reviewers to observe planning without needing a license.
See [License Count and Warnings](/planningboard/guides/troubleshooting/license-issues) for more detail.
***
## Drag and drop does not save changes
Cards appear to move when dragged but snap back to their original position after the drop, or the change is not visible after a page reload.
**Common causes and fixes:**
1. **Unlicensed user** — Drag and drop is blocked for users without a Planningboard license. The card animates but the assignment is not persisted. See the section above.
2. **Read-only mode active** — If the board is configured in read-only mode, all editing operations including drag and drop are disabled. Check the widget configuration for a read-only parameter.
3. **Insufficient Polarion permissions** — The user needs write permission on the work items being moved. Check Polarion role assignments for the affected project.
4. **Plan date range mismatch** — Work items are assigned to plans based on `start_date` and `end_date`. If the target plan's date range does not encompass the work item's dates, the assignment may be rejected silently.
See [Drag and Drop Issues](/planningboard/guides/troubleshooting/drag-and-drop-issues) for a complete diagnostic flow.
***
## Capacity bar shows no data or incorrect values
The capacity bar appears empty or shows values that do not match expected effort.
**Steps to diagnose:**
1. Confirm that **Capacity Load** is enabled in the widget configuration (`capacityLoad` parameter).
2. Verify that the work items on the board have `remainingEstimate` or `initialEstimate` values set. If neither field has data, the capacity bar will be empty.
3. If using a custom capacity field (`capacityField`), confirm the field ID is spelled exactly as it appears in the Polarion field configuration — the parameter is case-sensitive.
**Capacity configuration parameters are whitespace-sensitive**
Extra spaces around parameter values in the widget configuration can cause the parameter to be ignored silently. Verify there is no leading or trailing whitespace in `capacityField`, `hoursPerDay`, or related capacity parameters.
See [Capacity Calculation Issues](/planningboard/guides/troubleshooting/capacity-issues) for a full walkthrough.
***
## Diagnostic flow
***
## Verification
After applying a fix, use the board's **Refresh** button to reload the current state from the server without a full page reload. You should now see the board load completely, swimlanes expand to the correct row, the expected toolbar buttons appear, and card moves persist after a page reload.
***
## See also
* [Swimlane Expansion Issues](/planningboard/guides/troubleshooting/swimlane-expansion)
* [Script Errors](/planningboard/guides/troubleshooting/script-errors)
* [Capacity Calculation Issues](/planningboard/guides/troubleshooting/capacity-issues)
* [License Count and Warnings](/planningboard/guides/troubleshooting/license-issues)
* [Drag and Drop Issues](/planningboard/guides/troubleshooting/drag-and-drop-issues)
* [Network and Firewall Requirements](/planningboard/guides/troubleshooting/network-requirements)
* [Enumeration Field Swimlanes](/planningboard/guides/swimlanes/enum-swimlanes)
* [Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration)
**KB Articles**
* Troubleshooting Script Errors in Planningboard
**Support Tickets**
* [#6659](https://support.nextedy.com/helpdesk/tickets/6659)
* [#6688](https://support.nextedy.com/helpdesk/tickets/6688)
* [#6777](https://support.nextedy.com/helpdesk/tickets/6777)
**Source Code**
* `PlanningBoardWidgetDependenciesProcessor.java`
* `PlanningBoardWidgetRenderer.java`
* `PlanningBoardDataService.java`
* `licenseReadonly.cy.ts`
* `PlanningBoardWidget.java`
# Drag and Drop Issues
Source: https://learn.nextedy.com/planningboard/guides/troubleshooting/drag-and-drop-issues
Resolve the most common reasons why cards fail to move, snap back, or behave unexpectedly when dragging on the Nextedy PLANNINGBOARD.
***
## Prerequisites
* You have a Planningboard widget configured on a Polarion page.
* You are logged in with a licensed Planningboard user account.
* You know which swimlane and Plan column you are trying to move cards between.
***
## Symptom Checklist
Use the table below to jump to the relevant fix.
| Symptom | Jump to |
| ------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| Card moves but snaps back to its original swimlane | [Check your license](#cards-snap-back-unlicensed-user) |
| All drag-and-drop stopped working after a recent upgrade | [Version 25.2.0 fix](#drag-and-drop-broken-after-upgrade-special-characters-in-scripts) |
| Card with **Verified** status cannot be moved or unplanned | [Verified items are locked](#verified-work-items-cannot-be-dragged) |
| Dragging a card to the Not Assigned/Other swimlane removes a value unexpectedly | [Multi-valued field behavior](#multi-valued-field-swimlanes-unassigned-row) |
| Board is unresponsive or loading indefinitely | [Network and firewall check](#board-is-unresponsive-or-loading-indefinitely) |
***
## Cards Snap Back — Unlicensed User
If a card appears to drag normally but returns to its original position when you release it, the most likely cause is that your account does not hold a Planningboard license.
**How Planningboard enforces this:** Unlicensed users can view the full board (all swimlanes, cards, and capacity bars are visible), but editing operations — including drag-and-drop, unplanning items, and creating new Plans — are blocked. Changes are not persisted.
**To verify:**
1. Look at the toolbar. If the **Show Unplanned** button and the **Create New Plan** button are both absent, your account is unlicensed.
2. Ask your Polarion administrator to assign you a Planningboard license.
3. After the license is applied, reload the page and retry the drag.
**Visibility does not imply edit access**
An unlicensed user sees the same board content as a licensed user. The only difference is that no edit operation — including drag-and-drop — is persisted. If drag-and-drop silently fails, always check the license before investigating configuration.
***
## Drag-and-Drop Broken After Upgrade — Special Characters in Scripts
Planningboard versions before 25.2.0 contained a bug where drag-and-drop failed completely when any board script (item script, config script, or data script) included special characters (for example, accented letters, ampersands, or non-ASCII punctuation).
**Fix:** Upgrade to Planningboard version 25.2.0 or later. This bug was resolved in the February 17, 2025 release.
**To check your version:** Go to **Administration > Nextedy PLANNINGBOARD** and read the installed version number. If it is earlier than 25.2.0 and your scripts contain special characters, upgrade first before investigating other drag-and-drop issues.
**Upgrade is the fastest resolution**
If drag-and-drop worked before and stopped after adding a new script or editing an existing one, check whether the change introduced special characters. Upgrading to v25.2.0+ removes the underlying cause entirely.
***
## Verified Work Items Cannot Be Dragged
Work items with a **Verified** status are intentionally locked. Once a card reaches the Verified state it cannot be dragged to a different Plan or swimlane, and the unplan action (the quick-action icon that returns a card to the Unplanned section) is also disabled for it.
This is expected product behavior — it prevents accidental re-planning of completed work.
**If you need to move a Verified item:**
1. Open the work item in Polarion and change its status to a non-Verified state.
2. Return to the Planningboard and refresh the board using the **Refresh data** button in the toolbar.
3. The card is now draggable.
***
## Multi-Valued Field Swimlanes — Unassigned Row
When the board uses a multi-valued field (for example, a multi-user assignee field or a multi-enum field) as the swimlane assignment type, the same work item can appear in multiple swimlane rows — one row per value. Dragging a card from one of these rows to the **Not Assigned/Other** swimlane removes only that specific value from the field, not all values.
**Example:** A work item assigned to both Alice and Bob appears in both the Alice swimlane and the Bob swimlane. Dragging it from the Alice swimlane to Not Assigned/Other removes Alice from the assignees list, leaving Bob. The card then disappears from the Alice row but remains in the Bob row.
**Not Assigned/Other removes, not moves**
Dropping a card onto the Not Assigned/Other row is a field-value removal operation. It does not simply reposition the card — it modifies the work item's field in Polarion. This change persists after board refresh. If you dropped a card on Not Assigned/Other unintentionally, undo it by adding the value back through the work item properties sidebar or directly in Polarion.
**To confirm the change persisted:** Click the **Refresh data** button in the toolbar after the drag. If the card no longer appears in the row you dragged from, the field was updated correctly.
***
## Board Is Unresponsive or Loading Indefinitely
Infinite loading on the board (the spinner never resolves) is most often caused by a firewall or proxy blocking the network requests the board makes to the Polarion server — not a drag-and-drop configuration issue. However, it prevents any interaction, including dragging.
**Diagnostic steps:**
1. Open your browser's developer tools (press **F12**) and go to the **Network** tab.
2. Reload the board page.
3. Look for requests that are blocked, timing out, or returning non-200 responses.
4. If requests to your Polarion server domain are failing, contact your IT/network team to allow them through any corporate firewall or proxy.
For detailed network prerequisites, see [Network and Firewall Requirements](/planningboard/guides/troubleshooting/network-requirements).
***
## General Troubleshooting Flow
```text theme={null}
Card won't stay where I dropped it
|
v
Is the user licensed?
(Check toolbar: Show Unplanned visible?)
|
NO | YES
| |
| v
| Is the card's status "Verified"?
| |
| YES | NO
| | |
| | v
| | Is the board version < 25.2.0
| | AND do any scripts contain
| | special characters?
| | |
| | YES | NO
| | | |
| | | v
| | | Is this a multi-valued
| | | field swimlane and was the
| | | target the UNASSIGNED row?
| | | |
| | | YES | NO
| | | | |
v v v v v
Assign Change Upgrade This is Check
license status to 25.2.0 expected network
first behavior / console
```
***
## Verification
After applying the relevant fix above, confirm drag-and-drop is working:
1. Open the Planningboard page in Polarion.
2. Drag any unlocked card from the **Unplanned** section (or from one Plan column) to a different Plan column or swimlane row.
3. Release the card. It should remain in the new position.
4. Click the **Refresh data** button in the toolbar.
5. You should now see the card still in its new position after the refresh, confirming that the change was persisted to Polarion.
***
## See Also
* [Drag and Drop Planning](/planningboard/guides/planning/drag-and-drop) — how drag-and-drop assignment works for Plans and swimlanes
* [Basic Board Interactions](/planningboard/getting-started/basic-interactions) — toolbar controls, card quick actions, and the Unplanned section
* [Multi-Valued Field Swimlanes](/planningboard/guides/swimlanes/multi-valued-swimlanes) — how items appear in multiple rows and how dragging to Not Assigned/Other updates field values
* [License Count and Warnings](/planningboard/guides/troubleshooting/license-issues) — diagnosing license assignment problems
* [Network and Firewall Requirements](/planningboard/guides/troubleshooting/network-requirements) — prerequisites for the board to load and function
* [Swimlane Expansion Issues](/planningboard/guides/troubleshooting/swimlane-expansion) — related browser-specific interaction issues
**KB Articles**
* Planningboard interface & basic interactions
* Troubleshooting Script Errors in Planningboard
**Support Tickets**
* [#6357](https://support.nextedy.com/helpdesk/tickets/6357)
* [#6688](https://support.nextedy.com/helpdesk/tickets/6688)
* [#6659](https://support.nextedy.com/helpdesk/tickets/6659)
**Source Code**
* `licenseReadonly.cy.ts`
* `PlanningBoardWidgetDependenciesProcessor.java`
* `PlanningBoardWidget.java`
* `displayingMultiEvents.cy.ts`
* `PlanningBoardDataService.java`
# Troubleshooting
Source: https://learn.nextedy.com/planningboard/guides/troubleshooting/index
This section collects solutions to the most common problems encountered when running Nextedy PLANNINGBOARD in Siemens Polarion ALM.
Use the pages below when the board is not behaving as expected, a widget parameter is producing unexpected output, or an error message appears during planning work.
## Errors and Configuration
**[Script Errors](/planningboard/guides/troubleshooting/script-errors)** — Diagnose and fix runtime errors from item scripts, config scripts, and data scripts embedded in widget parameters.
**[Common Errors](/planningboard/guides/troubleshooting/common-errors)** — Reference for error messages that appear in the board or browser console, with causes and resolution steps.
## Capacity
**[Capacity Calculation Issues](/planningboard/guides/troubleshooting/capacity-issues)** — Resolve discrepancies in capacity bar totals, incorrect effort aggregation, and capacity normalization problems. See also the known limitations around multi-assignee and sub-item effort distribution.
## Planning Interactions
**[Drag and Drop Issues](/planningboard/guides/troubleshooting/drag-and-drop-issues)** — Fix problems where cards cannot be moved between swimlanes or Plans, including permission and configuration causes.
**[Swimlane Expansion Issues](/planningboard/guides/troubleshooting/swimlane-expansion)** — Address swimlanes that fail to expand, collapse unexpectedly, or do not display expected work items.
**[Scroll and Focus Behavior](/planningboard/guides/troubleshooting/scroll-behavior)** — Resolve unexpected scroll jumps, lost focus, or board viewport issues after interacting with cards.
## Installation and Licensing
**[License Count and Warnings](/planningboard/guides/troubleshooting/license-issues)** — Understand license seat consumption, resolve over-limit warnings, and verify license configuration.
**[Version Updates and Checking](/planningboard/guides/troubleshooting/version-updates)** — Determine the installed Planningboard version and apply updates correctly.
**[Network and Firewall Requirements](/planningboard/guides/troubleshooting/network-requirements)** — Ensure the Polarion server and browser client can reach required endpoints; resolve connectivity-related failures.
**Before raising a support request**
Check the browser developer console for JavaScript errors and the Polarion server log for plugin exceptions. Include the Planningboard version (see [Version Updates and Checking](/planningboard/guides/troubleshooting/version-updates)) and the relevant widget parameter values when reporting an issue.
**KB Articles**
* Troubleshooting Script Errors in Planningboard
**Support Tickets**
* [#6659](https://support.nextedy.com/helpdesk/tickets/6659)
* [#6688](https://support.nextedy.com/helpdesk/tickets/6688)
**Source Code**
* `PlanningBoardWidgetDependenciesProcessor.java`
* `PlanningBoardWidgetRenderer.java`
* `PlanningBoardDataService.java`
* `licenseReadonly.cy.ts`
* `PlanningBoardWidget.java`
# License Count and Warnings
Source: https://learn.nextedy.com/planningboard/guides/troubleshooting/license-issues
Diagnose and resolve Nextedy PLANNINGBOARD license status messages, understand which features are restricted for unlicensed users, and confirm your license is correctly applied.
***
## Check the License Status
Navigate to **Administration > Nextedy PLANNINGBOARD** in your Polarion instance to open the license view. The page shows a color-coded status panel and the full license details (the signature field is automatically redacted for security — the license is still validated server-side).
The license view reports one of three states:
| Status | Meaning |
| --------- | --------------------------------------------------------------------------------- |
| Valid | License is installed and verified. All editing features are available. |
| `INFO` | No production license detected — Planningboard is running in evaluation mode. |
| `INVALID` | A license file is present but failed validation (expired, wrong host, corrupted). |
***
## Evaluation Mode
If no production license is installed, Planningboard runs for **30 days in evaluation mode**. The license view displays a notice and provides links to the installation guide and the pricing page.
**Evaluation mode ends after 30 days**
After the evaluation period expires, the board becomes read-only for all users until a valid production license is applied. Install the license before the 30-day window closes to avoid disruption.
***
## What Unlicensed Users Can and Cannot Do
License enforcement is per-user, not per-instance. A user without a Planningboard license assigned to their account can view the board but cannot modify it.
**Visibility is preserved for unlicensed users**
Unlicensed users retain full read access to all board content — cards, swimlanes, capacity bars, and calendar columns are all visible. This supports transparency for stakeholders who do not need editing rights.
***
## Resolve an INVALID License Status
If the status panel shows `INVALID`, work through these checks:
**1. Confirm the license file is in the correct location.**
The license file must be placed inside the Planningboard plugin folder on the Polarion server before startup. Refer to the [License Installation](/planningboard/getting-started/licensing) guide for the exact path.
**2. Restart Polarion after placing the license.**
The license is read at startup. If you dropped the file into the folder while Polarion was running, the status will remain `INVALID` until the server restarts.
**3. Verify the license was issued for this server.**
Licenses are host-bound. If you copied a license from a staging or evaluation environment to production (or vice versa), it will fail validation. Contact Nextedy support to request a license reissue for the correct host.
**4. Check for file corruption.**
Open the license file in a text editor. It should be a plain-text block with recognizable fields (licensee, product, expiry, etc.) and a signature block at the end. If the file is binary, empty, or truncated, it was likely corrupted during transfer — request a fresh copy.
**Do not modify the license file**
Editing any character in the license file — including whitespace or line endings — invalidates the cryptographic signature and causes an `INVALID` status. Always transfer license files as binary (not text) when using FTP or SCP.
***
## Resolve Read-Only Behavior for a Specific User
If a specific user reports that they can view the board but cannot drag cards, create Plans, or see the sidebar, their Planningboard license seat has not been assigned.
**Steps to resolve:**
1. Go to **Administration > Nextedy PLANNINGBOARD** and open the license details panel.
2. Confirm the license includes enough seats for the user in question. The license details block lists the maximum user count.
3. Assign the user a Planningboard license seat through your Polarion user management. The exact menu path depends on your Polarion version — refer to Siemens Polarion ALM documentation for license seat assignment.
4. Have the user reload the board page (use the **Refresh** button or browser reload). License state is checked at board load time.
**Refresh resolves stale license state**
If a user was recently assigned a license but the board still shows read-only behavior, clicking the **Refresh** button (the reload icon on the board toolbar) reloads the current state from the server and re-evaluates license status without a full page reload.
***
## Transition from Evaluation to Production License
When you receive a production license from Nextedy:
1. Stop the Polarion server.
2. Replace the evaluation license file (if any) in the plugin folder with the new production license file.
3. Start the Polarion server.
4. Navigate to **Administration > Nextedy PLANNINGBOARD** and confirm the status panel shows a valid (non-`INFO`) status.
5. Confirm the licensed user count in the displayed license details matches your purchased seats.
***
## Verification
After applying a license or assigning a seat, you should now see:
* The **Administration > Nextedy PLANNINGBOARD** license panel displays a green/valid status block (not `INFO` or `INVALID`).
* Licensed users see the **Create New Plan** button, the **Show Unplanned** button, and the sidebar panel on the board.
* Licensed users can drag cards between swimlanes and see their changes persist after a board refresh.
* The license details block in the administration view shows the correct licensee name, expiry date, and seat count.
***
## See Also
* [License Installation](/planningboard/getting-started/licensing) — step-by-step instructions for placing the license file
* [Common Errors](/planningboard/guides/troubleshooting/common-errors) — other board-level error messages and resolutions
* [Version Updates and Checking](/planningboard/guides/troubleshooting/version-updates) — confirm the installed plugin version matches the license version
* [Network and Firewall Requirements](/planningboard/guides/troubleshooting/network-requirements) — connectivity prerequisites that can cause boards to fail to load
**Support Tickets**
* [#6659](https://support.nextedy.com/helpdesk/tickets/6659)
**Source Code**
* `licenseReadonly.cy.ts`
* `PlanningBoardWidgetRenderer.java`
* `PlanningBoardWidgetDependenciesProcessor.java`
* `PlanningBoardDataService.java`
* `viewLicense.vm`
# Network and Firewall Requirements
Source: https://learn.nextedy.com/planningboard/guides/troubleshooting/network-requirements
Verify that your network allows Nextedy PLANNINGBOARD to reach Polarion and confirm no firewall or proxy is silently blocking board data.
## Who this guide is for
Administrators and evaluators who see an infinite-loading board or a blank widget and need to rule out network-level causes before escalating to product support.
## What causes network-related loading failures
Planningboard renders as a widget inside a Polarion LiveDoc or Wiki page. The browser page loads the Polarion host directly; the widget then makes additional HTTP requests back to the same Polarion server to load Plans, work items, and capacity data. If a corporate firewall or proxy intercepts those requests — even silently — the board spinner never resolves.
All traffic is same-origin — the browser only ever contacts the Polarion server. There is no external CDN or cloud endpoint.
1. Open your browser and navigate to your Polarion instance (e.g. `https://polarion.example.com/polarion/`).
2. Confirm the Polarion login page loads and you can authenticate.
3. Navigate to the LiveDoc or Wiki page that contains the Planningboard widget.
If Polarion itself does not load, the problem is upstream of Planningboard — fix Polarion connectivity first.
When the board is stuck loading, browser developer tools show exactly which request is failing.
1. On the page with the stuck Planningboard widget, press **F12** (Windows/Linux) or **Cmd+Option+I** (macOS) to open DevTools.
2. Click the **Network** tab.
3. Reload the page (**F5** or **Cmd+R**).
4. Watch for requests that are red (failed) or that hang indefinitely (no response status).
Look for requests to `/polarion/rest/` or `/polarion/ws/` paths that return 0, timeout, or 403/407.
**407 Proxy Authentication Required**
A status of **407** means a proxy server is intercepting requests and demanding credentials. The Planningboard widget's HTTP calls do not carry proxy credentials — the browser must be configured to authenticate with the proxy, or the Polarion host must be added to the proxy bypass list.
1. In DevTools, click the **Console** tab.
2. Reload the page and look for red error messages.
Common error patterns and their causes:
| Console message | Likely cause |
| --------------------------------------------- | --------------------------------------------------- |
| `net::ERR_CONNECTION_TIMED_OUT` | Firewall is dropping packets silently |
| `net::ERR_CONNECTION_REFUSED` | Polarion port is blocked or Polarion is not running |
| `net::ERR_CERT_AUTHORITY_INVALID` | TLS certificate not trusted (corporate CA missing) |
| `Failed to fetch` / `TypeError: NetworkError` | CORS or proxy interception blocking the request |
| `401 Unauthorized` | Session expired — re-authenticate to Polarion |
Planningboard makes requests only to the Polarion server. The ports depend on your deployment:
| Protocol | Default port | When used |
| -------- | ------------ | -------------------------------- |
| HTTP | 80 or 8080 | Non-SSL Polarion deployments |
| HTTPS | 443 or 8443 | SSL-enabled Polarion deployments |
No other hosts, ports, or external services are required. If your Polarion is behind a reverse proxy, the proxy must forward the full request path (including `/polarion/rest/` and `/polarion/ws/`) without stripping headers.
**No external cloud endpoints**
Planningboard does not call any external APIs, license servers, or analytics endpoints at runtime. All requests are contained within the Polarion server. An outbound-only firewall rule to the Polarion host is sufficient.
If your organization routes browser traffic through a proxy, add the Polarion server hostname to the proxy bypass (no-proxy) list so that same-origin requests are not intercepted.
Examples by platform:
**Windows (Internet Options > LAN Settings > Exceptions):**
```text theme={null}
polarion.example.com; *.example.com
```
**macOS (System Settings > Network > Proxies > Bypass proxy settings for):**
```text theme={null}
polarion.example.com, *.example.com
```
**Environment variable (CLI / scripts):**
```text theme={null}
NO_PROXY=polarion.example.com,*.example.com
```
After updating bypass settings, close and reopen the browser entirely before retesting.
If your Polarion instance uses a certificate issued by a corporate or internal CA, the browser must trust that CA.
1. Click the padlock icon in the browser address bar on the Polarion page.
2. Verify the certificate chain shows no warnings.
3. If there is a certificate error, ask your IT team to install the corporate root CA into the browser trust store.
**TLS inspection proxies**
Some corporate proxies perform TLS inspection (SSL bump / man-in-the-middle). They replace the server certificate with a proxy-issued certificate. If the proxy's CA is not trusted by the browser, every HTTPS request from Planningboard fails with a certificate error. Ask your network team to exclude the Polarion host from TLS inspection, or ensure the inspection proxy's CA is deployed to all client machines.
If possible, test from a machine that is not behind the corporate firewall or proxy (for example, a home network or a mobile hotspot):
1. Connect to the alternative network.
2. Navigate to the Polarion Planningboard page.
3. If the board loads correctly, the problem is confirmed to be network/firewall-specific.
This test confirms the issue is environmental and not a Planningboard configuration problem.
## Common firewall rules to verify
Have your network or security team confirm the following:
| Rule | Direction | Protocol | Port | Host |
| ----------------------------- | --------- | -------- | ------------- | ----------------- |
| Allow browser to Polarion | Outbound | TCP | 443 (or 8443) | Polarion hostname |
| Allow WebSocket upgrades | Outbound | TCP | 443 | Polarion hostname |
| No TLS inspection on Polarion | — | HTTPS | — | Polarion hostname |
| Proxy bypass | — | — | — | Polarion hostname |
**WebSocket connections**
Polarion uses long-lived connections for some server push notifications. Ensure the firewall and any load balancer in front of Polarion allow WebSocket upgrade (`Connection: Upgrade`, `Upgrade: websocket`) on the Polarion port.
## You should now see
After resolving the network issue and reloading the page, the Planningboard widget should:
* Render the board within a few seconds (depending on the number of Plans and work items).
* Display swimlanes with cards populated from Polarion Plans.
* Show no red errors in the browser console Network tab.
If the board still does not load after confirming all network paths are open, check the [Common Errors](/planningboard/guides/troubleshooting/common-errors) guide or review [Version Updates and Checking](/planningboard/guides/troubleshooting/version-updates) to confirm the plugin is correctly installed.
## See also
* [Common Errors](/planningboard/guides/troubleshooting/common-errors)
* [License Count and Warnings](/planningboard/guides/troubleshooting/license-issues)
* [Version Updates and Checking](/planningboard/guides/troubleshooting/version-updates)
* [Installation](/planningboard/getting-started/installation)
**Support Tickets**
* [#6659](https://support.nextedy.com/helpdesk/tickets/6659)
**Source Code**
* `PlanningBoardDataService.java`
* `PlanningBoardWidgetDependenciesProcessor.java`
* `licenseReadonly.cy.ts`
* `PlanningBoardWidgetRenderer.java`
# Script Errors
Source: https://learn.nextedy.com/planningboard/guides/troubleshooting/script-errors
Diagnose and fix configuration or script errors that prevent your Nextedy PLANNINGBOARD from loading or displaying data correctly.
When Planningboard encounters a configuration or script error, it signals this through an error indicator in the board UI. The way errors are surfaced depends on who is viewing the board: widget editors see detailed error messages, while regular users see a generic warning. This guide walks you through identifying, reading, and resolving the most common error conditions.
## How Planningboard Signals Errors
Planningboard uses an error indicator built into the board toolbar. The indicator reflects the current state of the widget configuration and any scripts it evaluates at render time.
```text theme={null}
+--------------------------------------------------------------+
| Board Toolbar |
| |
| [Planningboard Title] [ ⚠ Configuration Error ]|
+--------------------------------------------------------------+
|
| Editor view
v
Detailed error message with property name, script
excerpt, and line reference
|
| Non-editor (user) view
v
Generic warning only — no internal detail exposed
```
* **Editor view** — if you have edit permissions on the widget, the error indicator shows the full detail: which property failed, what the script evaluated to, and where.
* **User view** — users without edit access see a generic warning indicator. They cannot proceed until an editor resolves the issue.
The board may still render partially even when an error is present. The error indicator shows that at least one configuration or script evaluation failed — it does not necessarily mean the whole board is blank.
1. On the Planningboard page, look for the warning indicator in the toolbar (top-right area of the board).
2. If you have widget-editor access, click the indicator to expand the error detail panel.
3. Read the full error message. Note:
* The **property name** involved (e.g., a widget parameter like `plansQuery`, a swimlane assignment expression, or a script field).
* The **error type** (syntax error, null reference, unresolved variable, etc.).
* The **script excerpt** or value that triggered the error, if shown.
If you do not see a detailed error (only the generic warning icon), check that you are logged in with a role that has edit access to the LiveDoc or Wiki page containing the widget.
Open the widget's configuration panel (**Edit > Widget Parameters** in the Polarion page editor). Cross-reference the property name from the error detail with the corresponding widget parameter.
Common parameters that drive script evaluation:
| Parameter type | What it does | Error-prone when… |
| ------------------------------ | ------------------------------------------- | ---------------------------------------------------------- |
| Plan query (`plansQuery`) | Lucene query selecting Plans onto the board | Query syntax is invalid or references a non-existent field |
| Swimlane assignment expression | Determines how work items map to swimlanes | Enum field ID is wrong, or field type is unsupported |
| Card content template | Velocity/script template for card body | Template references an undefined variable |
| Capacity configuration | Expressions used for capacity calculation | Whitespace-sensitive values contain extra spaces |
| Page parameters | Dynamic values injected from URL/page | Page parameter name does not match the declaration |
See [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) for a full parameter reference.
### Plan query syntax error
**Symptom:** Board shows no columns (Plans), error mentions `plansQuery` or a Lucene parse failure.
**Fix:** Open the widget configuration and correct the `plansQuery` value. Lucene queries are case-sensitive for field names. Example of a valid query:
```properties theme={null}
plansQuery=template.id:iteration AND NOT status:closed
```
Check that:
* Field names exactly match Polarion field IDs (e.g., `type.id`, not `typeId`).
* String values are unquoted when they contain no spaces, or double-quoted when they do.
* Boolean operators (`AND`, `OR`, `NOT`) are uppercase.
### Enum swimlane field not supported
**Symptom:** Swimlanes do not render, error references the resource field or assignment mode.
**Fix:** Planningboard's `ENUM` assignment mode supports `IEnumType` fields and `IListType` fields whose items are `IEnumType`. The following field types are **not supported** as swimlane assignment fields: `status`, `resolution`, and `type`. Switch to a custom enum field or choose a different assignment mode.
Using `status`, `resolution`, or `type` as the swimlane resource field is a known unsupported configuration. The board will show an error rather than silently grouping incorrectly. Replace the resource field with a supported custom enum field.
### Capacity configuration whitespace
**Symptom:** Capacity bar values appear zero or incorrect, or an error references capacity parsing.
**Fix:** Capacity configuration parameters are whitespace-sensitive. Remove leading or trailing spaces from all capacity-related widget parameter values:
```properties theme={null}
# Correct — no surrounding spaces
capacity=8
# Incorrect — trailing space causes parse failure
capacity=8
```
Whitespace around capacity parameter values is a known source of silent misconfiguration. Even a single trailing space can cause the capacity bar to show zero or trigger an error. Always verify there are no extra spaces when setting capacity parameters.
### Velocity template / card content error
**Symptom:** Cards render blank or show a raw error string; error mentions a template property or variable.
**Fix:** Card content templates use Velocity syntax. Common causes:
* Referencing a custom field using `$workItem.customFields.myField` — this form does not return the value. Use `$workItem.getValue("myField")` instead.
* Referencing an enum-typed field without calling `.getName()` — the raw `EnumOption[...]` object is printed instead of the label.
* An undefined variable reference (`$myVar`) with no fallback — Velocity prints the literal `$myVar` string when the variable is null.
Example of a correctly written card template snippet:
```javascript theme={null}
$workItem.getValue("severity").getName()
```
### Page parameter not resolved
**Symptom:** Board ignores URL-driven filters or shows an error about an unresolved parameter.
**Fix:** The page parameter name in the widget configuration must exactly match the parameter name declared in the page header or URL. Names are case-sensitive. See [Use Page Parameters](/planningboard/guides/configuration/page-parameters) and [Dynamic Filtering with Page Parameters](/planningboard/guides/advanced/dynamic-filtering) for the declaration syntax.
After correcting a widget parameter, save the widget configuration, then use the board's **Refresh** control (or reload the page) to force the board to re-fetch all data from the server. A refresh reloads all Plans and work items and resets the board state.
The board persists swimlane collapse state and scroll position in browser `localStorage`. If the board looks different after a fix than expected, try clearing `localStorage` for the page (browser DevTools > Application > Local Storage > clear the relevant keys) or open the board in a private/incognito window to rule out stale state.
If the board never finishes loading (infinite spinner) and no error indicator appears, the issue may not be a script error:
```text theme={null}
Board Load Attempt
|
+----------------+----------------+
| |
Script / Config Error Network / Firewall Issue
| |
Error indicator appears Infinite spinner, no error
in board toolbar indicator, DevTools shows
blocked or timed-out requests
```
* Open the browser developer tools (**F12**) and check the **Network** tab for failed or blocked requests to the Polarion server.
* If requests are being blocked by a firewall or proxy, this is a network-layer issue — not a Planningboard script error. Refer to [Network and Firewall Requirements](/planningboard/guides/troubleshooting/network-requirements) for the list of required endpoints.
* If requests reach the server but return error responses (HTTP 4xx/5xx), check the Polarion server logs and verify the widget configuration is valid.
Infinite loading that is never accompanied by a script error indicator is frequently caused by an internal firewall or proxy blocking requests to the Polarion server — not by a misconfigured widget. Diagnose network connectivity first before troubleshooting widget parameters.
## Verification
After applying your fix:
1. Save the widget configuration.
2. Reload the Planningboard page.
3. You should now see the board render without the warning indicator in the toolbar, Plans appear as columns, and work item cards distributed across swimlanes as expected.
If the error indicator persists, repeat Step 1 to read the updated error detail — the message may have changed to reflect a new underlying issue now that the previous one is resolved.
## See Also
* [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) — full reference for all widget parameters
* [Config Scripts](/planningboard/guides/advanced/config-scripts) — authoring configuration scripts
* [Item Scripts](/planningboard/guides/advanced/item-scripts) — authoring per-item scripts
* [Dynamic Filtering with Page Parameters](/planningboard/guides/advanced/dynamic-filtering) — page parameter syntax and usage
* [Network and Firewall Requirements](/planningboard/guides/troubleshooting/network-requirements) — required endpoints and proxy configuration
* [Common Errors](/planningboard/guides/troubleshooting/common-errors) — broader Planningboard error reference
**KB Articles**
* Troubleshooting Script Errors in Planningboard
**Support Tickets**
* [#6659](https://support.nextedy.com/helpdesk/tickets/6659)
**Source Code**
* `commons.js`
* `PlanningBoardWidgetDependenciesProcessor.java`
* `PlanningBoardWidgetRenderer.java`
# Scroll and Focus Behavior
Source: https://learn.nextedy.com/planningboard/guides/troubleshooting/scroll-behavior
Diagnose and work around scroll and focus issues that occur when editing cards on a Nextedy PLANNINGBOARD.
## The Problem: Board Scrolls to Top After a Card Update
When you update a card using the side panel, the board may scroll back to the top of the page and lose your current scroll position. This makes it difficult to continue working on boards that require vertical scrolling — for example, a board with many swimlanes or a large number of work items.
**Known behavior in earlier versions**
In versions of Planningboard prior to the focus-preservation fix, every card save via the side panel triggered a full board reload that reset the scroll position to the top. If you are experiencing this, check your installed version and upgrade if available. See [Version Updates and Checking](/planningboard/guides/troubleshooting/version-updates) for instructions.
***
Before troubleshooting, confirm which symptom you are seeing:
***
The scroll-to-top behavior after card updates was addressed in a Planningboard release that preserves focus on the last edited row after a card update.
1. Check your current Planningboard version: in Polarion, navigate to **Administration > Nextedy PLANNINGBOARD** (or your equivalent administration page) and note the installed version.
2. Compare it against the release notes at [Version Updates and Checking](/planningboard/guides/troubleshooting/version-updates).
3. If an updated version is available, follow the upgrade procedure described in [Version Updates and Checking](/planningboard/guides/troubleshooting/version-updates).
**After upgrading**
After installing an updated version, clear your browser cache and reload the Planningboard page. The board should now return focus to the swimlane row you were editing after you save a card.
***
Once you have upgraded:
1. Open a Planningboard with enough swimlanes that the board requires scrolling.
2. Scroll down to a swimlane in the lower half of the board.
3. Click a card to open the side panel.
4. Make a change to a field and save.
**You should now see** the board remain at (or return to) the swimlane row you were editing, rather than jumping back to the top of the page.
**Verify in application**
The exact mechanism for focus preservation (for example, whether it anchors to the swimlane row, the specific card, or the scroll offset) was not confirmed in the available source context. Observe the behavior in your environment after upgrading.
***
If upgrading is not immediately possible:
* **Use the keyboard:** after saving a card, use your browser's scroll position (`Page Down` / arrow keys) to navigate back to where you were.
* **Reduce swimlane count per board:** consider splitting a very tall board into multiple Planningboard instances, each covering a subset of swimlanes, to reduce the scrolling distance lost on reload. See [Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration) for swimlane filtering options.
* **Filter by Plan range:** narrow the board to a smaller set of Plans so fewer rows are rendered. See [Filter Swimlanes by Plan Range](/planningboard/guides/swimlanes/filtering-by-plan-range).
***
If the board shows a loading indicator that never resolves — rather than scroll loss — the cause is often a network or firewall issue rather than a Planningboard bug.
**Firewall and proxy interference**
Infinite loading on Planningboard pages has been confirmed to be caused by corporate firewalls and internal proxies blocking required network traffic. This is not a product defect. The board may appear stuck indefinitely with no error message.
To diagnose:
1. Open your browser's developer tools (`F12`).
2. Go to the **Network** tab.
3. Reload the Planningboard page.
4. Look for requests that are pending, blocked, or returning non-`200` status codes (for example `403`, `407`, `net::ERR_BLOCKED_BY_CLIENT`, or long-stalled requests with no response).
5. If you see blocked or failed requests, contact your network administrator to allow the relevant endpoints.
See [Network and Firewall Requirements](/planningboard/guides/troubleshooting/network-requirements) for the full list of network prerequisites for Planningboard.
**Quick isolation test**
Access the Planningboard page from a machine outside your corporate network (for example, via a personal hotspot). If the board loads correctly, a firewall or proxy on your network is the cause.
***
Whether you are experiencing scroll loss or infinite loading, the browser console often contains useful diagnostic information.
1. Open developer tools (`F12`) and go to the **Console** tab.
2. Reload the page or reproduce the action that causes the issue.
3. Look for red error entries or warnings referencing Planningboard resources.
4. Note the full error message and include it when reporting the issue to support.
**Verify in application**
Specific browser console error messages produced by scroll or focus issues are not documented in the available source context. If you encounter a specific error message, see [Common Errors](/planningboard/guides/troubleshooting/common-errors) for general error resolution guidance.
***
## Summary
| Symptom | Most Likely Cause | Resolution |
| ---------------------------------------- | -------------------------------------------------- | ------------------------------------------------- |
| Board scrolls to top after card save | Focus not preserved in older Planningboard version | Upgrade Planningboard |
| Board never finishes loading | Firewall or proxy blocking network requests | Check network requirements; contact network admin |
| Board loads but card save fails silently | Configuration or permission issue | Check browser console for errors |
***
## See Also
* [Version Updates and Checking](/planningboard/guides/troubleshooting/version-updates) — upgrade your Planningboard installation
* [Network and Firewall Requirements](/planningboard/guides/troubleshooting/network-requirements) — prerequisites for connectivity
* [Common Errors](/planningboard/guides/troubleshooting/common-errors) — general error resolution
* [Drag and Drop Issues](/planningboard/guides/troubleshooting/drag-and-drop-issues) — related board interaction issues
* [Swimlane Expansion Issues](/planningboard/guides/troubleshooting/swimlane-expansion) — other board rendering issues
* [Basic Board Interactions](/planningboard/getting-started/basic-interactions) — overview of board navigation
**KB Articles**
* Troubleshooting Script Errors in Planningboard
**Support Tickets**
* [#6659](https://support.nextedy.com/helpdesk/tickets/6659)
* [#6425](https://support.nextedy.com/helpdesk/tickets/6425)
# Swimlane Expansion Issues
Source: https://learn.nextedy.com/planningboard/guides/troubleshooting/swimlane-expansion
Diagnose and resolve problems where clicking to expand or collapse a swimlane produces unexpected behavior — including expanding the wrong swimlane, no response, or inconsistent results across browsers.
***
## Symptoms
| Symptom | Likely Cause |
| --------------------------------------------------------------------- | --------------------------------------------------------------------- |
| Clicking a swimlane expands a different swimlane (often the last one) | Known browser-specific rendering bug |
| Expand/collapse works in one browser but not another | Chrome vs Edge compatibility issue |
| Swimlane toggle is intermittent — works sometimes, fails other times | Same browser rendering issue |
| All swimlanes appear expanded and cannot be collapsed | `collapsibleSwimlanes` parameter set to `false` |
| Swimlanes are not visible at all | Assignment mode is set to `none`, or no items match swimlane criteria |
***
## Check the `collapsibleSwimlanes` Parameter
Before investigating browser issues, confirm that swimlane collapsibility is enabled in the widget configuration.
1. Open the Polarion page containing your Nextedy PLANNINGBOARD widget in edit mode.
2. Open the **Widget Parameters** panel.
3. Navigate to the **Swimlanes (Rows)** section.
4. Confirm that `collapsibleSwimlanes` is set to `true` (the default).
The property default is `true`. If it has been explicitly set to `false`, swimlanes will render as permanently expanded with no toggle control.
**Whitespace sensitivity in capacity and swimlane parameters**
Widget parameter values are whitespace-sensitive. A value of ` true` (with a leading space) will not be treated the same as `true`. Always verify there are no leading or trailing spaces when editing parameters directly.
***
## Address the Chrome Swimlane Expansion Bug
A confirmed browser-specific bug causes clicking to expand a swimlane to expand a **different swimlane** instead — typically the last swimlane in the list. This behavior is **intermittent** and has been reproduced in Chrome. Microsoft Edge does not exhibit this issue.
### Workaround: Use Microsoft Edge
The most reliable resolution is to switch from Chrome to Microsoft Edge for Planningboard sessions where swimlane expand/collapse interaction is required.
1. Open Microsoft Edge.
2. Navigate to the same Polarion page.
3. Verify that swimlane expand/collapse now responds to the correct swimlane.
**Known issue: Chrome swimlane expansion**
Clicking a swimlane header in Chrome may expand a different swimlane — usually the last one in the list — rather than the one you clicked. This is a known rendering issue in Chrome. No fix has been shipped for this issue. Use Microsoft Edge as the recommended browser for Planningboard if you rely on swimlane expand/collapse.
**Refresh before switching browsers**
If you have made planning changes in Chrome before encountering the issue, use the **Refresh** button (`#btnRefresh`) to reload the current board state from the server before switching to Edge. This ensures your changes are persisted and visible in Edge.
***
## Verify the Assignment Mode Is Set Correctly
Swimlane expansion is only meaningful when a swimlane assignment type is active. If the board uses `assignmentMode = none`, all items appear in a flat list with no swimlanes to expand or collapse.
```text theme={null}
Widget Parameters → Swimlanes (Rows) → Assignment Type
```
Confirm the **Assignment Type** is set to one of the supported modes:
* **Users (Assignee)** — one swimlane per assignee in the project
* **Parent Item** — one swimlane per parent work item
* **Enumeration Field** — one swimlane per field value
* **Project** — one swimlane per sub-project
* **SAFe assignment types** — for SAFe environments
If the assignment type is **No Swimlanes**, the board intentionally renders without rows — there is nothing to expand or collapse. See [No Swimlanes Mode](/planningboard/guides/swimlanes/no-swimlanes-mode) if this mode is intentional.
***
## Check Whether Empty Swimlanes Are Hidden
If swimlanes appear to be missing — rather than collapsed — the `showEmptySwimlanes` parameter may be hiding them.
The property default is `false`, meaning swimlanes with no matching work items are **not shown**. If a swimlane you expect to see is absent, either:
* No work items are currently assigned to that swimlane's criterion (e.g. no items assigned to that user or enum value), or
* The swimlane assignment criterion does not match any items given the current work-item query.
To confirm: temporarily set `showEmptySwimlanes = true` in the widget parameters. All swimlanes — including empty ones — will then appear on the board. If previously hidden swimlanes now show up empty, adjust your work-item query or swimlane assignment configuration rather than keeping `showEmptySwimlanes = true` in production.
**Distinguish missing from collapsed**
A collapsed swimlane shows a thin header bar. A completely absent swimlane — due to `showEmptySwimlanes = false` — leaves no visible trace. If you expect a swimlane and see nothing, check `showEmptySwimlanes` first before investigating the browser issue.
***
## Enumeration Field Swimlanes: Validation Error After Save
If you configured swimlanes using an **Enumeration Field** assignment type and see the error `field does not exist or is not of type enumeration` after saving:
**Global enumeration custom fields may not be supported**
Global enumeration custom fields (defined at the global level rather than at the project level) appear to have limited or unsupported status for Planningboard swimlanes. A global enum field may validate during initial configuration but fail after saving. If you encounter this error, use a **project-level enumeration custom field** instead. Contact Nextedy support if a global field is required for your workflow.
Steps to resolve:
1. Open **Widget Parameters → Swimlanes (Rows)**.
2. Note the **Field ID** value in the Enumeration Field configuration.
3. In Polarion Administration, confirm the field is defined at the **project** level (not global).
4. If the field is global, create an equivalent project-level enumeration field and reconfigure the widget parameter to reference that field ID.
See [Enumeration Field Swimlanes](/planningboard/guides/swimlanes/enum-swimlanes) for full configuration guidance.
***
## Decision Flow
```text theme={null}
Swimlane expansion not working as expected
|
v
collapsibleSwimlanes = false?
+-----------+-----------+
Yes No
| |
Set to true |
v
Wrong swimlane expands (last one)?
+-----------+-----------+
Yes No
| |
Switch to Edge Swimlane missing entirely?
(Chrome bug) +-----------+-----------+
Yes No
| |
showEmptySwimlanes = false? Refresh board,
Set to true to check check query
|
Check assignment mode —
is it 'none' / No Swimlanes?
```
***
## Verification
After applying a fix, confirm the behavior is resolved:
1. Reload the Planningboard page.
2. Click a swimlane header that is currently expanded.
3. Confirm **that specific swimlane** collapses — not another.
4. Click the same header again.
5. Confirm it expands back.
You should now see each swimlane header toggle only its own row, with the correct swimlane expanding or collapsing on each click. If you are on Edge and the behavior is correct, the Chrome issue is confirmed; consider making Edge the standard browser for Planningboard users in your team.
***
## See also
* [Configure Swimlanes (Rows)](/planningboard/guides/configuration/swimlanes-configuration) — widget parameters for swimlane assignment type and collapsibility
* [User and Assignee Swimlanes](/planningboard/guides/swimlanes/user-swimlanes)
* [Enumeration Field Swimlanes](/planningboard/guides/swimlanes/enum-swimlanes)
* [No Swimlanes Mode](/planningboard/guides/swimlanes/no-swimlanes-mode)
* [Common Errors](/planningboard/guides/troubleshooting/common-errors)
* [Scroll and Focus Behavior](/planningboard/guides/troubleshooting/scroll-behavior)
**KB Articles**
* Swimlane Assignment Types
**Support Tickets**
* [#6688](https://support.nextedy.com/helpdesk/tickets/6688)
* [#5760](https://support.nextedy.com/helpdesk/tickets/5760)
* [#6734](https://support.nextedy.com/helpdesk/tickets/6734)
**Source Code**
* `PlanningBoardWidgetDependenciesProcessor.java`
* `PlanningBoardWidgetRenderer.java`
* `PlanningBoardDataService.java`
* `AssignmentMode.java`
* `licenseReadonly.cy.ts`
# Version Updates and Checking
Source: https://learn.nextedy.com/planningboard/guides/troubleshooting/version-updates
Check which version of Nextedy PLANNINGBOARD is installed and upgrade to a newer release to resolve known bugs and gain access to new features.
## Check your current version
Before upgrading, confirm what is currently installed.
1. Open Siemens Polarion ALM as an administrator.
2. Navigate to **Administration > Nextedy PLANNINGBOARD** (or the equivalent Nextedy plugin administration area in your Polarion instance).
3. Look for the version number displayed in the Planningboard status or about section.
**Version number format**
Planningboard version numbers follow the `YY.M.patch` pattern — for example, `24.2.0` or `24.5.1`. The year and month indicate the release cycle; the patch component increments for bug-fix releases.
## Check for available updates
Planningboard can check for new releases via the administration panel, which contacts `download.nextedy.com`.
1. In **Administration > Nextedy PLANNINGBOARD**, locate the **Check for updates** or version-check control.
2. If a newer version is available, the panel displays the latest version number alongside a download link.
**Version check blocked by firewall**
If the version-check panel shows no result, displays an error, or hangs indefinitely, your server's outbound traffic to `download.nextedy.com` may be blocked by a network filter or corporate firewall. This is a common deployment scenario and does not indicate a product defect.
**Fallback:** Navigate directly to `https://download.nextedy.com` from a browser that has internet access, or contact [Nextedy support](https://www.nextedy.com) to obtain the latest release package and changelog.
## Upgrade Planningboard
Planningboard is installed on your Polarion server. The upgrade procedure mirrors the initial installation.
### Before you start
* Download the new plugin package (a `.zip` file or folder named `com.nextedy.planningboard`) from `download.nextedy.com` or from the link provided in the administration panel.
* Schedule a short Polarion downtime — the server must restart.
* Back up the existing plugin folder in case a rollback is needed.
### Upgrade steps
1. **Stop the Polarion server.**
2. Navigate to the Polarion `plugins/` directory on your server.
3. Remove (or rename as a backup) the existing `com.nextedy.planningboard` folder.
4. Copy the new `com.nextedy.planningboard` folder from the downloaded package into `plugins/`.
5. Delete the `.config` folder (or cache directory) if present — this forces Polarion to re-read the updated plugin manifest on startup.
6. **Start the Polarion server.**
7. After startup, return to **Administration > Nextedy PLANNINGBOARD** and confirm the version number has advanced.
**Do not skip the .config deletion step**
Leaving the old `.config` directory in place can cause Polarion to load a cached version of the plugin, making it appear that the upgrade did not take effect even though the new files are present. Always delete `.config` after replacing the plugin folder.
**Upgrade resolved item-movement errors**
A known issue in `24.2.0` caused error messages when moving work items between Plans on the board. Upgrading to `24.5.1` or later resolved this behaviour. If you are experiencing item-movement errors, check whether your installed version predates `24.5.1`.
## Verify the upgrade
After the server restarts:
1. Open a Polarion page that contains a Planningboard widget.
2. Confirm the board renders without errors.
3. Test a drag-and-drop move of a card between swimlanes to verify write operations work correctly.
4. In **Administration > Nextedy PLANNINGBOARD**, confirm the displayed version matches the package you installed.
You should now see the new version number in the administration panel, and the board should load and respond to interactions without the errors that were present in the previous version.
## Troubleshoot version-check failures
| Symptom | Likely cause | Resolution |
| ----------------------------------------------- | -------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| Version-check panel returns no result or hangs | Outbound connection to `download.nextedy.com` is blocked | Check firewall rules; use the direct download URL as a fallback |
| Board loads with infinite spinner after upgrade | Firewall or proxy blocking the board's client assets | See [Network and Firewall Requirements](/planningboard/guides/troubleshooting/network-requirements) |
| Version number unchanged after upgrade | `.config` folder not deleted before restart | Stop server, delete `.config`, restart |
| Item-movement errors persist after upgrade | Version still predates `24.5.1` | Confirm installed version; repeat upgrade steps |
| License warning appears after upgrade | License file not compatible with new version | See [License Count and Warnings](/planningboard/guides/troubleshooting/license-issues) |
**Infinite-loading board after upgrade**
If the board becomes unresponsive with an infinite loading indicator immediately after an upgrade, this is more likely a network or firewall issue than a product defect. Open the browser developer tools (F12) and check the **Console** and **Network** tabs for blocked requests. Refer to [Network and Firewall Requirements](/planningboard/guides/troubleshooting/network-requirements) for a full checklist.
## See also
* [Installation](/planningboard/getting-started/installation) — full installation instructions for reference during upgrades
* [License Count and Warnings](/planningboard/guides/troubleshooting/license-issues) — resolve license errors that may surface after an upgrade
* [Network and Firewall Requirements](/planningboard/guides/troubleshooting/network-requirements) — diagnose connectivity issues that affect version checking and board loading
* [Common Errors](/planningboard/guides/troubleshooting/common-errors) — general error reference for post-upgrade issues
**Support Tickets**
* [#6659](https://support.nextedy.com/helpdesk/tickets/6659)
* [#6072](https://support.nextedy.com/helpdesk/tickets/6072)
**Source Code**
* `PlanningBoardWidgetRenderer.java`
* `PlanningBoardWidgetDependenciesProcessor.java`
* `PlanningBoardDataService.java`
* `licenseReadonly.cy.ts`
# Planningboard
Source: https://learn.nextedy.com/planningboard/index
Capacity-aware sprint and release planning on a board of swimlanes and cards for Polarion.
Nextedy PLANNINGBOARD is a planning app for Siemens Polarion ALM that arranges Plans and work items as cards across swimlanes, giving teams a visual, capacity-aware view for sprint and release planning. It embeds directly into Polarion LiveDoc and Wiki pages as a configurable widget, complementing timeline-based tools with a board/Kanban-style planning experience.
## Quick Navigation
Install Planningboard, set up your first project, and create your first Planningboard step by step.
Understand board structure, swimlane assignment modes, Plans modes, capacity tracking, and prioritization.
How-to guides for configuration, swimlane setup, capacity management, planning workflows, and advanced scripting.
Complete widget parameter listings, configuration properties, scripting API, assignment modes, and UI elements.
Answers to common questions on configuration, capacity, swimlanes, SAFe integration, and licensing.
Resolve script errors, capacity calculation issues, drag-and-drop problems, and version update issues.
## Key Features
* **Board view of Plans and work items** — Polarion Plans become columns and work items render as cards, giving teams a visual overview of sprint and release scope
* **Configurable swimlanes** — Group cards by assignee, parent item, enumeration field, project, or SAFe team; run in no-swimlanes mode for a flat board
* **Capacity bars per swimlane** — Track capacity load visually with per-swimlane capacity bars and normalization across swimlanes
* **Plan queries** — Select which Plans appear on the board using Lucene-based Plan queries
* **Drag-and-drop planning** — Move work items between Plans and swimlanes directly on the board
* **Prioritization** — Order work items on the board and persist priority within Plans
* **Card content and appearance customization** — Configure which fields appear on cards, apply color rules, and highlight items planned after their due date
* **SAFe integration** — Support for SAFe Sprints, Program Increments, and Solution Train planning views with dedicated swimlane and Plans modes
* **Advanced scripting** — Item scripts, config scripts, data scripts, and template functions for extending board behavior
* **Cross-project planning** — Arrange work items from multiple Polarion projects on a single board
## Documentation Structure
| Section | Purpose | Start Here |
| -------------------------------------------------------------- | ------------------------------------------------------ | ----------------------------------------------------------------------------------- |
| [Getting Started](/planningboard/getting-started/index) | Install Planningboard and create your first board | [Installation](/planningboard/getting-started/installation) |
| [Concepts](/planningboard/concepts/index) | Understand how the board, swimlanes, and capacity work | [Introduction to Planningboard](/planningboard/concepts/introduction) |
| [Guides](/planningboard/guides/index) | Task-oriented how-to guides for all feature areas | [Widget Parameters Overview](/planningboard/guides/configuration/widget-parameters) |
| [Reference](/planningboard/reference/index) | Complete parameter and API lookup | [Widget Parameters](/planningboard/reference/widget-parameters/index) |
| [FAQ](/planningboard/faq/index) | Answers to common questions | [General](/planningboard/faq/general) |
| [Troubleshooting](/planningboard/guides/troubleshooting/index) | Diagnose and fix common problems | [Common Errors](/planningboard/guides/troubleshooting/common-errors) |
## Common Tasks
* [Install Planningboard into a new project](/planningboard/getting-started/installation)
* [Create your first Planningboard](/planningboard/getting-started/first-planning-board)
* [Configure swimlanes (rows)](/planningboard/guides/configuration/swimlanes-configuration)
* [Configure Plans (columns)](/planningboard/guides/configuration/plans-configuration)
* [Track team capacity](/planningboard/guides/capacity/team-capacity)
* [Drag and drop work items between Plans](/planningboard/guides/planning/drag-and-drop)
* [Customize card content and appearance](/planningboard/guides/customization/card-content)
***
Start with [Installation](/planningboard/getting-started/installation) to add the widget to your Polarion instance, then follow [Create Your First Planningboard](/planningboard/getting-started/first-planning-board) to set up your first board. The [Board Structure](/planningboard/concepts/board-structure) concept page explains how Plans, swimlanes, and cards relate to each other.
# Config Script API
Source: https://learn.nextedy.com/planningboard/reference/api/config-script-api
The Config Script API exposes the runtime configuration object that controls how the Nextedy PLANNINGBOARD renders and behaves.
## Overview
```text theme={null}
Planningboard initialisation
|
v
+----------------------------+
| Widget Parameters | (per-instance, set in Polarion page editor)
+----------------------------+
|
v
+----------------------------+
| Config Script | (JavaScript — runs server-side or client-side)
| receives config object | ← Config Script API described on this page
+----------------------------+
|
v
+----------------------------+
| Board renders |
| (swimlanes, cards, |
| capacity bars) |
+----------------------------+
```
The config object is the single place where tooltip templates, custom data per Plan column, and scheduler view settings are applied programmatically. Changes made inside the config script take effect on the next render; call `setCurrentView()` to force an immediate re-render after modifying the config at runtime.
***
## Capacity Tooltip Properties
These properties control how capacity information is presented in the tooltip that appears when hovering over a Plan column's capacity bar.
| Property | Type | Default | Description |
| ----------------------- | -------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `columnTooltipTemplate` | `string \| function` | `undefined` | Custom template for the capacity tooltip on Plan columns. When a string, treated as a template. When a function, receives `column` and `row` objects and must return an HTML string. When not set, the default tooltip is used. |
### Default Tooltip
When `columnTooltipTemplate` is not configured, the board displays an aggregate capacity tooltip showing:
* **Capacity** — total capacity for the Plan column
* **Done** — effort marked as done
* **Todo** — remaining effort
* **Available** — capacity minus allocated effort
### Custom Tooltip Function
When `columnTooltipTemplate` is a function, it receives the current column and row context objects:
```javascript theme={null}
config.columnTooltipTemplate = function(column, row) {
// column and row objects provide plan and resource data
// Must return an HTML string
return "Custom tooltip content
";
};
```
**Per-user allocation breakdown**
A function-based `columnTooltipTemplate` enables per-user capacity breakdowns showing Available / Allocated / Total for each team member. Overallocated users (negative available capacity) should be highlighted — for example, by wrapping negative values in a `` element.
**Overallocation display**
When a user's available capacity is negative (overallocated), the board renders the value in red by default in the built-in tooltip. Replicate this behaviour in custom templates by checking for negative values and applying appropriate styling.
***
## Plan Column Data Properties
These properties attach custom data to individual Plan columns, making it available inside tooltip templates and other rendering callbacks.
| Property | Type | Default | Description |
| ------------ | -------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `scriptData` | `object` | `undefined` | Arbitrary custom data stored per Plan in the scheduler config. Values set here are accessible inside `columnTooltipTemplate` and other scripting callbacks. Keyed by plan identifier. |
### Example: Storing custom data per Plan
```javascript theme={null}
// Attach custom data to a plan column identified by its ID
config.scriptData = {
"iteration-1": { team: "Backend", budget: 80 },
"iteration-2": { team: "Frontend", budget: 60 }
};
```
This data can then be read inside a `columnTooltipTemplate` function to render plan-specific information.
***
## Scheduler View Control
| Method | Signature | Description |
| ------------------ | ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `setCurrentView()` | `setCurrentView(): void` | Refreshes the scheduler view. Call after programmatically modifying `columnTooltipTemplate` or other view configuration properties to trigger a re-render. |
**When to call setCurrentView**
`setCurrentView()` is required whenever configuration properties are changed at runtime — for example, after updating `columnTooltipTemplate` in response to a user action. Changes made during the initial config script execution (before first render) do not require an explicit call.
***
## Configuration Example
The following example demonstrates a config script that adds a per-user capacity breakdown tooltip to all Plan columns.
```javascript theme={null}
// Custom capacity tooltip showing per-user allocation
config.columnTooltipTemplate = function(column, row) {
var html = '';
html += '
' + column.label + ' ';
// scriptData can carry plan-specific data set elsewhere in the config
var planData = config.scriptData && config.scriptData[column.id];
if (planData && planData.users) {
planData.users.forEach(function(user) {
var available = user.total - user.allocated;
var color = available < 0 ? 'red' : 'inherit';
html += '
' + user.name + ': ';
html += '' + available + ' ';
html += ' / ' + user.allocated + ' / ' + user.total;
html += '
';
});
}
html += '
';
return html;
};
// Attach per-plan user data
config.scriptData = {
"sprint-1": {
users: [
{ name: "Alice", allocated: 40, total: 40 },
{ name: "Bob", allocated: 50, total: 40 } // overallocated
]
}
};
// Force re-render to apply the new template
setCurrentView();
```
***
## REST API Integration
The Config Script API operates on the client-side configuration layer. The underlying data served to the board is provided by the REST API described on the [REST API](/planningboard/reference/api/rest-api) page. Key data endpoints relevant to capacity configuration:
| Endpoint | Method | Purpose |
| ----------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `/api/data` | `GET` | Retrieves Planningboard data (tasks, items) in JSON format. Date format: `dd-MM-yyyy HH:mm`. |
| `/capacity` | `POST` | Sets the capacity value for a specific Plan in a project. Request body requires `project`, `plan` (format: `planId/planName`), and `capacity` fields. |
These endpoints feed the data that capacity tooltip templates present. Customising the tooltip via `columnTooltipTemplate` does not change the underlying data — it only changes how that data is displayed.
***
## Limitations
**Verify in application**
The Config Script API surface documented here is based on confirmed source context (tooltip template and `scriptData` customisation, `setCurrentView` method). Additional scheduler configuration properties may be available in the running product. Consult the [Scripting Properties](/planningboard/reference/configuration-properties/scripting-properties) reference for administration-level scripting configuration options.
* **Multi-assignee capacity**: the capacity model does not support multi-assignee effort distribution. Per-user capacity breakdowns in custom tooltips reflect single-assignee allocation only.
* **Sub-item effort**: effort is not automatically distributed from parent items to sub-items. Tooltip data reflects top-level item estimates.
* **Whitespace sensitivity**: capacity-related configuration properties are whitespace-sensitive. Avoid leading or trailing spaces in property values passed to the config object.
***
## Related Pages
* [Scripting API](/planningboard/reference/api/scripting-api) — entry points and execution context for config scripts
* [Item Script API](/planningboard/reference/api/item-script-api) — API available when scripting individual card rendering
* [Data Script API](/planningboard/reference/api/data-script-api) — API for customising the data query and transformation layer
* [REST API](/planningboard/reference/api/rest-api) — HTTP endpoints for data retrieval and capacity updates
* [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) — widget parameters controlling capacity display
* [Scripting Properties](/planningboard/reference/configuration-properties/scripting-properties) — administration properties for enabling and configuring scripting
**KB Articles**
* Planningboard: Customizable Statistics and Capacity Indicators
* Planningboard Widget Parameters
**Source Code**
* `PlanningBoardApiServlet.java`
* `capacityTooltipRendering.cy.ts`
* `PlanningBoardViewServlet.java`
* `PlanningBoardWidget.java`
# Data Script API
Source: https://learn.nextedy.com/planningboard/reference/api/data-script-api
The Data Script API is the server-side interface through which Nextedy PLANNINGBOARD reads and writes planning data.
**Verify in application**
This page documents the API surface identified from source code analysis. Exact endpoint paths, parameter names, and response field names should be verified against your installed Planningboard version before integrating.
***
## Endpoint Overview
```text theme={null}
GET /api/data Retrieve planning board data (tasks and items)
POST /api/data Bulk update tasks
POST /planningboard_license Query current license status
POST /capacity Set capacity for a plan
POST /planservice/fetchNewPlanParams Retrieve parameters needed to create new plans
POST /planservice/createPlan Create one or more new plans
```
All relative paths above are resolved under the Planningboard servlet base URL within Polarion.
***
## GET /api/data
Retrieves the full Planningboard dataset for a configured board instance. The response includes work items (tasks), Plans, resources, assignments, dependencies, and capacity information, depending on the active `assignmentMode` and `plansMode`.
### Query Parameters
| Parameter | Type | Description |
| ---------------------------------- | ------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| *(board configuration parameters)* | string | Parameters describing the board configuration are passed as query parameters. Exact parameter names match the widget parameter set. See [Widget Parameters](/planningboard/reference/widget-parameters/index). |
### Date Format
Date values in request parameters and responses use the format:
```text theme={null}
dd-MM-yyyy HH:mm
```
Example: `25-06-2026 09:00`
### Response Structure
The response is a JSON object. The top-level structure follows the `Data` model returned by `PlanningBoardDataService.getData`:
```json theme={null}
{
"items": [ ... ]
}
```
The `items` array contains work item (task) objects. Each item's fields depend on the configured `assignmentMode`, `plansMode`, and capacity settings active for the board.
**Verify in application**
The exact fields present on each item object depend on the board configuration. Refer to [Work Item Fields](/planningboard/reference/fields/work-item-fields), [Plan Fields](/planningboard/reference/fields/plan-fields), and [Resource Fields](/planningboard/reference/fields/resource-fields) for the field reference.
***
## POST /api/data — Bulk Task Update
Updates one or more work items in a single request. Parameters are submitted as form-encoded key-value pairs.
### Bulk Update Parameter Convention
| Parameter | Type | Description |
| ------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------- |
| `ids` | string | Comma-separated list of task IDs to update. Example: `ids=1001,1002,1003` |
| `{taskId}_{fieldName}` | string | Value to set for `fieldName` on task `taskId`. One parameter per field per task. Example: `1001_assignee=alice` |
| `{taskId}_!nativeeditor_status` | string | Control field. Set to `deleted` to delete that task. Any other value performs an update. |
### Deletion via `_!nativeeditor_status`
Task deletion is triggered by including a parameter of the form:
```text theme={null}
{taskId}_!nativeeditor_status=deleted
```
When this control field is present with the value `deleted` for a given task ID, `PlanningBoardDataService.deleteItem` is called. **Deletion is permanent** — the work item is removed from Polarion.
**Deletion is permanent**
Setting `_!nativeeditor_status=deleted` permanently deletes the work item from Polarion. This action cannot be undone from the Planningboard interface.
### Update Response
A successful update returns the updated `Item` object as JSON, as produced by `PlanningBoardDataService.updateItem`.
***
## POST /planningboard\_license
Returns the current Planningboard license status.
### Request
No request body is required.
### Response — LicenseResponse
```json theme={null}
{
"isMaintenanceExpired": false,
"status": "VALID",
"message": "License is valid.",
"email": "admin@example.com",
"product": "Nextedy PLANNINGBOARD"
}
```
| Field | Type | Description |
| ---------------------- | ------- | ----------------------------------------------------------- |
| `isMaintenanceExpired` | boolean | `true` if the maintenance/support subscription has expired. |
| `status` | string | License status string (e.g. `VALID`, `EXPIRED`, `MISSING`). |
| `message` | string | Human-readable status message. |
| `email` | string | Registered license email address. |
| `product` | string | Product name associated with the license. |
See [License Panel](/planningboard/reference/ui-elements/license-panel) for how license status is surfaced in the board UI.
***
## POST /capacity
Sets the capacity value for a specific Plan within a project.
### Request Body
JSON object with the following fields:
```json theme={null}
{
"project": "MyProject",
"plan": "SPRINT-42/Sprint 42",
"capacity": 40
}
```
| Field | Type | Description |
| ---------- | ------ | ---------------------------------------------------------------------------------------------------- |
| `project` | string | Polarion project ID. |
| `plan` | string | Plan identifier in the format `planId/planName`. Both parts are required. |
| `capacity` | number | Capacity value to set for the plan (unit depends on capacity configuration — hours or story points). |
**Capacity configuration dependency**
The unit and interpretation of the `capacity` value depend on the active capacity configuration. See [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) and [Capacity Properties](/planningboard/reference/configuration-properties/capacity-properties) for details.
### Response
| Outcome | Response |
| ------- | ----------------------------------------------------------------- |
| Success | HTTP 200 with a success indicator in the response body. |
| Error | HTTP error status with an error description in the response body. |
**Verify in application**
The exact success/error response format should be confirmed against the installed version.
***
## POST /planservice/fetchNewPlanParams
Retrieves the parameters needed to create new Plans, based on a parameters request structure. Used by the board UI before presenting the Plan creation dialog.
### Request Body
A JSON object matching the `parametersRequest` structure:
```json theme={null}
{
"...": "..."
}
```
**Verify in application**
The exact fields of `parametersRequest` are not fully specified in the available source context. Capture a live request from the board UI to confirm the complete structure.
### Response
Returns a JSON object describing the available plan parameters (e.g. allowed plan types, date ranges, name templates). The response is used to populate the Plan creation form in the board.
***
## POST /planservice/createPlan
Creates one or more new Polarion Plans based on provided plan parameters.
### Request Body
A JSON object with a `planParams` array of `PlanParameters` objects:
```json theme={null}
{
"planParams": [
{
"...": "..."
}
]
}
```
Bulk creation is supported by including multiple objects in the `planParams` array.
**Verify in application**
The exact fields of the `PlanParameters` structure are not fully specified in the available source context. Use `fetchNewPlanParams` to discover the parameter schema at runtime, or capture a live request from the board UI.
### Response
Returns the created Plan objects or a status indicator. Exact response format should be confirmed against the installed version.
***
## Data Service — Assignment Modes
The `PlanningBoardDataService` that backs the API supports eight assignment modes, which control how work items map to swimlanes. The mode is set via the `assignmentMode` widget parameter.
| Mode | Value | Description |
| -------------------------------- | ----------------- | --------------------------------------------------------------------------------------------- |
| Users (Assignee) | `ASSIGNEE` | Items are assigned to swimlanes based on the work item's assignee field. |
| Parent Item | `PARENT` | Items are grouped under their parent work item. |
| Enumeration Field | `ENUM` | Items are grouped by the value of a configured enum field. Supports multi-select enum fields. |
| Project | `PROJECT` | Items are grouped by their source Polarion project. |
| Program / Solution Teams (SAFe) | `SAFE_TEAM` | SAFe-specific: items are grouped by team assignment. |
| Agile Release Train Teams (SAFe) | `SAFE_TRAIN_TEAM` | SAFe-specific: items are grouped at the Agile Release Train + team level. |
| Programs (SAFe) | `SAFE_PROGRAMS` | SAFe-specific: items are grouped by SAFe program. |
| No Swimlanes | `NONE` | All items appear in a single undivided board. |
See [Assignment Modes](/planningboard/reference/assignment-modes/index) for detailed configuration of each mode.
***
## Data Service — Plans Modes
The `plansMode` configuration controls which Plans appear as columns on the board and how they are loaded.
| Mode | Value | Description |
| ----------------------------------- | ------------------ | --------------------------------------------------------------------------------------- |
| Project Plans | `PROJECT_PLANS` | Loads Plans from a single Polarion project. Standard sprint/release planning. |
| SAFe Sprints in Program | `SAFE_SPRINTS` | Loads team-level sprint Plans in a SAFe configuration. |
| SAFe Sprints in Portfolio | `SAFE_PFL_SPRINTS` | Loads portfolio-level sprint Plans, spanning multiple programs in a solution portfolio. |
| SAFe Program Increments in Program | `SAFE_PIS` | Loads SAFe Program Increment Plans. |
| SAFe Program Increments in Solution | `SAFE_SOLUTION` | Loads SAFe Solution Train Plans. |
See [Plans Modes](/planningboard/reference/plans-modes/index) for details on each mode.
***
## Data Service — Capacity Tracking
### capacityLoad
Enables effort and capacity tracking on work items and Plans. When active, the data service calculates effort values from work item time tracking fields or a configured custom capacity field.
| Subfield | Description |
| ------------ | -------------------------------------------------------------- |
| `effort` | Total estimated effort for the item. |
| `effortDone` | Effort already completed. For resolved items, equals `effort`. |
| `effortTodo` | Remaining effort. For resolved items, equals `0`. |
Effort values can be sourced from:
* **Time tracking fields** — `remainingEstimate` / `initialEstimate` (time-based, converted using `hoursPerDay`).
* **Custom capacity field** — a numeric custom field specified via configuration.
### multiCapacityLoad
Enables per-swimlane or per-resource capacity tracking. Use this when the board is configured to show separate capacity bars per resource or team rather than a single board-wide capacity bar.
**Capacity configuration is whitespace-sensitive**
Capacity configuration property values must not contain leading or trailing whitespace. Incorrect whitespace causes capacity to silently fail to load. See [Capacity Properties](/planningboard/reference/configuration-properties/capacity-properties).
### useTeamsService
When `useTeamsService` is enabled, the data service integrates with the `IPlanningBoardTeamsService` to retrieve:
* Team capacity values
* Per-user capacity values
* Team member lists
When the Teams Service is active, its capacity data overrides any `plan.capacity` values set directly on the Plan. See [Teams Service API](/planningboard/reference/api/teams-service-api) and [Teams Service Properties](/planningboard/reference/configuration-properties/teams-properties).
***
## Data Service — Plan Assignment Logic
### setPlan — Date-Based Plan Assignment
When a card is dragged to a different column (Plan), the `setPlan` service method assigns the work item to plans based on `start_date` and `end_date`:
* The item is **added** to all Plans whose date range spans the given dates.
* The item is **removed** from Plans whose date range falls outside the given dates.
In SAFe modes, `setPlan` also automatically syncs parent Plan assignments (`syncSAFEParentsFromChildren`): when a User Story's team assignment changes, it is remapped to the correct Team Program Increment Plan based on the new team.
### setResource — Resource Assignment by Mode
When a card is moved to a different swimlane, `setResource` updates the work item's assignment based on the active `assignmentMode`:
| Mode | Assignment Action |
| ----------------- | -------------------------------------------------------------------------------- |
| `ASSIGNEE` | Updates the work item's assignee field. |
| `PARENT` | Updates the parent link to the target swimlane's parent item. |
| `ENUM` | Updates the configured enum field value. Multi-select enum fields are supported. |
| `PROJECT` | Moves the work item to the target project. |
| `SAFE_TEAM` | Updates the SAFe team assignment field. |
| `SAFE_TRAIN_TEAM` | Updates the SAFe train-team assignment. |
| `SAFE_PROGRAMS` | Updates the SAFe program assignment. |
| `NONE` | No resource assignment — drag between swimlanes has no effect. |
***
## Data Service — Dependency Link Roles
The `dependencyLinkRoles` configuration specifies which Polarion link roles are treated as task dependencies. Items connected by these link roles are rendered as arrows (connectors) on the Planningboard.
To configure dependency display, set `dependencyLinkRoles` to a comma-separated list of Polarion link role IDs. See [Advanced Parameters](/planningboard/reference/widget-parameters/advanced-parameters) for the widget-level setting.
***
## Configuration Example
The following example shows a widget configuration that exercises the key data service features:
```properties theme={null}
assignmentMode=ASSIGNEE
plansMode=PROJECT_PLANS
capacityLoad=true
dependencyLinkRoles=depends_on,blocks
```
With `capacityLoad=true`, the `GET /api/data` response will include `effort`, `effortDone`, and `effortTodo` fields on each item. With `dependencyLinkRoles` set, dependency arrows are rendered on the board for items linked via `depends_on` or `blocks` link roles.
***
## Data Flow Diagram
```text theme={null}
Board UI (browser)
|
| GET /api/data?
v
PlanningBoardApiServlet
|
| getData(paramMap)
v
PlanningBoardDataService
|
+---> Polarion Tracker API (work items, Plans)
+---> Polarion Resource API (assignees, users)
+---> IPlanningBoardTeamsService (if useTeamsService=true)
|
v
Data model { items: [...] }
|
v
JSON response --> Board UI renders cards and swimlanes
```
***
## Related Reference
* [Scripting API](/planningboard/reference/api/scripting-api) — client-side scripting hooks
* [Item Script API](/planningboard/reference/api/item-script-api) — per-item scripting context
* [Config Script API](/planningboard/reference/api/config-script-api) — board configuration scripting
* [REST API](/planningboard/reference/api/rest-api) — additional REST endpoints
* [Teams Service API](/planningboard/reference/api/teams-service-api) — teams integration API
* [Widget Parameters](/planningboard/reference/widget-parameters/index) — all widget-level configuration
* [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) — capacity widget parameters
* [Assignment Modes](/planningboard/reference/assignment-modes/index) — swimlane assignment modes
* [Plans Modes](/planningboard/reference/plans-modes/index) — Plans column modes
* [Scripting Properties](/planningboard/reference/configuration-properties/scripting-properties) — server-side scripting configuration
**KB Articles**
* Planningboard: Customizable Statistics and Capacity Indicators
**Source Code**
* `PlanningBoardApiServlet.java`
* `PlanningBoardDataService.java`
# API Reference
Source: https://learn.nextedy.com/planningboard/reference/api/index
Nextedy PLANNINGBOARD exposes several scripting and REST APIs that let administrators and integrators customize board behavior, extend card rendering, drive configuration programmatically, and query team data
Use the pages below to look up available objects, methods, and endpoints for each API surface.
Entry point for board-level scripts. Covers the scripting lifecycle, execution context, and how to attach scripts to a Planningboard widget.
Per-card scripting hooks. Control card appearance, tooltip content, and custom actions on individual work item cards.
Programmatic access to widget configuration. Read and override widget parameters at runtime from within a board script.
Access to board data during script execution — Plans, work items, swimlane assignments, and capacity values.
HTTP endpoints for querying and manipulating Planningboard data from external systems or automation scripts.
API surface for the Teams Service integration — query team membership, capacity, and resource assignments.
**Scripting vs. REST**
**Scripting APIs** (`Item Script API`, `Config Script API`, `Data Script API`) run inside the Planningboard server context and are configured through widget parameters. The **REST API** is called from outside Polarion over HTTP. The **Teams Service API** is relevant only when the Teams Service integration is enabled — see [Teams Service Properties](/planningboard/reference/configuration-properties/teams-properties) and [Scripting Properties](/planningboard/reference/configuration-properties/scripting-properties).
## API Relationships
**KB Articles**
* Planningboard: Customizable Statistics and Capacity Indicators
**Source Code**
* `PlanningBoardApiServlet.java`
* `PlanningBoardViewServlet.java`
# Item Script API
Source: https://learn.nextedy.com/planningboard/reference/api/item-script-api
The Item Script API exposes the data structures and update conventions used when Nextedy PLANNINGBOARD reads, modifies, and deletes work items (tasks) through its server-side data service.
**Thin coverage**
Source coverage for this page is limited to the servlet layer (`PlanningBoardApiServlet`). Deeper scripting-hook documentation (item lifecycle callbacks, custom field transformation scripts) is not confirmed in the available context.
See also the [Scripting API](/planningboard/reference/api/scripting-api) for the general scripting model, the [Config Script API](/planningboard/reference/api/config-script-api) for board-configuration scripting, and the [Data Script API](/planningboard/reference/api/data-script-api) for board-data scripting.
***
## Overview
***
## Data Model
### `Data` Object
The top-level object returned by the data-retrieval endpoint.
| Field | Type | Description |
| ------- | -------- | -------------------------------------------------- |
| `items` | `Item[]` | Array of Planningboard items (work items / tasks). |
### `Item` Object
Each element of `data.items` represents a single Planningboard work item (card).
**Verify in application**
The full set of `Item` fields is not exhaustively listed in the available source context. The fields below are confirmed from the servlet and data-service layer. Additional fields (custom fields, display-only properties) may be present at runtime.
| Field | Type | Default | Description |
| ------------- | -------- | --------------- | -------------------------------------------------------------------------------------------------------- |
| `id` | `string` | — | Unique identifier for the item. Used as the key for all update and delete operations. |
| `{fieldName}` | varies | See application | Any work-item field value. Field names match Polarion field IDs (e.g., `title`, `priority`, `assignee`). |
***
## Update Convention
Planningboard uses a parameter-map convention (not a JSON body) when submitting item updates. Understanding this convention is required when constructing manual or scripted requests.
### Parameter Naming
Updates are submitted as flat key-value parameters. Each updated field follows the pattern:
```
{taskId}_{fieldName}
```
Where `{taskId}` is the item's `id` value and `{fieldName}` is the Polarion field ID to update.
**Example — updating the `priority` field of item `WI-42`:**
```text theme={null}
WI-42_priority=high
```
**Example — bulk update of two fields on two items:**
```text theme={null}
WI-42_priority=high
WI-42_assignee=jsmith
WI-99_title=Revised+Story+Title
ids=WI-42,WI-99
```
### `ids` Parameter
| Parameter | Type | Description |
| --------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `ids` | `string` | Comma-separated list of task IDs included in the bulk update request. Must list every item whose fields are being submitted in the same request. |
***
## Deletion Convention
Item deletion uses the same parameter-map mechanism as updates, with a reserved field name.
### `_!nativeeditor_status` Field
| Parameter | Value | Effect |
| ------------------------------- | ----------- | ------------------------------------------------------ |
| `{taskId}_!nativeeditor_status` | `"deleted"` | Permanently deletes the item identified by `{taskId}`. |
**Deletion is permanent**
When `{taskId}_!nativeeditor_status` equals `"deleted"`, the item is **permanently removed** from Polarion. This operation cannot be undone through the Planningboard UI. Ensure the item ID and intent are correct before submitting.
**Example — deleting item `WI-42`:**
```text theme={null}
WI-42_!nativeeditor_status=deleted
ids=WI-42
```
***
## Data Retrieval
### `GET /api/data`
Retrieves the current Planningboard data set — Plans and items — for the board instance.
| Query Parameter | Type | Default | Description |
| ------------------- | ---- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| *(see application)* | — | — | Query parameters control which Plans and items are returned. Parameter names and accepted values should be verified against the running application. |
**Date format used in response values:**
```
dd-MM-yyyy HH:mm
```
All date/time fields in the response payload use this format. Parse accordingly in any scripting context that processes item dates.
**Response structure:**
```json theme={null}
{
"items": [
{
"id": "",
"": ""
}
]
}
```
**Verify in application**
The full list of query parameters accepted by `GET /api/data` is not confirmed in the available context. Inspect the network requests made by the Planningboard client in your browser's developer tools to enumerate the parameters used for your board configuration.
***
## Bulk Update Request
### `POST /api/data` (bulk)
Submits field updates for one or more items in a single request.
**Request format:** `application/x-www-form-urlencoded`
| Parameter | Type | Required | Description |
| ------------------------------- | -------- | -------- | -------------------------------------------------------------- |
| `ids` | `string` | Yes | Comma-separated list of item IDs being updated. |
| `{taskId}_{fieldName}` | varies | Yes | One entry per field per item. Use the naming convention above. |
| `{taskId}_!nativeeditor_status` | `string` | No | Set to `"deleted"` to delete the item. |
**Example request body:**
```text theme={null}
ids=WI-10,WI-11
WI-10_priority=high
WI-10_assignee=jsmith
WI-11_!nativeeditor_status=deleted
```
**Response:** Returns the updated `Item` object for each modified item, or confirms deletion.
**Verify in application**
The exact response envelope structure for bulk updates is not confirmed in the available source context. Verify the response format against the live application before building integrations that parse the response body.
***
## Service Methods
The following service-layer methods underlie the HTTP endpoints. These are relevant when extending or scripting Planningboard via server-side hooks.
### `getData(parameterMap)`
| Aspect | Detail |
| ----------- | --------------------------------------------------------------------------- |
| Returns | `Data` object containing an `items` array |
| Input | Parameter map (matches the query parameters of `GET /api/data`) |
| Description | Retrieves all Planningboard items matching the current board configuration. |
### `updateItem(parameterMap)`
| Aspect | Detail |
| ----------- | ------------------------------------------------------------------- |
| Returns | Updated `Item` object |
| Input | Parameter map using `{taskId}_{fieldName}` convention |
| Description | Updates a single Planningboard item and returns the new item state. |
### `deleteItem(id)`
| Aspect | Detail |
| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| Returns | Confirmation of deletion |
| Input | Item `id` string |
| Description | Permanently deletes the Planningboard item with the given ID. Triggered by the `_!nativeeditor_status=deleted` convention at the HTTP layer. |
***
## Configuration Example
The following example illustrates a scripted bulk update that re-assigns two cards to a new sprint Plan and deletes one stale card. The parameter map follows the conventions described on this page.
```javascript theme={null}
// Example: bulk update submitted via HTTP POST to /api/data
// Reassign WI-10 and WI-20 to a new plan; delete WI-30.
const params = new URLSearchParams();
params.append("ids", "WI-10,WI-20,WI-30");
// Move WI-10 to the new Plan
params.append("WI-10_plan", "Sprint-5");
params.append("WI-10_priority", "high");
// Move WI-20 to the new Plan
params.append("WI-20_plan", "Sprint-5");
// Delete WI-30 (stale card)
params.append("WI-30_!nativeeditor_status", "deleted");
// Submit
fetch("/polarion/planningboard/api/data", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: params.toString()
});
```
The exact servlet URL path (`/polarion/planningboard/api/data`) should be confirmed against your Polarion installation. The path prefix may vary depending on your Polarion context path and Planningboard installation.
***
## Related Reference Pages
* [Scripting API](/planningboard/reference/api/scripting-api) — general scripting model and entry points
* [Config Script API](/planningboard/reference/api/config-script-api) — board configuration via scripting
* [Data Script API](/planningboard/reference/api/data-script-api) — board data scripting
* [REST API](/planningboard/reference/api/rest-api) — full HTTP endpoint reference including capacity and plan service endpoints
* [Widget Parameters — Advanced Parameters](/planningboard/reference/widget-parameters/advanced-parameters) — widget-level scripting parameters
* [Scripting Properties](/planningboard/reference/configuration-properties/scripting-properties) — system-wide scripting configuration properties
**KB Articles**
* Planningboard: Customizable Statistics and Capacity Indicators
**Source Code**
* `PlanningBoardApiServlet.java`
# REST API
Source: https://learn.nextedy.com/planningboard/reference/api/rest-api
The Nextedy PLANNINGBOARD REST API exposes endpoints for retrieving board data, updating work items, managing capacity, and interacting with Plans programmatically.
**Verify in application**
The REST API surface described here is derived from source code analysis. Endpoint paths, parameter names, and response structures should be verified against the running Planningboard instance. Some details — particularly exact error codes and optional fields — may differ between versions.
***
## Base URL
All Planningboard API endpoints are relative to the Polarion server base. The admin API base path (`apiBase`) is set dynamically by the servlet at runtime.
```text theme={null}
POST /planningboard_license
GET /api/data
POST /api/data (bulk task update)
POST /capacity
POST /planservice/fetchNewPlanParams
POST /planservice/createPlan
```
***
## Endpoints
### GET /api/data
Retrieves Planningboard data — the set of work items and Plans currently rendered on the board — as a JSON response.
**Request parameters**
| Name | Type | Required | Description |
| ------------------------ | ------ | --------------- | ------------------------------------------------------------------------------------------------------------------------ |
| (board query parameters) | string | See application | Parameters controlling which Plans and work items are fetched. Derived from the board's widget configuration at runtime. |
**Date format**
Dates in the response use the format `dd-MM-yyyy HH:mm`.
**Response**
Returns a JSON object containing an `items` array. Each item in the array represents a work item or Plan card.
```json theme={null}
{
"items": [ ... ]
}
```
**Item object fields**
| Field | Type | Description |
| ------------------- | --------------- | ------------------------------------------------------------------- |
| `id` | string | Work item identifier |
| (additional fields) | See application | Field set depends on board configuration and Polarion field mapping |
**Verify in application**
The full set of fields returned per item depends on the board's widget parameter configuration. Verify the exact response schema against the live board.
***
### POST /api/data — Bulk Task Update
Updates one or more work items in a single request. Task IDs and field values are submitted as form parameters using a specific naming convention.
**Parameter naming convention**
Each field update is submitted as a separate parameter following the pattern:
```text theme={null}
{taskId}_{fieldName}
```
For example, to update the `status` field of task `WI-42`:
```text theme={null}
WI-42_status=done
```
**Special parameter: `_!nativeeditor_status`**
The `_!nativeeditor_status` parameter controls the operation type for each task:
| Value | Behavior |
| ---------------- | --------------------------------- |
| `deleted` | Permanently deletes the task |
| (other / absent) | Updates field values for the task |
**Deletion example**
To delete task `WI-42`:
```text theme={null}
WI-42_!nativeeditor_status=deleted
```
**Deletion is permanent**
When `{taskId}_!nativeeditor_status=deleted` is submitted, the item is permanently deleted from Polarion. This action cannot be undone from the board.
**Bulk parameter format**
Multiple tasks can be updated in a single POST by providing parameters for each task. The `ids` parameter supplies a comma-separated list of task IDs to process:
| Parameter | Type | Description |
| ------------------------------- | ------ | --------------------------------------------------------------------- |
| `ids` | string | Comma-separated list of task IDs to update (e.g. `WI-42,WI-43,WI-44`) |
| `{taskId}_{fieldName}` | string | Field value for the named field on the named task |
| `{taskId}_!nativeeditor_status` | string | Operation flag; set to `deleted` to delete the task |
**Response**
Returns the updated `Item` object for each processed task (update operations). Deletion operations return a confirmation. See application for exact response envelope.
***
### POST /planningboard\_license
Returns the current license status for the Planningboard installation.
**Request**
No request body parameters required.
**Response — LicenseResponse**
| Field | Type | Description |
| ---------------------- | ------- | -------------------------------------------- |
| `isMaintenanceExpired` | boolean | `true` if the maintenance period has expired |
| `status` | string | License status identifier |
| `message` | string | Human-readable status message |
| `email` | string | License contact email address |
| `product` | string | Product identifier (value: `PLANNINGBOARD`) |
**Example response**
```json theme={null}
{
"isMaintenanceExpired": false,
"status": "active",
"message": "License is valid.",
"email": "license@example.com",
"product": "PLANNINGBOARD"
}
```
***
### POST /capacity
Sets the capacity value for a specific Plan within a project.
**Request body (JSON)**
| Field | Type | Required | Description |
| ---------- | ------ | -------- | ---------------------------------------------- |
| `project` | string | Yes | Polarion project ID |
| `plan` | string | Yes | Plan reference in the format `planId/planName` |
| `capacity` | number | Yes | Capacity value to assign to the Plan |
**Example request body**
```json theme={null}
{
"project": "MyProject",
"plan": "sprint-12/Sprint 12",
"capacity": 40
}
```
**Response**
Returns a success or error response. See application for exact response envelope structure.
**Plan format**
The `plan` field uses the composite format `planId/planName`. Both parts are required. Verify the exact IDs against the Plans configured in your Polarion project.
***
### POST /planservice/fetchNewPlanParams
Retrieves the parameters needed to create new Plans, based on a parameters request. Used to pre-populate the Plan creation form.
**Request body**
Submit a `parametersRequest` JSON object. The exact schema of `parametersRequest` depends on the Plan type and project configuration.
```json theme={null}
{
"parametersRequest": { ... }
}
```
**Response**
Returns a plan parameters object used to drive the `createPlan` endpoint. See application for exact field structure.
**Verify in application**
The `parametersRequest` schema and the returned plan parameters format are dependent on your Polarion project configuration and Plan types. Verify the exact structures in the running application.
***
### POST /planservice/createPlan
Creates one or more new Plans based on provided plan parameters. Supports bulk creation in a single request.
**Request body**
Submit a `planParams` array, where each element is a `PlanParameters` object.
```json theme={null}
{
"planParams": [
{ ... },
{ ... }
]
}
```
**Bulk creation**
Provide multiple objects in the `planParams` array to create multiple Plans in one call.
**Verify in application**
The `PlanParameters` field structure is determined by the server-side model. Retrieve the required fields first using [POST /planservice/fetchNewPlanParams](#post-planservicefetchnewplanparams), then submit the populated objects to this endpoint.
***
## Data Flow Diagram
```text theme={null}
Polarion Client / Browser
|
| REST over HTTP
v
+----------------------------+
| PlanningBoardApiServlet |
| (main entry point) |
+----------------------------+
|
+-----------> GET /api/data
| |
| v
| PlanningBoardDataService.getData()
| |
| v
| [ items[] JSON response ]
|
+-----------> POST /api/data (bulk update)
| |
| v
| PlanningBoardDataService.updateItem()
| PlanningBoardDataService.deleteItem()
|
+-----------> POST /capacity
| |
| v
| Sets capacity on Plan in project
|
+-----------> POST /planservice/fetchNewPlanParams
| |
| v
| Returns PlanParameters for new Plan form
|
+-----------> POST /planservice/createPlan
|
v
Creates Plan(s) in Polarion project
```
***
## Admin Interface Properties
The following properties are set by the admin servlet and are relevant when integrating with or extending the Planningboard admin interface. These are not configurable by end users.
| Property | Description |
| -------------- | ----------------------------------------------------------------------------------------------------------------- |
| `productName` | Identifies the product as `PLANNINGBOARD` in all admin interfaces |
| `version` | Runtime version string; the `qualifier` segment is replaced with a timestamp for cache busting after updates |
| `apiBase` | Base URL path for all Planningboard admin API endpoints |
| `libBase` | Base URL path for Planningboard JavaScript and CSS library assets |
| `roleId` | Polarion role identifier required to access Planningboard features; must be granted to users during project setup |
| `docUrl` | External support documentation link displayed in the admin interface |
| `pricingUrl` | External pricing information link shown during license configuration |
| `versionUrl` | Remote endpoint the admin interface queries for the latest available Planningboard version |
| `changelogUrl` | External URL to the Planningboard release changelog, accessible from the admin interface |
**Role assignment**
The `roleId` property defines which Polarion role grants access to Planningboard features. Administrators must assign this role to users during project setup. Refer to [License Installation](/planningboard/getting-started/licensing) for the setup process.
***
## Configuration Example
The following example shows a typical sequence for reading board data and updating a task via the REST API.
**Step 1 — fetch board data**
```text theme={null}
GET /api/data?
```
Response:
```json theme={null}
{
"items": [
{ "id": "WI-100", "title": "Implement login screen", "status": "open" },
{ "id": "WI-101", "title": "Write unit tests", "status": "open" }
]
}
```
**Step 2 — update a task field**
```text theme={null}
POST /api/data
Content-Type: application/x-www-form-urlencoded
ids=WI-100&WI-100_status=in-progress
```
**Step 3 — delete a task**
```text theme={null}
POST /api/data
Content-Type: application/x-www-form-urlencoded
ids=WI-101&WI-101_!nativeeditor_status=deleted
```
**Step 4 — set capacity for a Plan**
```text theme={null}
POST /capacity
Content-Type: application/json
{
"project": "MyProject",
"plan": "sprint-12/Sprint 12",
"capacity": 40
}
```
***
## Related Reference
* [Scripting API](/planningboard/reference/api/scripting-api) — JavaScript scripting interface for board customization
* [Config Script API](/planningboard/reference/api/config-script-api) — Configuration-time scripting hooks
* [Data Script API](/planningboard/reference/api/data-script-api) — Data-layer scripting interface
* [Teams Service API](/planningboard/reference/api/teams-service-api) — Teams service integration endpoints
* [Widget Parameters](/planningboard/reference/widget-parameters/index) — Per-instance board configuration
* [Configuration Properties](/planningboard/reference/configuration-properties/index) — System-wide administration properties
**KB Articles**
* Planningboard: Customizable Statistics and Capacity Indicators
**Source Code**
* `PlanningBoardApiServlet.java`
* `PlanningBoardViewServlet.java`
# Scripting API
Source: https://learn.nextedy.com/planningboard/reference/api/scripting-api
The Nextedy PLANNINGBOARD scripting API is a server-side REST interface embedded in the `PlanningBoardApiServlet`.
## Endpoint Overview
***
## Data Retrieval
### `GET /api/data`
Retrieves all Planningboard data for the current board context, including work items and Plan membership information.
| Parameter | Type | Required | Description |
| ------------------ | ------- | --------------- | ------------------------------------------------------------- |
| (query parameters) | Various | See application | Parameters determine which project and Plan scope is queried. |
**Date format:** All date values in the response use the format `dd-MM-yyyy HH:mm`.
**Response structure:**
```json theme={null}
{
"items": [
{
"id": "",
"": ""
}
]
}
```
The response contains a top-level `items` array. Each element represents a work item (card) with its field values. Field names and their exact keys depend on the board configuration.
**Verify in application**
The complete set of query parameters accepted by `GET /api/data` and the full response schema (all field names, pagination, and filtering behavior) require verification against the live application. The above reflects the confirmed structure from source context only.
***
## Work Item Updates
### `POST /api/data` — Bulk Update
Updates one or more work items in a single request. Items are identified by their task IDs, and each field to update is passed as a separate request parameter.
**Parameter naming convention:** `{taskId}_{fieldName}`
For example, to update the `status` field of work item `WI-42`, pass:
```text theme={null}
WI-42_status=inProgress
```
Multiple work items can be updated in the same request by including parameters for each item.
| Parameter | Type | Description |
| ------------------------------- | ------ | ------------------------------------------------------------------- |
| `ids` | String | Comma-separated list of task IDs to update. Example: `WI-42,WI-43` |
| `{taskId}_{fieldName}` | String | Field value for the named field on the named task. |
| `{taskId}_!nativeeditor_status` | String | Control parameter. Set to `deleted` to delete the item (see below). |
**Example request parameters:**
```text theme={null}
ids=WI-42,WI-43
WI-42_status=inProgress
WI-43_priority=high
```
***
### Work Item Deletion via `_!nativeeditor_status`
To delete a work item, include its ID in the `ids` parameter and set the special control parameter `{taskId}_!nativeeditor_status` to `deleted`.
```text theme={null}
ids=WI-42
WI-42_!nativeeditor_status=deleted
```
**Deletion is permanent**
Deleting a work item via `_!nativeeditor_status=deleted` permanently removes the item. This operation cannot be undone through the API.
***
## Capacity Management
### `POST /capacity`
Sets the capacity value for a specific Plan within a project. Capacity values appear in the [capacity bar](/planningboard/reference/widget-parameters/capacity-parameters) displayed per swimlane.
**Request body (JSON):**
```json theme={null}
{
"project": "",
"plan": "/",
"capacity":
}
```
| Field | Type | Required | Description |
| ---------- | ------ | -------- | ------------------------------------------------------------------------------ |
| `project` | String | Yes | The Polarion project ID. |
| `plan` | String | Yes | Plan identifier in the format `planId/planName`. Both components are required. |
| `capacity` | Number | Yes | The capacity value to set for this Plan. |
**Response:**
Returns a success or error response. The exact structure of the response object requires verification against the live application.
**Verify in application**
The success and error response field names for `POST /capacity` are not fully specified in the available context. Verify the exact response shape against the live application before building integrations.
**Whitespace sensitivity**
Capacity configuration parameters are whitespace-sensitive. Ensure no leading or trailing spaces appear in the `project`, `plan`, or `capacity` field values.
***
## Plan Management
### `POST /planservice/fetchNewPlanParams`
Retrieves the parameters required to create new Plans. Call this endpoint first to obtain valid `planParams` values before calling `createPlan`.
**Request body:** A `parametersRequest` JSON object. The exact structure depends on your board and project configuration.
```json theme={null}
{
"parametersRequest": { }
}
```
**Response:** Returns a plan parameters object for use in the `createPlan` request. The exact fields in the returned parameters depend on your Plan configuration.
**Verify in application**
The fields within `parametersRequest` and the structure of the returned plan parameters object require verification against the live application. These depend on your project's Plan type configuration.
***
### `POST /planservice/createPlan`
Creates one or more new Plans based on the parameters retrieved from `fetchNewPlanParams`. Bulk creation is supported by providing an array of plan parameter objects.
**Request body:**
```json theme={null}
{
"planParams": [
{
"": ""
}
]
}
```
| Field | Type | Required | Description |
| ------------ | ----- | -------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `planParams` | Array | Yes | Array of `PlanParameters` objects. Provide one element per Plan to create. Multiple Plans can be created in a single request. |
**Verify in application**
The individual fields within each `PlanParameters` element depend on the response from `fetchNewPlanParams`. Do not hard-code parameter names without first calling that endpoint for your environment.
***
## License Status
### `POST /planningboard_license`
Returns the current Planningboard license status. Useful for diagnostics or for conditionally enabling features in integrations.
**Response structure (`LicenseResponse`):**
```json theme={null}
{
"isMaintenanceExpired": false,
"status": "",
"message": "",
"email": "",
"product": ""
}
```
| Field | Type | Description |
| ---------------------- | ------- | ---------------------------------------------------------------- |
| `isMaintenanceExpired` | Boolean | `true` if the maintenance period has expired; `false` otherwise. |
| `status` | String | Machine-readable license status code. |
| `message` | String | Human-readable status description. |
| `email` | String | Email address associated with the license registration. |
| `product` | String | Product name as recorded in the license. |
***
## Data Model
The following data model structures are returned or consumed by the API. Field names are as confirmed from source context.
### Item Object
Returned by `GET /api/data` and by the internal `updateItem` service method after a successful update.
| Field | Type | Description |
| ----------------- | ------- | ---------------------------------------------------------------------------------------- |
| `id` | String | The work item identifier. |
| Additional fields | Various | Work item field values. Exact field names depend on the board and project configuration. |
### Data Object
Returned by `GET /api/data`.
| Field | Type | Description |
| ------- | ------------- | ---------------------------------------------------------------- |
| `items` | Array of Item | The list of work items (cards) matching the current board query. |
***
## Configuration Example
The following example illustrates a typical sequence of API calls to update work item planning assignments on the board:
**Step 1 — Retrieve board data**
```text theme={null}
GET /api/data?
```
**Step 2 — Move a card to a new Plan (bulk update)**
```text theme={null}
POST /api/data
Content-Type: application/x-www-form-urlencoded
ids=WI-42
WI-42_planId=SPRINT-7
```
**Step 3 — Set capacity for the target Plan**
```text theme={null}
POST /capacity
Content-Type: application/json
{
"project": "MyProject",
"plan": "SPRINT-7/Sprint 7",
"capacity": 40
}
```
***
## Related Reference
* [Widget Parameters](/planningboard/reference/widget-parameters/index) — per-instance configuration options that control what the board queries and displays
* [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) — widget parameters related to capacity bars and normalization
* [Scripting Properties](/planningboard/reference/configuration-properties/scripting-properties) — server-side configuration properties for scripting behavior
* [Item Script API](/planningboard/reference/api/item-script-api) — scripting API for individual work item operations
* [Config Script API](/planningboard/reference/api/config-script-api) — scripting API for board configuration
* [Data Script API](/planningboard/reference/api/data-script-api) — scripting API for data access and transformation
* [REST API](/planningboard/reference/api/rest-api) — full REST API reference
**KB Articles**
* Planningboard: Customizable Statistics and Capacity Indicators
**Source Code**
* `PlanningBoardApiServlet.java`
# Teams Service API
Source: https://learn.nextedy.com/planningboard/reference/api/teams-service-api
The Teams Service API provides programmatic access to team membership, capacity calculations, and team work item data in Nextedy PLANNINGBOARD.
Enable the Teams Service by setting `useTeamsService = true` in the widget configuration. When active, Teams Service data overrides plan capacity values for swimlanes.
***
## Overview
***
## Configuration Properties
The Teams Service behavior is governed by the following widget and system configuration properties. See [Teams Service Properties](/planningboard/reference/configuration-properties/teams-properties) for full system-level configuration.
### Widget Parameters
| Parameter | Type | Default | Description |
| ------------------- | --------- | ------- | ------------------------------------------------------------------------------------------------------------------------- |
| `useTeamsService` | `boolean` | `false` | Enables integration with the Teams Service. When `true`, team capacity and membership data override plan capacity values. |
| `selectedTeam` | `string` | `None` | ID of the team to use for filtering swimlanes and capacity calculations. Leave empty to show all teams. |
| `userCapacityLoad` | `boolean` | `false` | Enables per-user capacity loading when the Teams Service is active. Requires `useTeamsService = true`. |
| `multiCapacityLoad` | `boolean` | `false` | Enables per-swimlane capacity aggregation across team members. Used together with `useTeamsService`. |
### System Configuration Properties
These properties are set at the Polarion administration level, not per widget instance.
| Property | Type | Default | Description |
| ---------------------------------------- | --------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `nextedy.gantt.calendarHolder` | `string` | `None` | Base user whose calendar is used as a fallback when a team member has no calendar defined. Optional; falls back to system default calendar if absent. |
| `nextedy.gantt.useTeamCapacityModifiers` | `boolean` | `false` | Enables capacity modifier fields (`capModA`, `capModB`) on team work items. When `true`, the team's total capacity is reduced by the modifier percentages. |
| `nextedy.gantt.capacityModifierAField` | `string` | `capModA` | Field name on team work items for the primary capacity modifier percentage (integer, 0–100). Represents a percentage reduction applied to total team capacity. |
| `nextedy.gantt.capacityModifierBField` | `string` | `capModB` | Field name on team work items for the secondary capacity modifier percentage (integer, 0–100). Represents a second independent reduction factor. Only read when `useTeamCapacityModifiers=true`. |
**Whitespace sensitivity**
Capacity configuration property values are whitespace-sensitive. Do not add trailing spaces or extra whitespace around values in `.properties` files.
***
## Teams Data Model
### Team Work Item
Teams are represented as Polarion work items. The Teams Service retrieves and queries these items by project and team ID.
| Field | Description |
| ---------- | ------------------------------------------------------------------------------------------------------------------------ |
| Team ID | The work item ID identifying the team within the project |
| Project ID | The Polarion project containing the team work item |
| `capModA` | Primary capacity modifier percentage (integer 0–100); field name configurable via `nextedy.gantt.capacityModifierAField` |
| `capModB` | Secondary capacity modifier percentage (integer 0–100) |
Teams may exist in a supporting project and be assigned to the current project. The Teams Service automatically remaps team IDs when the team work item originates from a supporting project.
### Team Assignment Work Item
Team membership is defined via team assignment work items. These items carry date range fields used when filtering active members:
| Field | Description |
| ------ | -------------------------------------------------------------------------- |
| `from` | Start date of the team member's assignment (used for date-range filtering) |
| `to` | End date of the team member's assignment (used for date-range filtering) |
Users whose assignment work items cannot be resolved are excluded from results.
***
## Method Reference
### `getTeamItem`
Retrieves the Polarion work item representing a specific team.
| Parameter | Type | Description |
| ----------- | -------- | ------------------------------------------------- |
| `teamId` | `string` | The team's work item ID |
| `projectId` | `string` | The Polarion project ID where the team is defined |
**Returns:** The team work item. Team IDs are automatically remapped if the team exists in a supporting project rather than the project specified.
**Notes:**
* Use this method when you need access to team work item fields, including capacity modifier fields.
* Returns `null` if no matching team is found.
***
### `getTeams`
Retrieves all teams configured for a specific project, including teams from supporting projects that are assigned to this project.
| Parameter | Type | Description |
| ----------- | -------- | -------------------------------- |
| `projectId` | `string` | The Polarion project ID to query |
**Returns:** A collection of team work items.
**Notes:**
* The query includes both teams defined directly in the project and teams in supporting projects that have been assigned to this project.
* Results ordering follows the underlying Polarion query order.
**Verify in application**
Whether archived or inactive teams are included in results has not been confirmed from available source context. Verify against the live application.
***
### `getTeamUserIds` (basic)
Retrieves the collection of user IDs belonging to a team.
| Parameter | Type | Description |
| ----------- | -------- | ----------------------- |
| `teamId` | `string` | The team's work item ID |
| `projectId` | `string` | The Polarion project ID |
**Returns:** A collection of user ID strings for all members of the team.
***
### `getTeamUserIds` (filtered)
Retrieves team user IDs with optional active-only filtering and date range constraints.
| Parameter | Type | Description |
| ------------ | ------------------- | -------------------------------------------------- |
| `teamId` | `string` | The team's work item ID |
| `projectId` | `string` | The Polarion project ID |
| `activeOnly` | `boolean` | When `true`, returns only currently active members |
| `from` | `Date` / `DateOnly` | Start of the date range for membership filtering |
| `to` | `Date` / `DateOnly` | End of the date range for membership filtering |
**Returns:** A filtered collection of user ID strings.
**Notes:**
* Date-range filtering uses the `from` and `to` fields on team assignment work items. A member is included if their assignment overlaps the requested date range.
* When `activeOnly` is `true`, members whose assignment has ended before the request date are excluded.
**Verify in application**
The exact definition of "active" (e.g. whether it checks `to` against today's date vs. the `from`/`to` range) should be verified against the live application.
***
### `getTeamUsers` (basic)
Retrieves full user objects for all team members.
| Parameter | Type | Description |
| ----------- | -------- | ----------------------- |
| `teamId` | `string` | The team's work item ID |
| `projectId` | `string` | The Polarion project ID |
**Returns:** A collection of Polarion `IUser` objects.
**Notes:**
* Users that cannot be resolved from Polarion (e.g. deleted accounts) are excluded from results.
* For large teams, this method resolves full user profile data for each member.
***
### `getTeamUsers` (filtered)
Retrieves full user objects for team members with active-only filtering and date range constraints.
| Parameter | Type | Description |
| ------------ | ------------------- | -------------------------------------------------- |
| `teamId` | `string` | The team's work item ID |
| `projectId` | `string` | The Polarion project ID |
| `activeOnly` | `boolean` | When `true`, returns only currently active members |
| `from` | `Date` / `DateOnly` | Start of the date range for membership filtering |
| `to` | `Date` / `DateOnly` | End of the date range for membership filtering |
**Returns:** A filtered collection of Polarion `IUser` objects. Unresolvable users are excluded.
***
### `getTeamCapacity` (Date variant)
Calculates the total team capacity in work hours for a date range, using `Date` objects (includes time component).
| Parameter | Type | Description |
| ----------- | -------- | ----------------------- |
| `teamId` | `string` | The team's work item ID |
| `projectId` | `string` | The Polarion project ID |
| `from` | `Date` | Start of the date range |
| `to` | `Date` | End of the date range |
**Returns:** Total team capacity as a numeric value in hours.
**Calculation:**
Capacity is computed as the sum of individual user capacities across all team members for the date range:
```text theme={null}
teamCapacity = Σ getUserCapacity(userId, teamId, projectId, from, to)
```
Each user's capacity accounts for:
* Working hours per day (from the user's or fallback calendar)
* Off days and holidays
* The user's assignment percentage within the team
When `nextedy.gantt.useTeamCapacityModifiers = true`, the total is further reduced by the capacity modifier percentages (`capModA`, `capModB`) defined on the team work item.
***
### `getTeamCapacity` (DateOnly variant)
Calculates total team capacity for a date range using `DateOnly` objects (no time component).
| Parameter | Type | Description |
| ----------- | ---------- | -------------------------------------------- |
| `teamId` | `string` | The team's work item ID |
| `projectId` | `string` | The Polarion project ID |
| `from` | `DateOnly` | Start of the date range (date only, no time) |
| `to` | `DateOnly` | End of the date range (date only, no time) |
**Returns:** Total team capacity in hours.
**Notes:**
* Use this variant when the caller works with date-only values (e.g. Plan start/end dates with no time precision).
* Results are equivalent to the `Date` variant for full-day ranges; prefer `DateOnly` when time zone ambiguity could affect boundary calculations.
***
### `getUserCapacity` (Date variant)
Calculates an individual user's capacity within a team for a date range, using `Date` objects.
| Parameter | Type | Description |
| ----------- | -------- | ----------------------- |
| `userId` | `string` | The Polarion user ID |
| `teamId` | `string` | The team's work item ID |
| `projectId` | `string` | The Polarion project ID |
| `from` | `Date` | Start of the date range |
| `to` | `Date` | End of the date range |
**Returns:** The user's available capacity in hours for the given range.
**Calculation:**
```text theme={null}
userCapacity = workingHours(from, to, calendar) × assignmentPercentage
```
* `workingHours` counts working days in the range, excluding off days from the user's calendar (or the fallback `calendarHolder` calendar, or the system default).
* `assignmentPercentage` is the user's allocation percentage within the team assignment work item.
* Users split across multiple teams have their capacity calculated independently per team.
***
### `getUserCapacity` (DateOnly variant)
Calculates an individual user's capacity within a team for a date range, using `DateOnly` objects.
| Parameter | Type | Description |
| ----------- | ---------- | ----------------------- |
| `userId` | `string` | The Polarion user ID |
| `teamId` | `string` | The team's work item ID |
| `projectId` | `string` | The Polarion project ID |
| `from` | `DateOnly` | Start of the date range |
| `to` | `DateOnly` | End of the date range |
**Returns:** The user's available capacity in hours.
**Notes:**
* Functionally equivalent to the `Date` variant for whole-day ranges.
* Preferred when working with Plan date fields that carry no time component.
***
### `getTeamUserCapacities`
Returns a map of all team members' individual capacities for a date range.
| Parameter | Type | Description |
| ----------- | ------------------- | ----------------------- |
| `teamId` | `string` | The team's work item ID |
| `projectId` | `string` | The Polarion project ID |
| `from` | `Date` / `DateOnly` | Start of the date range |
| `to` | `Date` / `DateOnly` | End of the date range |
**Returns:** `Map` — a map where keys are user ID strings and values are individual capacity hours (as floating-point numbers).
**Example structure:**
```json theme={null}
{
"john.smith": 64.0,
"anna.jones": 56.0,
"peter.muller": 48.0
}
```
**Notes:**
* Use this method to display per-member capacity breakdowns alongside the capacity bar.
* Unresolvable users are excluded from the map.
***
## Capacity Calculation Flow
***
## Integration with Widget Configuration
### Enabling Teams Service
```properties theme={null}
useTeamsService = true
selectedTeam = teamWorkItemId
userCapacityLoad = true
```
When `useTeamsService = true`, the Teams Service provides capacity values for the capacity bar in each swimlane, overriding the plan's own capacity field. See [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) for related widget parameters.
### Assignment Mode Interaction
The Teams Service integrates with the **Users (Assignee)** assignment mode (`ASSIGNEE`). When `useTeamsService = true` and `assignmentMode = ASSIGNEE`, swimlanes are populated from team membership rather than all Polarion users. Filtering by `selectedTeam` restricts the displayed swimlanes to members of that team.
See [Assignee Mode](/planningboard/reference/assignment-modes/assignee-mode) for full details on how user swimlanes are populated.
### SAFe Mode Interaction
In the SAFe assignment modes — **Program / Solution Teams (SAFe)** (`SAFE_TEAM`) and **Agile Release Train Teams (SAFe)** (`SAFE_TRAIN_TEAM`) — the Teams Service may be used to retrieve capacity data for SAFe teams. See [SAFe Team Mode](/planningboard/reference/assignment-modes/safe-team-mode) for configuration details.
***
## Configuration Example
The following example configures a Planningboard widget to use the Teams Service for a sprint Planningboard, showing team member swimlanes with per-user capacity.
```properties theme={null}
# Plans
plansMode = PROJECT_PLANS
plansQuery = type:iterationPlan AND status:open
nextPlans = 3
lastPlans = 1
# Swimlanes
assignmentMode = ASSIGNEE
# Teams Service
useTeamsService = true
selectedTeam = TEAM-42
userCapacityLoad = true
capacityLoad = true
hoursPerDay = 8
```
System-level properties (set in Polarion administration):
```properties theme={null}
nextedy.gantt.calendarHolder = john.smith
nextedy.gantt.useTeamCapacityModifiers = true
nextedy.gantt.capacityModifierAField = capModA
```
With this configuration:
* Swimlanes display only members of team `TEAM-42`.
* Each swimlane's capacity bar reflects the user's working hours for the Plan date range, adjusted by their assignment percentage.
* The team's overall capacity is further reduced by the `capModA` modifier field on the `TEAM-42` work item.
* When no user calendar exists, `john.smith`'s calendar is used as the fallback.
***
## Limitations
**Known limitations**
* **No multi-assignee capacity distribution.** Planningboard does not distribute effort across multiple assignees on a single work item. Capacity is attributed to one assignee per work item. This is a known gap compared to Nextedy GANTT.
* **Sub-item effort.** Effort from child work items is not automatically rolled up into a parent item's capacity contribution. Configure `capacityField` or use time-tracking fields directly on the planned work items.
* **Swimlane sort order.** Swimlane sort order is coupled to item sort order; independent swimlane-level sorting is not currently supported.
***
## Related Pages
* [Teams Service Properties](/planningboard/reference/configuration-properties/teams-properties) — system-level configuration properties
* [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) — widget parameters controlling capacity display
* [Assignee Mode](/planningboard/reference/assignment-modes/assignee-mode) — swimlane assignment by user, with Teams Service integration
* [SAFe Team Mode](/planningboard/reference/assignment-modes/safe-team-mode) — SAFe team swimlanes
* [Scripting API](/planningboard/reference/api/scripting-api) — scripting API overview
* [API Reference](/planningboard/reference/api/index) — full API index
**KB Articles**
* Planningboard: Customizable Statistics and Capacity Indicators
**Source Code**
* `PlanningBoardApiServlet.java`
* `PlanningBoardWidgetRenderer.java`
* `PlanningBoardDataService.java`
* `IPlanningBoardTeamsService.java`
* `Config.java`
# Assignee Mode
Source: https://learn.nextedy.com/planningboard/reference/assignment-modes/assignee-mode
**Assignee mode** is a swimlane assignment type that groups work items into horizontal swimlanes by the user assigned to each item.
## Overview
When Assignee mode is active, the board shows one swimlane per user who holds the configured **User Role** in the current project. Work items are placed in the swimlane matching their assignee field. Items whose assignee does not match any displayed swimlane appear in a catch-all **Not Assigned/Other** row.
***
## Widget Parameters
Configure Assignee mode in the **Swimlanes (Rows)** section of the Widget Parameters panel. Set **Assignment Type** to `Users (Assignee)`.
| Parameter | Type | Default | Description |
| ---------------------- | ------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `assignmentMode` | string | `ASSIGNEE` | Activates Assignee mode. Set to `ASSIGNEE` (case-sensitive). |
| `userRole` | string | — | Polarion role ID whose members populate the swimlanes. Example: `project_user`. Only users holding this role in the current project appear as rows. |
| `showEmptySwimlanes` | boolean | `false` | When `true`, displays swimlanes for all matching-role users even if they have no planned work items in the current view. When `false`, empty rows are hidden. |
| `swimlaneSort` | string | `alphabetical` | Sort order for swimlane rows. Value `alphabetical` orders users by display name. Other values depend on the application configuration. |
| `collapsibleSwimlanes` | boolean | `true` | Allows users to collapse and expand individual swimlane rows. Useful when the board has many assignees. |
| `reportLink` | string | — | Optional. URL or report identifier to attach a per-swimlane report link for deeper analysis. |
**User Role is required**
If `userRole` is not set, the board cannot determine which users to display as swimlane rows. Set it to a valid Polarion role ID — for example, `project_user` — to populate the board.
***
## Configuration Properties
The following administration-level configuration properties affect Assignee mode behavior. Set these in **Polarion Administration → Configuration Properties**.
| Property | Type | Default | Description |
| ------------------------------------------------------------ | ------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `nextedy.planningboard.activeTeamAssignmentsInPlanRangeOnly` | boolean | `false` | When `true`, user swimlanes derived from Team Assignments show only users whose Team Assignment overlaps the time range of the currently displayed Plans. Users with assignments entirely outside the shown Plans are hidden; their items move to **Not Assigned/Other**. Available from version **25.12.0**. |
| `nextedy.planningboard.activeTeamAssignmentsOnly` | boolean | `false` | **Deprecated since 25.12.0.** Earlier variant that hid only past Team Assignments regardless of Plan scope. Use `activeTeamAssignmentsInPlanRangeOnly` instead. |
**Deprecated property**
`nextedy.planningboard.activeTeamAssignmentsOnly` was introduced in version 25.3.0 and deprecated in version 25.12.0. Migrate to `nextedy.planningboard.activeTeamAssignmentsInPlanRangeOnly=true` for Plan-range-aware filtering.
***
## Required Data Structure
For Assignee mode to populate swimlanes correctly, the project must meet these requirements:
* At least one Polarion role must be assigned to the relevant users (e.g. `project_user`).
* Work items must have an assignee field set to a user who holds the configured role.
* When using Team Assignments for Plan-range filtering (`activeTeamAssignmentsInPlanRangeOnly=true`), the project must have configured Teams and Team Assignments.
***
## How Swimlane Population Works
1. The board reads all users who hold the role specified in `userRole`.
2. One swimlane row is created per matching user.
3. Each work item is placed in the swimlane whose user matches the item's assignee.
4. Items with an assignee not present in the user list (or with no assignee) go to **Not Assigned/Other**.
***
## Teams Service Integration
When `useTeamsService=true` is set on the widget, Assignee mode integrates with the Polarion Teams Service:
* Team membership data is sourced from the Teams Service rather than solely from role membership.
* Per-user capacity values come from the Teams Service, enabling the capacity bar to reflect actual user capacity.
* The `selectedTeam` widget parameter filters swimlanes to members of a specific team.
See [Swimlanes (Rows) Parameters](/planningboard/reference/widget-parameters/swimlanes-parameters) and [Teams Service Properties](/planningboard/reference/configuration-properties/teams-properties) for related configuration.
***
## Drag-and-Drop Behavior
* Dragging a card from the **Unplanned** sidebar to a swimlane row assigns the work item to that row's user and plans it into the target column (Plan).
* Dropping a card on a different swimlane row reassigns the work item's assignee to that row's user.
* Holding **Alt** while dragging creates a duplicate assignment: the item is added to the target user in addition to the original assignee (comma-separated assignee list). Duplicating to the **Not Assigned/Other** swimlane is not supported.
* Cards with status **Verified** cannot be moved or unplanned.
***
## Capacity Bar
When `capacityLoad=true` is enabled, each swimlane displays a capacity bar showing planned effort against available capacity. In Assignee mode:
* Column-level capacity bars aggregate effort for all items in that Plan column.
* When `userCapacityLoad=true` and the Teams Service is active, capacity bars reflect per-user available capacity sourced from Team Assignments.
* Hovering over a capacity bar shows a detailed tooltip (requires capacity configuration via widget parameters).
See [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) for the full set of capacity configuration options.
***
## Filtering Plan-Range Active Users
When your project uses Team Assignments and you want swimlanes to reflect only users active during the displayed Plans:
```properties theme={null}
nextedy.planningboard.activeTeamAssignmentsInPlanRangeOnly=true
```
**Effect:** users whose Team Assignments fall entirely outside the date range of the currently shown Plans are hidden from the board. Their work items are moved to **Not Assigned/Other**.
**Required setup:**
* Project has configured Teams and Team Assignments.
* Nextedy PLANNINGBOARD is configured with user-based swimlanes derived from Team Assignments.
* Property set under Polarion Administration → Configuration Properties.
**Property not applying?**
If the property does not take effect after saving, make any minor change in Configuration Properties and save again to force a refresh.
***
## Configuration Example
The following example configures a Planningboard widget with Assignee mode using the `project_user` role, with empty swimlanes hidden and collapsible rows enabled.
**Widget Parameters (Swimlanes section):**
```properties theme={null}
assignmentMode=ASSIGNEE
userRole=project_user
showEmptySwimlanes=false
collapsibleSwimlanes=true
swimlaneSort=alphabetical
```
**Configuration Properties (for Plan-range filtering, optional):**
```properties theme={null}
nextedy.planningboard.activeTeamAssignmentsInPlanRangeOnly=true
```
**Scenario:** A project has two users — Alex Seller and Carl User — both with the `project_user` role. The board displays one swimlane per user. A third user, Mark Test, has no Team Assignment within the shown Plans' time range; with `activeTeamAssignmentsInPlanRangeOnly=true` enabled, Mark Test's swimlane is hidden and any items assigned to him appear in **Not Assigned/Other**.
***
## Limitations
* **No multi-assignee capacity distribution.** When a work item has multiple assignees, its effort is not distributed across multiple swimlanes. The capacity calculation does not split effort proportionally between co-assignees.
* **Swimlane sort order is coupled to item sort order.** Changing the swimlane sort may affect the item sort order within cells.
* Assignee mode sources users from the current project's role membership. Cross-project user lists require the [Project Mode](/planningboard/reference/assignment-modes/project-mode) or a SAFe assignment type.
* Team Assignment-based Plan-range filtering (`activeTeamAssignmentsInPlanRangeOnly`) requires version **25.12.0** or later.
***
## Related Pages
* [Assignment Modes](/planningboard/reference/assignment-modes/index) — overview of all available swimlane assignment types
* [Swimlanes (Rows) Parameters](/planningboard/reference/widget-parameters/swimlanes-parameters) — full widget parameter reference for swimlane configuration
* [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) — configure capacity bars and effort tracking
* [Teams Service Properties](/planningboard/reference/configuration-properties/teams-properties) — Teams Service integration properties
* [Parent Item Mode](/planningboard/reference/assignment-modes/parent-mode) — swimlanes grouped by parent work item instead of assignee
* [Enumeration Field Mode](/planningboard/reference/assignment-modes/enum-mode) — swimlanes grouped by a custom enumeration field
* [Project Mode](/planningboard/reference/assignment-modes/project-mode) — swimlanes grouped by sub-project
**KB Articles**
* Swimlane Assignment Types
* Filter user swimlanes by Plan range
* Planningboard interface & basic interactions
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
**Source Code**
* `PlanningBoardWidgetRenderer.java`
* `PlanningBoardDataService.java`
* `PlansMode.java`
* `PlanningBoardWidget.java`
* `AssignmentMode.java`
# Enumeration Field Mode
Source: https://learn.nextedy.com/planningboard/reference/assignment-modes/enum-mode
Enumeration Field mode groups work items into swimlanes based on the values of a Polarion enumeration custom field.
This page is a reference for the parameters, supported field types, filtering options, and known limitations of the Enumeration Field assignment mode.
For an overview of all available swimlane assignment types, see [Assignment Modes](/planningboard/reference/assignment-modes/index).
***
## How It Works
When `assignmentMode` is set to `ENUM`, Nextedy PLANNINGBOARD reads the configured enumeration field on each work item and places the card in the swimlane that corresponds to that field's value. Work items whose field is empty or whose value is not included in the rows filter are placed in the **Not Assigned / Other** swimlane at the bottom of the board.
When a work item has a **multi-value** enumeration field (list type), the card can appear in multiple swimlanes simultaneously — one per value held by that field.
***
## Widget Parameters
Configure Enumeration Field mode in the **Swimlanes (Rows)** section of the Widget Parameters panel.
### Core Parameters
| Name | Type | Default | Description |
| ---------------- | ------ | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `assignmentMode` | string | `ASSIGNEE` | Set to `ENUM` to enable Enumeration Field mode. |
| `enumFieldId` | string | — | **Required.** The field ID of the Polarion enumeration custom field to use for swimlane grouping. Example: `team`, `component`, `severity`. Must match the exact field ID as configured in Polarion. |
### Row Visibility
| Name | Type | Default | Description |
| -------------------- | ------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `showEmptySwimlanes` | boolean | `false` | When `true`, swimlanes with no work items are shown. When `false` (default), only swimlanes that contain at least one card are rendered. |
| `swimlaneSort` | string | `alphabetical` | Sort order for swimlane rows. Applies to Enumeration Field mode. |
### Row Filtering
| Name | Type | Default | Description |
| ------------ | -------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `rowsFilter` | multi-value selector | (all values) | Limits which enumeration values appear as swimlane rows. When no values are selected, all values from the field's enumeration are shown. When one or more values are selected, only those values appear as rows. Configured via the **Rows Filter** dialog in the Widget Parameters panel. |
### Optional
| Name | Type | Default | Description |
| ------------ | ------ | ------- | ------------------------------------------------------------------------------------------------------------------- |
| `reportLink` | string | — | Optionally attach a Polarion report URL. The link is surfaced per swimlane for deeper analysis of that field value. |
***
## Supported Field Types
Planningboard supports the following Polarion field types for Enumeration Field mode:
| Field Type | Supported | Notes |
| --------------------------------------------------- | --------- | ----------------------------------------------------------------------------- |
| Single-value enumeration (`IEnumType`) | Yes | Each card appears in exactly one swimlane. |
| Multi-value enumeration (list of `IEnumType` items) | Yes | A card with multiple values appears in each matching swimlane simultaneously. |
| `status` field | **No** | Not supported as a swimlane grouping field. |
| `resolution` field | **No** | Not supported as a swimlane grouping field. |
| `type` (work item type) field | **No** | Not supported as a swimlane grouping field. |
| Free-text or numeric fields | **No** | Only enumeration-typed fields are valid. |
**Global enumeration fields — known limitation**
Global enumeration custom fields (defined at the global Polarion administration level rather than per project) are not reliably supported for swimlane grouping. A global field may appear to validate correctly during initial widget configuration but fail post-save with the error **"field does not exist or is not of type enumeration"**.
**Workaround:** Use project-specific enumeration custom fields. If you require a global enum field, contact Nextedy support.
**Multi-value enum swimlanes**
Full support for multi-value (multi-select) enumeration fields as swimlane sources was under active development as of early 2026. If you encounter issues with multi-enum swimlanes, verify you are running a current release and contact support.
***
## Rows Filter
The **Rows Filter** lets you restrict which enumeration values are displayed as swimlane rows, without modifying the field definition in Polarion.
**Behaviour:**
* An **empty filter** (no values selected) shows all values from the enumeration — every option defined on the field for the current work item type appears as a swimlane row.
* A **populated filter** shows only the selected values. Values not in the filter are hidden; work items whose field holds a hidden value are placed in the **Not Assigned / Other** swimlane.
* Available enum values in the Rows Filter dialog reflect the **selected work item type** on the board. Different work item types may define different option sets for the same field ID.
**How to configure:**
1. Open the Widget Parameters panel and navigate to **Swimlanes (Rows)**.
2. Set **Assignment Type** to **Enumeration Field**.
3. Enter the **Field ID** of your enumeration field.
4. Click the **Rows Filter** selector to open the multi-value dialog.
5. Select the values you want to appear as rows and confirm.
***
## Configuration Example
The following example configures a Planningboard to display swimlanes grouped by a project-level `team` enumeration field, showing only two specific teams and hiding empty rows.
**Widget Parameters — Swimlanes (Rows) section:**
```properties theme={null}
assignmentMode=ENUM
enumFieldId=team
showEmptySwimlanes=false
swimlaneSort=alphabetical
```
**Rows Filter selection:** `Team Alpha`, `Team Beta`
In this configuration:
* Work items with `team=Team Alpha` appear in the **Team Alpha** swimlane.
* Work items with `team=Team Beta` appear in the **Team Beta** swimlane.
* Work items with any other team value, or no team value, appear in **Not Assigned / Other**.
* Empty swimlanes are hidden — if no items are planned for a team in the visible Plans, that row does not render.
***
## Drag-and-Drop Assignment
When a user drags a card from one swimlane to another in Enumeration Field mode, Planningboard updates the enumeration field on the work item to the value corresponding to the target swimlane. This write-back happens immediately on drop.
**Restrictions:**
* Dragging a card to the **Not Assigned / Other** swimlane clears the field value on the work item (sets it to empty).
* In read-only mode, drag-and-drop is disabled and field values cannot be changed from the board.
* In prioritize mode, drag-and-drop is also blocked.
**Multi-value field drag-and-drop**
When using a multi-value enumeration field, dragging a card between swimlanes appends or removes individual values rather than replacing the entire field. Verify the resulting field state in Polarion after moving items with multiple values.
***
## Swimlane Sort Order
The `swimlaneSort` parameter controls the vertical order of swimlane rows when using Enumeration Field mode.
| Value | Behaviour |
| ------------------------ | --------------------------------------------------------------------------- |
| `alphabetical` (default) | Swimlane rows are sorted A–Z by the display label of the enumeration value. |
**Verify in application**
Additional sort options (e.g., by enumeration option order as defined in Polarion, or custom ordering) may be available. Verify against the running application for the current option set.
***
## Capacity in Enumeration Field Mode
Capacity bars and capacity load work with Enumeration Field mode in the same way as other assignment modes. Each swimlane row shows a capacity bar reflecting the total effort of cards assigned to that row across the visible Plans.
When a work item appears in multiple swimlanes (multi-value field), its effort is counted in each swimlane it appears in. This can result in effort being counted more than once across the board total.
See [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) for capacity configuration details.
***
## Limitations
| Limitation | Details |
| ----------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| Global enumeration custom fields | Not reliably supported. Use project-specific fields. See the warning above. |
| `status`, `resolution`, and `type` fields | Cannot be used as the swimlane grouping field. |
| Multi-enum swimlane support | Was under active development as of early 2026; verify support in your installed version. |
| Capacity double-counting | When a multi-value field places a card in multiple swimlanes, effort is counted per swimlane — not de-duplicated at board level. |
| Swimlane sort is coupled to item sort | The vertical order of swimlanes and the order of items within swimlanes share the same underlying sort mechanism; configuring one affects the other. |
| Custom-enum card coloring | Card coloring based on enumeration values may have parity gaps compared to other Nextedy board products. |
***
## Troubleshooting
### "Field does not exist or is not of type enumeration" after saving
**Cause:** The configured `enumFieldId` either does not exist in the project, is not an enumeration type, or is a global field that is not supported in this context.
**Steps:**
1. Verify the field ID is spelled exactly as defined in Polarion Administration → Custom Fields for the relevant work item type.
2. Confirm the field type is **Enumeration** (single or multi-value list), not text or numeric.
3. If using a global field, switch to a project-level enumeration field instead.
4. After correcting the field ID, save the widget configuration. If the error persists, rebuild the widget configuration: remove the swimlane configuration, save, re-add it with the correct field ID, and save again.
### Rows Filter shows no options
**Cause:** The enumeration field has no values defined for the currently selected work item type, or the field ID is incorrect.
**Steps:**
1. Confirm the **Field ID** is correct and the field is associated with the work item type shown on the board.
2. Check that the enumeration has at least one option defined in Polarion Administration for that work item type.
3. Change the work item type selector on the board to the type that has the field configured, then re-open the Rows Filter dialog.
### Cards appear in "Not Assigned / Other" unexpectedly
**Cause:** The field value on the work item is empty, or the value is excluded by the Rows Filter.
**Steps:**
1. Open the work item in Polarion and confirm the enumeration field has a value set.
2. Check the Rows Filter in the widget configuration — if specific values are selected, items with other values are routed to Not Assigned / Other.
3. Clear the Rows Filter (deselect all values) to show all enum values as rows, and verify where items land.
***
## Related Pages
* [Assignment Modes](/planningboard/reference/assignment-modes/index) — overview of all swimlane assignment types
* [Assignee Mode](/planningboard/reference/assignment-modes/assignee-mode) — swimlanes by user/assignee
* [Parent Item Mode](/planningboard/reference/assignment-modes/parent-mode) — swimlanes by parent work item
* [Project Mode](/planningboard/reference/assignment-modes/project-mode) — swimlanes by sub-project
* [Swimlanes (Rows) Parameters](/planningboard/reference/widget-parameters/swimlanes-parameters) — full swimlane widget parameter reference
* [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) — capacity bar configuration
**KB Articles**
* Swimlane Assignment Types
* Filter user swimlanes by Plan range
* What is 'Normalization'
**Support Tickets**
* [#6777](https://support.nextedy.com/helpdesk/tickets/6777)
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#6734](https://support.nextedy.com/helpdesk/tickets/6734)
**Source Code**
* `PlanningBoardWidgetRenderer.java`
* `PlansMode.java`
* `PlanningBoardDataService.java`
* `PlanningBoardWidgetDependenciesProcessor.java`
* `planningboard.js`
# Assignment Modes
Source: https://learn.nextedy.com/planningboard/reference/assignment-modes/index
**Assignment modes** control how Nextedy PLANNINGBOARD groups work items into swimlanes.
**Swimlane assignment type**
The term **swimlane assignment type** refers to the mode setting that determines which attribute maps a work item to a swimlane row. It is configured via the `assignmentMode` widget parameter on the [Swimlanes (Rows) Parameters](/planningboard/reference/widget-parameters/swimlanes-parameters) page.
## Standard Modes
**[Assignee Mode](/planningboard/reference/assignment-modes/assignee-mode)** — Each swimlane represents a user (assignee). Work items are grouped by the person they are assigned to. Supports capacity tracking per person.
**[Parent Item Mode](/planningboard/reference/assignment-modes/parent-mode)** — Each swimlane represents a parent work item. Child work items are grouped under their parent, enabling a feature- or epic-level board view.
**[Enumeration Field Mode](/planningboard/reference/assignment-modes/enum-mode)** — Each swimlane represents a value of a configurable enumeration field on the work item. Suitable for grouping by team, component, priority class, or any other enum-typed custom field.
**[Project Mode](/planningboard/reference/assignment-modes/project-mode)** — Each swimlane represents a Polarion project. Work items are grouped by the project they belong to, useful for multi-project boards.
**[No Swimlanes Mode](/planningboard/reference/assignment-modes/no-swimlanes-mode)** — All work items appear in a single flat board with no row grouping. Use when swimlane separation is not needed.
## SAFe Modes
These modes are specific to Scaled Agile Framework (SAFe) configurations. They require the SAFe structure (Agile Teams, Release Trains, Programs) to be present in Polarion.
**[SAFe Team Mode](/planningboard/reference/assignment-modes/safe-team-mode)** — Each swimlane represents a SAFe Agile Team. Work items are grouped by their assigned Agile Team.
**[SAFe Train Team Mode](/planningboard/reference/assignment-modes/safe-train-team-mode)** — Each swimlane represents a SAFe Release Train team combination. Groups work items at the Agile Release Train level.
**[SAFe Programs Mode](/planningboard/reference/assignment-modes/safe-programs-mode)** — Each swimlane represents a SAFe Program (ART). Groups work items by their Program-level assignment.
## Choosing a Mode
| Goal | Recommended Mode |
| -------------------------------------------------- | -------------------------------------------------------------------------------------- |
| Track per-person capacity and workload | [Assignee Mode](/planningboard/reference/assignment-modes/assignee-mode) |
| Organize board by feature or epic | [Parent Item Mode](/planningboard/reference/assignment-modes/parent-mode) |
| Group by team, component, or custom attribute | [Enumeration Field Mode](/planningboard/reference/assignment-modes/enum-mode) |
| Consolidate work across multiple Polarion projects | [Project Mode](/planningboard/reference/assignment-modes/project-mode) |
| Simple flat board without row grouping | [No Swimlanes Mode](/planningboard/reference/assignment-modes/no-swimlanes-mode) |
| SAFe Agile Team-level planning | [SAFe Team Mode](/planningboard/reference/assignment-modes/safe-team-mode) |
| SAFe Release Train planning | [SAFe Train Team Mode](/planningboard/reference/assignment-modes/safe-train-team-mode) |
| SAFe Program Increment planning | [SAFe Programs Mode](/planningboard/reference/assignment-modes/safe-programs-mode) |
**KB Articles**
* Swimlane Assignment Types
* Filter user swimlanes by Plan range
* What is 'Normalization'
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#6777](https://support.nextedy.com/helpdesk/tickets/6777)
**Source Code**
* `PlanningBoardWidgetRenderer.java`
* `PlanningBoardDataService.java`
* `PlansMode.java`
* `AssignmentMode.java`
* `PlanningBoardWidgetDependenciesProcessor.java`
# No Swimlanes Mode
Source: https://learn.nextedy.com/planningboard/reference/assignment-modes/no-swimlanes-mode
**No Swimlanes** is the `NONE` assignment mode for Nextedy PLANNINGBOARD swimlanes.
This mode is the simplest possible board layout. It is controlled by the `assignmentMode` widget parameter.
***
## Parameters
### Swimlanes (Rows) Parameters
| Parameter | Type | Default | Description |
| ---------------- | ------ | ---------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `assignmentMode` | string | `ASSIGNEE` | Set to `none` to activate No Swimlanes mode. All other assignment-mode parameters are hidden and ignored when this value is set. |
When `assignmentMode` is set to `none`, the following swimlane parameters become inactive and their values are not evaluated by the board:
| Parameter | Status in No Swimlanes mode |
| ---------------------- | --------------------------- |
| `enumFieldId` | Ignored |
| `parentWorkItemType` | Ignored |
| `showEmptySwimlanes` | Ignored |
| `swimlaneSort` | Ignored |
| `collapsibleSwimlanes` | Ignored |
| `safeProgramField` | Ignored |
| `safeTeamField` | Ignored |
> See [Swimlanes (Rows) Parameters](/planningboard/reference/widget-parameters/swimlanes-parameters) for the full parameter reference for all assignment modes.
***
## Behavior
### Board Layout
In No Swimlanes mode the board displays a single undivided content area spanning the full board height. Work items appear as cards in their assigned Plan columns without any row segmentation. The board still shows Plan columns (governed by the [Plans (Columns) Parameters](/planningboard/reference/widget-parameters/plans-parameters)) and the [Unplanned Sidebar](/planningboard/reference/ui-elements/sidebar) when enabled.
### Resource Assignment
Because there are no swimlanes, no resource field is written when a card is dragged between columns. Moving a card from one Plan column to another updates only the work item's Plan membership — the assignee, parent, enumeration field, or any other field that the other assignment modes write is **not changed**.
### Capacity Bars
Per-swimlane capacity bars are not rendered in this mode. The `capacityLoad` and `multiCapacityLoad` parameters remain functional for total Plan-level capacity display if configured, but there is no per-row capacity breakdown.
### Drag and Drop
Drag and drop operates across Plan columns as normal. Cards can be moved freely between Plan columns, and within a column cards can be reordered to express priority. Because there are no swimlane rows, drag targets are the Plan column areas only — there is no row constraint.
**Parent Item mode enforces row placement**
In [Parent Item Mode](/planningboard/reference/assignment-modes/parent-mode), dragging a card to the wrong parent's swimlane causes the board to automatically reposition the card to the correct row. No Swimlanes mode has no such constraint — cards move freely to any column.
### Sort Order
Work items within each Plan column follow the sort order defined in the Work Items widget parameters (`sortField`, `sortOrder`). See [Work Items Parameters](/planningboard/reference/widget-parameters/work-items-parameters).
***
## Widget Parameters Visibility
The Planningboard widget parameter panel dynamically hides swimlane-specific fields when `assignmentMode` is set to `none`. The following configuration sections are not shown:
* **User Role** (shown only for Assignee mode)
* **Resource Field** / **Field ID** (shown only for Enumeration Field mode)
* **Selected Rows** / **Rows Filter** (shown only for Enumeration Field mode)
* **Parent Role** / **Parent Query** / **Sort By** (shown only for Parent Item mode)
* **ART ID** (shown only for SAFe Train Team mode)
This is controlled by `PlanningBoardWidgetDependenciesProcessor`, which hides irrelevant fields based on the selected assignment mode. No additional manual steps are required to hide them.
***
## Configuration Example
The following widget parameter snippet activates No Swimlanes mode. The board will show work items of type `task` spread across the five nearest upcoming Plans, with no row grouping.
```properties theme={null}
assignmentMode=none
plansMode=PROJECT_PLANS
nextPlans=5
lastPlans=1
query=type:task
```
In the widget editor, navigate to **Swimlanes (Rows)** and set **Assignment Type** to **No Swimlanes**. The remaining fields in the Swimlanes section collapse automatically.
***
## Board Layout Diagram
***
## When to Use
No Swimlanes mode is suited for the following scenarios:
| Scenario | Why No Swimlanes fits |
| ---------------------------------------------------------- | ------------------------------------------------------------------------ |
| High-level roadmap or release overview | Focus on which Plan items fall into rather than who owns them |
| Quick backlog triage across Plans | Single view reduces visual noise; fast drag-and-drop to Plans |
| Board where items lack a consistent assignee or team field | No swimlane grouping means no empty-lane clutter |
| Portfolio-level views with many items | Simplifies the layout when per-assignee breakdown adds no planning value |
| Demonstration or onboarding boards | Simplest layout for teaching Planningboard basics |
**Combine with a focused work-item query**
In No Swimlanes mode, all items share a single vertical space per column. Use the `query` parameter (for example `type:feature AND priority:high`) to keep card counts manageable and the board readable.
***
## Limitations
* **No per-lane capacity tracking.** Capacity bars show totals per Plan column only. Per-assignee, per-team, or per-parent capacity breakdowns require a different assignment mode.
* **No resource write on drag.** Moving a card between columns does not update any assignment field. If you need drag-and-drop to also reassign work items, select [Assignee Mode](/planningboard/reference/assignment-modes/assignee-mode), [Enumeration Field Mode](/planningboard/reference/assignment-modes/enum-mode), or another mode that writes a field on drop.
* **No swimlane-based filtering.** The "Rows Filter" and user-role filter capabilities of other modes are unavailable. Filtering must be achieved through the work-item `query` parameter instead.
***
## Related Pages
* [Assignment Modes](/planningboard/reference/assignment-modes/index) — overview of all assignment modes and how to choose between them
* [Assignee Mode](/planningboard/reference/assignment-modes/assignee-mode) — swimlanes grouped by user (assignee)
* [Enumeration Field Mode](/planningboard/reference/assignment-modes/enum-mode) — swimlanes grouped by a custom enumeration field
* [Parent Item Mode](/planningboard/reference/assignment-modes/parent-mode) — swimlanes grouped by parent work items
* [Project Mode](/planningboard/reference/assignment-modes/project-mode) — swimlanes grouped by sub-project
* [Swimlanes (Rows) Parameters](/planningboard/reference/widget-parameters/swimlanes-parameters) — full parameter reference for swimlane configuration
* [Work Items Parameters](/planningboard/reference/widget-parameters/work-items-parameters) — query and sort parameters that govern card content in all modes
**KB Articles**
* Swimlane Assignment Types
* Filter user swimlanes by Plan range
* What is 'Normalization'
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#6777](https://support.nextedy.com/helpdesk/tickets/6777)
* [#6734](https://support.nextedy.com/helpdesk/tickets/6734)
**Source Code**
* `PlanningBoardWidgetRenderer.java`
* `PlanningBoardWidgetDependenciesProcessor.java`
* `PlanningBoardWidget.java`
* `PlanningBoardDataService.java`
* `AssignmentMode.java`
# Parent Item Mode
Source: https://learn.nextedy.com/planningboard/reference/assignment-modes/parent-mode
**Parent Item Mode** is a swimlane assignment type that groups work items into horizontal swimlanes by their parent work item.
This mode is one of the eight assignment modes available in Nextedy PLANNINGBOARD. See [Assignment Modes](/planningboard/reference/assignment-modes/index) for a full comparison.
***
## Overview
**Key behaviour:** When Parent Item Mode is active, Planningboard resolves each work item's parent via the configured link role and places the card into the swimlane belonging to that parent. If you drag a card to the wrong swimlane, Planningboard automatically moves it back to the correct parent's row. You cannot freely choose a swimlane — the parent relationship is enforced.
**Plan normalization not supported**
Parent Item Mode does **not** support plan normalization (`planCellsMode`). Capacity normalization across plan columns is unavailable when this assignment mode is selected.
***
## Widget Parameters
Configure Parent Item Mode in the **Widget Parameters** panel under **Swimlanes (Rows)**.
| Parameter | Type | Default | Description |
| ---------------- | --------------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `assignmentMode` | enum | — | Set to `PARENT` to activate this mode. |
| `swimlaneSort` | enum | See application | Determines the vertical order of parent swimlanes on the board. See [Swimlane Sort Order](#swimlane-sort-order) below. |
| `parentRole` | string | — | The Polarion link role that connects child work items to their parent (e.g., `implements`). Must be a valid link role ID in your project. |
| `parentQuery` | string (Lucene) | — | Optional Lucene query to filter which parent items appear as swimlanes. When empty, all parents reachable via the configured link role are shown. |
| `filterParents` | string | `No` | When set to `Yes`, restricts the visible swimlanes to parents matched by `parentQuery`. When `No`, all parents with linked items are shown. |
| `reportLink` | string (URL template) | — | Optional URL opened when clicking a swimlane label. May contain template variables referencing the parent work item. |
### Swimlane Sort Order
The `swimlaneSort` parameter controls the vertical ordering of parent swimlanes. Available options depend on your Planningboard version and project configuration.
**Verify in application**
The exact enumeration values for `swimlaneSort` in Parent Item Mode are documented in the separate KB article [Sorting of Swimlanes (Parent Item Assignment Type)](https://support.nextedy.com/support/solutions/articles/48001277117-sorting-of-swimlanes-parent-item-assignment-type-). Confirm available options in your installation.
***
## Assignment Mode Properties
The following properties from `AssignmentMode` apply when Parent Item Mode is active.
| Property | Type | Default | Description |
| ---------------------- | ------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `assignmentMode` | string | `ASSIGNEE` | Set to `PARENT` to enable Parent Item Mode. |
| `showEmptySwimlanes` | boolean | `false` | When `true`, swimlanes for parent items with no child work items are still rendered on the board. When `false`, empty parent swimlanes are hidden. |
| `swimlaneSort` | string | `alphabetical` | Sort order applied to parent swimlanes. Controls vertical ordering of lanes. |
| `collapsibleSwimlanes` | boolean | `true` | Allows users to collapse and expand individual swimlanes. Useful when the board has many parent items. |
The `parentWorkItemType` property (from `AssignmentMode`) can filter parent items by work item type. When set, only parent items of the specified type are loaded as swimlanes.
***
## Drag-and-Drop Behaviour
Parent Item Mode enforces the parent–child relationship during drag-and-drop operations.
| Action | Behaviour |
| -------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Drag a card to the correct parent's swimlane | Card is dropped and planned into that Plan column. |
| Drag a card to a different parent's swimlane | Card is automatically moved back to the swimlane of its actual parent. The incorrect placement is not persisted. |
| Drag a card from the Unplanned section | Card is placed under the swimlane matching its configured parent item. |
| Alt+drag a card | Creates a duplicate assignment to another resource. This interaction is available in compatible modes; verify behaviour in Parent Item Mode in your installation. |
**Swimlane is determined by the parent link — not by drop target**
Unlike [Assignee Mode](/planningboard/reference/assignment-modes/assignee-mode) or [Enumeration Field Mode](/planningboard/reference/assignment-modes/enum-mode), you cannot freely reassign a work item to a different swimlane by dragging. The parent link on the work item determines its swimlane. To move a card to a different parent's swimlane, update the parent link role on the work item directly in Polarion.
***
## Limitations
* **Plan normalization** (`planCellsMode`) is **not supported** in Parent Item Mode. Capacity bars will not reflect normalized values across plan columns.
* Parent swimlanes are derived from the link role configured in `parentRole`. Work items with no matching parent link are not displayed unless the board is configured to show unlinked items separately.
* The swimlane sort order is coupled to the item sort order in this mode — see the Planningboard generation guidance for details on this known constraint.
***
## Configuration Example
The following example configures the **Swimlanes (Rows)** section of the widget to use Parent Item Mode, grouping User Stories by their parent Feature via the `implements` link role. Only Features matching a Lucene query are shown as swimlanes.
**Widget Parameters — Swimlanes (Rows):**
```properties theme={null}
# Assignment Type
Assignment Type = Parent Item
# Link role connecting User Stories to Features
Parent Role = implements
# Lucene query: only show Features from the current release
Parent Query = type:feature AND linkedWorkItems.role:implements
# Show only the Features matched by the query
Filter Parents = Yes
# Report link: open a Feature details report when clicking the swimlane label
Report Link = /polarion/#/project/${r.objectId.projectId}/wiki/FEATURE_REPORT?feature=${r.objectId.itemId}
```
**Result:** The board renders one swimlane per Feature returned by the query. Each swimlane contains the User Story cards linked to that Feature via the `implements` role. Dragging a User Story to a Feature swimlane it does not belong to causes the card to snap back to its correct parent's row.
**Parent Query syntax**
The `Parent Query` field uses standard Polarion Lucene query syntax. Combine field filters to narrow which parent items appear — for example, `type:feature AND status:open` to show only open Features.
***
## Related Pages
* [Assignment Modes](/planningboard/reference/assignment-modes/index) — Overview and comparison of all assignment modes
* [Assignee Mode](/planningboard/reference/assignment-modes/assignee-mode) — Groups swimlanes by user (assignee)
* [Enumeration Field Mode](/planningboard/reference/assignment-modes/enum-mode) — Groups swimlanes by a custom enumeration field value
* [Project Mode](/planningboard/reference/assignment-modes/project-mode) — Groups swimlanes by sub-project
* [Swimlanes (Rows) Parameters](/planningboard/reference/widget-parameters/swimlanes-parameters) — Full widget parameter reference for swimlane configuration
* [Work Items Parameters](/planningboard/reference/widget-parameters/work-items-parameters) — Configuring which work items appear on the board
**KB Articles**
* Swimlane Assignment Types
* Planningboard interface & basic interactions
* Planningboard Widget Parameters
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
**Source Code**
* `PlanningBoardWidgetRenderer.java`
* `PlanningBoardDataService.java`
* `PlansMode.java`
* `PlanningBoardWidgetDependenciesProcessor.java`
* `planningboard.js`
# Project Mode
Source: https://learn.nextedy.com/planningboard/reference/assignment-modes/project-mode
**Project Mode** is a swimlane assignment type for Nextedy PLANNINGBOARD that groups work items into horizontal swimlanes based on the sub-projects within the current project group.
See [Assignment Modes](/planningboard/reference/assignment-modes/index) for an overview of all available swimlane assignment types.
***
## Overview
When `assignmentMode` is set to **Project** (`PROJECT`), the board automatically discovers the sub-projects of the current Polarion project group and renders one swimlane per sub-project. Only sub-projects the current user can read are included; the current project itself is excluded from the swimlane list.
This mode is suited to teams or program managers who need to plan and track work across multiple projects simultaneously — for example, a program-level Planningboard spanning several team projects.
***
## Widget Parameters
Configure Project Mode in the **Widget Parameters** panel under **Swimlanes (Rows)** → **Assignment Type**.
### Assignment Mode Parameter
| Parameter | Type | Default | Description |
| ---------------- | -------- | ---------- | ------------------------------------------------------------------------------------------------ |
| `assignmentMode` | `string` | `ASSIGNEE` | Set to `PROJECT` to enable Project Mode. Controls how work items are grouped into swimlane rows. |
### Swimlane Display Parameters
The following parameters apply when `assignmentMode = PROJECT`.
| Parameter | Type | Default | Description |
| ---------------------- | --------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `showEmptySwimlanes` | `boolean` | `false` | When `true`, sub-project swimlanes are displayed even if they contain no planned work items. When `false`, empty swimlane rows are hidden. |
| `collapsibleSwimlanes` | `boolean` | `true` | Allows users to collapse and expand individual swimlane rows to manage board complexity. |
| `swimlaneSort` | `string` | `alphabetical` | Determines the vertical order of swimlanes. Controls how sub-project rows are sorted on the board. |
### Optional Report Link
| Parameter | Type | Default | Description |
| ------------ | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| `reportLink` | `string` | — | Attaches a project-specific report URL to each swimlane. Allows navigating to a report filtered for that sub-project directly from the board. |
**Report Link is optional**
The `reportLink` parameter is optional. If not configured, swimlane headers render without a report navigation link.
***
## Swimlane Discovery
Planningboard resolves the swimlane list at render time by querying the sub-projects of the current Polarion project group. The discovery behavior follows these rules:
| Rule | Detail |
| -------------- | -------------------------------------------------------- |
| Scope | Sub-projects within the current project group only |
| Exclusion | The current project itself is not included as a swimlane |
| Access filter | Only sub-projects readable by the current user are shown |
| Empty projects | Controlled by `showEmptySwimlanes`; hidden by default |
**Verify in application**
The exact mechanism for project group resolution (e.g., whether nested sub-groups are traversed) is not confirmed by available context. Verify the depth of sub-project discovery against the live product.
***
## Dragging and Assigning Work Items
When Project Mode is active, dragging a card from the unplanned sidebar or another swimlane to a project's row assigns that work item to the corresponding sub-project. The assignment is made according to the configured `assignmentMode = PROJECT` logic in the data service.
**Verified items cannot be moved**
Work items with status **Verified** are locked on the board. They cannot be dragged to a different swimlane or unplanned. This restriction applies to all assignment modes including Project Mode.
***
## Configuration Example
The following widget parameter snippet shows a minimal Project Mode configuration. Widget parameters are set in the **Widget Parameters** panel when editing the Planningboard widget on a Polarion LiveDoc or Wiki page.
```properties theme={null}
assignmentMode=PROJECT
showEmptySwimlanes=false
collapsibleSwimlanes=true
swimlaneSort=alphabetical
```
Extended example with capacity tracking enabled:
```properties theme={null}
assignmentMode=PROJECT
showEmptySwimlanes=true
collapsibleSwimlanes=true
swimlaneSort=alphabetical
capacityLoad=true
hoursPerDay=8
```
**Show empty swimlanes during initial setup**
Set `showEmptySwimlanes=true` when first configuring a cross-project board so all sub-projects appear as rows, making it easier to distribute unplanned items. Switch back to `false` once the board is populated to keep the layout focused.
***
## Capacity Tracking in Project Mode
When `capacityLoad=true`, Planningboard renders capacity bars for each Plan column and can aggregate capacity per swimlane. In Project Mode each swimlane corresponds to a sub-project rather than an individual resource, so capacity reflects the aggregated effort of all work items planned to that sub-project.
| Parameter | Type | Default | Description |
| ------------------- | --------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `capacityLoad` | `boolean` | `false` | Enables capacity load visualization. Renders capacity bars in Plan column headers and swimlane cells. |
| `multiCapacityLoad` | `boolean` | `false` | Enables per-swimlane capacity tracking. When `true`, each swimlane cell shows its own capacity progress independently. |
| `capacityField` | `string` | — | Custom field ID containing capacity values (e.g., story points). If not set, time-tracking fields (`remainingEstimate` / `initialEstimate`) are used. |
| `hoursPerDay` | `number` | `8` | Number of working hours per day used for capacity calculations when converting between time and day-based values. |
**Capacity whitespace sensitivity**
Capacity configuration parameters are whitespace-sensitive. Ensure values do not contain leading or trailing spaces when entered in the Widget Parameters panel.
***
## Sorting
The `swimlaneSort` parameter controls the vertical order of sub-project swimlanes.
| Value | Behavior |
| -------------- | ------------------------------------------------------------------------- |
| `alphabetical` | Sub-project swimlanes are sorted alphabetically by project name (default) |
**Verify in application**
Whether additional sort values (e.g., by project ID or custom order) are supported in Project Mode is not confirmed by available context. Check the **Assignment Type** → **Sort By** dropdown in the Widget Parameters panel for the current list of available options.
***
## Limitations
* **Current project excluded:** The project in which the Planningboard widget is embedded is never rendered as a swimlane row. Only sibling sub-projects within the same project group appear.
* **Read permission required:** Sub-projects the current user cannot read are silently excluded from the swimlane list. Users with partial project access see only the sub-projects they can read.
* **No multi-assignee distribution:** Project Mode does not distribute capacity across multiple assignees within a sub-project swimlane. Capacity is aggregated at the project level. This is consistent with the general Planningboard limitation of no multi-assignee capacity distribution (see [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters)).
* **Swimlane sort coupled to item sort:** The swimlane sort order in Project Mode is coupled to the overall item sort order on the board. Reordering items may affect swimlane rendering order.
***
## Relationship to Other Assignment Modes
Project Mode is one of several swimlane assignment types available in Planningboard.
| Assignment Mode | Swimlane rows based on |
| ----------------- | -------------------------------------------------- |
| `PROJECT` | Sub-projects in the current project group |
| `ASSIGNEE` | Individual users (assignees) in the project |
| `PARENT` | Parent work items linked via a specified link role |
| `ENUM` | Values of an enumeration custom field |
| `SAFE_TEAM` | SAFe teams within the current program |
| `SAFE_TRAIN_TEAM` | Teams within a specific Agile Release Train |
| `SAFE_PROGRAMS` | SAFe programs within a solution train |
| `none` | No swimlane grouping; all items in a single view |
For details on each mode, see:
* [Assignee Mode](/planningboard/reference/assignment-modes/assignee-mode)
* [Parent Item Mode](/planningboard/reference/assignment-modes/parent-mode)
* [Enumeration Field Mode](/planningboard/reference/assignment-modes/enum-mode)
* [SAFe Team Mode](/planningboard/reference/assignment-modes/safe-team-mode)
* [SAFe Train Team Mode](/planningboard/reference/assignment-modes/safe-train-team-mode)
* [SAFe Programs Mode](/planningboard/reference/assignment-modes/safe-programs-mode)
* [No Swimlanes Mode](/planningboard/reference/assignment-modes/no-swimlanes-mode)
***
## Where to Configure
1. Open the Polarion LiveDoc or Wiki page containing the Planningboard widget.
2. Enter edit mode and open the widget's **Widget Parameters** panel.
3. Navigate to **Swimlanes (Rows)**.
4. Set **Assignment Type** to **Project**.
5. Optionally configure `showEmptySwimlanes`, `collapsibleSwimlanes`, `swimlaneSort`, and `reportLink`.
6. Save the widget parameters.
For full parameter reference, see [Swimlanes (Rows) Parameters](/planningboard/reference/widget-parameters/swimlanes-parameters).
**KB Articles**
* Swimlane Assignment Types
* Filter user swimlanes by Plan range
* Planningboard interface & basic interactions
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#6777](https://support.nextedy.com/helpdesk/tickets/6777)
**Source Code**
* `PlanningBoardWidgetRenderer.java`
* `PlansMode.java`
* `PlanningBoardDataService.java`
* `PlanningBoardWidgetDependenciesProcessor.java`
* `AssignmentMode.java`
# SAFe Programs Mode
Source: https://learn.nextedy.com/planningboard/reference/assignment-modes/safe-programs-mode
**SAFe Programs Mode** (`SAFE_PROGRAMS`) is a swimlane assignment type in Nextedy PLANNINGBOARD that organises the board into horizontal rows representing **SAFe Programs** (Agile Release Trains or Value Stre
**SAFe Solution required**
SAFe Programs Mode requires a Polarion SAFe Solution configuration. Programs are discovered automatically from the SAFe Solution data at portfolio level. Contact Nextedy support if the SAFe Solution has not been set up in your Polarion instance.
***
## Overview
In this mode the board renders one swimlane per SAFe Program discovered in the solution train. Work items are placed in the swimlane that corresponds to their `safeProgram` custom field value. Planners can drag cards between swimlanes to reassign a work item to a different program, and between columns to move it between PIs.
***
## Assignment Mode Parameter
| Parameter | Value |
| ------------------- | --------------------- |
| Widget parameter | `assignmentMode` |
| Value for this mode | `SAFE_PROGRAMS` |
| Defined in | `AssignmentMode.java` |
Set this in the **Swimlanes (Rows)** section of the widget parameters panel.
***
## Parameters
The following parameters apply when `assignmentMode` is set to **Programs (SAFe)** (`SAFE_PROGRAMS`).
### Core Assignment Parameters
| Name | Type | Default | Description |
| ---------------------- | --------- | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `assignmentMode` | `string` | `ASSIGNEE` | Set to `SAFE_PROGRAMS` to activate SAFe Programs Mode. |
| `safeProgramField` | `string` | `safeProgram` | Custom field ID that stores the SAFe Program assignment for work items. Must reference a valid Polarion enumeration field. Change this only if your SAFe Solution uses a non-standard field ID. |
| `showEmptySwimlanes` | `boolean` | `false` | When `true`, all programs from the solution train are shown as swimlanes even if they have no planned work items in the current view. When `false`, empty program rows are hidden. |
| `swimlaneSort` | `string` | `alphabetical` | Sort order for program swimlanes. Controls the vertical ordering of program rows on the board. |
| `collapsibleSwimlanes` | `boolean` | `true` | Enables users to collapse and expand individual program swimlanes to reduce visual complexity on large boards. |
### Swimlane Sort Options
The `swimlaneSort` parameter accepts the following values:
| Value | Behaviour |
| -------------- | --------------------------------------------------------------- |
| `alphabetical` | Swimlanes are ordered alphabetically by program name (default). |
**Verify in application**
Additional `swimlaneSort` values beyond `alphabetical` may be available. Verify the full set of accepted values against the live Planningboard widget configuration panel.
### Plans Mode Parameters (used with SAFe Programs Mode)
SAFe Programs Mode is typically combined with a SAFe plans mode. The `plansMode` parameter controls which plan type appears as columns.
| Name | Type | Default | Description |
| ----------- | -------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `plansMode` | `string` | `PROJECT_PLANS` | Set to `SAFE_PIS` (Program Increments in Program mode) or `SAFE_SOLUTION` (Program Increments in Solution mode) for SAFe portfolio-level planning alongside SAFe Programs swimlanes. |
See [SAFe Program Increments](/planningboard/reference/plans-modes/safe-pis) and [SAFe Solution Trains](/planningboard/reference/plans-modes/safe-solutions) for column configuration when using this swimlane mode.
### Capacity Parameters (interaction with SAFe Programs Mode)
| Name | Type | Default | Description |
| ------------------- | --------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `capacityLoad` | `boolean` | `false` | Enables capacity tracking. When enabled, capacity bars appear per swimlane (per program) reflecting planned effort vs. program capacity. |
| `multiCapacityLoad` | `boolean` | `false` | Enables per-cell capacity tracking. Each plan–program cell shows its own capacity progress bar. Use when individual programs have different capacities per PI. |
| `capacityField` | `string` | — | Custom field ID containing capacity values (e.g., story points). If not set, time-based tracking (`remainingEstimate` / `initialEstimate`) is used. |
| `hoursPerDay` | `number` | `8` | Working hours per day used in capacity calculations when time-based tracking is active. |
**Capacity whitespace sensitivity**
Capacity configuration parameters are whitespace-sensitive. Ensure there are no leading or trailing spaces when entering field IDs or numeric values.
### General Swimlane Parameters
| Name | Type | Default | Description |
| ---------- | -------- | --------- | ------------------------------------------------------------------------------------------------ |
| `query` | `string` | `NOT *:*` | Lucene query to filter which work items are loaded onto the board. |
| `maxItems` | `number` | `1000` | Maximum number of work items loaded. |
| `wiType` | `string` | — | Work item type filter (e.g., `feature`, `story`) to restrict displayed items to a specific type. |
***
## SAFe Program Field
The `safeProgramField` property defines which custom field on each work item carries the program assignment.
| Name | Type | Default |
| ------------------ | -------- | ------------- |
| `safeProgramField` | `string` | `safeProgram` |
**Behaviour:**
* The field must be an enumeration field whose options correspond to the programs in your SAFe Solution.
* When a planner drags a card from one program swimlane to another, Planningboard writes the new program value back to this field on the work item.
* If the field does not exist on the work item type being displayed, items cannot be assigned to program swimlanes via drag-and-drop.
**Example — custom field ID:**
```properties theme={null}
safeProgramField=program_assignment
```
Use this override when your SAFe Solution uses a field with a different ID than the default `safeProgram`.
***
## Configuration Example
The following widget parameter configuration sets up a portfolio-level Planningboard with SAFe Programs as swimlanes and Program Increments as columns.
```properties theme={null}
# Swimlanes — SAFe Programs
assignmentMode=SAFE_PROGRAMS
safeProgramField=safeProgram
showEmptySwimlanes=false
swimlaneSort=alphabetical
collapsibleSwimlanes=true
# Plans (Columns) — SAFe Program Increments at Solution level
plansMode=SAFE_SOLUTION
# Work items
query=type:feature
maxItems=500
# Capacity
capacityLoad=true
capacityField=storyPoints
hoursPerDay=8
```
**Page Parameters and Program Increment Parameter ID**
When configuring SAFe Programs Mode with Program Increment columns, the **Program Increment Parameter ID** field must reference a Page Parameter that you create explicitly in the widget configuration. Configuration UI fields differ by `plansMode` selection — switching from **Project Plans** (`PROJECT_PLANS`) to **SAFe Program Increments in Solution** (`SAFE_SOLUTION`) changes which fields are visible in the widget panel. Create the Page Parameter first, then reference its ID in the PI increment field.
***
## Swimlane Discovery
Programs are not manually defined in the widget — they are sourced automatically from the Polarion SAFe Solution data at portfolio level.
**Implications:**
* Adding or removing a program in the SAFe Solution is reflected on the board after a page reload.
* Programs with no work items are hidden by default (`showEmptySwimlanes=false`). Set `showEmptySwimlanes=true` to always show all programs.
* The board does not allow creating new programs from the board UI — program management is done in the Polarion SAFe Solution configuration.
***
## Drag-and-Drop Behaviour
| Action | Result |
| ------------------------------------------------------------ | ---------------------------------------------------------------------------- |
| Drag a card to a different program swimlane | Updates the `safeProgramField` value on the work item to the target program. |
| Drag a card to a different plan column | Updates the work item's plan assignment (start/end date logic applies). |
| Drag a card to both a different program and a different plan | Updates both the program field and the plan assignment. |
| Drag in prioritize mode | Drag-and-drop between swimlanes is blocked in prioritize mode. |
| Drag in read-only mode | Drag-and-drop is blocked entirely when the board is in read-only mode. |
***
## Comparison with Related Assignment Modes
| Mode | Swimlane Unit | Typical Planning Level | Requires SAFe Solution |
| -------------------------------------------------------- | --------------------------------- | ---------------------- | ---------------------- |
| **Programs (SAFe)** (`SAFE_PROGRAMS`) | SAFe Program (ART / Value Stream) | Portfolio | Yes |
| **Program / Solution Teams (SAFe)** (`SAFE_TEAM`) | SAFe Team within current program | Program | Yes |
| **Agile Release Train Teams (SAFe)** (`SAFE_TRAIN_TEAM`) | Teams within a specific ART | ART / Train | Yes |
| **Users (Assignee)** (`ASSIGNEE`) | Individual user | Team / Sprint | No |
| **Project** (`PROJECT`) | Sub-project | Cross-project | No |
| **Enumeration Field** (`ENUM`) | Custom enumeration field value | Any | No |
For team-level SAFe planning within a single program, use [SAFe Team Mode](/planningboard/reference/assignment-modes/safe-team-mode). For planning across all teams of a specific Agile Release Train, use [SAFe Train Team Mode](/planningboard/reference/assignment-modes/safe-train-team-mode).
***
## Limitations
* **No multi-assignee capacity distribution:** Capacity load in SAFe Programs Mode reflects work item totals per program swimlane. Multi-assignee effort distribution (splitting capacity across multiple resources) is not supported — this is a known gap versus Nextedy GANTT.
* **Swimlane sort order coupled to item sort:** The sort order of swimlanes affects the sort order of items within those swimlanes. It is not possible to independently configure swimlane order and item order within swimlanes.
* **Parent Mode normalization not available:** Plan normalization (`planCellsMode`) is not supported when `assignmentMode` is set to **Programs (SAFe)** (`SAFE_PROGRAMS`).
* **SAFe Solution dependency:** If no SAFe Solution is configured in Polarion, the board will render no swimlanes in this mode. The mode silently produces an empty board rather than an error when the data source is missing.
* **Portfolio suffix configuration:** Portfolio-level program discovery may require additional portfolio suffix configuration. Contact Nextedy support for environment-specific setup guidance.
***
## Related Pages
* [Assignment Modes](/planningboard/reference/assignment-modes/index) — overview of all swimlane assignment types
* [SAFe Team Mode](/planningboard/reference/assignment-modes/safe-team-mode) — swimlanes by SAFe team within the current program
* [SAFe Train Team Mode](/planningboard/reference/assignment-modes/safe-train-team-mode) — swimlanes by teams within a specific ART
* [SAFe Parameters](/planningboard/reference/widget-parameters/safe-parameters) — full SAFe widget parameter reference
* [SAFe Program Increments](/planningboard/reference/plans-modes/safe-pis) — configuring PI columns
* [SAFe Solution Trains](/planningboard/reference/plans-modes/safe-solutions) — solution-level plan columns
* [Swimlanes Parameters](/planningboard/reference/widget-parameters/swimlanes-parameters) — all swimlane widget parameters
* [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) — capacity bar configuration
**KB Articles**
* Swimlane Assignment Types
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
**Source Code**
* `PlanningBoardWidgetRenderer.java`
* `PlansMode.java`
* `PlanningBoardDataService.java`
* `AssignmentMode.java`
* `PlanningBoardWidgetDependenciesProcessor.java`
# SAFe Team Mode
Source: https://learn.nextedy.com/planningboard/reference/assignment-modes/safe-team-mode
SAFe Team Mode is a swimlane assignment type for the Nextedy PLANNINGBOARD that groups board rows by **SAFe teams within the current program**.
**SAFe Solution required**
SAFe Team Mode requires a configured Polarion SAFe Solution project hierarchy. The board must reside in a program-level project that is part of a SAFe portfolio structure. Contact Nextedy support for initial setup guidance.
***
## Overview
When `assignmentMode` is set to **Program / Solution Teams (SAFe)** (`SAFE_TEAM`), Planningboard discovers all team-level projects within the current SAFe portfolio and renders one swimlane per team. Work items are assigned to swimlanes based on the value of the `safeTeam` custom field (configurable via `safeTeamField`).
Dragging a card to a different swimlane updates the work item's `safeTeam` field to the target team.
***
## Widget Parameters
Configure SAFe Team Mode in the **Swimlanes (Rows)** section of the widget parameters panel. See [Swimlanes (Rows) Parameters](/planningboard/reference/widget-parameters/swimlanes-parameters) for the full swimlane parameter reference and [SAFe Parameters](/planningboard/reference/widget-parameters/safe-parameters) for SAFe-specific parameters.
### Assignment Mode Parameter
| Name | Type | Default | Description |
| ---------------- | -------- | ---------- | -------------------------------------------------------------------------------------------------- |
| `assignmentMode` | `string` | `ASSIGNEE` | Set to `SAFE_TEAM` to enable SAFe Team Mode. Determines how work items are grouped into swimlanes. |
### SAFe Team Mode Parameters
| Name | Type | Default | Description |
| ---------------------- | --------- | -------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `safeTeamField` | `string` | `safeTeam` | Custom field ID that stores the SAFe team assignment on work items. Must reference a valid Polarion enumeration custom field. |
| `showEmptySwimlanes` | `boolean` | `false` | When `true`, swimlanes for teams with no assigned work items are still displayed. When `false`, empty team rows are hidden. |
| `swimlaneSort` | `string` | `alphabetical` | Sort order of team swimlanes. Controls the vertical ordering of rows on the board. |
| `collapsibleSwimlanes` | `boolean` | `true` | Allows users to collapse or expand individual team swimlanes to reduce visual clutter on boards with many teams. |
### Swimlane Sort Values
| Value | Description |
| -------------- | ---------------------------------------- |
| `alphabetical` | Teams sorted A–Z by team name (default). |
**Verify in application**
Additional `swimlaneSort` values beyond `alphabetical` may be available. Verify the full set of accepted values in the widget parameter panel of the running application.
***
## Relationship to Other SAFe Assignment Modes
Planningboard provides three SAFe-specific assignment modes. Choose the correct mode based on the planning level:
| Mode | `assignmentMode` value | Swimlane source | Typical planning level |
| -------------------------------------------------------------------------------------- | ---------------------- | ----------------------------------------------- | -------------------------------- |
| SAFe Team Mode | `SAFE_TEAM` | All teams in the current program (ART) | Program / ART level |
| [SAFe Train Team Mode](/planningboard/reference/assignment-modes/safe-train-team-mode) | `SAFE_TRAIN_TEAM` | Teams within a specific ART, filtered by ART ID | Multi-ART / Solution Train level |
| [SAFe Programs Mode](/planningboard/reference/assignment-modes/safe-programs-mode) | `SAFE_PROGRAMS` | Programs within a solution train | Portfolio level |
Use SAFe Team Mode when the board is embedded in a **program-level project** and you want all teams in that program to appear as rows. Use [SAFe Train Team Mode](/planningboard/reference/assignment-modes/safe-train-team-mode) if you need to scope rows to a specific ART by ID.
***
## Configuration Example
The following example shows a Planningboard widget configured with SAFe Team Mode for program-level sprint planning. Plans columns display SAFe sprints (`plansMode = SAFE_SPRINTS`) while rows show teams in the current ART.
```properties theme={null}
# Swimlane assignment
assignmentMode=SAFE_TEAM
safeTeamField=safeTeam
showEmptySwimlanes=false
swimlaneSort=alphabetical
collapsibleSwimlanes=true
# Plans mode (columns) — SAFe sprints at program level
plansMode=SAFE_SPRINTS
```
In the widget parameters panel, navigate to **Swimlanes (Rows)** and select **Program / Solution Teams (SAFe)** from the **Assignment Type** dropdown.
**Empty swimlanes during sprint planning**
Enable `showEmptySwimlanes=true` during initial sprint planning so that teams with no items assigned yet appear on the board and can receive cards by drag-and-drop.
***
## How Team Discovery Works
When SAFe Team Mode is active, Planningboard uses the Polarion SAFe Solution project hierarchy to identify teams:
1. The board's host project is identified as a program-level project within a SAFe portfolio.
2. All team-level projects (`getTeamProjects()`) within the same portfolio are retrieved.
3. One swimlane is created per team.
4. Work items are matched to team swimlanes via the `safeTeamField` custom field value.
Only projects that are **readable** by the current user appear as swimlanes. Projects the user cannot read are excluded silently.
***
## Work Item Assignment Behavior
| Action | Result |
| ---------------------------------------------------------------- | -------------------------------------------------------------- |
| Drag card to a team swimlane | Updates the work item's `safeTeam` field to the target team. |
| Drag card to the **Not Assigned/Other** row | Clears the `safeTeam` field value. |
| Alt+drag card to a second team | Creates a multi-team assignment (comma-separated field value). |
| Drop card onto an incorrect swimlane (if field validation fails) | Card returns to its original swimlane. |
### SAFe Parent Sync
When a work item's team assignment changes (by drag-and-drop), Planningboard automatically syncs the User Story to the correct Team Program Increment plan. This `syncSAFEParentsFromChildren` behavior ensures that plan membership stays consistent with team assignment without requiring manual updates. Plan IDs are remapped based on the new team assignment.
**Capacity and multi-assignee limitations**
SAFe Team Mode does not support multi-assignee capacity distribution. Capacity bars reflect per-team totals only; effort is not split across individual team members. This is a known gap versus Nextedy GANTT's capacity model.
***
## Capacity Behavior
When capacity tracking is enabled alongside SAFe Team Mode, capacity bars appear per team swimlane. Capacity is aggregated at the team level across the displayed Plan columns.
| Parameter | Relevance to SAFe Team Mode |
| ------------------- | ----------------------------------------------------------------------------------------------------------- |
| `capacityLoad` | Enables effort/capacity tracking. Uses `remainingEstimate` / `initialEstimate` or a custom `capacityField`. |
| `multiCapacityLoad` | Enables per-swimlane (per-team) capacity tracking with individual progress bars per cell. |
| `useTeamsService` | Integrates with the Teams Service to supply team capacity data, overriding plan-level capacity values. |
See [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) and [Teams Service Properties](/planningboard/reference/configuration-properties/teams-properties) for full parameter details.
***
## Filtering Active Teams by Plan Range
When swimlanes are derived from Team Assignments via the Teams Service, you can restrict displayed team rows to those with active assignments within the time range of the currently shown Plans.
Enable this in **Administration > Configuration Properties**:
```properties theme={null}
nextedy.planningboard.activeTeamAssignmentsInPlanRangeOnly=true
```
When enabled:
* Teams with no assignments overlapping the displayed Plans' date range are hidden.
* Work items assigned to hidden teams move to the **Not Assigned / Other** swimlane.
This behavior is available from version **25.12.0**.
**Deprecated predecessor**
`nextedy.planningboard.activeTeamAssignmentsOnly=true` was the earlier variant (introduced in 25.3.0). It filtered only past assignments, independent of the shown Plans' scope. It was deprecated in version 25.12.0 in favor of `activeTeamAssignmentsInPlanRangeOnly`.
See [Teams Service Properties](/planningboard/reference/configuration-properties/teams-properties) for the full property reference.
***
## Required Data Structure
For SAFe Team Mode to function correctly, the Polarion environment must have:
* A SAFe Solution project hierarchy (portfolio → program → team projects).
* The board's host project configured as a program-level project within that hierarchy.
* A custom enumeration field (default: `safeTeam`) present on the work item types shown on the board.
* Work items populated with `safeTeam` field values matching the team project identifiers.
If using the Teams Service integration (`useTeamsService=true`), also configure:
* Teams and Team Assignments within each team project.
* The Teams Service properties in **Administration > Configuration Properties** (see [Teams Service Properties](/planningboard/reference/configuration-properties/teams-properties)).
***
## Limitations
* **No sub-item effort distribution:** Capacity is tracked at the team swimlane level only. Effort is not automatically distributed across individual team members or child work items.
* **No multi-assignee capacity:** SAFe Team Mode does not split capacity across multiple team assignments on a single work item.
* **Swimlane sort is fixed to alphabetical:** Only alphabetical sort order is confirmed for team swimlanes. Sort options available for other assignment modes (such as [Assignee Mode](/planningboard/reference/assignment-modes/assignee-mode)) may not apply.
* **SAFe hierarchy required:** The mode produces no swimlanes if the host project is not part of a recognized SAFe portfolio structure. No error is surfaced; the board renders with no rows.
* **Configuration UI changes with Plans Mode:** The widget parameters panel shows different configuration fields depending on the selected Plans Mode. SAFe-specific configuration fields (including PI increment selection) appear only when a SAFe plans mode is active. See [SAFe Parameters](/planningboard/reference/widget-parameters/safe-parameters).
***
## Related Pages
* [Assignment Modes](/planningboard/reference/assignment-modes/index) — Overview of all assignment modes
* [SAFe Train Team Mode](/planningboard/reference/assignment-modes/safe-train-team-mode) — Scope teams to a specific ART by ID
* [SAFe Programs Mode](/planningboard/reference/assignment-modes/safe-programs-mode) — Portfolio-level program swimlanes
* [Swimlanes (Rows) Parameters](/planningboard/reference/widget-parameters/swimlanes-parameters) — Full swimlane parameter reference
* [SAFe Parameters](/planningboard/reference/widget-parameters/safe-parameters) — SAFe-specific widget parameters
* [SAFe Sprints](/planningboard/reference/plans-modes/safe-sprints) — SAFe sprint columns (typical pairing with SAFe Team Mode)
* [SAFe Program Increments](/planningboard/reference/plans-modes/safe-pis) — PI-level columns
* [Teams Service Properties](/planningboard/reference/configuration-properties/teams-properties) — Teams Service configuration
* [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) — Capacity tracking configuration
**KB Articles**
* Swimlane Assignment Types
* What is 'Normalization'
* Filter user swimlanes by Plan range
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
**Source Code**
* `PlansMode.java`
* `PlanningBoardWidgetRenderer.java`
* `PlanningBoardDataService.java`
* `AssignmentMode.java`
* `PlanningBoardWidgetDependenciesProcessor.java`
# SAFe Train Team Mode
Source: https://learn.nextedy.com/planningboard/reference/assignment-modes/safe-train-team-mode
**SAFe Train Team Mode** (`SAFE_TRAIN_TEAM`) is a swimlane assignment type in Nextedy PLANNINGBOARD that organizes swimlanes by the teams belonging to a specific Agile Release Train (ART).
**SAFe environment required**
SAFe Train Team Mode requires a Polarion project configured with the SAFe Solution. Contact your Polarion administrator if the SAFe assignment modes are not visible in your widget's Assignment Type dropdown.
***
## Overview
| Property | Value |
| ------------------------------ | ----------------------------------------------------------- |
| **Assignment mode identifier** | `SAFE_TRAIN_TEAM` |
| **Swimlane grouping** | One swimlane per ART team, filtered by the specified ART ID |
| **SAFe level** | Program (ART) |
| **Requires SAFe Solution** | Yes |
| **Team field default** | `safeTeam` |
When this mode is active, Planningboard discovers all teams that belong to the configured Agile Release Train and renders one swimlane per team. Work items are distributed into swimlanes based on their `safeTeam` field value. Items whose team is outside the selected ART are not displayed in a named swimlane.
***
## Widget Parameters
Configure SAFe Train Team Mode in the **Swimlanes (Rows)** section of the widget's Parameters panel.
### Core Parameters
| Name | Type | Default | Description |
| ---------------------- | ------- | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `assignmentMode` | string | `ASSIGNEE` | Set to `SAFE_TRAIN_TEAM` to activate this mode. Controls how work items are grouped into swimlanes. |
| `safeTeamField` | string | `safeTeam` | Custom field ID that stores the SAFe Team assignment on work items. Must match the Polarion field ID exactly. |
| `showEmptySwimlanes` | boolean | `false` | When `true`, swimlanes for ART teams that have no planned work items are still rendered. Useful for capacity planning across all teams in the ART. |
| `swimlaneSort` | string | `alphabetical` | Determines the sort order of team swimlanes. Controls vertical ordering of lanes. |
| `collapsibleSwimlanes` | boolean | `true` | Enables users to collapse or expand individual swimlanes. Improves usability on boards with many ART teams. |
### ART Filtering
**Verify in application**
The specific widget parameter name for specifying the ART ID filter should be confirmed in the widget's configuration UI. The source code confirms that `SAFE_TRAIN_TEAM` mode filters teams by ART ID parameter — consult the widget Parameters panel under **Swimlanes (Rows)** for the exact field label.
SAFe Train Team Mode distinguishes itself from [SAFe Team Mode](/planningboard/reference/assignment-modes/safe-team-mode) by accepting an explicit ART ID filter. Where SAFe Team Mode shows teams from the current program's SAFe Solution data without ART scoping, SAFe Train Team Mode restricts the swimlane list to teams that belong to the specified ART.
This makes SAFe Train Team Mode suitable when:
* A Polarion project contains multiple ARTs and you want the board scoped to one ART.
* You are planning at the ART level across a subset of teams in a larger solution train.
For portfolio-level planning across multiple programs, see [SAFe Programs Mode](/planningboard/reference/assignment-modes/safe-programs-mode).
***
## Relationship to Plans Modes
SAFe Train Team Mode is a swimlane assignment type (rows). It works in combination with a plans mode (columns). The compatible plans modes for ART-level team planning are:
| Plans Mode | Description | Reference |
| ----------------------------------------------- | --------------------------------------- | ------------------------------------------------------------------------ |
| SAFe Sprints in Program (`SAFE_SPRINTS`) | Displays iteration plans within the ART | [SAFe Sprints](/planningboard/reference/plans-modes/safe-sprints) |
| SAFe Program Increments in Program (`SAFE_PIS`) | Displays PI-level plans | [SAFe Program Increments](/planningboard/reference/plans-modes/safe-pis) |
**Common configuration**
For ART-level sprint planning, combine `assignmentMode = SAFE_TRAIN_TEAM` with `plansMode = SAFE_SPRINTS`. For PI planning across ART teams, combine with `plansMode = SAFE_PIS`.
***
## Work Item Assignment
When `assignmentMode` is `SAFE_TRAIN_TEAM`, the `safeTeam` field (or the field specified in `safeTeamField`) determines which swimlane each work item appears in. Dragging a card from one team swimlane to another updates the work item's `safeTeam` field value accordingly.
### Field Requirements
| Field | Required | Notes |
| -------------------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `safeTeam` (or custom `safeTeamField`) | Yes | Must be an enumeration field in Polarion. The enum values must correspond to the SAFe Team IDs in the Polarion SAFe Solution. |
### Unassigned Items
Work items that have no value in the `safeTeam` field, or whose team value does not match any team in the selected ART, appear in the **Not Assigned / Other** swimlane at the bottom of the board.
***
## Capacity Tracking
Capacity bars are supported in SAFe Train Team Mode. Capacity is displayed per swimlane (per ART team) when capacity tracking is enabled.
### Capacity Parameters
| Name | Type | Default | Description |
| ------------------- | ------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `capacityLoad` | boolean | `false` | Enables capacity loading calculations per team swimlane. |
| `multiCapacityLoad` | boolean | `false` | Enables per-swimlane capacity tracking — each team swimlane shows its own capacity progress independently. |
| `useTeamsService` | boolean | `false` | Enables integration with the Planningboard Teams Service for team capacity, user capacity, and team member data. When enabled, overrides plan-level capacity values with team-sourced data. |
| `userCapacityLoad` | boolean | `false` | Enables user-level capacity loading when the Teams Service is active. |
| `capacityField` | string | — | Custom field ID to use as the capacity value (e.g., story points). Leave unset to use time tracking fields (`remainingEstimate` / `initialEstimate`). |
| `hoursPerDay` | number | `8` | Working hours per day for time-based capacity calculations. |
**Capacity configuration is whitespace-sensitive**
Configuration property values for capacity must not contain leading or trailing whitespace. A stray space in a capacity property value will cause the value to be ignored silently.
For full capacity parameter documentation, see [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters).
***
## SAFe-Specific Automation
### Parent Plan Synchronization
When a work item's SAFe team assignment changes (by dragging it to a different team swimlane), Planningboard can automatically sync the work item's Team Program Increment plan to match the new team assignment. This synchronization (`syncSAFEParentsFromChildren`) remaps plan IDs based on the updated team assignment.
**Verify in application**
Whether automatic parent PI plan synchronization is enabled by default or requires explicit configuration should be confirmed against the live product.
***
## Configuration Example
The following example configures a Planningboard for ART-level sprint planning with team-based swimlanes, capacity tracking enabled, and empty swimlanes shown for all ART teams.
```properties theme={null}
# Swimlane assignment
assignmentMode=SAFE_TRAIN_TEAM
safeTeamField=safeTeam
showEmptySwimlanes=true
swimlaneSort=alphabetical
collapsibleSwimlanes=true
# Plans mode — SAFe Sprints at program level
plansMode=SAFE_SPRINTS
# Capacity tracking per team
capacityLoad=true
multiCapacityLoad=true
useTeamsService=true
hoursPerDay=8
# Work items dataset
query=type:story OR type:task
maxItems=1000
```
**Empty swimlanes for planning sessions**
Set `showEmptySwimlanes=true` during PI planning sessions so that all ART teams are visible on the board even before stories are assigned, making it easier to distribute new work across teams.
***
## Comparison with Related Assignment Modes
| Mode | Swimlane grouping | SAFe level | ART filter |
| --------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | -------------------- | ----------------------------------- |
| Agile Release Train Teams (SAFe) (`SAFE_TRAIN_TEAM`) | Teams within a specific ART | Program | Yes — scoped to one ART |
| [Program / Solution Teams (SAFe)](/planningboard/reference/assignment-modes/safe-team-mode) (`SAFE_TEAM`) | Teams in the current program's SAFe Solution | Program | No — all teams in the SAFe Solution |
| [Programs (SAFe)](/planningboard/reference/assignment-modes/safe-programs-mode) (`SAFE_PROGRAMS`) | Programs within a solution train | Portfolio / Solution | — |
| [Users (Assignee)](/planningboard/reference/assignment-modes/assignee-mode) (`ASSIGNEE`) | Individual users (assignees) | Any | — |
| [Enumeration Field](/planningboard/reference/assignment-modes/enum-mode) (`ENUM`) | Enumeration field values (e.g., a `team` custom field) | Any | — |
Use SAFe Train Team Mode when your Polarion project contains multiple ARTs and you need the board scoped to a single ART's teams. Use [SAFe Team Mode](/planningboard/reference/assignment-modes/safe-team-mode) when you want all teams from the SAFe Solution without ART scoping.
***
## Configuration Fields Shown in Widget UI
The widget's dependency processor shows and hides configuration fields based on the selected assignment mode. When **Agile Release Train Teams (SAFe)** (`SAFE_TRAIN_TEAM`) is selected, the following behavior applies:
* The **resource field selector** (used by the Enumeration Field (`ENUM`) mode) is hidden.
* The **selected rows / row filter** (used by the Enumeration Field (`ENUM`) mode) is hidden.
* The **user role selector** (used by the Users (Assignee) (`ASSIGNEE`) mode) is hidden.
* ART-specific fields for team filtering are shown.
For the complete list of widget parameters available across all swimlane modes, see [Swimlanes (Rows) Parameters](/planningboard/reference/widget-parameters/swimlanes-parameters).
***
## Limitations
* **No multi-assignee capacity distribution.** Capacity load calculations do not distribute effort across multiple assignees. This is a known gap relative to Nextedy GANTT's capacity model.
* **Swimlane sort order is coupled to item sort order.** The vertical ordering of team swimlanes follows the same sort configuration as item ordering within swimlanes; independent swimlane-level sort overrides are not supported.
* **SAFe Solution required.** If the Polarion project does not have a SAFe Solution configured, the **Agile Release Train Teams (SAFe)** (`SAFE_TRAIN_TEAM`) mode will not populate any swimlanes.
* **Parent mode incompatibility.** `assignmentMode=PARENT` does not support plan normalization (`planCellsMode`). This restriction does not apply to **Agile Release Train Teams (SAFe)** (`SAFE_TRAIN_TEAM`), but mixing parent-based hierarchy with SAFe team assignment is not supported in a single board instance.
***
## Related Pages
* [Assignment Modes](/planningboard/reference/assignment-modes/index) — overview of all swimlane assignment types
* [SAFe Team Mode](/planningboard/reference/assignment-modes/safe-team-mode) — similar mode without ART ID scoping
* [SAFe Programs Mode](/planningboard/reference/assignment-modes/safe-programs-mode) — portfolio-level swimlanes by program
* [SAFe Parameters](/planningboard/reference/widget-parameters/safe-parameters) — SAFe-specific widget parameters
* [SAFe Sprints](/planningboard/reference/plans-modes/safe-sprints) — compatible plans mode for ART sprint planning
* [SAFe Program Increments](/planningboard/reference/plans-modes/safe-pis) — compatible plans mode for PI planning
* [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) — full capacity configuration reference
* [Teams Service Properties](/planningboard/reference/configuration-properties/teams-properties) — server-side Teams Service configuration
**KB Articles**
* Swimlane Assignment Types
* What is 'Normalization'
* Filter user swimlanes by Plan range
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
**Source Code**
* `PlansMode.java`
* `PlanningBoardWidgetRenderer.java`
* `PlanningBoardDataService.java`
* `AssignmentMode.java`
* `PlanningBoardWidgetDependenciesProcessor.java`
# Appearance Properties
Source: https://learn.nextedy.com/planningboard/reference/configuration-properties/appearance-properties
This page lists the Nextedy PLANNINGBOARD configuration properties that affect board display and visual output.
**Verify in application**
The gathered source context for this page covers the configuration model and capacity visualization properties confirmed in code. Properties related to card color rules, custom card templates, and additional visual theming options should be verified in the live application, as the source context does not confirm their exact property names or defaults.
***
## Overview
Appearance properties configure how Planningboard renders cards, capacity indicators, and column tooltips at the board level. Some properties are set via administration configuration; others are supplied as scripting configuration in the board's embedded config object.
```text theme={null}
Widget Parameters (per instance)
|
v
+----------------------------------+
| Planningboard Board |
| |
| Cards | Swimlanes | Plans |
| | | |
| Capacity Bars (per swimlane) |
| Column Tooltips (per plan) |
+----------------------------------+
|
v
Administration Properties (system-wide)
```
***
## Capacity Visualization Properties
These properties control whether capacity bars and per-user capacity breakdown are displayed on the board. They are set in the board's embedded configuration or via administration.
| Property | Type | Default | Description |
| ------------------- | ------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `capacityLoad` | boolean | `false` | Enable capacity loading calculations for resources. When `true`, capacity bars appear on plan columns. |
| `multiCapacityLoad` | boolean | `false` | Enable multi-plan capacity loading across multiple plans simultaneously. |
| `userCapacityLoad` | boolean | `false` | Enable user-level capacity loading. Requires `useTeamsService=true`. When enabled, per-user allocation breakdowns are shown in capacity tooltips. |
| `useTeamsService` | boolean | `false` | Enable integration with the Polarion Teams service for team-based planning. Required for per-swimlane capacity visualization and user capacity breakdown. |
**Teams service required for per-user capacity**
Setting `userCapacityLoad=true` without also setting `useTeamsService=true` will not produce per-user capacity breakdowns. Both properties must be enabled together. This combination is confirmed by ticket insight: the `nextedy.planningboard.useTeamsService` property enables important capacity visualization but is underexposed in configuration documentation.
### Capacity Hours Configuration
| Property | Type | Default | Description |
| --------------- | ------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `hoursPerDay` | number | `8` | Number of working hours per day used in capacity calculations. Affects how effort estimates are converted to capacity percentages. |
| `capacityField` | string | `None` | Custom field ID containing capacity values (for example, story points or hours). When set, Planningboard reads capacity from this field rather than the default time-tracking fields. |
**Whitespace sensitivity**
Capacity configuration parameters are whitespace-sensitive. Ensure no leading or trailing spaces are present in property values, particularly for `capacityField` and `selectedTeam`.
***
## Column Tooltip Properties
Column tooltips appear when a user hovers over a plan column's capacity bar. Planningboard supports both a default tooltip format and a custom template.
| Property | Type | Default | Description |
| ----------------------- | ------------------ | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `columnTooltipTemplate` | string or function | `None` (uses default) | Customizable template for rendering capacity tooltips on plan columns. Can be a string template or a function receiving `column` and `row` objects. When not set, the default tooltip is shown. |
### Default Tooltip Format
When `columnTooltipTemplate` is not configured, the default tooltip displays:
* **Capacity** — total capacity for the plan column
* **Done** — completed effort
* **Todo** — remaining effort
* **Available** — remaining capacity after allocation
### Custom Tooltip with Per-User Breakdown
When `columnTooltipTemplate` is configured and `userCapacityLoad` is enabled, the tooltip can display a per-user breakdown:
```javascript theme={null}
columnTooltipTemplate = function(column, row) {
// column and row objects passed by Planningboard
// Returns HTML string for the tooltip
// Per-user format: Available (negative = overallocated) / Allocated / Total
};
```
The per-user breakdown format shows:
* **Available** (shown in red if negative — overallocated)
* **Allocated** — sum of remaining estimates for tasks assigned to the user within the plan
* **Total** — user's total capacity from team calendar for the plan period
**Overallocation visualization**
Overallocation is visually indicated with red text for negative available capacity values. This makes it easy to identify resource bottlenecks directly from the board without navigating to a separate report.
***
## Plan Column Link Property
| Property | Type | Default | Description |
| ---------- | ------ | -------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `planLink` | string | `/polarion/#/project/${plan.objectId.projectId}/plan?id=${plan.objectId.itemId}` | URL template for linking to individual plans when a user clicks a column label. Supports `${plan.*}` variables. |
The default `planLink` value navigates to the standard Polarion plan page. You can override this to link to a custom report or Wiki page. The template variable `${plan.objectId.projectId}` resolves to the plan's project ID and `${plan.objectId.itemId}` resolves to the plan's item ID.
**Example — link to a custom Wiki report:**
```properties theme={null}
planLink = /polarion/#/project/${plan.objectId.projectId}/wiki/SPRINT_REPORT?plan=${plan.objectId.itemId}
```
***
## Teams Service Capacity Data
When `useTeamsService=true`, Planningboard calculates capacity data per user per plan. The following computed values appear in capacity tooltips and scripting contexts:
| Field | Description |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------- |
| `allocatedCapacity` | Sum of remaining estimates for all tasks assigned to a user within a plan. Rounded to one decimal place. |
| `totalCapacity` | User's total available capacity from team calendar for the plan period. Users without calendar entries default to `0.0`. |
| `availableCapacity` | Remaining capacity: `totalCapacity − allocatedCapacity`. Negative values indicate overallocation. Rounded to one decimal place. |
| `childRemainingEstimate` | Sum of remaining estimates from all child tasks within a plan. Aggregate workload metric. |
| `allChildTasksCount` | Total count of child task work items within a plan. |
| `assigneeCount` | Number of unique users assigned to tasks within the plan. Always equals the length of the `userCapacities` list. |
**Zero-fallback for users without calendar**
Users who have no team calendar entry for the plan period will have `totalCapacity = 0.0` (confirmed: NPT-1211 zero-fallback behavior). This will cause `availableCapacity` to equal `−allocatedCapacity`, showing as overallocated even when capacity data is simply missing.
***
## Board View Mode Properties
The following properties affect what is displayed on the board at a structural level.
| Property | Type | Default | Description |
| --------------- | ------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `plansMode` | string | `PROJECT_PLANS` | Determines how plans are organized and displayed. Controls the organizational structure of plan columns. See [Plans Modes](/planningboard/reference/plans-modes/index) for available values. |
| `lastPlans` | number | `1` | Number of past or completed plans to display on the board. |
| `nextPlans` | number | `5` | Number of future or upcoming plans to display on the board. |
| `planCellsMode` | boolean | `false` | Enable plan cells mode for SAFe or stemming-based planning. When enabled, items belong to specific plan–resource cells rather than plan columns only. |
***
## Work Item Display Properties
| Property | Type | Default | Description |
| ---------- | ------ | --------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `maxItems` | number | `1000` | Maximum number of work items loaded into the board. Increasing this value affects board load time. |
| `wiType` | string | `None` | Work item type filter (for example, `task`, `story`, `feature`). When set, restricts displayed cards to the specified work item type. |
| `query` | string | `NOT *:*` | Lucene query to filter which work items appear on the board. The default `NOT *:*` loads no items unless overridden. |
***
## Configuration Example
The following example enables capacity visualization with per-user breakdown using the Teams service, and sets the plan column link to a custom report.
```properties theme={null}
# Enable Teams service for per-swimlane capacity visualization
nextedy.planningboard.useTeamsService=true
# Enable user-level capacity breakdown in column tooltips
nextedy.planningboard.userCapacityLoad=true
# Show capacity bars on plan columns
nextedy.planningboard.capacityLoad=true
# Working hours per day for capacity calculations
nextedy.planningboard.hoursPerDay=8
# Custom plan column link pointing to a sprint report Wiki page
nextedy.planningboard.planLink=/polarion/#/project/${plan.objectId.projectId}/wiki/SPRINT_REPORT?plan=${plan.objectId.itemId}
```
```text theme={null}
Board with capacity visualization enabled:
Plan Column (Sprint 1) Plan Column (Sprint 2)
+---------------------------+ +---------------------------+
| [Capacity Bar: 80%] | | [Capacity Bar: 110%] |
| Hover → tooltip shows: | | Hover → tooltip shows: |
| Alex: 4h avail / | | Alex: -2h (red) / |
| 12h alloc / | | 18h alloc / |
| 16h total | | 16h total |
| Carl: 8h avail / | | Carl: 4h avail / |
| 8h alloc / | | 12h alloc / |
| 16h total | | 16h total |
+---------------------------+ +---------------------------+
```
***
## Related Pages
* [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) — per-widget capacity parameters
* [Configuration Properties](/planningboard/reference/configuration-properties/index) — index of all configuration property pages
* [Capacity Properties](/planningboard/reference/configuration-properties/capacity-properties) — capacity-specific administration properties
* [Teams Service Properties](/planningboard/reference/configuration-properties/teams-properties) — Teams service configuration
* [Scripting API](/planningboard/reference/api/scripting-api) — scripting API for custom tooltip templates and board customization
* [Plans Modes](/planningboard/reference/plans-modes/index) — available `plansMode` values
**KB Articles**
* Planningboard: Customizable Statistics and Capacity Indicators
* Planningboard Widget Parameters
* Swimlane Assignment Types
**Support Tickets**
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
* [#4714](https://support.nextedy.com/helpdesk/tickets/4714)
* [#6496](https://support.nextedy.com/helpdesk/tickets/6496)
**Source Code**
* `viewSetup.vm`
* `capacityHelperData.cy.ts`
* `capacityTooltipRendering.cy.ts`
* `Item.java`
* `unplanned_sidebar.js`
# Capacity Properties
Source: https://learn.nextedy.com/planningboard/reference/configuration-properties/capacity-properties
Configuration properties that control how Nextedy PLANNINGBOARD calculates, displays, and tracks capacity for swimlanes and team members.
**Whitespace sensitivity**
Capacity configuration property values are whitespace-sensitive. Trailing spaces, leading spaces, or unexpected line breaks in property values will silently break capacity calculations. Validate each value carefully before saving.
***
## Overview
The capacity system has two layers:
1. **Widget-level** — whether capacity tracking is active for a board instance (controlled by widget parameters such as `capacityLoad` and `useTeamsService`).
2. **Administration-level** — how capacity is calculated globally, including calendar fallback behaviour and capacity modifier fields (controlled by the properties documented on this page).
***
## Capacity Calculation Properties
These properties affect how Planningboard computes user and team capacity from calendars and team work items.
| Property | Type | Default | Description |
| ---------------------------------------- | --------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `nextedy.gantt.calendarHolder` | `string` | *(none)* | User ID of a base user whose calendar is used as a fallback when a team member has no personal calendar defined. Optional. When absent, the system default calendar applies. |
| `nextedy.gantt.useTeamCapacityModifiers` | `boolean` | `false` | Enables capacity modifier fields (`capModA`, `capModB`) on team work items, allowing team capacity to be reduced by a configurable percentage. When `false`, modifier fields are ignored. |
| `nextedy.gantt.capacityModifierAField` | `string` | `capModA` | Field name (on team work items) used as the primary capacity modifier. An integer field representing the percentage reduction (0–100). Only read when `nextedy.gantt.useTeamCapacityModifiers` is `true`. |
| `nextedy.gantt.capacityModifierBField` | `string` | `capModB` | Field name (on team work items) used as the secondary capacity modifier. An integer field representing the percentage reduction (0–100). Only read when `nextedy.gantt.useTeamCapacityModifiers` is `true`. |
**Where to set these properties**
These properties are set in your Polarion administration area under **Administration > Nextedy PLANNINGBOARD** (or in the relevant `context.properties` file, depending on your setup). They are shared with the Nextedy GANTT product — the `nextedy.gantt.*` prefix does not restrict them to GANTT only.
***
## Calendar Fallback Property
| Property | Type | Default | Description |
| ------------------------------ | -------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `nextedy.gantt.calendarHolder` | `string` | *(none)* | Base user ID. If a team member has no personal calendar in Polarion, the working hours and off days from this user's calendar are used to calculate `totalCapacity`. When not set, Polarion's system default calendar applies. |
**Effect on capacity calculation:**
* `totalCapacity` for a user = working hours derived from their calendar (or the fallback calendar) × their capacity percentage, summed over the Plan's date range.
* Users with no calendar and no `calendarHolder` configured default to `totalCapacity = 0.0`.
**Zero-capacity fallback**
Team members without a personal calendar and without `nextedy.gantt.calendarHolder` configured will show `totalCapacity = 0.0`. This is a known behaviour (see NPT-1211). Always configure `calendarHolder` or ensure every team member has a Polarion calendar.
**Configuration example:**
```properties theme={null}
nextedy.gantt.calendarHolder=jsmith
```
Replace `jsmith` with the Polarion user ID of the user whose calendar should serve as the shared fallback.
***
## Capacity Modifier Properties
Capacity modifiers allow administrators to reduce a team's calculated capacity by a percentage — for example, to account for planned overhead, meetings, or non-project work.
| Property | Type | Default | Description |
| ---------------------------------------- | --------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `nextedy.gantt.useTeamCapacityModifiers` | `boolean` | `false` | Master switch. Set to `true` to enable reading of modifier fields from team work items. |
| `nextedy.gantt.capacityModifierAField` | `string` | `capModA` | Field name for the primary modifier. Must be an integer custom field on the team work item type, holding a percentage value between 0 and 100. |
| `nextedy.gantt.capacityModifierBField` | `string` | `capModB` | Field name for the secondary modifier. Must be an integer custom field on the team work item type, holding a percentage value between 0 and 100. |
**How modifiers reduce capacity:**
When `nextedy.gantt.useTeamCapacityModifiers = true`, Planningboard reads the value of the field named by `nextedy.gantt.capacityModifierAField` from each team work item. The modifier percentage reduces the team's computed capacity for that team.
**Verify in application**
The exact formula applying the modifier percentage to computed capacity (e.g., `totalCapacity × (1 - modifierA/100)`) should be verified against the live product.
**Configuration example — enabling capacity modifiers:**
```properties theme={null}
nextedy.gantt.useTeamCapacityModifiers=true
nextedy.gantt.capacityModifierAField=capModA
```
In this configuration, Planningboard reads the `capModA` integer field from each team work item and applies it as a percentage reduction to that team's capacity.
**Custom field name example:**
```properties theme={null}
nextedy.gantt.useTeamCapacityModifiers=true
nextedy.gantt.capacityModifierAField=overheadPct
```
Use this when your team work items use a differently named field (e.g., `overheadPct` instead of `capModA`).
***
## Capacity Calculation Model
Understanding how Planningboard derives capacity values helps you configure the above properties correctly.
### Per-User Capacity Metrics
For each user assigned to tasks within a Plan, Planningboard computes:
| Metric | Calculation | Notes |
| ------------------- | --------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------- |
| `totalCapacity` | Working hours from user calendar (or fallback) × capacity assignment percentage, over the Plan date range | Defaults to `0.0` if no calendar is found and no `calendarHolder` is set |
| `allocatedCapacity` | Sum of remaining estimates for all tasks assigned to this user within the Plan | Rounded to 1 decimal place |
| `availableCapacity` | `totalCapacity − allocatedCapacity` | Negative values indicate overallocation; displayed in red in the capacity tooltip |
### Overallocation
When `availableCapacity` is negative, the user is overallocated for that Plan period. Planningboard displays this visually in the capacity tooltip.
The default tooltip (when no custom `columnTooltipTemplate` is configured) shows aggregate values: Capacity, Done, Todo, and Available.
### Plan-Level Metrics
| Metric | Description |
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `childRemainingEstimate` | Sum of remaining estimates across all child tasks within the Plan. Should approximate the sum of `allocatedCapacity` values when all tasks are assigned. |
| `allChildTasksCount` | Total number of child task work items in the Plan, regardless of assignment status. |
| `assigneeCount` | Number of unique users assigned to tasks in the Plan. Equals the number of entries in the per-user capacity breakdown. |
***
## Known Limitations
The following capacity limitations are confirmed from ticket analysis. Do not rely on features that are listed here as absent.
**Multi-assignee not supported**
Planningboard capacity load does not support multiple assignees on a single work item. If a work item has multiple assignees, capacity is not correctly distributed across them. This is a known gap compared to Nextedy GANTT.
**Sub-item effort not distributed**
Planningboard does not calculate capacity from sub-item efforts. Only direct remaining estimates on assigned tasks are used for `allocatedCapacity`. Hierarchical effort roll-up (as supported in GANTT) is not available.
**Teams service is a prerequisite**
Per-user capacity tracking (showing `totalCapacity`, `allocatedCapacity`, and `availableCapacity` per user per sprint) requires the Teams service to be configured. Without it, only aggregate effort totals are available. See [Teams Service Properties](/planningboard/reference/configuration-properties/teams-properties) for the Teams service setup.
***
## Configuration Example
The following is a complete example configuration combining all capacity properties:
```properties theme={null}
# Calendar fallback for users without a personal Polarion calendar
nextedy.gantt.calendarHolder=admin
# Enable capacity modifier fields on team work items
nextedy.gantt.useTeamCapacityModifiers=true
# Field name on team work items holding the modifier percentage (0-100)
nextedy.gantt.capacityModifierAField=capModA
```
With this configuration:
* Users without personal calendars inherit working hours and off days from the `admin` user's calendar.
* Team work items are checked for the `capModA` integer field, and its value reduces the team's computed capacity proportionally.
* Users with no resolved calendar and no `calendarHolder` still fall back to `totalCapacity = 0.0`.
***
## Related Pages
* [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) — per-widget parameters controlling whether capacity tracking is active on a board instance.
* [Teams Service Properties](/planningboard/reference/configuration-properties/teams-properties) — configuration properties for the Teams service, required for per-user capacity breakdown.
* [Configuration Properties](/planningboard/reference/configuration-properties/index) — all administration configuration properties for Planningboard.
* [Reference](/planningboard/reference/index) — full reference index.
**KB Articles**
* Planningboard: Customizable Statistics and Capacity Indicators
* Planningboard Widget Parameters
* Swimlane Assignment Types
**Support Tickets**
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
* [#4714](https://support.nextedy.com/helpdesk/tickets/4714)
* [#6605](https://support.nextedy.com/helpdesk/tickets/6605)
**Source Code**
* `capacityHelperData.cy.ts`
* `UserCapacityInfo.java`
* `capacityTooltipRendering.cy.ts`
* `PlanningBoardTeamsService.java`
* `IPlanningBoardTeamsService.java`
# Configuration Properties
Source: https://learn.nextedy.com/planningboard/reference/configuration-properties/index
Configuration properties are system-level settings that control global behavior of Nextedy PLANNINGBOARD across all board instances in a Polarion project.
This section covers the four property groups: appearance, capacity, Teams Service integration, and scripting.
Control the visual presentation of the board: card colors, highlighting rules, and custom-enum color mappings.
Configure calendar fallback for users without a personal calendar, and capacity modifier fields on team work items.
Configure the Teams Service integration used to resolve team membership and assignee-based swimlane capacity.
Register scripting hooks that extend board behavior: item scripts, config scripts, and data scripts.
**Configuration properties vs. widget parameters**
Configuration properties are set once at the project or system level and affect all board instances. [Widget parameters](/planningboard/reference/widget-parameters/index) are set per board instance directly in the Polarion page editor. When you need to tune a single board's layout, swimlanes, or Plan query, use widget parameters. When you need to change behavior that applies to every board in the project — such as capacity normalization rules or scripting hooks — use configuration properties.
## Property groups at a glance
## Where to set configuration properties
Configuration properties are administered through the Polarion administration interface, not through the page editor. Navigate to **Administration > Nextedy PLANNINGBOARD** to view and edit these properties for the current project.
**Capacity properties are whitespace-sensitive**
Values for capacity configuration properties must not have leading or trailing whitespace. Unexpected spaces in capacity property values cause silent misreads at runtime. Always verify values exactly as entered.
**KB Articles**
* Planningboard: Customizable Statistics and Capacity Indicators
* Planningboard Widget Parameters
* Swimlane Assignment Types
**Support Tickets**
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#6546](https://support.nextedy.com/helpdesk/tickets/6546)
**Source Code**
* `viewSetup.vm`
* `capacityHelperData.cy.ts`
* `capacityTooltipRendering.cy.ts`
* `Item.java`
* `IPlanningBoardTeamsService.java`
# Scripting Properties
Source: https://learn.nextedy.com/planningboard/reference/configuration-properties/scripting-properties
Reference for configuration properties that control scripting and custom rendering behaviour in Nextedy PLANNINGBOARD.
See [Configuration Properties](/planningboard/reference/configuration-properties/index) for an overview of the configuration property system. For the scripting API surface that these properties interact with, see [Scripting API](/planningboard/reference/api/scripting-api) and [Config Script API](/planningboard/reference/api/config-script-api).
***
## Overview
Scripting properties let administrators supply custom JavaScript templates and data objects that the board evaluates at render time. The primary use case is customising how capacity tooltips, column labels, and per-plan data appear on the board.
***
## Property Reference
### `columnTooltipTemplate`
| Property | Type | Default | Scope |
| ----------------------- | ---------------------- | ------------------------------- | ------------------------ |
| `columnTooltipTemplate` | `string` or `function` | *(default tooltip — see below)* | Board / scheduler config |
Controls the HTML rendered inside capacity tooltips on Plan columns. Accepts either a static string template or a JavaScript function that receives the column and row objects and returns an HTML string.
When `columnTooltipTemplate` is **not configured**, the board falls back to the default tooltip format, which shows aggregate capacity metrics:
| Field shown in default tooltip | Description |
| ------------------------------ | ------------------------------------ |
| Capacity | Total capacity for the column period |
| Done | Completed work within the column |
| Todo | Remaining work within the column |
| Available | Remaining capacity after allocation |
When `columnTooltipTemplate` **is configured**, the template receives `column` and `row` objects and can render per-user allocation breakdowns. The rendered HTML is stored on the `.capacityLoad` element's `data-html` attribute and displayed by the tooltip engine.
**Per-user allocation format (custom template)**
A custom template can expose the following data per team member:
| Field | Description |
| -------------- | ---------------------------------------------------------------------------- |
| Available | `totalCapacity - allocatedCapacity`; negative values indicate overallocation |
| Allocated | Sum of remaining estimates for tasks assigned to this user within the plan |
| Total Capacity | User's total capacity from the team calendar for the plan period |
**Overallocation indicator**
When `availableCapacity` is negative for a user, the tooltip renders the value in red text. This is a visual-only signal — the board does not prevent further assignment when a user is overallocated.
**Configuration example — function form**
```javascript theme={null}
columnTooltipTemplate: function(column, row) {
var html = '';
return html;
}
```
**Re-render required**
After programmatically changing `columnTooltipTemplate`, call `setCurrentView()` to trigger a re-render. Without this call, the board continues showing the previous tooltip template.
***
### `scriptData`
| Property | Type | Default | Scope |
| ------------ | -------- | ----------- | -------------------------------- |
| `scriptData` | `object` | `undefined` | Per-plan (`userData.scriptData`) |
Stores arbitrary custom data per plan in the scheduler configuration. This data is attached to each plan's `userData` object and is available inside `columnTooltipTemplate` functions and other custom rendering logic via `column.scriptData`.
The server-side capacity helper (`ColumnDataScriptHelper`) populates `scriptData` with capacity metrics for each plan. The board configuration is embedded server-side — not delivered via XHR — so `scriptData` values are available immediately when the board initialises.
**Fields populated by the capacity helper**
| Field | Type | Description |
| ------------------------ | -------- | --------------------------------------------------------------------- |
| `userCapacities` | `array` | Per-user capacity breakdown for the plan period (see below) |
| `childRemainingEstimate` | `number` | Aggregate sum of remaining estimates from all child tasks in the plan |
| `allChildTasksCount` | `number` | Total count of child task work items in the plan |
| `assigneeCount` | `number` | Number of unique assignees; always equals `userCapacities.length` |
**`userCapacities` entry structure**
| Field | Type | Description |
| ------------------- | -------- | ---------------------------------------------------------------------------------------------------------- |
| `userId` | `string` | Polarion user ID of the assignee |
| `allocatedCapacity` | `number` | Sum of remaining estimates for tasks assigned to this user; rounded to 1 decimal place |
| `totalCapacity` | `number` | Total capacity from the team calendar for the plan period; defaults to `0.0` when no calendar entry exists |
| `availableCapacity` | `number` | `totalCapacity - allocatedCapacity`; negative indicates overallocation; rounded to 1 decimal place |
**Zero fallback for missing calendar data**
Users without a team calendar entry for a plan's date range receive `totalCapacity: 0.0`. This means `availableCapacity` will equal `-allocatedCapacity` (always negative) for those users, which may trigger the overallocation indicator even when total capacity is simply unknown. Verify team calendar coverage when unexpected overallocation warnings appear.
**Configuration example — accessing scriptData in a tooltip template**
```javascript theme={null}
// Accessing scriptData from a column object inside columnTooltipTemplate
columnTooltipTemplate: function(column, row) {
var data = column.scriptData; // populated server-side per plan
if (!data) return ''; // guard: scriptData may be absent if capacity helper is not configured
var lines = ['Team capacity summary '];
lines.push('Tasks: ' + data.allChildTasksCount);
lines.push('Remaining: ' + data.childRemainingEstimate + 'h');
lines.push('Assignees: ' + data.assigneeCount);
return lines.join(' ');
}
```
***
### `setCurrentView()`
| Method | Returns | When to call |
| ------------------ | ------- | --------------------------------------------------------------------------------------- |
| `setCurrentView()` | `void` | After any programmatic change to scheduler configuration (e.g. `columnTooltipTemplate`) |
A method on the scheduler/board instance that refreshes the current view. Must be called after programmatically updating `columnTooltipTemplate` or other view configuration properties to trigger a re-render. Without calling `setCurrentView()`, the board continues to display stale rendered output.
**Not a configuration property**
`setCurrentView()` is a method on the board/scheduler instance, not a configuration property you set in a config object. It is documented here because it is the required companion to any programmatic change to scripting configuration properties such as `columnTooltipTemplate`.
***
## Related Configuration Properties
Scripting properties interact closely with capacity configuration. See the following references for the capacity properties that drive the data available in `scriptData`:
* [Capacity Properties](/planningboard/reference/configuration-properties/capacity-properties) — `nextedy.gantt.calendarHolder`, `nextedy.gantt.useTeamCapacityModifiers`, `nextedy.gantt.capacityModifierAField`, and related settings
* [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) — widget-level capacity parameters (`capacityLoad`, `userCapacityLoad`, `multiCapacityLoad`, `hoursPerDay`)
For the scripting API objects and functions available within templates:
* [Scripting API](/planningboard/reference/api/scripting-api) — overview of the scripting API
* [Config Script API](/planningboard/reference/api/config-script-api) — configuration script API reference
* [Data Script API](/planningboard/reference/api/data-script-api) — data script API reference
***
## Configuration Example
The following example shows a board configuration that uses `scriptData` and a custom `columnTooltipTemplate` together to render a per-user capacity tooltip with overallocation highlighting.
```javascript theme={null}
// Board / scheduler config object (embedded server-side)
{
// ... other board configuration properties ...
columnTooltipTemplate: function(column, row) {
var data = column.scriptData;
if (!data || !data.userCapacities || data.userCapacities.length === 0) {
// Fall back to default rendering when no user capacity data is available
return null;
}
var rows = data.userCapacities.map(function(u) {
var avail = u.availableCapacity;
var color = avail < 0 ? '#e53935' : '#43a047';
var label = avail < 0 ? '(overallocated)' : '';
return ''
+ '' + u.userId + ' '
+ '' + u.allocatedCapacity + 'h '
+ '' + u.totalCapacity + 'h '
+ '' + avail + 'h ' + label + ' '
+ ' ';
});
return ''
+ 'User Allocated Total Available '
+ '' + rows.join('') + ' '
+ '
'
+ 'Tasks: '
+ data.allChildTasksCount + ' | Remaining: ' + data.childRemainingEstimate + 'h
';
}
}
```
After applying this configuration, call `setCurrentView()` on the board instance to trigger a re-render.
***
## Limitations
**Verify in application**
The scripting properties documented here (`columnTooltipTemplate`, `scriptData`) are confirmed by test evidence (`capacityTooltipRendering.cy.ts`, `capacityHelperData.cy.ts`). The full set of scriptable configuration hooks beyond tooltip rendering is not confirmed by the available source context — do not assume that other rendering phases (card content, swimlane labels, etc.) expose equivalent template hooks unless confirmed in the product.
* **`columnTooltipTemplate` only** — custom scripting is confirmed for column capacity tooltips. Card-level, swimlane-level, and other rendering phases do not have confirmed equivalent scripting hooks in the available source context.
* **Server-side embedding** — `scriptData` is populated server-side and embedded into the board configuration at render time. It is not refreshed via live XHR after initial load.
* **No multi-assignee capacity distribution** — capacity calculations assign effort to the named assignee only; there is no distribution across multiple assignees per work item. See [Capacity Properties](/planningboard/reference/configuration-properties/capacity-properties) for the full list of known capacity limitations.
* **PARENT assignment mode incompatibility** — the `PARENT` swimlane assignment mode does not support plan normalization (`planCellsMode`). Scripting properties that rely on normalization data are unaffected when `planCellsMode` is disabled, but custom templates must account for the absence of normalization-derived fields when this mode is in use.
**KB Articles**
* Planningboard: Customizable Statistics and Capacity Indicators
* Planningboard Widget Parameters
* Troubleshooting Script Errors in Planningboard
**Support Tickets**
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
**Source Code**
* `capacityTooltipRendering.cy.ts`
* `PlanningBoardWidgetRenderer.java`
* `viewSetup.vm`
* `capacityHelperData.cy.ts`
* `unplanned_sidebar.js`
# Teams Service Properties
Source: https://learn.nextedy.com/planningboard/reference/configuration-properties/teams-properties
Reference for the Polarion Administration **Configuration Properties** that control the Teams Service integration in Nextedy PLANNINGBOARD.
For widget-level parameters that select a specific team or enable the teams service per board, see [Widget Parameters](/planningboard/reference/widget-parameters/index). For the scripting interface that reads team data at runtime, see [Teams Service API](/planningboard/reference/api/teams-service-api).
***
## Overview
The Teams Service powers per-swimlane capacity visualization and team-filtered user rows on the Planningboard. It must be enabled both at the widget level (`useTeamsService=true`) and configured via the properties below before team-based capacity data appears.
**Shared properties with Gantt**
Properties prefixed `nextedy.gantt.*` are shared between Planningboard and Nextedy GANTT. Changing them affects both products simultaneously.
***
## Core Teams Service Properties
### `nextedy.planningboard.useTeamsService`
| Attribute | Value |
| ------------------- | --------------- |
| **Type** | `boolean` |
| **Default** | `false` |
| **Available since** | See application |
Enables integration with the Planningboard Teams Service. When `true`, the board can retrieve team members, filter user swimlanes by team membership, and calculate per-user and per-team capacity from the team calendar.
When `false`, capacity values fall back to the plan's own configured capacity field or remain uncalculated.
**Widget parameter also required**
Setting this property to `true` activates the service globally, but each widget instance must also set `useTeamsService=true` in its widget parameters and specify a `selectedTeam`. Without a selected team, team-based capacity rows do not render. See [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters).
**Example:**
```properties theme={null}
nextedy.planningboard.useTeamsService=true
```
***
## Swimlane Filtering Properties
### `nextedy.planningboard.activeTeamAssignmentsInPlanRangeOnly`
| Attribute | Value |
| ------------------- | --------- |
| **Type** | `boolean` |
| **Default** | `false` |
| **Available since** | 25.12.0 |
When `true`, Planningboard shows only users whose Team Assignments overlap with the time range covered by the Plans currently displayed on the board. Users whose assignments fall entirely outside the shown Plan range (only in the past or only in the future relative to the displayed scope) are hidden from user swimlanes.
If a hidden user has work items assigned to them, those items move to the **Not Assigned/Other** swimlane rather than being lost.
**Required data structure:**
* A Polarion project with configured Teams and Team Assignments
* Planningboard configured with user-based swimlanes derived from Team Assignments
**Example:**
```properties theme={null}
nextedy.planningboard.activeTeamAssignmentsInPlanRangeOnly=true
```
**Troubleshooting**
If the property does not take effect after saving, make a minor change to any Configuration Property value and save again. This forces Polarion to flush its configuration cache.
**Interaction with `activeTeamAssignmentsOnly`:**
This property supersedes `nextedy.planningboard.activeTeamAssignmentsOnly` (deprecated in 25.12.0). The two properties serve overlapping purposes — enable only one at a time. The recommended property for new configurations is `activeTeamAssignmentsInPlanRangeOnly`.
***
### `nextedy.planningboard.activeTeamAssignmentsOnly`
| Attribute | Value |
| -------------------- | --------- |
| **Type** | `boolean` |
| **Default** | `false` |
| **Available since** | 25.3.0 |
| **Deprecated since** | 25.12.0 |
**Deprecated**
This property was deprecated in version 25.12.0. Use `nextedy.planningboard.activeTeamAssignmentsInPlanRangeOnly` instead. The deprecated property hides only users whose Team Assignments are entirely in the past, regardless of the Plans currently shown on the board. This behavior is less precise than the replacement.
When `true`, users with no active (present or future) Team Assignments are hidden from user swimlanes. Users with only past assignments are treated as inactive.
**Example:**
```properties theme={null}
nextedy.planningboard.activeTeamAssignmentsOnly=true
```
***
## Capacity Calculation Properties
These properties are shared with Nextedy GANTT and control how team and user capacity is calculated from calendar data.
### `nextedy.gantt.calendarHolder`
| Attribute | Value |
| ----------- | ----------------------------------- |
| **Type** | `string` (Polarion user ID) |
| **Default** | None (system default calendar used) |
Specifies a Polarion user ID whose calendar is used as a fallback when a team member has no personal calendar defined. This affects both working-hours calculation and off-days (holidays) determination within the Teams Service capacity engine.
When not set, the system default Polarion calendar applies. Setting a `calendarHolder` allows a shared "base calendar" user to represent standard working patterns for the organization.
**Example:**
```properties theme={null}
nextedy.gantt.calendarHolder=calendar_admin
```
***
### `nextedy.gantt.useTeamCapacityModifiers`
| Attribute | Value |
| ----------- | --------- |
| **Type** | `boolean` |
| **Default** | `false` |
When `true`, enables reading capacity modifier fields (`capModA`, `capModB` by default) from team work items. These fields hold integer percentages (0–100) that reduce the calculated team capacity proportionally.
This allows modeling scenarios such as overhead, meetings, or partial team availability without changing individual user calendars.
**Example:**
```properties theme={null}
nextedy.gantt.useTeamCapacityModifiers=true
```
Capacity modifiers apply to the aggregate team capacity calculation, not to individual user capacity rows. Individual user capacity continues to respect each user's own calendar and assignment percentage.
***
### `nextedy.gantt.capacityModifierAField`
| Attribute | Value |
| ----------- | ------------------- |
| **Type** | `string` (field ID) |
| **Default** | `capModA` |
Specifies the field ID on team work items that holds the primary capacity modifier percentage. The field must be an integer custom field on the team work item type. The value is treated as a percentage reduction applied to the computed team capacity.
Only read when `nextedy.gantt.useTeamCapacityModifiers=true`.
**Example:**
```properties theme={null}
nextedy.gantt.capacityModifierAField=teamOverheadPct
```
***
### `nextedy.gantt.capacityModifierBField`
| Attribute | Value |
| ----------- | ------------------- |
| **Type** | `string` (field ID) |
| **Default** | `capModB` |
Specifies the field ID on team work items that holds the secondary capacity modifier percentage. Behaves identically to `capacityModifierAField` but represents a second, independent reduction factor (for example, separating planned overhead from unplanned availability reduction).
Only read when `nextedy.gantt.useTeamCapacityModifiers=true`.
**Example:**
```properties theme={null}
nextedy.gantt.capacityModifierBField=teamAbsencePct
```
***
## Property Summary Table
| Property | Type | Default | Since | Description |
| ------------------------------------------------------------ | ------- | --------- | --------------- | -------------------------------------------------------------------- |
| `nextedy.planningboard.useTeamsService` | boolean | `false` | See application | Enables Teams Service integration for team membership and capacity |
| `nextedy.planningboard.activeTeamAssignmentsInPlanRangeOnly` | boolean | `false` | 25.12.0 | Hides users with no Team Assignments within the displayed Plan range |
| `nextedy.planningboard.activeTeamAssignmentsOnly` | boolean | `false` | 25.3.0 | **Deprecated 25.12.0.** Hides users with only past Team Assignments |
| `nextedy.gantt.calendarHolder` | string | None | See application | Fallback calendar user for capacity calculation |
| `nextedy.gantt.useTeamCapacityModifiers` | boolean | `false` | See application | Enables capModA/capModB modifier fields on team work items |
| `nextedy.gantt.capacityModifierAField` | string | `capModA` | See application | Field ID for primary capacity modifier percentage |
| `nextedy.gantt.capacityModifierBField` | string | `capModB` | See application | Field ID for secondary capacity modifier percentage |
***
## Capacity Calculation Model
When `useTeamsService=true`, capacity for each user in a Plan is calculated as follows:
```text theme={null}
totalCapacity = working hours in plan date range (from user calendar)
× assignment percentage (from Team Assignment work item)
allocatedCapacity = sum of remainingEstimate (from child task work items
for all tasks assigned to user within the plan)
availableCapacity = totalCapacity − allocatedCapacity
(negative = overallocated)
```
Both `allocatedCapacity` and `availableCapacity` are rounded to one decimal place. Users with no calendar entry and no team calendar fallback (`nextedy.gantt.calendarHolder`) receive `totalCapacity = 0.0`.
When `useTeamCapacityModifiers=true`, the aggregate team capacity is further reduced by the modifier percentages read from `capacityModifierAField` and `capacityModifierBField` on the team work item.
**Verify in application**
The exact formula for combining `capModA` and `capModB` (additive vs. multiplicative) is not confirmed in the available source context. Verify the combined modifier behavior against the live product before documenting it in downstream materials.
***
## Limitations
* **Custom Team work item types are not supported.** Planningboard requires the standard Nextedy Team work item structure with its specific custom fields (`from`, `to`, assignment percentage). Unlike Nextedy GANTT (which added support for custom team work item types in 25.5.0), Planningboard does not support custom team types. Projects requiring custom team structures should evaluate whether GANTT is the appropriate primary planning tool.
* **Page parameters not supported in swimlane configuration.** Polarion page parameters (e.g., `$pageParameters.xxx`) cannot be used to dynamically filter team-based swimlanes. Static workarounds include separate Planningboard pages per team or link-role–based swimlane assignment.
* **`activeTeamAssignmentsInPlanRangeOnly` requires a Plan date range.** If the displayed Plans have no start/due date, the property cannot determine the active range and falls back to showing all users.
***
## Configuration Example
The following example shows a complete Teams Service configuration for a project using team-based capacity bars and swimlane filtering by Plan range:
```properties theme={null}
# Enable Teams Service integration
nextedy.planningboard.useTeamsService=true
# Show only users with active assignments within the displayed Plans
nextedy.planningboard.activeTeamAssignmentsInPlanRangeOnly=true
# Use 'base_calendar' user as fallback calendar for users without personal calendars
nextedy.gantt.calendarHolder=base_calendar
# Enable capacity modifiers to account for team overhead
nextedy.gantt.useTeamCapacityModifiers=true
nextedy.gantt.capacityModifierAField=overheadPct
nextedy.gantt.capacityModifierBField=absencePct
```
In the widget parameters for each board that should use this configuration, also set:
```properties theme={null}
useTeamsService=true
selectedTeam=TeamAlpha
userCapacityLoad=true
```
For more on the widget-side parameters, see [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters).
***
## Related Pages
* [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) — widget-level parameters for enabling and displaying capacity bars
* [Capacity Properties](/planningboard/reference/configuration-properties/capacity-properties) — system-wide capacity calculation configuration
* [Teams Service API](/planningboard/reference/api/teams-service-api) — scripting interface for reading team and capacity data
* [SAFe Team Mode](/planningboard/reference/assignment-modes/safe-team-mode) — swimlane assignment by SAFe team
* [Assignee Mode](/planningboard/reference/assignment-modes/assignee-mode) — swimlane assignment by individual user
* [Configuration Properties](/planningboard/reference/configuration-properties/index) — index of all administration configuration properties
**KB Articles**
* Planningboard: Customizable Statistics and Capacity Indicators
* Planningboard Widget Parameters
* Filter user swimlanes by Plan range
**Support Tickets**
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
* [#6546](https://support.nextedy.com/helpdesk/tickets/6546)
* [#6496](https://support.nextedy.com/helpdesk/tickets/6496)
**Source Code**
* `PlanningBoardDataService.java`
* `IPlanningBoardTeamsService.java`
* `capacityHelperData.cy.ts`
* `Config.java`
* `PlanningBoardTeamsService.java`
# Fields
Source: https://learn.nextedy.com/planningboard/reference/fields/index
Nextedy PLANNINGBOARD surfaces data from three categories of Polarion objects — work items, Plans, and resources — onto the board.
Fields read from Polarion work items: identifiers, types, assignees, effort estimates, priorities, statuses, and custom fields that drive card appearance and capacity.
Fields read from Polarion Plans that control which Plans appear as columns, their display names, date ranges, and capacity limits.
Fields that represent people and team resources used for swimlane assignment and capacity normalization across the board.
**Field IDs are case-sensitive**
When referencing field IDs in widget parameters (for example in `sidebarFields`, `enumFieldId`, or `capacityField`), use the exact casing shown in Polarion's field definitions. Wrong casing fails silently at runtime.
## Related Reference
* [Widget Parameters](/planningboard/reference/widget-parameters/index) — configure which fields appear on cards and how Plans are queried
* [Assignment Modes](/planningboard/reference/assignment-modes/index) — how resource and work-item fields determine swimlane grouping
* [Plans Modes](/planningboard/reference/plans-modes/index) — how Plan fields drive column selection and ordering
**KB Articles**
* Swimlane Assignment Types
* Planningboard Widget Parameters
* Planningboard interface & basic interactions
**Support Tickets**
* [#5960](https://support.nextedy.com/helpdesk/tickets/5960)
* [#6496](https://support.nextedy.com/helpdesk/tickets/6496)
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
**Source Code**
* `Config.java`
* `PlanningBoardWidget.java`
* `PlanningBoardWidgetDependenciesProcessor.java`
* `widget.vm`
* `Resource.java`
# Plan Fields
Source: https://learn.nextedy.com/planningboard/reference/fields/plan-fields
This page lists the fields and properties used to create and configure Plans in Nextedy PLANNINGBOARD.
See also:
* [Work Item Fields](/planningboard/reference/fields/work-item-fields) — fields on work item cards
* [Resource Fields](/planningboard/reference/fields/resource-fields) — fields on swimlane resources
* [Plans (Columns) Parameters](/planningboard/reference/widget-parameters/plans-parameters) — widget parameters that control how Plans are loaded
* [Plans Modes](/planningboard/reference/plans-modes/index) — available planning mode options
***
## Plan creation parameters
These fields are set when creating a new Plan through Planningboard (via the **New Plan** feature in the toolbar). They correspond to the properties of `PlanParameters`.
| Name | Type | Default | Description |
| -------------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `projectID` | `string` | — | Polarion project ID where the Plan will be created. Must match an existing project. |
| `planId` | `string` | — | Unique identifier for the new Plan. Must be unique within the project. |
| `planName` | `string` | — | Human-readable display name for the Plan. Shown in the column header and reports. |
| `templateId` | `string` | — | Plan template ID to copy configuration from. The template must exist in the same project (for example: `iteration`, `release`). |
| `startDate` | `string` | — | Plan start date in ISO 8601 format (`YYYY-MM-DD`). |
| `dueDate` | `string` | — | Plan due date in ISO 8601 format (`YYYY-MM-DD`). |
| `parentId` | `string` | — | Optional parent Plan ID for hierarchical Plan structures. If set, the parent Plan must exist and be resolvable. |
| `teamId` | `string` | — | Team identifier for the Plan. The field that stores this value is controlled by the `com.nextedy.planningboard.createplans.team_field_id` configuration property. |
| `customFields` | `object` | `{}` | Map of custom field IDs to their values. Field types are validated against the Plan schema — supports enums and other types. |
### Configuration property
| Name | Type | Default | Description |
| ----------------------------------------------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------- |
| `com.nextedy.planningboard.createplans.team_field_id` | `string` | — | Specifies which custom field ID on the Plan represents team assignment. Read from the project's context properties. |
**Template ID examples**
Common values for `templateId` are `iteration` and `release`. The available templates depend on your Polarion project configuration. Check **Administration > Plans** in Polarion to see the template IDs available for your project.
***
## Plan display configuration (widget parameters)
These parameters control which Plans are shown on the board and how they are displayed. They are set per widget instance in the widget parameters editor.
| Name | Type | Default | Description |
| ----------------- | --------- | -------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `plansMode` | `string` | `PROJECT_PLANS` | Determines the planning model. See [Plans Modes](/planningboard/reference/plans-modes/index) for all available values. |
| `plansQuery` | `string` | — | Lucene query to filter which Plans are displayed as columns on the board. |
| `lastPlans` | `number` | `1` | Number of past or completed Plans to display on the board. |
| `nextPlans` | `number` | `5` | Number of future or upcoming Plans to display on the board. |
| `planLink` | `string` | `/polarion/#/project/${plan.objectId.projectId}/plan?id=${plan.objectId.itemId}` | URL template for linking to individual Plans when clicking a column label. Supports `${plan.*}` variables. |
| `stemming` | `boolean` | `false` | Enable automatic Plan generation by parsing resource field values — splits enum values into plan-resource pairs. |
| `planCellsMode` | `boolean` | `false` | Enable plan cells mode for SAFe or stemming-based planning. Items belong to specific plan-resource cells. |
| `plansTemplateId` | `string` | — | Polarion Plan template ID to use when generating Plans automatically. |
### Plans mode values
| Value | Description | Reference |
| ------------------ | ---------------------------------------------------------------- | --------------------------------------------------------------------------- |
| `PROJECT_PLANS` | Standard Polarion Plans for a single project. | [Project Plans](/planningboard/reference/plans-modes/project-plans) |
| `SAFE_SPRINTS` | SAFe sprint Plans at program level (single Agile Release Train). | [SAFe Sprints](/planningboard/reference/plans-modes/safe-sprints) |
| `SAFE_PFL_SPRINTS` | SAFe portfolio-level sprint Plans. | [SAFe Sprints](/planningboard/reference/plans-modes/safe-sprints) |
| `SAFE_PIS` | SAFe Program Increments. | [SAFe Program Increments](/planningboard/reference/plans-modes/safe-pis) |
| `SAFE_SOLUTION` | SAFe Solution Train Plans. | [SAFe Solution Trains](/planningboard/reference/plans-modes/safe-solutions) |
**Plan items configuration is only available in Project Plans (`PROJECT_PLANS`) mode**
The plan items configuration section in the widget parameters editor is only shown when `plansMode` is set to `PROJECT_PLANS`. SAFe modes use a different configuration path.
***
## Plan scheduling fields
These fields are on the Plan data model itself (as resolved from Polarion) and drive how Planningboard assigns work items to Plans.
| Name | Type | Description |
| ------------ | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `start_date` | `date` | The Plan's start date. Planningboard uses this when assigning work items to Plans by date range — items are added to Plans whose date range spans the item's scheduled dates. |
| `end_date` | `date` | The Plan's due date (end date). Used alongside `start_date` for date-based Plan assignment logic. |
**Date-based plan assignment**
When a work item is dragged onto a Plan column, Planningboard assigns it to Plans whose `start_date`–`end_date` range spans the item's dates. If `stemming` is enabled and `syncSAFEParentsFromChildren` applies, parent Plans are automatically updated when team assignments change.
***
## Plan link URL template
The `planLink` parameter accepts a URL template with `${plan.*}` variable substitution. Clicking a column header opens the resolved URL.
| Variable | Resolves to |
| ---------------------------- | ----------------------------------- |
| `${plan.objectId.projectId}` | The Polarion project ID of the Plan |
| `${plan.objectId.itemId}` | The Plan ID within the project |
### Example — link to Polarion Plan page
```properties theme={null}
planLink=/polarion/#/project/${plan.objectId.projectId}/plan?id=${plan.objectId.itemId}
```
### Example — link to a custom report parameterized by Plan
```properties theme={null}
planLink=/polarion/#/project/${plan.objectId.projectId}/wiki/REPORTS/SprintReport?plan=${plan.objectId.itemId}
```
***
## New Plan configuration
These parameters appear in the **New Plan** section of the widget parameters editor. They define the rules used when a user creates a Plan directly from the Planningboard toolbar.
| Name | Type | Default | Description |
| ------------------- | ---------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Template ID` | `string` | — | The plan template type to use when creating a new Plan (for example: `iteration`, `release`). |
| `Parent ID` | `string` | — | Optional parent Plan ID. New Plans will be created as children of this Plan. |
| `Plan Name Pattern` | `string` | — | Display name pattern for newly created Plans. Supports Teams variable substitution when Teams are enabled. |
| `Plan ID Pattern` | `string` | — | ID pattern that newly created Plans follow. Supports Teams variable substitution when Teams are enabled. |
| `New Plan Duration` | `duration` | — | Duration for newly created Plans. |
| `Enable Teams` | `boolean` | `false` | When enabled, new Plans are created per team using the Teams configuration. |
| `Teams` | `array` | — | List of team name and ID pairs used when `Enable Teams` is active. |
| `Last Plan Query` | `string` | — | Lucene query to find the "last Plan" as the reference point for new Plan creation. When empty, defaults to the latest Plan in the same project with the same template type. |
| `Last Plan Sort` | `string` | — | Determines which Plan from the `Last Plan Query` result is treated as the last one. When empty, sorts by `dueDate` descending (Plan with the latest due date). |
**Plan Name Pattern and Plan ID Pattern with Teams**
When `Enable Teams` is active, the Plan Name Pattern and Plan ID Pattern fields come pre-populated with Teams variable syntax. If you are **not** using Teams, change these patterns — the default values include team substitution tokens that will not resolve correctly without the Teams configuration.
### New Plan without Teams — example
```text theme={null}
Template ID: iteration
Parent ID: Version_3_0
Plan Name Pattern: Iteration {planNum}
Plan ID Pattern: Iteration_{planNum}
New Plan Duration: 14d
Enable Teams: false
```
This creates a new iteration under `Version_3_0` each time the **+** button is clicked in the toolbar.
### New Plan with Teams — example
```text theme={null}
Template ID: iteration
Enable Teams: true
Teams:
- name: Team Alpha id: team_alpha
- name: Team Beta id: team_beta
```
With Teams enabled, one Plan is created per team when the **+** button is clicked.
***
## Capacity-related Plan fields
These parameters control how Plan capacity is calculated and displayed. They interact with the capacity bar shown on each Plan column.
| Name | Type | Default | Description |
| ------------------- | --------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `capacityLoad` | `boolean` | `false` | Enable capacity loading calculations for Plans. When `true`, capacity bars appear on each Plan column. |
| `multiCapacityLoad` | `boolean` | `false` | Enable per-swimlane or per-resource capacity tracking across multiple Plans simultaneously. |
| `userCapacityLoad` | `boolean` | `false` | Enable user-level capacity loading. Requires `useTeamsService=true`. |
| `capacityField` | `string` | — | Custom field ID containing capacity values (for example: story points, hours). When set, capacity is read from this field rather than time-tracking fields. |
| `hoursPerDay` | `number` | `8` | Number of working hours per day used in capacity calculations that convert between time-based and day-based values. |
| `useTeamsService` | `boolean` | `false` | Enable integration with the Planningboard Teams Service for team capacity, user capacity, and team member data. When enabled, this overrides plan-level `capacity` values with team service data. |
**Consistent calculation types are required across all Plans**
All Plans displayed on the board must use the same calculation type. Mixing calculation types across Plans causes incorrect capacity summation. This is a critical setup requirement — verify all Plans in your project use a consistent type before enabling capacity display.
**Enabling team capacity visualization**
To enable per-swimlane capacity visualization (as shown in the demo board), set `useTeamsService=true` in your widget parameters. Without this property, team capacity data is not loaded and the capacity bar reflects only plan-level totals.
***
## Plan fields diagram
***
## Configuration example
The following example shows a complete widget parameter configuration for a sprint-planning board using Project Plans with capacity enabled:
```properties theme={null}
# Plans (Columns)
plansMode=PROJECT_PLANS
lastPlans=1
nextPlans=5
plansQuery=type:iteration AND NOT status:closed
planLink=/polarion/#/project/${plan.objectId.projectId}/plan?id=${plan.objectId.itemId}
# Capacity
capacityLoad=true
hoursPerDay=8
capacityField=storyPoints
useTeamsService=true
# New Plan creation
templateId=iteration
parentId=Version_3_0
```
**Verify in application**
The exact field IDs for `capacityField` depend on your Polarion project's custom field configuration. Check **Administration > Work Item Custom Fields** in Polarion for available field IDs.
***
## Related reference
* [Plans Modes](/planningboard/reference/plans-modes/index) — full list of `plansMode` values and when to use each
* [Plans (Columns) Parameters](/planningboard/reference/widget-parameters/plans-parameters) — all widget parameters for Plans columns
* [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) — full capacity configuration reference
* [Work Item Fields](/planningboard/reference/fields/work-item-fields) — fields on work item cards displayed within Plan columns
* [SAFe Parameters](/planningboard/reference/widget-parameters/safe-parameters) — SAFe-specific Plan configuration
**KB Articles**
* Planningboard Widget Parameters
* Introduction to Planningboard
* Planningboard interface & basic interactions
**Support Tickets**
* [#5960](https://support.nextedy.com/helpdesk/tickets/5960)
* [#6496](https://support.nextedy.com/helpdesk/tickets/6496)
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
**Source Code**
* `PlanningBoardWidget.java`
* `PlanningBoardWidgetDependenciesProcessor.java`
* `PlanningBoardDataService.java`
* `widget.vm`
* `Item.java`
# Resource Fields
Source: https://learn.nextedy.com/planningboard/reference/fields/resource-fields
Reference for the resource (swimlane) data model used in Nextedy PLANNINGBOARD. Resources map Polarion users onto swimlane rows and drive capacity calculations.
***
## Overview
In Planningboard a **resource** is the entity that represents one swimlane row when the board uses an assignee-based or teams-based layout. Resources are created automatically from Polarion users and carry the data the board needs to show labels, calculate capacity, and route work items to the correct row.
***
## Resource Fields
| Field | Type | Default | Description |
| --------------- | -------------------- | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `label` | `string` | User name or user ID | Display name shown in the swimlane header. Derived from the Polarion user's name. Falls back to the user ID when the user cannot be resolved. |
| `objectId` | `ObjectID` | — | Polarion object identity of the resource. Contains the project ID and item ID (user ID). Used internally to route work item assignments. |
| `multiCapacity` | `Map` | `{}` | Map of named capacity values for this resource. Keys are capacity type names; values are numeric capacity amounts (typically hours). Populated when multi-capacity tracking is enabled. |
***
## Label Resolution
The `label` field is set at resource creation time from the Polarion user object.
| Condition | Label value |
| ------------------------------------------ | --------------------------------------------------------- |
| User is resolvable and has a display name | User's display name (full name as configured in Polarion) |
| User is resolvable but has no display name | User ID string |
| User is **unresolvable** | User ID string (fallback) |
**Unresolvable users**
When a Polarion user account is deactivated or removed, the corresponding resource becomes unresolvable. Planningboard falls back to displaying the user ID as the swimlane label. Work items assigned to that user remain on the board but the swimlane label loses the human-readable name. Remove or reassign such work items to keep the board clean.
***
## `multiCapacity` Map
The `multiCapacity` field is a map that supports storing more than one capacity value per resource. This is used when `multiCapacityLoad` is enabled in the widget configuration.
| Map key | Map value type | Meaning |
| ----------------------------- | -------------- | ----------------------------------------------- |
| Capacity type name (`string`) | `float` | Capacity amount for that type (typically hours) |
**When populated:** `multiCapacity` entries are written when the board loads capacity data in multi-capacity mode. With `multiCapacityLoad = false` (the default), the map is empty and capacity is tracked at the plan level only.
**Units:** capacity values are floating-point numbers. The unit depends on your project configuration — typically hours, derived from the `hoursPerDay` parameter and the plan date range.
**Capacity mode interaction**
`multiCapacity` is only meaningful when `multiCapacityLoad = true` is set in the widget parameters. See [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) for the full capacity configuration reference.
***
## Item-Level Resource Fields
Work items on the board carry resource assignment fields that connect them to a resource (swimlane row). These fields live on the `Item` model, not on the `Resource` model itself, but they are the link between a card and its swimlane.
| Field | Type | Description |
| ------------- | -------------- | -------------------------------------------------------------------------------------------- |
| `resourceId` | `string` | ID of the single resource (user) assigned to this item. Used for single-assignee assignment. |
| `resourceIds` | `List` | List of resource IDs when an item is assigned to multiple resources. |
### Single vs. Multiple Resource Assignment
| Scenario | Field used | Notes |
| ------------------ | ------------- | ---------------------------------------------------- |
| Single assignee | `resourceId` | Standard case. Item appears in exactly one swimlane. |
| Multiple assignees | `resourceIds` | Item may appear in more than one swimlane row. |
**Verify in application**
Multi-resource assignment (`resourceIds`) is present in the data model. Confirm behavior in the live Planningboard application for your version — specifically how an item with multiple resource IDs is displayed across swimlanes.
***
## Resource Creation from Polarion Users
Resources are not configured manually. Planningboard creates them automatically by reading the Polarion user list for the project, filtered by the role configured in the widget's **User Role** parameter.
The `Resource(IUser user)` constructor sets `label` from `user.getName()` (or falls back to `user.getId()` when `isUnresolvable()` is true).
A separate constructor `Resource(ObjectID objectId)` exists for deserialization and programmatic creation via the scripting API.
***
## Assignment Modes That Use Resources
Resources (and their fields) are active only when the board's `assignmentMode` routes items through user-based or enum-based swimlanes. The table below shows which modes create resource objects.
| Assignment Mode | Resources created from | Resource label source |
| ----------------- | --------------------------------------- | --------------------- |
| `ASSIGNEE` | Polarion users with the configured role | User display name |
| `ENUM` | Enum field values on work items | Enum value label |
| `PARENT` | Parent work items | Parent item title |
| `PROJECT` | Polarion projects | Project name |
| `SAFE_TEAM` | SAFe team work items | Team name |
| `SAFE_TRAIN_TEAM` | SAFe Agile Release Train teams | Team name |
| `SAFE_PROGRAMS` | SAFe Programs | Program name |
| `none` | — (no swimlanes) | — |
For the full assignment mode reference, see [Assignment Modes](/planningboard/reference/assignment-modes/index).
***
## Capacity Fields on Resources
When capacity tracking is active, resource-level capacity data flows from the Teams Service into the `multiCapacity` map. The following configuration properties control this behavior.
| Configuration property | Default | Effect on resource capacity |
| ---------------------- | ------- | ------------------------------------------------------------------------------------------ |
| `capacityLoad` | `false` | Enables effort tracking. Without this, capacity bars are not shown. |
| `multiCapacityLoad` | `false` | Enables per-swimlane capacity breakdown via `multiCapacity`. |
| `userCapacityLoad` | `false` | Enables individual user capacity loading from the Teams Service. |
| `useTeamsService` | `false` | Activates the Teams Service integration that provides per-user and per-team capacity data. |
| `capacityField` | `None` | Custom field ID to use as the capacity value instead of time-tracking fields. |
| `hoursPerDay` | `8` | Working hours per day used in capacity calculations. |
See [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) and [Capacity Properties](/planningboard/reference/configuration-properties/capacity-properties) for the full capacity configuration reference.
***
## Report Link Parameterization
The swimlane **Report Link** widget parameter can embed the resource's identity into a URL. Use the `${r.objectId.itemId}` placeholder to insert the user ID of the resource associated with a swimlane.
**Example report link value:**
```text theme={null}
/polarion/#/project/PlanningBoard/wiki/SOME_REPORT?user=${r.objectId.itemId}
```
This opens a Polarion Wiki report filtered to the user whose swimlane was clicked. Configure this in **Widget Parameters > Swimlanes (Rows) > Report Link**.
***
## Configuration Example
The example below shows a board using **Users (Assignee)** (`ASSIGNEE`) mode with capacity tracking enabled via the Teams Service.
**Widget parameters (relevant excerpt):**
```properties theme={null}
# Swimlane assignment
assignmentMode=ASSIGNEE
userRole=project_user
# Capacity
capacityLoad=true
userCapacityLoad=true
useTeamsService=true
hoursPerDay=8
```
**Result on the board:**
Each swimlane label (`Alex Seller`, `Carl User`) comes from the resource's `label` field. The capacity bar reads from the resource's capacity data loaded by the Teams Service.
***
## Limitations
* **Single-assignee only in standard modes:** The `resourceId` (single resource) is the primary assignment path. Multi-resource assignment via `resourceIds` is present in the data model but capacity aggregation behavior across multiple resources should be verified in the live application.
* **No multi-assignee capacity distribution:** Effort for a work item is not automatically split across multiple assignees. This is a known capacity-load limitation compared to Nextedy GANTT. See the capacity documentation for current behavior.
* **User role drives swimlane membership:** Only users who hold the configured role in the project appear as swimlane rows. Users outside that role are not shown even if they are assigned to work items on the board.
* **Unresolvable users:** Deactivated Polarion users cause a label fallback to user ID. There is no automatic cleanup of swimlane rows for removed users.
***
## Related Pages
* [Work Item Fields](/planningboard/reference/fields/work-item-fields) — fields on cards (including `resourceId`, `resourceIds`, effort fields)
* [Plan Fields](/planningboard/reference/fields/plan-fields) — fields on Plan columns
* [Assignment Modes](/planningboard/reference/assignment-modes/index) — how items map to swimlane rows
* [Swimlanes (Rows) Parameters](/planningboard/reference/widget-parameters/swimlanes-parameters) — widget parameters controlling swimlane behavior
* [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) — widget parameters for capacity tracking
* [Capacity Properties](/planningboard/reference/configuration-properties/capacity-properties) — system-level capacity configuration
* [Teams Service Properties](/planningboard/reference/configuration-properties/teams-properties) — Teams Service configuration
**KB Articles**
* Planningboard Widget Parameters
* Swimlane Assignment Types
* Planningboard interface & basic interactions
**Support Tickets**
* [#5960](https://support.nextedy.com/helpdesk/tickets/5960)
* [#6496](https://support.nextedy.com/helpdesk/tickets/6496)
* [#6523](https://support.nextedy.com/helpdesk/tickets/6523)
**Source Code**
* `Resource.java`
* `PlanningBoardWidgetDependenciesProcessor.java`
* `Config.java`
* `PlanningBoardWidget.java`
* `PlanningBoardDataService.java`
# Work Item Fields
Source: https://learn.nextedy.com/planningboard/reference/fields/work-item-fields
This page lists the work item fields that Nextedy PLANNINGBOARD reads, writes, and exposes through its data model. Fields are grouped by functional area.
***
## Core Identity Fields
These fields identify the work item and are always loaded.
| Field | Type | Description |
| ------- | ------ | ------------------------------------------------------------------------------------------------------------------------ |
| `id` | string | Polarion work item ID (e.g. `PROJ-42`). Read-only. |
| `title` | string | Work item title/summary. Displayed on cards and in the sidebar. |
| `type` | string | Work item type ID (e.g. `task`, `story`, `feature`). Used by the `wiType` widget parameter to restrict which items load. |
***
## Scheduling and Date Fields
Planningboard uses both actual and planned dates to support baseline planning and schedule variance tracking.
| Field | Type | Description |
| --------------- | ---- | -------------------------------------------------------------------------------------------- |
| `start_date` | date | Actual or scheduled start date. Used when assigning an item to a Plan. |
| `end_date` | date | Actual or scheduled end date. Used with `start_date` to determine which Plan spans the item. |
| `planStartDate` | date | Originally planned start date. Distinct from `start_date`; supports baseline comparison. |
| `planEndDate` | date | Originally planned end date. Distinct from `end_date`; supports schedule variance tracking. |
**Date precedence**
`start_date` and `end_date` drive plan assignment logic. `planStartDate` and `planEndDate` are stored for baseline reference only and do not affect which Plan an item is placed in.
***
## Effort and Capacity Fields
These fields power the capacity bar and capacity load calculations. Planningboard derives `effort`, `effortDone`, and `effortTodo` from Polarion's time-tracking fields or from a custom capacity field (configured via the `capacityField` widget parameter).
| Field | Type | Description |
| ------------ | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `effort` | number | Total estimated effort/work for the item. In time-tracking mode this is derived from `initialEstimate`. |
| `effortDone` | number | Effort already completed. In time-tracking mode this is derived from `timeSpent`. For resolved items, `effortDone` is set equal to `effort` and `effortTodo` is set to `0`. |
| `effortTodo` | number | Remaining effort still required. In time-tracking mode this is derived from `remainingEstimate`. |
### Effort Calculation Modes
**Calculation type consistency**
All Plans in a project must use the same calculation type (time-based or custom field). Mixing calculation types across Plans causes incorrect effort summation in capacity bars. Verify this in your Polarion project configuration before enabling capacity load.
### Related Widget Parameters
| Parameter | Default | Description |
| ------------------- | -------- | ----------------------------------------------------------------------------- |
| `capacityLoad` | `false` | Enable capacity/effort tracking on work items and Plans. |
| `multiCapacityLoad` | `false` | Enable per-swimlane or per-resource capacity aggregation. |
| `userCapacityLoad` | `false` | Enable user-level capacity loading when using the Teams service. |
| `capacityField` | *(none)* | Custom field ID to use as the effort source instead of time-tracking fields. |
| `hoursPerDay` | `8` | Working hours per day used when converting Polarion duration values to hours. |
See [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) for the full parameter listing.
***
## Resource Assignment Fields
These fields control which swimlane an item appears in and support multi-resource assignment scenarios.
| Field | Type | Description |
| ------------- | --------- | --------------------------------------------------------------------------------------------------- |
| `resourceId` | string | Single resource (user) assigned to this item. Drives swimlane placement in Assignee mode. |
| `resourceIds` | string\[] | List of multiple resources assigned to the item. Populated when an item has more than one assignee. |
**Multi-resource assignment**
`resourceIds` stores all assignees when multiple users are assigned. However, Planningboard's capacity load does not distribute effort across multiple assignees — the item's full effort appears under each assigned swimlane. This is a known limitation relative to Nextedy GANTT's multi-assignee support. See [Assignee Mode](/planningboard/reference/assignment-modes/assignee-mode) for details.
### Assignment Mode Impact on Resource Fields
| Assignment Mode | Field Used | Notes |
| ----------------- | ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------- |
| `ASSIGNEE` | `resourceId` / `resourceIds` | Swimlane = assignee from Polarion user role. |
| `ENUM` | Custom enum field (configured via `enumFieldId`) | Supports single and multi-value enum fields. Status, resolution, and type fields are not supported as enum swimlane sources. |
| `PARENT` | Parent link role | Swimlane = parent work item. Does not support plan normalization (`planCellsMode`). |
| `PROJECT` | Project ID | Swimlane = sub-project. Only readable sub-projects are included. |
| `SAFE_TEAM` | SAFe team data | Requires Polarion SAFe Solution. |
| `SAFE_TRAIN_TEAM` | ART-filtered SAFe team data | Requires ART ID parameter. |
| `SAFE_PROGRAMS` | SAFe program data | Requires portfolio-level SAFe Solution. |
| `none` | *(no swimlane grouping)* | All items appear in a single row. |
See [Assignment Modes](/planningboard/reference/assignment-modes/index) for configuration details for each mode.
***
## Dependency Fields
| Field | Type | Description |
| -------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `dependencies` | string\[] | Set of work item IDs that this item depends on (predecessor relationships). Populated from link roles configured in `dependencyLinkRoles`. |
Dependency links are visualized as arrows on the board when **Show Dependencies** is enabled in the toolbar. The link roles that define dependency relationships are configured via the `Dependency Roles` widget parameter.
See [Work Items Parameters](/planningboard/reference/widget-parameters/work-items-parameters) for the `PARAMETER_DEPENDENCY_LINK_ROLE` setting.
***
## Sidebar Display Fields
When a user clicks a card, the **Work Item Properties** sidebar opens. The fields shown in the sidebar are configured via the `Sidebar Fields` widget parameter (`PARAMETER_SIDEBAR_FIELDS`).
| Default Sidebar Fields | Field ID | Notes |
| ---------------------- | ----------- | ---------------------------------------------- |
| Title | `title` | Always visible on the card and in the sidebar. |
| Status | `status` | Work item status enum. |
| Planned In | `plannedIn` | Plans the item is currently assigned to. |
Additional fields can be added by listing their Polarion field IDs in the sidebar fields configuration. Users can also personalize visible fields using the gear icon in the sidebar; these personal selections apply only to that user and affect all work items of the same type.
**Preserving scroll position**
When you save changes in the sidebar, Planningboard preserves your swimlane and scroll position. The board does not jump back to the top after saving.
***
## Card Display Fields (Item Script)
The content of each card is customizable via the **Item script** in the Advanced Parameters section. The `wiFields` API exposes work item fields for rendering.
### Commonly Used Fields in Item Scripts
```javascript theme={null}
// Display assignee on the card
wiFields.assignee().render()
// Display status
wiFields.status().render()
// Display remaining estimate
wiFields.remainingEstimate().render()
// Display a custom field by ID
wiFields.customField("myFieldId").render()
```
**Adding assignee to cards**
A common request is to show the assignee alongside the work item ID, title, and remaining estimate. Add `wiFields.assignee().render()` to the Item script in the Advanced properties section. See [Item Script API](/planningboard/reference/api/item-script-api) for the full `wiFields` reference.
See [Advanced Parameters](/planningboard/reference/widget-parameters/advanced-parameters) for the Item script parameter, and [Item Script API](/planningboard/reference/api/item-script-api) for the complete `wiFields` API surface.
***
## Work Item Type Filtering
The `wiType` widget parameter restricts which work item types are loaded onto the board. Only items matching the specified type ID are shown; items of other types are excluded from both the board and the unplanned sidebar.
| Parameter | Type | Default | Description |
| --------- | ------ | -------------------- | -------------------------------------------------------------------------------- |
| `wiType` | string | *(none — all types)* | Work item type ID to restrict displayed items (e.g. `task`, `story`, `feature`). |
Changing the work item type also affects which enum field values are available in the Rows Filter for Enumeration Field swimlane mode — enum options are type-specific and reflect the per-type enumeration configuration in Polarion.
***
## Query and Scope Fields
These parameters determine which work items are loaded onto the board.
| Parameter | Type | Default | Description |
| ------------ | ------- | ---------- | ------------------------------------------------------------------------------------------------- |
| `query` | string | `NOT *:*` | Lucene query to filter work items displayed on the board. |
| `maxItems` | number | `1000` | Maximum number of work items to load. Applies across all Plans. |
| `addPlanned` | boolean | *(see UI)* | When enabled, loads all planned items in addition to those matched by the type and query filters. |
***
## Configuration Example
The following widget parameter excerpt shows a typical Work Items configuration referencing these fields:
```properties theme={null}
# Work item type to display
wiType=story
# Lucene query — load open stories only
query=type:story AND NOT status:done
# Maximum items to load
maxItems=500
# Sidebar fields to show when clicking a card
sidebarFields=title,status,plannedIn,remainingEstimate,assignee
# Capacity field — use story points custom field instead of time tracking
capacityField=storyPoints
# Dependency link roles
dependencyLinkRoles=depends_on
```
**Sidebar fields format**
`sidebarFields` takes a comma-separated list of Polarion field IDs. Use exact field IDs as they appear in your Polarion project configuration — wrong IDs fail silently.
***
## Limitations
* **No multi-assignee effort distribution.** When a work item has multiple assignees (`resourceIds`), its full effort is counted under each assigned swimlane rather than split proportionally. This differs from Nextedy GANTT behavior.
* **Sub-item effort distribution not supported.** Capacity bars reflect effort on the direct work item only; child item effort is not automatically rolled up.
* **Enum swimlane restrictions.** The `status`, `resolution`, and `type` built-in Polarion fields cannot be used as Enumeration Field swimlane sources.
* **Parent mode and normalization.** Assignment mode **Parent Item** (`PARENT`) does not support plan normalization (`planCellsMode`).
* **Calculation type consistency.** All Plans in the project must use the same calculation type. Mismatches produce incorrect capacity totals with no runtime error.
***
## Related Reference Pages
* [Work Items Parameters](/planningboard/reference/widget-parameters/work-items-parameters) — widget parameters for filtering and displaying work items
* [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) — effort, capacity, and teams service parameters
* [Assignment Modes](/planningboard/reference/assignment-modes/index) — how resource fields map to swimlanes
* [Item Script API](/planningboard/reference/api/item-script-api) — `wiFields` API for card content customization
* [Plan Fields](/planningboard/reference/fields/plan-fields) — fields on Plan objects (columns)
* [Resource Fields](/planningboard/reference/fields/resource-fields) — fields on resource (assignee/team) objects
**KB Articles**
* Planningboard interface & basic interactions
* Planningboard Widget Parameters
* Swimlane Assignment Types
**Support Tickets**
* [#5960](https://support.nextedy.com/helpdesk/tickets/5960)
* [#6496](https://support.nextedy.com/helpdesk/tickets/6496)
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
**Source Code**
* `Config.java`
* `PlanningBoardWidget.java`
* `widget.vm`
* `Item.java`
* `enum-rows-filter.cy.ts`
# Reference
Source: https://learn.nextedy.com/planningboard/reference/index
The Reference section is the complete technical lookup for Nextedy PLANNINGBOARD.
**Start here if you are new to configuration**
[Widget Parameters](/planningboard/reference/widget-parameters/index) covers the most frequently used options — they control what Plans appear as columns, how swimlanes are grouped, and how capacity is tracked. If you are setting up a board for the first time, see [Create Your First Planningboard](/planningboard/getting-started/first-planning-board) first.
## Widget Parameters
Widget parameters configure each individual board instance embedded in a Polarion page. Set them in the widget editor when inserting the board widget.
**[Widget Parameters](/planningboard/reference/widget-parameters/index)** — Overview of all widget parameter groups
**[Plans (Columns) Parameters](/planningboard/reference/widget-parameters/plans-parameters)** — Parameters that control which Plans appear as board columns and how they are queried
**[Swimlanes (Rows) Parameters](/planningboard/reference/widget-parameters/swimlanes-parameters)** — Parameters that control swimlane grouping, assignment type, sorting, and filtering
**[Work Items Parameters](/planningboard/reference/widget-parameters/work-items-parameters)** — Parameters that control which work items appear on the board and how cards are rendered
**[Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters)** — Parameters that configure capacity bars, normalization, and effort tracking per swimlane
**[UI and Display Parameters](/planningboard/reference/widget-parameters/ui-parameters)** — Parameters that control board appearance, card content, and highlighting rules
**[SAFe Parameters](/planningboard/reference/widget-parameters/safe-parameters)** — Parameters specific to SAFe (Scaled Agile Framework) planning boards
**[Advanced Parameters](/planningboard/reference/widget-parameters/advanced-parameters)** — Low-level and infrequently changed parameters for specialized configurations
## Configuration Properties
Configuration properties are system-wide settings applied at the server or project level. They are set in administration properties files rather than per-widget.
**[Configuration Properties](/planningboard/reference/configuration-properties/index)** — Overview of all server-side configuration properties
**[Appearance Properties](/planningboard/reference/configuration-properties/appearance-properties)** — Properties that control default board appearance and card display
**[Capacity Properties](/planningboard/reference/configuration-properties/capacity-properties)** — Properties that govern capacity calculation behaviour and normalization defaults
**[Teams Service Properties](/planningboard/reference/configuration-properties/teams-properties)** — Properties for the integrated Teams service
**[Scripting Properties](/planningboard/reference/configuration-properties/scripting-properties)** — Properties that enable and configure the scripting extension points
## API Reference
The scripting and REST interfaces let you extend board behaviour programmatically.
**[API Reference](/planningboard/reference/api/index)** — Overview of all API surfaces
**[Scripting API](/planningboard/reference/api/scripting-api)** — Entry point for board-level scripting
**[Item Script API](/planningboard/reference/api/item-script-api)** — Methods available in per-card item scripts
**[Config Script API](/planningboard/reference/api/config-script-api)** — Methods available in board configuration scripts
**[Data Script API](/planningboard/reference/api/data-script-api)** — Methods for reading and transforming board data in scripts
**[REST API](/planningboard/reference/api/rest-api)** — HTTP endpoints exposed by the Planningboard server
**[Teams Service API](/planningboard/reference/api/teams-service-api)** — API for the Teams service integration
## Assignment Modes
Assignment modes determine how swimlane rows are populated — which field or relationship maps each work item to a swimlane.
**[Assignment Modes](/planningboard/reference/assignment-modes/index)** — Overview of all swimlane assignment types
**[Assignee Mode](/planningboard/reference/assignment-modes/assignee-mode)** — Groups work items by their assigned user
**[Parent Item Mode](/planningboard/reference/assignment-modes/parent-mode)** — Groups work items by their parent work item
**[Enumeration Field Mode](/planningboard/reference/assignment-modes/enum-mode)** — Groups work items by the value of an enumeration custom field
**[Project Mode](/planningboard/reference/assignment-modes/project-mode)** — Groups work items by their Polarion project
**[SAFe Team Mode](/planningboard/reference/assignment-modes/safe-team-mode)** — Groups work items by SAFe Agile Team
**[SAFe Train Team Mode](/planningboard/reference/assignment-modes/safe-train-team-mode)** — Groups work items by SAFe Agile Release Train team
**[SAFe Programs Mode](/planningboard/reference/assignment-modes/safe-programs-mode)** — Groups work items by SAFe Program
**[No Swimlanes Mode](/planningboard/reference/assignment-modes/no-swimlanes-mode)** — Displays all work items in a single row with no grouping
## Plans Modes
Plans modes control how Plan columns are sourced — from standard Polarion Plans, or from SAFe planning structures.
**[Plans Modes](/planningboard/reference/plans-modes/index)** — Overview of all Plans column source types
**[Project Plans](/planningboard/reference/plans-modes/project-plans)** — Columns sourced from standard Polarion Plans in a project
**[SAFe Sprints](/planningboard/reference/plans-modes/safe-sprints)** — Columns sourced from SAFe Sprint Plans
**[SAFe Program Increments](/planningboard/reference/plans-modes/safe-pis)** — Columns sourced from SAFe Program Increment Plans
**[SAFe Solution Trains](/planningboard/reference/plans-modes/safe-solutions)** — Columns sourced from SAFe Solution Train Plans
## Fields
Field reference pages list the identifiers, types, and descriptions for fields used in widget parameters and scripts.
**[Fields](/planningboard/reference/fields/index)** — Overview of all field categories
**[Work Item Fields](/planningboard/reference/fields/work-item-fields)** — Field identifiers for work item cards (type, status, priority, assignee, effort, custom fields)
**[Plan Fields](/planningboard/reference/fields/plan-fields)** — Field identifiers for Plan columns (name, start date, due date, capacity)
**[Resource Fields](/planningboard/reference/fields/resource-fields)** — Field identifiers for resource and capacity data
## UI Elements
UI element pages describe each interactive control in the board interface — what it does and where to find it.
**[UI Elements](/planningboard/reference/ui-elements/index)** — Overview of all board UI controls
**[Toolbar Controls](/planningboard/reference/ui-elements/toolbar)** — Buttons and controls in the board toolbar
**[Unplanned Sidebar](/planningboard/reference/ui-elements/sidebar)** — The sidebar panel listing work items not yet assigned to a Plan
**[Card Quick Actions](/planningboard/reference/ui-elements/card-quick-actions)** — Actions available on hover over a card
**[Swimlane Controls](/planningboard/reference/ui-elements/swimlane-controls)** — Controls on each swimlane row (collapse, expand, capacity indicator)
**[License Panel](/planningboard/reference/ui-elements/license-panel)** — The license status and activation panel
# Plans Modes
Source: https://learn.nextedy.com/planningboard/reference/plans-modes/index
Plans modes control how Nextedy PLANNINGBOARD selects and displays Polarion Plans as columns on the board.
## Topics
Display standard Polarion Plans as board columns. Use a Plan query to select which Plans appear and in what order.
Show SAFe iteration-level Sprints as board columns, scoped to a Program Increment or release boundary.
Show SAFe PI-level Plans as board columns for PI planning and capacity allocation across Agile Release Trains.
Show Solution Train Plans as board columns for large-scale, multi-ART planning across a solution.
**Choosing a Plans mode**
Use **Project Plans** for standard Scrum or release planning with Polarion's built-in Plan hierarchy. Switch to one of the **SAFe** modes when your organization runs a Scaled Agile Framework programme — SAFe Sprints for iteration-level boards, SAFe Program Increments for PI-level boards, and SAFe Solution Trains for cross-ART coordination.
## Plans mode and the board layout
The Plans mode you select determines what appears as columns on the board. Swimlanes (rows) are configured independently via the swimlane assignment type — see [Swimlanes (Rows) Parameters](/planningboard/reference/widget-parameters/swimlanes-parameters).
The active Plans mode is set via the Plans (Columns) widget parameters — see [Plans (Columns) Parameters](/planningboard/reference/widget-parameters/plans-parameters) for the full parameter reference.
**KB Articles**
* Swimlane Assignment Types
* Planningboard interface & basic interactions
* Introduction to Planningboard
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#4711](https://support.nextedy.com/helpdesk/tickets/4711)
* [#6685](https://support.nextedy.com/helpdesk/tickets/6685)
**Source Code**
* `PlanningBoardDataService.java`
* `PlanningBoardWidgetRenderer.java`
* `PlansMode.java`
* `Config.java`
* `PlanningBoardWidgetDependenciesProcessor.java`
# Project Plans
Source: https://learn.nextedy.com/planningboard/reference/plans-modes/project-plans
**Project Plans** is the default plans mode in Nextedy PLANNINGBOARD. It loads standard Polarion Plans from the current project and displays them as columns on the board.
This page is a complete reference for the Project Plans mode: what it controls, how it interacts with other configuration, and the parameters that govern it.
***
## Mode Overview
Project Plans mode is selected by setting the `plansMode` widget parameter to **Project Plans** (`PROJECT_PLANS`). This is the default value and requires no SAFe configuration.
***
## Mode Identifier
| Value | Type | Description |
| --------------- | -------- | ----------------------------------------------------------------------------------------------------------- |
| `PROJECT_PLANS` | `string` | Activates Project Plans mode. Standard project-based planning hierarchy without SAFe framework constraints. |
Set via widget parameter `plansMode`. See [Plans (Columns) Parameters](/planningboard/reference/widget-parameters/plans-parameters) for the full parameter reference.
***
## Plans Query
The Plans query controls which Plans from the current project appear as columns on the board. It uses standard Polarion Lucene query syntax.
| Parameter | Type | Default | Description |
| ------------ | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `plansQuery` | `string` | `None` | Lucene query to filter which Plans are loaded and displayed as columns. When empty, all Plans in the project are candidates (subject to `lastPlans`/`nextPlans` limits). |
### Query Syntax
Plans are queried using Polarion's Lucene query syntax. Common examples:
```properties theme={null}
# Show only Plans whose name contains "Sprint"
plansQuery=name:Sprint*
# Show only Plans of a specific plan type
plansQuery=type:iteration
# Show Plans not yet finished (open Plans)
plansQuery=NOT status:closed
```
**Query scope**
The `plansQuery` filter is applied within the current Polarion project. Plans from other projects are not included in Project Plans mode. For cross-project planning, use the [Project assignment mode](/planningboard/reference/assignment-modes/project-mode) for swimlanes, not a different plans mode.
***
## Plan Count Controls
These parameters limit how many Plans appear as columns, independent of the query. Plans are ordered chronologically.
| Parameter | Type | Default | Description |
| ----------- | -------- | ------- | -------------------------------------------------------------------- |
| `lastPlans` | `number` | `1` | Number of past (completed or overdue) Plans to display on the board. |
| `nextPlans` | `number` | `5` | Number of future or active upcoming Plans to display on the board. |
### Behavior
* Plans are ordered chronologically by their start date.
* `lastPlans` controls how many Plans whose end date is in the past appear.
* `nextPlans` controls how many Plans whose start/due date is current or future appear.
* Increasing either value loads more data — large values may affect rendering performance on projects with many Plans.
### Configuration Example
```properties theme={null}
lastPlans=2
nextPlans=6
```
This shows the 2 most recently completed Plans and the next 6 upcoming Plans as columns.
***
## Plan Link Template
| Parameter | Type | Default | Description |
| ---------- | -------- | -------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `planLink` | `string` | `/polarion/#/project/${plan.objectId.projectId}/plan?id=${plan.objectId.itemId}` | URL template for linking Plan column headers to the corresponding Polarion Plan view. Supports `${plan.*}` variable substitution. |
### Supported Variables
| Variable | Resolves To |
| ---------------------------- | ------------------------------------------ |
| `${plan.objectId.projectId}` | The Polarion project ID that owns the Plan |
| `${plan.objectId.itemId}` | The Plan's item ID within the project |
The plan link renders as a clickable header on each column. The default template navigates to the standard Polarion Plan view.
**Custom Plan link**
If your Polarion instance uses a custom URL pattern or you want to deep-link to a filtered plan view, override `planLink` with a custom template string. Variable substitution uses `${plan.*}` syntax.
***
## Work Item Assignment to Plans
In Project Plans mode, Planningboard assigns work items to Plans based on date overlap. A work item is placed in a Plan column when its `start_date` and `end_date` fall within the Plan's date range.
| Field | Description |
| ------------ | --------------------------------------------------------------- |
| `start_date` | Work item's scheduled start date used for Plan column placement |
| `end_date` | Work item's scheduled end date used for Plan column placement |
### Assignment Logic
* When a user drags a card into a Plan column, Planningboard sets the work item's `start_date` and `end_date` to values within that Plan's date range.
* When a work item's dates span multiple Plans, it may appear in multiple columns.
* Work items without dates appear in the **Unplanned** sidebar.
**Verified items cannot be moved**
Work items with status `Verified` are locked. Once placed on the board, they cannot be dragged to a different Plan or moved back to Unplanned.
***
## Plan Items Section
The **Plan items** configuration section in the widget parameters is visible **only** when `plansMode` is set to **Project Plans** (`PROJECT_PLANS`). It is hidden for SAFe modes.
| Parameter | Type | Default | Description |
| ---------- | -------- | --------- | -------------------------------------------------------------------------------------------------------------- |
| `wiType` | `string` | `None` | Work item type filter. Restricts which work item types appear on the board (e.g., `task`, `story`, `feature`). |
| `query` | `string` | `NOT *:*` | Lucene query to filter which work items are loaded onto the board. |
| `maxItems` | `number` | `1000` | Maximum number of work items loaded into the Planningboard. |
### Work Item Query
```properties theme={null}
# Show only open stories assigned to the current user
query=type:story AND NOT status:closed
# Show features and tasks that are not verified
query=(type:feature OR type:task) AND NOT status:verified
# Show all open items (override the NOT *:* default)
query=NOT status:closed
```
**Default query loads nothing**
The default value `NOT *:*` matches no work items. You must provide a meaningful query to populate the board with work items.
***
## Sync to Parent
The **Sync to parent** option is available **only** in Project Plans mode. It is not available for SAFe modes.
| Parameter | Type | Default | Description |
| --------------- | --------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `stemming` | `boolean` | `false` | Enables automatic plan generation by parsing resource field values. When enabled, plan stemming splits enum values into plan–resource pairs and affects other plan-related field visibility. |
| `planCellsMode` | `boolean` | `false` | Enables plan cells mode. Items belong to specific plan–resource cells. **Not compatible with Parent assignment mode** — the Parent assignment mode does not support plan normalization via `planCellsMode`. |
**Verify in application**
The exact label and behavior of "sync to parent" in the widget UI may vary by Planningboard version. The `stemming` and `planCellsMode` parameters above are the underlying configuration properties. Confirm current behavior in the widget parameters panel.
***
## Capacity in Project Plans Mode
Project Plans mode supports capacity tracking per Plan column. Capacity configuration applies when `capacityLoad` or `multiCapacityLoad` is enabled.
| Parameter | Type | Default | Description |
| ------------------- | --------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `capacityLoad` | `boolean` | `false` | Enables capacity/effort tracking per Plan column. Uses `remainingEstimate`/`initialEstimate` from work items, or a custom `capacityField`. |
| `multiCapacityLoad` | `boolean` | `false` | Enables per-swimlane or per-resource capacity tracking across multiple capacity dimensions simultaneously. |
| `capacityField` | `string` | `None` | Custom work item field ID to use as the effort/capacity value (e.g., story points). When set, overrides time-tracking fields. |
| `hoursPerDay` | `number` | `8` | Working hours per day, used to convert time-based estimates to day equivalents in capacity calculations. |
| `userCapacityLoad` | `boolean` | `false` | Enables user-level capacity loading. Requires `useTeamsService` to be `true`. |
| `useTeamsService` | `boolean` | `false` | Enables integration with the Polarion Teams service for team capacity, user capacity, and team member data. When enabled, overrides plan capacity values from the Teams service. |
### Capacity Tooltip
Hovering over the capacity bar on a Plan column shows a detailed capacity tooltip. This tooltip is only available when capacity tracking is configured via the widget parameters.
**Capacity configuration is whitespace-sensitive**
Capacity-related configuration parameters are whitespace-sensitive. Ensure there are no leading or trailing spaces in parameter values; these cause silent miscalculation.
See [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) and [Capacity Properties](/planningboard/reference/configuration-properties/capacity-properties) for the full capacity reference.
***
## Plan Object Fields
When Plans are loaded in Project Plans mode, the following fields are available on each Plan object. These are used in `planLink` templates and scripting.
| Field | Type | Description |
| --------------- | -------- | --------------------------------------------------------------------------------------------- |
| `name` | `string` | Plan name, normalized/stemmed for consistent identification |
| `startDate` | `string` | Plan start date formatted as US MEDIUM locale (e.g., `Jan 1, 2026`) |
| `dueDate` | `string` | Plan due date formatted as US MEDIUM locale (e.g., `Jan 15, 2026`) |
| `color` | `string` | Visual color identifier assigned to the Plan for the board display |
| `capacity` | `number` | Single numeric capacity value representing available work capacity for the Plan |
| `multiCapacity` | `map` | Per-dimension capacity values (e.g., by team or resource) when `multiCapacityLoad` is enabled |
| `planUrls` | `map` | Context-specific URLs for the Plan (used when multiple project contexts exist) |
| `planFullIds` | `map` | Full Plan identifiers in different contexts (distinct from stemmed IDs used internally) |
***
## Dependency Link Roles
In Project Plans mode, work item dependencies can be visualized as arrows between cards on the board. Configure which link roles represent dependencies using the following parameter.
| Parameter | Type | Default | Description |
| --------------------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `dependencyLinkRoles` | `string` | `None` | Comma-separated list of Polarion link role IDs that define task dependencies. These render as connectors between cards when **Show Dependencies** is enabled in the toolbar. |
### Example
```properties theme={null}
dependencyLinkRoles=depends_on,blocks
```
Dependencies are shown using the **Show Dependencies** toolbar button. Unlike the per-card **Show Links** quick action, the toolbar control reveals all dependencies across the entire board simultaneously.
***
## Plans Mode Comparison
The following table summarizes when to use Project Plans mode versus the available SAFe plans modes.
| Mode | Value | Use When |
| ------------------------ | ------------------ | -------------------------------------------------------------------------- |
| **Project Plans** | `PROJECT_PLANS` | Standard Polarion project planning; no SAFe framework; custom Plan queries |
| SAFe Sprints (Program) | `SAFE_SPRINTS` | SAFe iteration sprint planning within an Agile Release Train |
| SAFe Sprints (Portfolio) | `SAFE_PFL_SPRINTS` | Sprint-level planning across multiple programs at portfolio level |
| SAFe Program Increments | `SAFE_PIS` | PI-level planning within an Agile Release Train |
| SAFe Solution Trains | `SAFE_SOLUTION` | Coordinated PI planning across multiple ARTs in a solution train |
See [Plans Modes](/planningboard/reference/plans-modes/index), [SAFe Sprints](/planningboard/reference/plans-modes/safe-sprints), [SAFe Program Increments](/planningboard/reference/plans-modes/safe-pis), and [SAFe Solution Trains](/planningboard/reference/plans-modes/safe-solutions) for the other modes.
**Configuration UI differs by mode**
When you change the `plansMode` value, the widget parameters panel changes which fields are visible. The **Plan items** section, **Sync to parent** option, and the `plansQuery` field are only shown when **Project Plans** (`PROJECT_PLANS`) is active. SAFe modes show different fields specific to their hierarchy levels.
***
## Configuration Example
The following example shows a complete Project Plans widget configuration for a Scrum team running two-week sprints. It loads the last completed sprint and the next four, shows only Stories and Tasks, and enables capacity tracking using story points.
```properties theme={null}
# Plans (Columns)
plansMode=PROJECT_PLANS
plansQuery=type:iteration
lastPlans=1
nextPlans=4
# Work Items
query=type:story OR type:task
wiType=
maxItems=500
# Capacity
capacityLoad=true
capacityField=storyPoints
hoursPerDay=8
# Assignment Mode (Rows)
assignmentMode=ASSIGNEE
```
With this configuration:
* Columns show one past and four future iteration Plans.
* Only Stories and Tasks appear as cards on the board.
* The capacity bar on each column reflects story point totals.
* Swimlanes are grouped by assignee.
***
## Limitations
* **No multi-assignee capacity distribution:** Capacity load in Project Plans mode does not distribute effort across multiple assignees on a single work item. Only the primary assignee's capacity is affected. This is a known gap relative to Nextedy GANTT behavior.
* **Parallel sprint capacity:** Capacity calculation behavior across overlapping/parallel Plans may not match GANTT's calculation for the same items. If your team runs parallel sprints, verify capacity totals against the GANTT view.
* **Parent assignment mode incompatibility:** `planCellsMode` (plan normalization) is not supported when the assignment mode is set to **Parent Item**. The Parent assignment mode does not support plan cells.
* **Plan names with dashes:** Plan names containing dash characters (e.g., `PI-2401`, `I-2401-1`) were affected by a parsing bug causing incorrect column spans, zero capacity display, and missing plan shortcuts. This was partially fixed in version `23.8.0` and fully resolved in version `25.3.0`. If you use SAFe-style dash-containing plan names, ensure you are running version `25.3.0` or later.
***
## Related Reference Pages
* [Plans (Columns) Parameters](/planningboard/reference/widget-parameters/plans-parameters) — full widget parameter listings for the Plans section
* [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) — capacity widget parameters
* [Capacity Properties](/planningboard/reference/configuration-properties/capacity-properties) — server-side capacity configuration
* [Plans Modes](/planningboard/reference/plans-modes/index) — overview of all available plans modes
* [SAFe Sprints](/planningboard/reference/plans-modes/safe-sprints) — SAFe sprint-level plans mode reference
* [SAFe Program Increments](/planningboard/reference/plans-modes/safe-pis) — SAFe PI-level plans mode reference
* [Assignment Modes](/planningboard/reference/assignment-modes/index) — swimlane row configuration
* [Plan Fields](/planningboard/reference/fields/plan-fields) — all fields available on Plan objects
**KB Articles**
* Swimlane Assignment Types
* Introduction to Planningboard
* Planningboard interface & basic interactions
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#4711](https://support.nextedy.com/helpdesk/tickets/4711)
* [#6685](https://support.nextedy.com/helpdesk/tickets/6685)
**Source Code**
* `PlanningBoardDataService.java`
* `PlansMode.java`
* `PlanningBoardWidgetRenderer.java`
* `Config.java`
* `PlanningBoardWidgetDependenciesProcessor.java`
# SAFe Program Increments
Source: https://learn.nextedy.com/planningboard/reference/plans-modes/safe-pis
Reference for the SAFe Program Increments plans mode in Nextedy PLANNINGBOARD.
## Overview
Planningboard supports two SAFe Program Increment plans modes:
| Mode Value | Display Name | Level |
| --------------- | -------------------------------------- | ----------------------------------------- |
| `SAFE_PIS` | SAFe Program Increments (Program mode) | Agile Release Train (ART) — Program level |
| `SAFE_SOLUTION` | SAFe Solution Trains | Solution Train — Portfolio level |
These modes are set via the [`plansMode`](#plansmode-parameter) widget parameter. The active value determines which configuration fields are available in the widget and how Program Increment plans are loaded and displayed.
***
## Plans Mode Values
### SAFe Program Increments in Program (`SAFE_PIS`)
Displays PI-level plans within a single Agile Release Train. Plans are loaded from the current Polarion project using the SAFe Program Increment structure. Columns represent individual Program Increments (typically 8–12 week cadences).
**Use when:** planning at the ART (Program) level, where swimlanes represent SAFe teams, assignees, or enumeration fields within one release train.
### SAFe Program Increments in Solution (`SAFE_SOLUTION`)
Displays PI-level plans at the Solution Train level, coordinating planning across multiple Agile Release Trains. Columns represent Program Increments visible from the solution portfolio project.
**Use when:** planning across multiple ARTs from a portfolio or solution train project in Polarion.
***
## Widget Parameter Reference
### `plansMode` Parameter
| Name | Type | Default | Description |
| ----------- | -------- | --------------- | ------------------------------------------------------------------------------------------------------ |
| `plansMode` | `string` | `PROJECT_PLANS` | Selects the planning model. Set to `SAFE_PIS` for Program level or `SAFE_SOLUTION` for Solution level. |
**Accepted values for Program Increment modes:**
| Value | Description |
| --------------- | ------------------------------------------------------------------- |
| `SAFE_PIS` | SAFe Program Increments in Program (ART) mode |
| `SAFE_SOLUTION` | SAFe Solution Trains — PI plans at Solution Train (Portfolio) level |
Other accepted values for this parameter (other modes) are documented in [Plans Modes](/planningboard/reference/plans-modes/index).
***
### Plans (Columns) Parameters
The following parameters control which Program Increment plans appear as columns on the board. These are set in the **Plans (Columns)** section of the widget parameters panel.
| Name | Type | Default | Description |
| ------------ | -------- | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `plansQuery` | `string` | `None` | Lucene query to filter which PI plans are displayed as columns. When empty, plans are loaded automatically from the SAFe solution structure. |
| `lastPlans` | `number` | `1` | Number of past (completed) Program Increments to include on the board. |
| `nextPlans` | `number` | `5` | Number of upcoming Program Increments to include on the board. |
| `planLink` | `string` | `/polarion/#/project/${plan.objectId.projectId}/plan?id=${plan.objectId.itemId}` | URL template for linking card column headers to the corresponding Polarion Plan. Supports `${plan.*}` variables. |
**Plan query in SAFe modes**
In the SAFe Program Increments in Program (`SAFE_PIS`) and SAFe Program Increments in Solution (`SAFE_SOLUTION`) modes, plans are sourced from the Polarion SAFe Solution structure rather than a freeform Lucene query. The `plansQuery` parameter can further filter which PIs appear, but the base set is determined by the SAFe hierarchy — not an arbitrary project query as in Project Plans mode.
***
### Capacity Parameters
| Name | Type | Default | Description |
| ------------------- | --------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `capacityLoad` | `boolean` | `false` | Enables capacity/effort tracking. When `true`, capacity bars appear on swimlanes showing planned vs. available effort. |
| `multiCapacityLoad` | `boolean` | `false` | Enables per-swimlane capacity tracking across multiple plans simultaneously. |
| `userCapacityLoad` | `boolean` | `false` | Enables user-level capacity loading when the Teams Service integration is active. |
| `capacityField` | `string` | `None` | Custom field ID used for effort values (e.g., story points). When not set, time-tracking fields (`remainingEstimate` / `initialEstimate`) are used. |
| `hoursPerDay` | `number` | `8` | Working hours per day used in capacity conversions between time-based estimates and day fractions. Whitespace-sensitive — do not include trailing spaces. |
| `useTeamsService` | `boolean` | `false` | Enables integration with the Polarion Teams Service for team capacity, user capacity, and team membership data. When enabled, Teams Service data overrides `plan.capacity` values. |
See [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) for full capacity configuration reference.
***
### SAFe-Specific Parameters
| Name | Type | Default | Description |
| ------------------ | -------- | ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `selectedTeam` | `string` | `None` | ID of the SAFe team to use for filtering and capacity calculations. When set, the board focuses on plans and items relevant to the selected team. |
| `safeTeamField` | `string` | `safeTeam` | Custom field ID storing the SAFe Team assignment on work items. Used when assignment mode is `safe` or `safeTrain`. |
| `safeProgramField` | `string` | `safeProgram` | Custom field ID storing the SAFe Program assignment on work items. Used when assignment mode is `safePrograms`. |
See [SAFe Parameters](/planningboard/reference/widget-parameters/safe-parameters) for the complete SAFe parameter reference.
***
### Assignment Mode Compatibility
The SAFe Program Increments in Program (`SAFE_PIS`) and SAFe Program Increments in Solution (`SAFE_SOLUTION`) plans modes are designed to work with SAFe-aware swimlane assignment types. The following assignment modes are compatible:
| Assignment Mode | Description | Reference |
| ---------------------------------------------------- | -------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| Program / Solution Teams (SAFe) (`SAFE_TEAM`) | Swimlanes represent SAFe teams within the current program, sourced from the Polarion SAFe Solution | [SAFe Team Mode](/planningboard/reference/assignment-modes/safe-team-mode) |
| Agile Release Train Teams (SAFe) (`SAFE_TRAIN_TEAM`) | Swimlanes represent teams within a specific ART, filtered by ART ID | [SAFe Train Team Mode](/planningboard/reference/assignment-modes/safe-train-team-mode) |
| Programs (SAFe) (`SAFE_PROGRAMS`) | Swimlanes represent SAFe programs within a solution train (portfolio-level planning) | [SAFe Programs Mode](/planningboard/reference/assignment-modes/safe-programs-mode) |
| Users (Assignee) (`ASSIGNEE`) | Swimlanes grouped by individual assignees | [Assignee Mode](/planningboard/reference/assignment-modes/assignee-mode) |
| Enumeration Field (`ENUM`) | Swimlanes grouped by enumeration custom field values | [Enumeration Field Mode](/planningboard/reference/assignment-modes/enum-mode) |
**Programs (SAFe) mode requires portfolio-level project**
The Programs (SAFe) (`SAFE_PROGRAMS`) assignment mode requires a Polarion SAFe Solution configured at the portfolio level. It is not available for standard project-level boards. Contact Nextedy support for setup guidance.
***
## Configuration Fields by Mode
The widget parameters panel shows different fields depending on the selected `plansMode`. This table summarizes which sections appear for Program Increment modes versus Project Plans mode:
| Configuration Section | Project Plans (`PROJECT_PLANS`) | SAFe Program Increments in Program (`SAFE_PIS`) | SAFe Program Increments in Solution (`SAFE_SOLUTION`) |
| --------------------------- | ------------------------------- | ----------------------------------------------- | ----------------------------------------------------- |
| Plans query (custom Lucene) | Yes | Filtered | Filtered |
| Plan items section | Yes | No | No |
| SAFe PI increment field | No | Yes | No |
| Sync to parent | Yes | No | No |
| Plan stemming | Yes | No | No |
| Plan link field | Yes | Yes | Yes |
| Capacity parameters | Yes | Yes | Yes |
| SAFe team/program fields | No | Yes | Yes |
**Plan items section not available in SAFe modes**
The plan items configuration section (which controls which work item types appear as Plan cards in columns) is only available in Project Plans (`PROJECT_PLANS`) mode. In SAFe Program Increment modes, the column structure is derived from the Polarion SAFe hierarchy.
***
## SAFe Hierarchy Structure
The following diagram shows how Polarion plans map to Planningboard columns in the SAFe Program Increment modes:
***
## Plan Naming and Version Requirements
**Dash characters in plan names require version 25.3.0+**
SAFe naming conventions commonly use dash characters in plan names (e.g., `PI-2401`, `I-2401-1`). Planningboard versions prior to 25.3.0 had a parsing bug where dash-containing plan names caused:
* Incorrect column span rendering
* Capacity display showing zero
* Plan shortcuts disappearing from the board
**Version 23.8.0** included a partial fix. **Version 25.3.0** fully resolved the issue. If your organization uses SAFe naming conventions with dashes, upgrade to 25.3.0 or later before deploying Planningboard for PI planning.
***
## SAFe Parent Synchronization
When a work item's team assignment changes on the board (drag to a different swimlane in Program / Solution Teams (SAFe) (`SAFE_TEAM`) or Agile Release Train Teams (SAFe) (`SAFE_TRAIN_TEAM`) mode), Planningboard automatically synchronizes the SAFe User Story to the correct Team Program Increment plan. This `syncSAFEParentsFromChildren` behavior:
* Triggers when team assignment is updated via drag-and-drop
* Remaps the plan assignment based on the new team assignment
* Updates parent plan links to match the team's Program Increment
This automation ensures that stories remain correctly nested under the appropriate team PI plan after reassignment, without requiring manual plan updates.
***
## Page Parameters and Program Increment Parameter ID
When configuring a Planningboard board for SAFe PI planning, widget parameters can be externalized as **Page Parameters** — Polarion page-level variables that are referenced by the widget instead of being hard-coded per widget instance.
The **Program Increment Parameter ID** field (shown in the widget when SAFe Program Increments in Program (`SAFE_PIS`) or SAFe Program Increments in Solution (`SAFE_SOLUTION`) is active) links the board to a specific Page Parameter that controls which Program Increment is currently selected. This allows a single board page to switch between PIs without reconfiguring the widget.
**Setup steps:**
1. In the Polarion page editor, add a Page Parameter (e.g., `currentPI`) and set its default value to a PI plan ID.
2. In the Planningboard widget, set the **Plans Type** to **SAFe Program Increments in Program** (`SAFE_PIS`) (or **SAFe Program Increments in Solution** (`SAFE_SOLUTION`)).
3. In the SAFe parameters section, enter the Page Parameter name (e.g., `currentPI`) in the **Program Increment Parameter ID** field.
4. The board will load the PI referenced by that page parameter. Changing the parameter value switches the active PI.
**Configuration UI differs by plans mode**
The Program Increment Parameter ID field is only visible when SAFe Program Increments in Program (`SAFE_PIS`) or SAFe Program Increments in Solution (`SAFE_SOLUTION`) is selected as the plans mode. When Project Plans (`PROJECT_PLANS`) is active, this field is hidden and replaced by standard plan query and scope fields.
***
## Capacity Limitations
The following capacity-related limitations apply specifically to SAFe Program Increment modes:
| Limitation | Detail |
| --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| No multi-assignee capacity distribution | Capacity is tracked per swimlane as a whole; effort is not automatically split across multiple assignees of a single work item. This differs from Nextedy GANTT behavior. |
| No sub-item effort distribution | Effort from child work items (e.g., tasks under a story) is not automatically rolled up into the parent's capacity calculation. |
| Parallel PI capacity calculation | When multiple PIs overlap in time, capacity calculations may not match GANTT behavior for the same work items. This is an ongoing product limitation. |
| Swimlane sort order coupling | Swimlane sort order is coupled to item sort order — reordering items may affect swimlane display sequence. |
See [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) for configuration options within these constraints.
***
## Configuration Example
The following example configures a Planningboard widget for Program-level SAFe PI planning with SAFe teams as swimlanes, capacity enabled, and five upcoming PIs displayed:
```properties theme={null}
# Plans (Columns)
plansMode=SAFE_PIS
nextPlans=5
lastPlans=1
# Swimlanes (Rows)
assignmentMode=SAFE_TEAM
safeTeamField=safeTeam
# Work Items
query=type:story
maxItems=500
# Capacity
capacityLoad=true
capacityField=storyPoints
hoursPerDay=8
# SAFe
selectedTeam=
```
For a Solution-level board spanning multiple ARTs:
```properties theme={null}
# Plans (Columns)
plansMode=SAFE_SOLUTION
nextPlans=3
lastPlans=1
# Swimlanes (Rows)
assignmentMode=SAFE_PROGRAMS
safeProgramField=safeProgram
# Work Items
query=type:feature
maxItems=300
# Capacity
capacityLoad=true
multiCapacityLoad=true
```
***
## Related Reference Pages
* [Plans Modes](/planningboard/reference/plans-modes/index) — overview of all plans modes including Project Plans (`PROJECT_PLANS`) and SAFe Sprints
* [SAFe Sprints](/planningboard/reference/plans-modes/safe-sprints) — reference for SAFe Sprints in Program (`SAFE_SPRINTS`) and SAFe Sprints in Portfolio (`SAFE_PFL_SPRINTS`) modes
* [SAFe Solution Trains](/planningboard/reference/plans-modes/safe-solutions) — extended solution-level SAFe configuration
* [SAFe Parameters](/planningboard/reference/widget-parameters/safe-parameters) — complete SAFe widget parameter reference
* [Plans Parameters](/planningboard/reference/widget-parameters/plans-parameters) — all Plans (Columns) widget parameters
* [SAFe Team Mode](/planningboard/reference/assignment-modes/safe-team-mode) — swimlane assignment by SAFe team
* [SAFe Train Team Mode](/planningboard/reference/assignment-modes/safe-train-team-mode) — swimlane assignment by ART team
* [SAFe Programs Mode](/planningboard/reference/assignment-modes/safe-programs-mode) — swimlane assignment by SAFe program
* [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) — capacity bar configuration
**KB Articles**
* Swimlane Assignment Types
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#4711](https://support.nextedy.com/helpdesk/tickets/4711)
* [#6685](https://support.nextedy.com/helpdesk/tickets/6685)
**Source Code**
* `PlansMode.java`
* `PlanningBoardWidgetRenderer.java`
* `PlanningBoardDataService.java`
* `Config.java`
* `PlanningBoardWidgetDependenciesProcessor.java`
# SAFe Solution Trains
Source: https://learn.nextedy.com/planningboard/reference/plans-modes/safe-solutions
Reference for Nextedy PLANNINGBOARD's **SAFe Solution Trains** plans mode (`SAFE_SOLUTION`).
## Overview
The **SAFe Program Increments in Solution** (`SAFE_SOLUTION`) plans mode loads Program Increment plans at the **solution level** — that is, from the portfolio project that sits above individual ART program projects in the Polarion SAFe project hierarchy. Columns represent coordinated PIs spanning all ARTs; swimlanes can be configured to show either Programs (ARTs) or Teams within the solution portfolio.
**Requires Polarion SAFe Solution**
**SAFe Program Increments in Solution** (`SAFE_SOLUTION`) mode requires the Siemens Polarion SAFe Solution to be enabled and a valid SAFe portfolio hierarchy to be configured in Polarion. Without it, the mode cannot discover portfolio, program, or team projects.
***
## Plans Mode Value
| Property | Value |
| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| Widget parameter name | `plansMode` |
| Mode identifier | `SAFE_SOLUTION` |
| Internal enum name (`PlansMode.java`) | `safeSIs` |
| Description | SAFe Program Increments in Solution mode — displays PI planning at the solution portfolio level, coordinated across multiple ARTs |
| Config class default | `PROJECT_PLANS` |
Set the widget parameter `plansMode` to `SAFE_SOLUTION` to activate this mode.
***
## How Plans Are Loaded
In **SAFe Program Increments in Solution** (`SAFE_SOLUTION`) mode, Planningboard identifies the **portfolio project** from the current Polarion project's SAFe hierarchy and loads PI-level plans from that portfolio. The data service (`PlanningBoardDataService`) uses the `SAFE_SOLUTION` planning model to:
1. Detect the SAFe portfolio root for the current project via portfolio detection logic.
2. Retrieve all program-level project IDs within the portfolio.
3. Load PI plans from the portfolio scope, filtered to the plan count window defined by `lastPlans` and `nextPlans`.
4. Assign work items to swimlanes based on the configured SAFe assignment mode.
**Plan names with dashes**
SAFe naming conventions commonly produce plan names such as `PI-2401` or `PI-2401-1` (containing dashes). A parsing bug affecting these names was partially addressed in version **23.8.0** and **fully resolved in version 25.3.0**. On earlier versions, dash-containing plan names cause incorrect column spans, zero capacity display, and missing plan shortcuts. Upgrade to 25.3.0 or later before deploying solution-train boards with standard SAFe naming conventions.
***
## Compatible Swimlane Assignment Modes
**SAFe Program Increments in Solution** (`SAFE_SOLUTION`) mode is designed for use with the following assignment modes. Other assignment modes (such as **Users (Assignee)** (`ASSIGNEE`) or **Parent Item** (`PARENT`)) are available but are not the primary intent of solution-train boards.
| Assignment Mode | `assignmentMode` value | Description | Required fields |
| --------------------------- | ---------------------- | ------------------------------------------------------------------------------------------------------------ | --------------------------------- |
| SAFe Programs | `SAFE_PROGRAMS` | Swimlanes represent SAFe programs (ARTs) within the solution portfolio. Intended for portfolio-level boards. | `safeProgramField` |
| SAFe Team (program scope) | `SAFE_TEAM` | Swimlanes represent SAFe teams within the current program, sourced from Polarion SAFe Solution data. | `safeTeamField` |
| SAFe Train Team (ART scope) | `SAFE_TRAIN_TEAM` | Swimlanes represent teams within a specific ART, filtered by ART ID. | `safeTeamField`, ART ID parameter |
### SAFe Programs Assignment Mode
When `assignmentMode` is set to `SAFE_PROGRAMS`, each swimlane represents one SAFe program (ART) in the solution. Planningboard reads the program assignment from the field identified by `safeProgramField` on each work item.
| Property | Type | Default | Description |
| ---------------------- | ------- | -------------- | --------------------------------------------------------------------------------------------------------- |
| `safeProgramField` | string | `safeProgram` | Custom field ID that stores the SAFe Program assignment on work items. Must be a valid Polarion field ID. |
| `showEmptySwimlanes` | boolean | `false` | When `true`, programs with no cards in the visible PI range are still shown as rows. |
| `swimlaneSort` | string | `alphabetical` | Sort order for program swimlanes. |
| `collapsibleSwimlanes` | boolean | `true` | Allows users to collapse individual program rows. |
### SAFe Team Assignment Modes
When `assignmentMode` is `SAFE_TEAM` or `SAFE_TRAIN_TEAM`, each swimlane represents a team. The team assignment is read from `safeTeamField` on each work item.
| Property | Type | Default | Description |
| ---------------------- | ------- | -------------- | -------------------------------------------------------------------------------------------------- |
| `safeTeamField` | string | `safeTeam` | Custom field ID storing the SAFe Team assignment on work items. Must be a valid Polarion field ID. |
| `showEmptySwimlanes` | boolean | `false` | When `true`, teams with no items in the visible PI range appear as empty rows. |
| `swimlaneSort` | string | `alphabetical` | Sort order for team swimlanes. |
| `collapsibleSwimlanes` | boolean | `true` | Allows users to collapse individual team rows. |
For `SAFE_TRAIN_TEAM` specifically, an ART ID parameter must be supplied to filter teams to a single ART. Refer to [SAFe Train Team Mode](/planningboard/reference/assignment-modes/safe-train-team-mode) for the ART ID field details.
***
## Widget Parameters
The following widget parameters are relevant when configuring a solution-train board. See [SAFe Parameters](/planningboard/reference/widget-parameters/safe-parameters) for the complete SAFe parameter reference and [Plans (Columns) Parameters](/planningboard/reference/widget-parameters/plans-parameters) for all plan-column parameters.
### Plans (Columns) Parameters
| Parameter | Type | Default | Description |
| ----------- | ------ | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| `plansMode` | string | `PROJECT_PLANS` | Set to `SAFE_SOLUTION` to activate solution-train PI mode. |
| `lastPlans` | number | `1` | Number of past (completed) PI plans to include as columns. |
| `nextPlans` | number | `5` | Number of upcoming PI plans to include as columns. |
| `planLink` | string | `/polarion/#/project/${plan.objectId.projectId}/plan?id=${plan.objectId.itemId}` | URL template for linking column headers to Polarion Plans. Supports `${plan.*}` variables. |
### Swimlane (Rows) Parameters
| Parameter | Type | Default | Description |
| ---------------------- | ------- | -------------- | ------------------------------------------------------------------------------------ |
| `assignmentMode` | string | `ASSIGNEE` | Set to `SAFE_PROGRAMS`, `SAFE_TEAM`, or `SAFE_TRAIN_TEAM` for SAFe swimlanes. |
| `safeProgramField` | string | `safeProgram` | Field ID for SAFe program assignment (used with `SAFE_PROGRAMS` mode). |
| `safeTeamField` | string | `safeTeam` | Field ID for SAFe team assignment (used with `SAFE_TEAM` / `SAFE_TRAIN_TEAM` modes). |
| `showEmptySwimlanes` | boolean | `false` | Show swimlanes with no cards. |
| `collapsibleSwimlanes` | boolean | `true` | Enable collapsible swimlane rows. |
| `swimlaneSort` | string | `alphabetical` | Swimlane row sort order. |
### Work Items Parameters
| Parameter | Type | Default | Description |
| ---------- | ------ | --------- | ----------------------------------------------------------------------- |
| `query` | string | `NOT *:*` | Lucene query filtering which work items appear on the board. |
| `wiType` | string | none | Restrict cards to a specific work item type (e.g., `feature`, `story`). |
| `maxItems` | number | `1000` | Maximum number of work items loaded onto the board. |
### Capacity Parameters
| Parameter | Type | Default | Description |
| ------------------- | ------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `capacityLoad` | boolean | `false` | Enable capacity/effort tracking per swimlane and PI column. |
| `multiCapacityLoad` | boolean | `false` | Enable per-swimlane capacity tracking across multiple PI plans simultaneously. |
| `capacityField` | string | none | Custom field ID for capacity values (e.g., story points). When unset, time tracking fields (`remainingEstimate` / `initialEstimate`) are used. |
| `hoursPerDay` | number | `8` | Working hours per day used in effort-to-day conversions. |
| `useTeamsService` | boolean | `false` | Enable integration with the Planningboard Teams Service for team-based capacity data. |
**Capacity limitations in SAFe modes**
The capacity bar in **SAFe Program Increments in Solution** (`SAFE_SOLUTION`) mode reflects aggregate effort across the swimlane and PI column. Multi-assignee effort distribution (splitting effort across several users) is not currently supported. Parallel PI capacity calculation may also differ from Nextedy GANTT behavior. See [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) for full details.
***
## SAFe Project Hierarchy Detection
Planningboard uses internal SAFe hierarchy detection (via `SAFeImpl`) to identify the portfolio context and enumerate programs and teams. The detection logic works as follows:
The board's scope is determined by the project in which the Planningboard widget is embedded:
* When embedded in the **portfolio project**: all programs and their PI plans are in scope.
* When embedded in a **program project**: the portfolio is detected upward; PI plans from the portfolio are loaded, and team filtering can be applied.
Portfolio-level Lucene queries are built as `project.id:(portfolioId)`. Program IDs and team IDs are retrieved as space-separated strings and used internally for work item filtering.
***
## Configuration Example
The following example configures a solution-train board at the portfolio level, with SAFe Programs as swimlanes, showing the last 1 and next 3 PIs, with capacity tracking enabled.
```properties theme={null}
# Plans mode
plansMode=SAFE_SOLUTION
lastPlans=1
nextPlans=3
# Swimlanes: SAFe Programs (ARTs)
assignmentMode=SAFE_PROGRAMS
safeProgramField=safeProgram
showEmptySwimlanes=false
collapsibleSwimlanes=true
swimlaneSort=alphabetical
# Work items
query=type:feature OR type:story
maxItems=1000
# Capacity
capacityLoad=true
capacityField=storyPoints
hoursPerDay=8
```
**Page Parameters and Program Increment Parameter ID**
In some SAFe configurations, the widget requires a **Page Parameter** to pass the current Program Increment ID dynamically (for example, when a page hosts boards for multiple PIs). Create a Page Parameter in the widget's page settings and reference it via the Program Increment Parameter ID field. Without this, the board may default to the wrong PI range. See [SAFe Parameters](/planningboard/reference/widget-parameters/safe-parameters) for the relevant parameter field.
***
## Comparison with Related Plans Modes
| Mode | `plansMode` value | Scope | Typical use |
| ---------------------------------------------------------------------------------- | ------------------ | ------------------------------------ | --------------------------------------- |
| [SAFe Sprints (Program)](/planningboard/reference/plans-modes/safe-sprints) | `SAFE_SPRINTS` | Iteration plans within a single ART | Team sprint planning at program level |
| [SAFe Sprints (Portfolio)](/planningboard/reference/plans-modes/safe-sprints) | `SAFE_PFL_SPRINTS` | Iteration plans at portfolio level | Cross-ART sprint overview |
| [SAFe Program Increments (Program)](/planningboard/reference/plans-modes/safe-pis) | `SAFE_PIS` | PI plans within a single ART | PI planning within one program |
| **SAFe Solution Trains** | `SAFE_SOLUTION` | PI plans at solution/portfolio level | PI planning coordinated across all ARTs |
| [Project Plans](/planningboard/reference/plans-modes/project-plans) | `PROJECT_PLANS` | Standard project-based plans | Non-SAFe sprint and release planning |
***
## Limitations
* **No multi-assignee effort distribution.** Capacity bars reflect total effort per swimlane; effort is not split across multiple assignees within a single card.
* **Parallel PI capacity.** Capacity calculations across overlapping PIs may differ from Nextedy GANTT behavior. If your ARTs run concurrent PIs, validate capacity results against GANTT before relying on the numbers.
* **Plan names with dashes.** Fully supported from version **25.3.0** onward. Earlier versions have rendering issues with plan names matching SAFe naming patterns (e.g., `PI-2401`).
* **SAFe Solution requires Polarion SAFe.** The **SAFe Program Increments in Solution** (`SAFE_SOLUTION`), **Programs (SAFe)** (`SAFE_PROGRAMS`), **Program / Solution Teams (SAFe)** (`SAFE_TEAM`), and **Agile Release Train Teams (SAFe)** (`SAFE_TRAIN_TEAM`) modes require the Polarion SAFe Solution license and a valid SAFe project hierarchy. They cannot be used with standard Polarion project structures.
* **Configuration UI changes by plans mode.** When switching between **Project Plans** (`PROJECT_PLANS`) and SAFe modes in the widget parameter panel, some fields appear or disappear (e.g., plan stemming and sync-to-parent are only shown in **Project Plans** (`PROJECT_PLANS`) mode; the SAFe PI increment field appears only in **SAFe Sprints in Program** (`SAFE_SPRINTS`) / **SAFe Sprints in Portfolio** (`SAFE_PFL_SPRINTS`) modes). This is expected widget behavior, not an error.
***
## Related Pages
* [Plans Modes](/planningboard/reference/plans-modes/index) — overview of all plans modes
* [SAFe Program Increments](/planningboard/reference/plans-modes/safe-pis) — PI planning at program level
* [SAFe Sprints](/planningboard/reference/plans-modes/safe-sprints) — iteration-level SAFe planning
* [SAFe Programs Mode](/planningboard/reference/assignment-modes/safe-programs-mode) — swimlane assignment by SAFe program
* [SAFe Team Mode](/planningboard/reference/assignment-modes/safe-team-mode) — swimlane assignment by SAFe team
* [SAFe Train Team Mode](/planningboard/reference/assignment-modes/safe-train-team-mode) — swimlane assignment filtered by ART
* [SAFe Parameters](/planningboard/reference/widget-parameters/safe-parameters) — all SAFe-specific widget parameters
* [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) — capacity configuration reference
**KB Articles**
* Swimlane Assignment Types
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#4711](https://support.nextedy.com/helpdesk/tickets/4711)
* [#6685](https://support.nextedy.com/helpdesk/tickets/6685)
**Source Code**
* `PlanningBoardWidgetRenderer.java`
* `PlansMode.java`
* `PlanningBoardDataService.java`
* `Config.java`
* `PlanningBoardWidgetDependenciesProcessor.java`
# SAFe Sprints
Source: https://learn.nextedy.com/planningboard/reference/plans-modes/safe-sprints
Reference for the **SAFe Sprints** plans mode in Nextedy PLANNINGBOARD.
## Overview
The SAFe Sprints plans mode (`SAFE_SPRINTS`) is one of the planning modes available in Planningboard. When active, Planningboard automatically queries Polarion for iteration-level plans within an Agile Release Train (ART) rather than using a manually specified plan query. The mode is intended for teams operating at the program (ART) level of a SAFe hierarchy.
A second variant, the **SAFe Sprints in Portfolio** mode (`SAFE_PFL_SPRINTS`), targets the portfolio level — it displays sprint-level planning across multiple programs in a solution portfolio. Both variants are documented on this page; see [SAFe Program Increments](/planningboard/reference/plans-modes/safe-pis) and [SAFe Solution Trains](/planningboard/reference/plans-modes/safe-solutions) for PI-level and solution-level modes.
***
## Plans Mode Values
| Value | Description |
| ------------------ | ------------------------------------------------------------------------------------------------------------------ |
| `SAFE_SPRINTS` | SAFe Sprints in Program mode — displays sprint/iteration plans within a single Agile Release Train. |
| `SAFE_PFL_SPRINTS` | SAFe Sprints in Portfolio mode — displays sprint/iteration plans across multiple programs in a solution portfolio. |
These values are set via the **Plans (Columns)** widget parameter `plansMode`. See [Plans (Columns) Parameters](/planningboard/reference/widget-parameters/plans-parameters) for the full parameter reference.
***
## How Plans Are Loaded
When `plansMode` is `SAFE_SPRINTS` or `SAFE_PFL_SPRINTS`, Planningboard automatically sets the plan query to filter for iteration plans using the Polarion SAFe plan template:
```text theme={null}
template.id:iterationPlan
```
This query is applied automatically — you do not configure `plansQuery` manually in these modes. Planningboard uses the Polarion SAFe Solution data to discover the current program and its associated iteration plans.
**Requires Polarion SAFe Solution**
Both **SAFe Sprints in Program** (`SAFE_SPRINTS`) and **SAFe Sprints in Portfolio** (`SAFE_PFL_SPRINTS`) require **Polarion SAFe Solution** to be installed and configured. The board reads the SAFe hierarchy (portfolio, program, team projects) from Polarion's SAFe metadata. If SAFe Solution is not present, these modes will not load plans correctly.
***
## Widget Parameters
The following widget parameters are relevant when `plansMode` is set to `SAFE_SPRINTS` or `SAFE_PFL_SPRINTS`. Parameters from [Plans (Columns) Parameters](/planningboard/reference/widget-parameters/plans-parameters) apply; only SAFe-specific behavior is noted here.
### Core Plans Parameters
| Parameter | Type | Default | Description |
| ----------- | ------ | -------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `plansMode` | string | `PROJECT_PLANS` | Set to `SAFE_SPRINTS` (program-level sprints) or `SAFE_PFL_SPRINTS` (portfolio-level sprints) to activate this mode. |
| `lastPlans` | number | `1` | Number of past completed sprint Plans to display. |
| `nextPlans` | number | `5` | Number of upcoming sprint Plans to display. |
| `planLink` | string | `/polarion/#/project/${plan.objectId.projectId}/plan?id=${plan.objectId.itemId}` | URL template for linking card columns to their Polarion Plan. Supports `${plan.*}` variables. |
### SAFe-Specific Parameters
| Parameter | Type | Default | Description |
| ------------ | ------ | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `plansQuery` | string | *(auto-set)* | In SAFe Sprints mode, this is set automatically to `template.id:iterationPlan`. Manual override is not recommended and may break plan loading. |
**Verify in application**
The **Program Increment Parameter ID** field (referenced in support tickets for SAFe configuration) controls which PI's sprints are shown when the board is used within a specific Program Increment context. Confirm exact parameter name and behavior in the live widget configuration panel, as the field is shown only when **SAFe Sprints in Program** (`SAFE_SPRINTS`) or **SAFe Sprints in Portfolio** (`SAFE_PFL_SPRINTS`) is selected.
### SAFe Parameters
Additional SAFe-specific parameters are available under the **SAFe** section of the widget. See [SAFe Parameters](/planningboard/reference/widget-parameters/safe-parameters) for the full list.
***
## Configuration UI Differences by Plans Mode
Selecting **SAFe Sprints in Program** (`SAFE_SPRINTS`) or **SAFe Sprints in Portfolio** (`SAFE_PFL_SPRINTS`) changes which configuration fields are visible in the widget parameters panel:
| Field / Section | Project Plans | SAFe Sprints in Program | SAFe Sprints in Portfolio |
| ----------------------- | ------------- | ----------------------- | ------------------------- |
| Scope / Query / Type | Visible | Hidden | Hidden |
| Plan Items section | Visible | Hidden | Hidden |
| SAFe PI Increment field | Hidden | Visible | Visible |
| Sync to Parent | Visible | Hidden | Hidden |
| Plan Link field | Visible | Visible | Visible |
| Plan Stemming | Configurable | Not available | Not available |
The configuration UI changes dynamically when you switch the **Plans Type** (plans mode) selection. If fields you expect are missing, verify that the correct plans mode is selected.
***
## Swimlane Assignment Types for SAFe Sprints
SAFe Sprints mode is typically combined with SAFe-specific swimlane assignment types to display teams or programs as rows. The most relevant assignment modes are:
| Assignment Mode | Constant | Use With |
| -------------------------------- | ----------------- | --------------------------------------------------------------------------- |
| Program / Solution Teams (SAFe) | `SAFE_TEAM` | Swimlanes per SAFe team within the current program. Requires SAFe Solution. |
| Agile Release Train Teams (SAFe) | `SAFE_TRAIN_TEAM` | Swimlanes per team within a specific ART, filtered by ART ID parameter. |
| Programs (SAFe) | `SAFE_PROGRAMS` | Swimlanes per program (for portfolio-level boards). |
See [SAFe Team Mode](/planningboard/reference/assignment-modes/safe-team-mode), [SAFe Train Team Mode](/planningboard/reference/assignment-modes/safe-train-team-mode), and [SAFe Programs Mode](/planningboard/reference/assignment-modes/safe-programs-mode) for details.
Other assignment modes (Users (Assignee), Parent Item, Enumeration Field, Project, No Swimlanes) are also compatible with SAFe Sprints columns. See [Assignment Modes](/planningboard/reference/assignment-modes/index) for the full reference.
***
## Capacity in SAFe Sprints Mode
Capacity tracking works in SAFe Sprints mode through the same parameters as other modes. The capacity bar per swimlane reflects the configured capacity field or time-tracking fields aggregated across the sprint Plan.
| Parameter | Type | Default | Description |
| ------------------- | ------- | -------- | -------------------------------------------------------------------------- |
| `capacityLoad` | boolean | `false` | Enable capacity/effort tracking on work items and Plans. |
| `multiCapacityLoad` | boolean | `false` | Enable per-swimlane capacity tracking. |
| `userCapacityLoad` | boolean | `false` | Enable user-level capacity loading when using the Teams Service. |
| `capacityField` | string | *(none)* | Custom field ID containing capacity values (e.g., story points). |
| `hoursPerDay` | number | `8` | Working hours per day for capacity calculations. |
| `useTeamsService` | boolean | `false` | Enable integration with the Polarion Teams Service for team capacity data. |
See [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) for the complete capacity reference.
**Capacity limitation**
Planningboard does not support multi-assignee capacity distribution or sub-item effort distribution. Capacity is tracked per the configured `capacityField` or time-tracking fields on the work item itself. This is a known limitation relative to GANTT capacity features.
***
## SAFe Plan Naming and Version Compatibility
SAFe naming conventions typically use dash characters in plan names (for example, `PI-2401`, `I-2401-1`). A parsing bug in earlier versions caused these names to break column spanning, capacity display, and plan shortcuts.
| Version | Behavior |
| ------------- | --------------------------------------------------------------- |
| Before 23.8.0 | Dash characters in plan names cause rendering failures. |
| 23.8.0 | Partial fix for dash handling in plan names. |
| 25.3.0 | Full fix — dash characters in plan names are correctly handled. |
**Version requirement for SAFe naming conventions**
If your SAFe plans use dash-containing names (e.g., `PI-2401`, `I-2401-1`), upgrade to **version 25.3.0 or later** to avoid broken column spans, zero capacity display, and missing plan shortcuts.
***
## Multi-Sprint Item Display
When a work item is planned across multiple sprints, Planningboard renders it as a **continuous block spanning from the first to the last planned sprint**, regardless of whether intermediate sprints are included. This is current behavior; individual sprint instances are not shown separately.
**Known behavior: continuous span rendering**
Items planned across multiple sprints appear as one unbroken block from first to last sprint. Intermediate sprints that do not individually contain the item are visually covered by the span. There is no per-sprint instance rendering at this time.
***
## Configuration Example
The following example shows a widget configured for SAFe Sprints at the program level, with SAFe Team swimlanes and story-point capacity tracking.
```properties theme={null}
# Plans (Columns)
plansMode = SAFE_SPRINTS
lastPlans = 1
nextPlans = 4
# Work Items
query = type:story OR type:task
wiType = story
# Swimlanes (Rows)
assignmentMode = SAFE_TEAM
# Capacity
capacityLoad = true
capacityField = storyPoints
hoursPerDay = 8
```
For portfolio-level sprint planning across multiple programs, change `plansMode` to `SAFE_PFL_SPRINTS` and `assignmentMode` to `SAFE_PROGRAMS`.
***
## Related Pages
* [Plans Modes](/planningboard/reference/plans-modes/index) — Overview of all available plans modes
* [SAFe Program Increments](/planningboard/reference/plans-modes/safe-pis) — PI-level planning at program and solution levels
* [SAFe Solution Trains](/planningboard/reference/plans-modes/safe-solutions) — Solution-level planning
* [Project Plans](/planningboard/reference/plans-modes/project-plans) — Standard project-based plans mode
* [SAFe Parameters](/planningboard/reference/widget-parameters/safe-parameters) — Full SAFe widget parameter reference
* [Plans (Columns) Parameters](/planningboard/reference/widget-parameters/plans-parameters) — Complete plans parameter reference
* [SAFe Team Mode](/planningboard/reference/assignment-modes/safe-team-mode) — Swimlanes by SAFe team
* [SAFe Train Team Mode](/planningboard/reference/assignment-modes/safe-train-team-mode) — Swimlanes by ART team
* [SAFe Programs Mode](/planningboard/reference/assignment-modes/safe-programs-mode) — Swimlanes by SAFe program
* [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) — Capacity and effort tracking configuration
**KB Articles**
* Swimlane Assignment Types
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#4711](https://support.nextedy.com/helpdesk/tickets/4711)
* [#5921](https://support.nextedy.com/helpdesk/tickets/5921)
**Source Code**
* `PlansMode.java`
* `PlanningBoardDataService.java`
* `PlanningBoardWidgetRenderer.java`
* `Config.java`
* `PlanningBoardWidgetDependenciesProcessor.java`
# Card Quick Actions
Source: https://learn.nextedy.com/planningboard/reference/ui-elements/card-quick-actions
Card quick actions are contextual controls that appear on a card when you hover over it.
## Overview
The three quick actions appear in the upper-right corner of the card, from left to right:
| Position | Action | One-line description |
| ------------ | ----------- | --------------------------------------------------------- |
| 1st (left) | Show Links | Filters the board to this card and its linked cards only |
| 2nd (middle) | Add Link | Enters link-creation mode to connect this card to another |
| 3rd (right) | Unplan Item | Moves this card back to the Unplanned section |
Quick actions are available on every card that represents a work item on the board. They are only visible on hover — they do not occupy permanent space on the card face — so the card display remains clean when not in use.
***
## Actions Reference
### Show Links
**Behavior:** Clicking this action filters the board to show only the selected card and any cards that have a direct link to it. All other cards on the board are hidden while this mode is active. This gives a focused, clutter-free view of the dependencies and relationships for a single work item.
* All cards that are directly linked to the selected card (in any direction) remain visible.
* All cards with no direct link to the selected card are hidden.
* The selected card itself stays in its position within its swimlane and column.
* To return to the full board view, click the Show Links action on the same card again, or use the **Refresh data** button in the [toolbar](/planningboard/reference/ui-elements/toolbar).
This action is useful for quickly auditing a card's relationships — for example, confirming that a Story has a "depends on" link to the blocking item before planning it into a sprint.
**Show Links vs Show Dependencies**
**Show Links** (card quick action) is a per-card, focused filter: it hides all cards not directly linked to the selected card. **Show Dependencies** in the [toolbar](/planningboard/reference/ui-elements/toolbar) is a board-level toggle that renders all link lines across all cards simultaneously without hiding any cards. Use Show Links for inspecting one card's connections; use Show Dependencies for a board-wide dependency overview.
***
### Add Link
**Behavior:** Clicking this action enters link-creation mode. The same link icon then appears on every other card currently displayed on the board. Click a second card to create a link between the originating card and that target card.
* When Add Link mode is active, every other card shows the link icon.
* A **red icon** on a target card indicates a link between that target and the originating card already exists. Clicking a card with the red icon opens the option to **delete** that existing link.
* After the link is created or an existing link is deleted, the board exits link-creation mode and returns to the normal view.
* If you change your mind and do not want to create a link, click the originating card's link icon again (or click away from all cards) to cancel link-creation mode.
Link creation and deletion here operate on Polarion work item links — the same links that appear in the work item's Links tab inside Polarion. Changes are persisted to Polarion immediately.
**Inspecting links after creation**
After using Add Link to create a connection, use Show Links on the same card to verify the full set of connections now attached to it.
***
### Unplan Item
**Behavior:** Clicking this action removes the card from its current Plan column on the board and moves it to the [Unplanned sidebar](/planningboard/reference/ui-elements/sidebar). The work item's Plan assignment is cleared.
* The card appears in the Unplanned section immediately after the action.
* The card is removed from the Plan (column) it was previously assigned to.
* This action is functionally equivalent to dragging the card from the board back into the Unplanned section.
* After unplanning, the card is available to be dragged back to any Plan column on the board.
**Verified items cannot be unplanned**
Cards with the **Verified** status are locked on the board. The Unplan Item quick action has no effect on verified work items, and drag-and-drop movement is also blocked for them. This lock applies to all card interactions — not just the quick action — to prevent accidental changes to completed, verified work.
***
## Behavior Under License Restrictions
Quick actions are part of the interactive editing surface of the board. Nextedy PLANNINGBOARD enforces license-based access control. Unlicensed users can view the full board but cannot make any changes:
| User type | Quick action availability |
| --------------- | ----------------------------------------------------------------- |
| Licensed user | All three quick actions are visible on hover and fully functional |
| Unlicensed user | Quick actions are not available; the board is read-only |
Specifically, for unlicensed users:
* The Unplan Item action is not accessible (the Unplanned sidebar is also hidden).
* The Add Link action is not accessible.
* The Show Links action availability for read-only users is .
* Drag-and-drop is also blocked — cards cannot be moved even if dragged.
See [License Panel](/planningboard/reference/ui-elements/license-panel) for details on license states and how to obtain a license.
***
## Accessibility and Card Identification
Cards on the board are identified by an `aria-label` attribute that contains the work item ID and title (for example, `MAP-531 - Fix login screen`). This label is used by assistive technologies and is also what appears when the browser's accessibility tree reads a card. The quick action icons inherit their context from the parent card's label.
***
## Interaction Summary
| Action | Trigger | Reversible? | Side effects on other cards |
| ----------- | ---------------------------------------------------- | ------------------------------------------- | ---------------------------------------------- |
| Show Links | Hover card → click Show Links icon | Yes — click again or refresh board | Hides all cards not linked to this card |
| Add Link | Hover card → click Add Link icon → click target card | Yes — use red icon to delete link | Shows link icon on all other cards during mode |
| Unplan Item | Hover card → click Unplan Item icon | Yes — drag card back from Unplanned section | None |
***
## Edge Cases and Limitations
* **Verified items:** Cards in **Verified** status cannot be moved or unplanned via any mechanism, including quick actions and drag-and-drop.
* **Show Links scope:** Show Links only reveals direct (one-hop) links. Cards linked to the selected card's linked cards (two-hop) are not shown.
* **Add Link scope:** Link-creation mode only shows cards that are currently rendered on the board (visible in their swimlanes and columns). Cards in the Unplanned section are not targetable in Add Link mode.
* **Link type:** The specific link role used when creating a link via Add Link is . Consult the [Widget Parameters](/planningboard/reference/widget-parameters/ui-parameters) for any configuration affecting link behavior.
* **Unlicensed read-only:** All card editing actions, including quick actions, are blocked for unlicensed users. The board remains fully visible for transparency and collaboration.
***
## Related Pages
* [Toolbar Controls](/planningboard/reference/ui-elements/toolbar) — board-level controls including Show Dependencies (all links at once), Refresh, Collapse/Expand All, and Prioritize
* [Unplanned Sidebar](/planningboard/reference/ui-elements/sidebar) — where cards go after the Unplan Item action; filtering, searching, and drag-and-drop back to the board
* [Swimlane Controls](/planningboard/reference/ui-elements/swimlane-controls) — per-swimlane collapse, expand, and capacity information
* [Basic Board Interactions](/planningboard/getting-started/basic-interactions) — drag-and-drop planning, clicking cards to open the properties sidebar, and scroll/swimlane position preservation
* [UI Elements](/planningboard/reference/ui-elements/index) — full index of Planningboard UI element reference pages
* [License Panel](/planningboard/reference/ui-elements/license-panel) — license status display and what read-only mode affects
**KB Articles**
* Planningboard interface & basic interactions
**Source Code**
* `unplanned_sidebar.js`
* `viewLicense.vm`
* `widget.vm`
* `licenseReadonly.cy.ts`
* `enum-rows-filter-folder-scope.cy.ts`
# UI Elements
Source: https://learn.nextedy.com/planningboard/reference/ui-elements/index
The Nextedy PLANNINGBOARD interface is composed of several distinct UI elements — the toolbar, the unplanned sidebar, card quick actions, swimlane controls, and the license panel.
Global board actions: refresh, save layout, toggle sidebar, and board-wide display options.
The collapsible panel listing work items not yet assigned to any Plan or swimlane.
Inline actions available directly on a card — open, move, and other per-card operations.
Per-swimlane controls including the capacity bar, swimlane header, and collapse/expand.
Panel for viewing and entering the Planningboard license key.
**UI elements and widget parameters work together**
Most UI elements reflect the current widget parameter configuration. For example, whether the capacity bar appears in a swimlane is governed by the `capacity` widget parameters. See [Widget Parameters](/planningboard/reference/widget-parameters/index) for the configuration reference.
## Board layout at a glance
**KB Articles**
* Planningboard interface & basic interactions
**Source Code**
* `unplanned_sidebar.js`
* `widget.vm`
* `viewLicense.vm`
* `enum-rows-filter-folder-scope.cy.ts`
* `license-panel.js`
# License Panel
Source: https://learn.nextedy.com/planningboard/reference/ui-elements/license-panel
The **License Panel** is a non-intrusive notification component that appears at the bottom-right corner of the Nextedy PLANNINGBOARD viewport when a license issue is detected.
***
## Overview
The panel renders as a custom web component with shadow DOM encapsulation, which means its internal styles are isolated from the host Polarion page and cannot be overridden via external CSS.
***
## Variants
The panel behavior and visual style are controlled by the `variant` attribute. There are four possible values:
| Variant | Visible | Background | Text color | When used |
| --------- | ----------- | ------------------------------ | -------------------- | --------------------------------------------------- |
| `ok` | No (hidden) | — | — | License is valid; panel does not appear |
| `warning` | Yes | `#fffaf3` (light orange/beige) | `#573a08` (brown) | License is approaching expiry or requires attention |
| `error` | Yes | `#fff6f6` (light red) | `#9f3a38` (dark red) | License has expired or is missing |
| `invalid` | Yes | `#fff6f6` (light red) | `#9f3a38` (dark red) | License data is structurally invalid or tampered |
**Auto-hide on valid license**
When the variant is `ok`, the panel is automatically hidden. Users with a valid Planningboard license will never see the panel. If the panel is not visible, that is expected behavior — it is not a bug.
**Error and invalid share the same styling**
The `error` and `invalid` variants use identical visual styling (red palette). The distinction is in the license condition they represent: `error` indicates an expired or absent license, while `invalid` indicates a license that fails validation checks.
***
## Attributes
| Attribute | Type | Default | Description |
| ---------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `variant` | `string` | — | Controls visual style and visibility. Accepted values: `ok`, `warning`, `error`, `invalid`. |
| `linkHref` | `string` | `#` | URL for the **Contact us** link. When not set, defaults to `#` (no navigation). Configure this to point to the Nextedy evaluation license request page. |
***
## Contact Link
The panel contains a **Contact us** link that opens in a new tab. This link is intended to help users or administrators reach Nextedy to request an evaluation license or resolve a licensing issue.
The link target URL is set via the `linkHref` attribute. If `linkHref` is not configured, the link defaults to `#` and does not navigate anywhere.
**Evaluation period**
Planningboard can be used for 30 days without a production license. The license panel communicates this state and provides the path to obtain a full license. See [License Installation](/planningboard/getting-started/licensing) for the full installation procedure.
***
## License Status in the Administration View
The administration view (`viewLicense`) displays full license details for administrators. It is separate from the user-facing License Panel but reflects the same license states.
### License states
| Status value | Meaning |
| ------------ | --------------------------------------------------------- |
| `INVALID` | The license file is missing, corrupt, or fails validation |
| `INFO` | Evaluation mode — no production license is installed |
| Valid | License is present and passes all checks |
### Administration view features
| Feature | Description |
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| License status message | Color-coded panel matching the current license state |
| License information block | Full license content in preformatted text; signature field is automatically redacted |
| Signature redaction | The `signature` field is stripped from the displayed text using regex replacement. The license is still validated server-side — redaction is for display only. |
| No-license fallback | When no production license is detected, the administration view shows an evaluation mode notice and a link to the license installation KB article. |
| Contact support link | Email link to the Nextedy support team |
| Documentation link | Opens the Planningboard support documentation in a new tab |
| Pricing FAQ link | Opens the Planningboard pricing information page in a new tab |
***
## License-Based Access Control
Planningboard enforces license-based access control at the board level. Unlicensed users retain read-only visibility of the board but cannot perform editing actions.
### Capability comparison by license state
| Capability | Licensed user | Unlicensed user |
| ---------------------------------------------------- | --------------------------------- | ----------------------------------------------- |
| View board content (cards, swimlanes, calendar data) | Yes | Yes |
| Drag and drop cards between swimlanes | Yes | No (drag is blocked; position is not persisted) |
| Create a new Plan | Yes (`#btnCreateNewPlan` visible) | No (button hidden) |
| Toggle the Unplanned section | Yes (`#btnShowUnplanned` visible) | No (button hidden) |
| Open the Work Item Properties sidebar | Yes | No (sidebar hidden) |
| Refresh the board | Yes | Yes (`#btnRefresh` available) |
**Drag-and-drop silently blocked for unlicensed users**
Unlicensed users can physically drag a card, but the operation is not persisted — the card returns to its original swimlane. There is no error message. If users report that cards are not saving after drag-and-drop, verify that their Planningboard license is active.
***
## Positioning and Layout
The License Panel is anchored to the **bottom-right** of the Planningboard viewport. It is rendered as a fixed-position overlay and does not interfere with board layout, card interaction, or swimlane scrolling.
The panel uses shadow DOM encapsulation:
* Its internal structure (markup, styles) is isolated from the Polarion host page.
* External CSS selectors cannot target elements inside the panel.
* Custom styling of the panel via page-level CSS is not supported.
***
## Developer Notes
The following information is relevant when integrating or extending the License Panel component.
### Component registration
The `initLicensePanel` function registers the component with the browser's custom element registry. It accepts an optional custom tag name parameter. This function must be called before the component is used in the DOM.
### Slotted content
The panel supports slotted HTML content via the default slot mechanism. Custom message text can be inserted into the panel by placing content inside the component's slot.
**Verify in application**
The exact tag name used by the component in the shipped Planningboard build and the specific slot usage pattern are internal implementation details. Consult the Planningboard administration page or contact Nextedy support for integration guidance.
***
## Related Pages
* [License Installation](/planningboard/getting-started/licensing) — step-by-step instructions for installing a production license
* [Toolbar Controls](/planningboard/reference/ui-elements/toolbar) — reference for the board toolbar, including controls affected by license state
* [UI Elements](/planningboard/reference/ui-elements/index) — index of all UI element reference pages
* [Reference](/planningboard/reference/index) — top-level reference index
**KB Articles**
* Planningboard interface & basic interactions
**Source Code**
* `license-panel.js`
* `widget.vm`
* `licenseReadonly.cy.ts`
* `viewLicense.vm`
* `viewSetup.vm`
# Unplanned Sidebar
Source: https://learn.nextedy.com/planningboard/reference/ui-elements/sidebar
The **Unplanned Sidebar** is a collapsible panel displayed on the right side of the Nextedy PLANNINGBOARD. It serves as a backlog holding all work items not yet assigned to a Plan.
***
***
## Overview
| Attribute | Value |
| --------------------- | ------------------------------------------------------------------ |
| Panel position | Right side of the board |
| Default visibility | Visible (toggle with **Show Unplanned** toolbar button) |
| License requirement | Licensed users only — panel is hidden for unlicensed users |
| Primary interaction | Drag card from sidebar onto a board swimlane/Plan cell to schedule |
| Secondary interaction | Click a card to open the Work Item Properties sidebar |
***
## Visibility Toggle
The sidebar can be shown or hidden using the **Show Unplanned** toolbar button (`#btnShowUnplanned`). This button is only visible to licensed users.
* When hidden, the board area expands to fill the full width.
* When shown, the board area narrows to accommodate the sidebar.
* The panel preference is saved between sessions.
**License restriction**
The **Show Unplanned** button and the sidebar panel itself are only rendered for licensed users. Unlicensed users see neither the button nor the sidebar.
***
## Item Display and Grouping
Items in the sidebar are grouped by **parent hierarchy**. The `updateSidebarHeader` function applies all active filters, sorts items by parent, groups them into parent-hierarchy dividers, and updates the item count indicator.
### Item Counter
A counter at the bottom of the sidebar displays the number of currently visible items relative to the total:
```
X out of Y work items
```
The counter updates in real time as filters are applied or cleared.
### Parent Hierarchy Grouping
Items are organized under collapsible parent-group dividers. The depth of parent levels loaded is controlled by the `PARAMETER_US_DEPTH` widget parameter (see [Work Items Parameters](/planningboard/reference/widget-parameters/work-items-parameters)).
The link role used to determine parent-child relationships is set by `PARAMETER_PARENTS_LINK_ROLE` (see [Work Items Parameters](/planningboard/reference/widget-parameters/work-items-parameters)).
| Widget Parameter | Purpose | Default |
| ----------------------------- | ----------------------------------------------------------- | --------------- |
| `PARAMETER_US_DEPTH` | Number of parent levels loaded in sidebar hierarchy | See application |
| `PARAMETER_PARENTS_LINK_ROLE` | Link role defining parent-child relationships for hierarchy | See application |
**Performance note**
Deep parent hierarchies (high `PARAMETER_US_DEPTH` values) increase data load time. Keep depth to the minimum required for your planning workflow.
***
## Filters
The sidebar supports multiple filter modes. Some filter modes are mutually exclusive — enabling one clears the other.
### Filter Controls
| Control | Element | Description |
| ------------------------------ | ------------------- | ------------------------------------------------------------------ |
| Funnel icon | Filter button | Opens the filter panel to select resource or query filters |
| **Filter Verified WIs** button | Upper-right button | Toggles whether resolved/verified work items appear in the sidebar |
| **Filter columns** option | Filter panel option | Hides verified work items that are already planned on the board |
| Search field | Text input | Real-time text search across item content and parent names |
| Clear filter | Clear action | Removes all active resource and query filters |
***
### Filter: Resolved / Verified Items (`toggleFilterResolved`)
Toggles whether **resolved** (verified) work items appear in the sidebar.
* When active: resolved items are hidden from the sidebar.
* When inactive: resolved items are shown alongside unresolved items.
* Items with the `Verified` status that have already been placed on the board **cannot be moved or unplanned**.
**Verified item lock**
Once a card with `Verified` status is placed on the board, it cannot be moved or returned to the sidebar via drag and drop.
***
### Filter: Column Filtering (`toggleFilterColumns`)
Hides verified work items that are **already planned** (already placed in a Plan column on the board).
* Differs from the resolved toggle: this filter targets items that appear on the board in a plan column, regardless of their resolved status.
* Use this to keep the sidebar clean by removing items that have already been scheduled.
***
### Filter: Resource Filter (`filterSidebarByResource`)
Filters sidebar items to show only those assigned to a **specific resource** (person or team).
* Accessed via the funnel icon filter panel.
* **Mutually exclusive with query filtering** — enabling a resource filter clears any active query filter.
* To remove: use the clear filter action (`clearSidebarFiler`).
***
### Filter: Query Filter (`filterSidebarByQuery`)
Filters sidebar items to show only those matching a **specific Polarion query**.
* Predefined queries must be configured via widget parameters (see [Work Items Parameters](/planningboard/reference/widget-parameters/work-items-parameters)).
* Accessed via the funnel icon filter panel under the **Queries** section.
* **Mutually exclusive with resource filtering** — enabling a query filter clears any active resource filter.
***
### Filter: Search (`searchSidebar`)
Performs real-time text search across sidebar items.
| Attribute | Behavior |
| ------------------------------ | ----------------------------------------------------------------------------------------------------------- |
| Scope | Searches both item content and parent names |
| Case sensitivity | Case-insensitive |
| Interaction with other filters | Combines with active resource/query filters (search narrows the already-filtered set) |
| Clearing search | Clearing the search text restores the previously filtered set — it does not clear resource or query filters |
***
### Clearing Filters (`clearSidebarFiler`)
The clear filter action removes all active **resource** and **query** filters and shows all unplanned items (subject to the resolved toggle state).
**What clear does NOT reset**
Clearing filters does **not** reset the search text field or the resolved/verified toggle. Those must be cleared independently.
***
## Filter Precedence and Combination
* Resource filter and query filter are **mutually exclusive** — enabling one clears the other.
* Search combines with whichever of the above filters are active.
* The resolved toggle and column filter apply independently before resource/query filtering.
***
## Drag and Drop
The primary interaction with the sidebar is **drag and drop**: drag a card from the sidebar onto a board cell (Plan column × swimlane row) to schedule it.
| Aspect | Behavior |
| --------------------------------- | ----------------------------------------------------------------------------- |
| Source | Unplanned sidebar items |
| Target | Board cells (Plan column × swimlane intersection) |
| Effect on drop | Work item is assigned to the Plan and resource/swimlane; removed from sidebar |
| Drag blocked in prioritize mode | Drag is disabled when Prioritization mode is active |
| Drag blocked for unlicensed users | Unlicensed users cannot drag cards; changes are not persisted |
### Alt+Drag to Duplicate
Holding **Alt** while dragging creates a **duplicate assignment** to another resource instead of moving the item:
* Creates a multi-resource assignment (comma-separated resource list on the work item).
* Cannot duplicate to the **Not Assigned/Other** swimlane.
* When duplicating from **Not Assigned/Other**, the **Not Assigned/Other** assignment is automatically removed.
***
## Click to Open Work Item Properties
Clicking a card in the sidebar opens the **Work Item Properties** sidebar, where fields of the selected work item can be reviewed and modified.
* Fields displayed in the properties sidebar are configured via the `PARAMETER_SIDEBAR_FIELDS` widget parameter.
* Default fields: `title`, `status`, `plannedIn`.
* Users can personalize displayed fields using the **Select Fields** (gear icon) button in the sidebar. These additions are per-user and apply to all work items of the same type.
* After saving changes in the properties sidebar, the board **preserves your swimlane and scroll position** — the board does not jump back to the top.
### Sidebar Fields Widget Parameter
| Widget Parameter | Type | Default | Description |
| -------------------------- | ------------------ | ------------------------------ | ---------------------------------------------------------------------- |
| `PARAMETER_SIDEBAR_FIELDS` | Array of field IDs | `title`, `status`, `plannedIn` | Work item fields shown in the properties sidebar when a card is opened |
See [Work Items Parameters](/planningboard/reference/widget-parameters/work-items-parameters) for the full field reference.
***
## Height Management (`modSchedHeight`)
The sidebar and board area heights are **automatically managed** to fit the browser window or Polarion iframe. No manual height configuration is required.
* Height adjusts dynamically when the browser window is resized.
* Behavior differs slightly when embedded in a Polarion LiveDoc or Wiki page (iframe) versus standalone.
***
## Unplanning Items from the Board
Items can be returned from the board to the sidebar using the **Unplan** card quick action (visible on hover). See [Card Quick Actions](/planningboard/reference/ui-elements/card-quick-actions) for details.
The **Unplan** action:
* Moves the card from its current Plan/swimlane cell back into the Unplanned Sidebar.
* Clears the work item's date and resource assignment.
* Makes the item available for re-planning.
**Verified items cannot be unplanned**
Cards with `Verified` status cannot be unplanned — the action is blocked for verified items.
***
## Configuration Reference
### Widget Parameters Affecting the Sidebar
| Parameter | Where Configured | Description | Reference |
| ----------------------------- | ----------------- | ---------------------------------------------- | ----------------------------------------------------------------------------------------- |
| `PARAMETER_SIDEBAR_FIELDS` | Widget Parameters | Fields shown in the Work Item Properties panel | [Work Items Parameters](/planningboard/reference/widget-parameters/work-items-parameters) |
| `PARAMETER_US_DEPTH` | Widget Parameters | Parent hierarchy depth loaded in the sidebar | [Work Items Parameters](/planningboard/reference/widget-parameters/work-items-parameters) |
| `PARAMETER_PARENTS_LINK_ROLE` | Widget Parameters | Link role used to build parent-child hierarchy | [Work Items Parameters](/planningboard/reference/widget-parameters/work-items-parameters) |
### Sidebar Behavior Summary
| Feature | Behavior | Notes |
| ------------------- | --------------------------------------------------------- | --------------------------------------------------- |
| Sidebar visibility | Toggle via **Show Unplanned** toolbar button | Licensed users only |
| Item grouping | Grouped by parent hierarchy | Depth set by `PARAMETER_US_DEPTH` |
| Item counter | Shows `X of Y work items` | Updates with each filter change |
| Resource filter | Filter by assignee or team | Mutually exclusive with query filter |
| Query filter | Filter by predefined Polarion query | Mutually exclusive with resource filter |
| Search | Real-time, case-insensitive, combined with active filters | Does not clear resource/query filters |
| Resolved toggle | Show/hide verified items | Does not affect already-placed verified items |
| Column filter | Hide already-planned verified items | Independent of resolved toggle |
| Clear filter | Clears resource and query filters only | Search text and resolved toggle unaffected |
| Drag and drop | Drag to board cell to schedule | Blocked in prioritize mode and for unlicensed users |
| Alt+drag | Create duplicate multi-resource assignment | Cannot target the **Not Assigned/Other** swimlane |
| Click card | Open Work Item Properties panel | Fields configured via `PARAMETER_SIDEBAR_FIELDS` |
| Scroll preservation | Board position preserved after saving properties | No jump to top on save |
| Height | Automatic, fits browser/iframe | No manual configuration |
***
## Related Pages
* [Toolbar Controls](/planningboard/reference/ui-elements/toolbar) — the **Show Unplanned** toggle button lives in the toolbar
* [Card Quick Actions](/planningboard/reference/ui-elements/card-quick-actions) — the Unplan action that returns items to the sidebar
* [Swimlane Controls](/planningboard/reference/ui-elements/swimlane-controls) — swimlane behavior that interacts with sidebar assignments
* [Work Items Parameters](/planningboard/reference/widget-parameters/work-items-parameters) — `PARAMETER_SIDEBAR_FIELDS`, `PARAMETER_US_DEPTH`, `PARAMETER_PARENTS_LINK_ROLE`
* [UI and Display Parameters](/planningboard/reference/widget-parameters/ui-parameters) — additional display configuration
* [License Panel](/planningboard/reference/ui-elements/license-panel) — license enforcement that controls sidebar access
**KB Articles**
* Planningboard interface & basic interactions
**Source Code**
* `unplanned_sidebar.js`
* `planningboard.js`
* `PlanningBoardWidgetRenderer.java`
* `PlanningBoardWidget.java`
* `widget.vm`
# Swimlane Controls
Source: https://learn.nextedy.com/planningboard/reference/ui-elements/swimlane-controls
Reference for all swimlane-level controls in Nextedy PLANNINGBOARD — the collapse/expand toggles, the capacity bar, the assignment type configuration, sorting options, and the Not Assigned/Other row behavior.
***
## Board Layout Overview
Each horizontal band is a **swimlane**. Swimlanes group work items (cards) by a chosen criterion — the **assignment type** — across all Plan columns.
***
## Collapse / Expand Controls
Individual swimlanes can be collapsed to hide their cards and save vertical space, then expanded again to reveal them.
### Per-swimlane toggle
Clicking the swimlane row header toggles that swimlane between collapsed and expanded state. The toolbar also provides global collapse/expand actions that affect all swimlanes simultaneously (see [Toolbar Controls](/planningboard/reference/ui-elements/toolbar)).
| Control | Location | Effect |
| ---------------------- | ------------------ | ------------------------------------------ |
| Click swimlane header | Swimlane row label | Toggles that swimlane collapsed / expanded |
| Collapse all (toolbar) | Upper-left toolbar | Collapses every swimlane on the board |
| Expand all (toolbar) | Upper-left toolbar | Expands every swimlane on the board |
### Widget parameter
| Parameter | Type | Default | Description |
| ---------------------- | ------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `collapsibleSwimlanes` | boolean | `true` | Enables per-swimlane collapse/expand. When `false`, swimlane headers are not interactive and all lanes remain permanently expanded. |
**Configuration example:**
```properties theme={null}
collapsibleSwimlanes=true
```
**Known issue — Chrome swimlane expansion**
An intermittent browser-specific bug causes clicking to expand a swimlane to expand a different swimlane (typically the last one in the list) instead. This has been observed in Chrome but not in Edge. **Workaround:** use Microsoft Edge, or click the global Expand all toolbar button and then collapse the lanes you do not need.
***
## Show Empty Swimlanes
By default, swimlanes with no matching work items are hidden. Enabling this option keeps all possible lanes visible even when empty.
| Parameter | Type | Default | Description |
| -------------------- | ------- | ------- | ---------------------------------------------------------------------------- |
| `showEmptySwimlanes` | boolean | `false` | When `true`, all swimlane rows are rendered even if they contain zero cards. |
**Configuration example:**
```properties theme={null}
showEmptySwimlanes=true
```
Showing empty swimlanes is useful when you want a consistent row structure across all iterations — for example, to confirm a team member truly has no work planned in a sprint rather than wondering whether the row is simply hidden.
***
## Assignment Type
The **assignment type** (widget parameter `assignmentMode`) determines how work items are grouped into swimlane rows. It is configured in the **Widget Parameters** panel under **Swimlanes (Rows) > Assignment Type**.
### Assignment type options
| Assignment Type | `assignmentMode` value | Swimlane rows represent |
| ----------------- | ---------------------- | --------------------------------------------------------- |
| Users (Assignee) | `ASSIGNEE` | Individual users who hold a specified role in the project |
| Parent Item | `PARENT` | Parent work items matched by a Lucene query and link role |
| Enumeration Field | `ENUM` | Values of a specified enumeration custom field |
| Project | `PROJECT` | Sub-projects within the current project group |
| SAFe Team | `SAFE_TEAM` | SAFe teams within the current program |
| SAFe Train Team | `SAFE_TRAIN_TEAM` | Teams within a specific Agile Release Train |
| SAFe Programs | `SAFE_PROGRAMS` | SAFe programs within a solution train |
| No Swimlanes | `none` | (all items in a single flat view — no rows) |
Each type exposes different configuration fields, described in the sections below.
***
### Users (Assignee)
Each swimlane row represents one user who holds a specified role in the current Polarion project.
| Field | Required | Description |
| -------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **User Role** (`userRole`) | Yes | The Polarion role ID whose members become swimlane rows. Example: `project_user`. |
| **Report Link** | No | URL template for a report link on the swimlane label. Supports `${r.objectId.itemId}` to pass the user ID. Example: `/polarion/#/project/PlanningBoard/wiki/SOME_REPORT?user=${r.objectId.itemId}` |
**Configuration example:**
```properties theme={null}
assignmentMode=ASSIGNEE
userRole=project_user
```
**When to use:** plan the workload of individual team members who are active in the project. Provides a per-person view for balancing assignments.
See also: [Assignee Mode](/planningboard/reference/assignment-modes/assignee-mode)
***
### Parent Item
Each swimlane row represents a parent work item. Items can only be placed under their actual parent — dragging to an incorrect row causes Planningboard to snap the card back to its correct parent's lane automatically.
| Field | Required | Description |
| ------------------------------------------------ | -------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| **Parent Role** (`parentRole`) | Yes | The link role that defines the parent relationship (e.g., `implements`). |
| **Parent Work Item Type** (`parentWorkItemType`) | No | Filters parent items to only those of this type. |
| **Parent Query** | No | Lucene query to restrict which parent items appear as rows. |
| **Filter Parents** | No | `Yes` / `No` — whether to limit visible parents to those matched by the query. |
| **Sort By** | No | Property by which parent swimlanes are ordered. Since Planningboard 25.9.0, any custom property including `priority` is supported. |
| **Report Link** | No | URL template for a report link on the swimlane label. |
**Configuration example:**
```properties theme={null}
assignmentMode=PARENT
parentRole=implements
parentWorkItemType=feature
```
**Limitation — no normalization with Parent mode**
Parent Item assignment mode does **not** support plan normalization (`planCellsMode`). Do not combine `assignmentMode=PARENT` with `planCellsMode=true`.
**When to use:** visualize and plan hierarchical relationships — for example, see how tasks distribute across features or initiatives.
See also: [Parent Item Mode](/planningboard/reference/assignment-modes/parent-mode), [Swimlanes Parameters](/planningboard/reference/widget-parameters/swimlanes-parameters)
***
### Enumeration Field
Each swimlane row represents a value from a specified enumeration custom field (e.g., `team`, component type, or priority tier).
| Field | Required | Description |
| ---------------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| **Field ID** (`enumFieldId`) | Yes | The Polarion custom field ID (e.g., `team`). Must reference a valid enumeration field (`IEnumType` or `IListType` containing enum items). |
| **Rows Filter** | No | Limits which enum values appear as rows. |
| **Report Link** | No | URL template for a report link on the swimlane label. |
**Configuration example:**
```properties theme={null}
assignmentMode=ENUM
enumFieldId=team
```
**Unsupported field types**
The `status`, `resolution`, and `type` built-in fields are **not** supported as enum swimlane sources. Only custom enumeration fields are valid.
**Multi-valued fields:** when a work item has multiple values for the enum field, it appears in each corresponding swimlane row simultaneously. Dragging the card to the **Not Assigned/Other** row removes that specific enum value from the field — not all values.
**When to use:** plan work by team, component, or any categorical attribute stored as a custom enumeration field.
See also: [Enumeration Field Mode](/planningboard/reference/assignment-modes/enum-mode)
***
### Project
Each swimlane row represents a sub-project within the current project group. Only projects readable by the current user are included; the current project itself is excluded.
| Field | Required | Description |
| --------------- | -------- | ----------------------------------------------------------------- |
| **Report Link** | No | URL template for a project-specific report on the swimlane label. |
**Configuration example:**
```properties theme={null}
assignmentMode=PROJECT
```
**When to use:** cross-project planning view for teams working across multiple projects simultaneously.
See also: [Project Mode](/planningboard/reference/assignment-modes/project-mode)
***
### SAFe Assignment Types
Three assignment types are available for SAFe (Scaled Agile Framework) environments. These require a Polarion SAFe Solution to be configured.
| Assignment Type | `assignmentMode` value | Additional field |
| --------------- | ---------------------- | ---------------------------------------------------------------------------------------------- |
| SAFe Team | `SAFE_TEAM` | `safeTeamField` — custom field storing the SAFe team assignment (default: `safeTeam`) |
| SAFe Train Team | `SAFE_TRAIN_TEAM` | `safeTeamField` + ART ID parameter to filter by Agile Release Train |
| SAFe Programs | `SAFE_PROGRAMS` | `safeProgramField` — custom field storing the SAFe program assignment (default: `safeProgram`) |
**Verify in application**
SAFe assignment type configuration requires Polarion SAFe Solution. Contact Nextedy support for setup guidance specific to your SAFe topology.
See also: [SAFe Team Mode](/planningboard/reference/assignment-modes/safe-team-mode), [SAFe Train Team Mode](/planningboard/reference/assignment-modes/safe-train-team-mode), [SAFe Programs Mode](/planningboard/reference/assignment-modes/safe-programs-mode)
***
### No Swimlanes
All work items appear in a single flat view. No horizontal grouping is applied.
**Configuration example:**
```properties theme={null}
assignmentMode=none
```
**When to use:** high-level planning or quick overviews where swimlane separation is unnecessary; focus is on columns (Plans) only.
See also: [No Swimlanes Mode](/planningboard/reference/assignment-modes/no-swimlanes-mode)
***
## Swimlane Sort Order
The `swimlaneSort` parameter controls the vertical ordering of swimlane rows (when using any assignment type other than `none`).
| Parameter | Type | Default | Description |
| -------------- | ------ | -------------- | ----------------------------------------------------------------------------------- |
| `swimlaneSort` | string | `alphabetical` | Sort order for swimlane rows. Controls vertical ordering of all lanes on the board. |
**Available values:**
| Value | Description |
| -------------- | ---------------------------------------------------------------------------------- |
| `alphabetical` | Rows sorted A–Z by the swimlane label (user name, enum value, project name, etc.). |
**Verify in application**
Additional sort values beyond `alphabetical` (including custom property sort introduced in Planningboard 25.9.0 for Parent mode via the **Sort By** field) may be available depending on the assignment type and version. Check the **Sort By** field in Widget Parameters > Swimlanes (Rows) for available options for your chosen assignment type.
**Note:** swimlane sort order is coupled to item sort order within each lane. The sort order of cards within a swimlane follows the same hierarchy: 1) resource name, 2) start date, 3) priority (if prioritization is enabled) or the custom sort field, 4) work item ID as tiebreaker.
***
## Capacity Bar
Each swimlane row displays a **capacity bar** that visualizes the load relative to available capacity for that resource. The capacity bar is a per-swimlane indicator — not to be confused with the per-Plan capacity tooltip displayed on column headers.
### Enabling capacity display
Capacity bar display is controlled by a combination of parameters:
| Parameter | Type | Default | Description |
| ------------------- | ------- | ------- | ----------------------------------------------------------------------------------------------------------------- |
| `capacityLoad` | boolean | `false` | Enables capacity/load calculations for resources. Must be `true` for capacity bars to appear. |
| `capacityField` | string | (none) | Custom field ID containing the capacity values used in load calculations (e.g., story points field, hours field). |
| `hoursPerDay` | number | `8` | Working hours per day, used in capacity normalization calculations. |
| `multiCapacityLoad` | boolean | `false` | Enables capacity loading across multiple plans simultaneously. |
| `userCapacityLoad` | boolean | `false` | Enables user-level capacity loading. Requires `useTeamsService=true`. |
**Configuration example:**
```properties theme={null}
capacityLoad=true
capacityField=storyPoints
hoursPerDay=8
```
**Whitespace sensitivity**
Capacity configuration parameter values are whitespace-sensitive. Do not add leading or trailing spaces around `=` assignments when editing capacity parameters.
### Capacity tooltip
Hovering over the capacity bar on a **Plan column header** (not the swimlane bar) displays a detailed tooltip with capacity information per plan. This tooltip is only available when `capacityLoad` is enabled via Widget Parameters.
**Limitation — capacity vs GANTT**
Planningboard capacity tracking has the following known gaps compared to Nextedy GANTT:
* **No multi-assignee capacity distribution** — if a work item has multiple assignees, capacity is not split across them.
* **No sub-item effort distribution** — effort from child work items is not rolled up to parent items for capacity purposes.
See also: [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters)
***
## Not Assigned/Other Row
When using Enumeration Field or Users (Assignee) assignment types, a special **Not Assigned/Other** row (`UNASSIGNED`) is displayed at the bottom of the swimlane list. It contains work items that have no value for the grouping field.
### Drag-and-drop behavior with Not Assigned/Other
| Action | Result |
| --------------------------------------------------------- | ---------------------------------------------------------------------------------------------------- |
| Drag card from user/enum swimlane to Not Assigned/Other | Removes **that specific value** from the multi-valued field. Other values on the card are preserved. |
| Drag card from Not Assigned/Other to a user/enum swimlane | Assigns that user or enum value to the work item. |
**Multi-valued fields**
When a work item has multiple values for the grouping field, it appears in each corresponding row simultaneously. Dropping it onto Not Assigned/Other removes only the value corresponding to the source swimlane row — not all values. The change persists after board refresh.
***
## License-Based Swimlane Access
Swimlane interaction is restricted based on whether the current user holds a Planningboard license.
| Capability | Licensed user | Unlicensed user |
| ---------------------------- | ------------- | -------------------------------------------------------------------- |
| View swimlane contents | Yes | Yes |
| Collapse / expand swimlane | Yes | Yes |
| Drag cards between swimlanes | Yes | No — drag operations are blocked; cards return to their original row |
| View capacity bar | Yes | Yes |
Unlicensed users retain full visibility of the board — including swimlane contents and capacity bars — for collaboration and review purposes. Editing capabilities (drag-and-drop, creating plans, accessing the sidebar) are restricted to licensed users.
See also: [License Panel](/planningboard/reference/ui-elements/license-panel)
***
## Configuration Example
The following example configures a board with user-based swimlanes, capacity enabled, and empty lanes hidden:
```properties theme={null}
# Swimlane assignment
assignmentMode=ASSIGNEE
userRole=project_user
swimlaneSort=alphabetical
showEmptySwimlanes=false
collapsibleSwimlanes=true
# Capacity
capacityLoad=true
capacityField=storyPoints
hoursPerDay=8
```
**Report link example for user swimlanes:**
```
/polarion/#/project/PlanningBoard/wiki/SOME_REPORT?user=${r.objectId.itemId}
```
The `${r.objectId.itemId}` placeholder is substituted at runtime with the user ID for the selected swimlane row.
***
## Related Reference
| Page | Description |
| --------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
| [Swimlanes Parameters](/planningboard/reference/widget-parameters/swimlanes-parameters) | Full widget parameter reference for swimlane configuration |
| [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) | Capacity and load parameters |
| [Assignment Modes](/planningboard/reference/assignment-modes/index) | Detailed reference for each assignment mode |
| [Toolbar Controls](/planningboard/reference/ui-elements/toolbar) | Global collapse/expand and other toolbar actions |
| [Unplanned Sidebar](/planningboard/reference/ui-elements/sidebar) | Sidebar controls for unplanned work items |
| [Card Quick Actions](/planningboard/reference/ui-elements/card-quick-actions) | Per-card hover actions |
**KB Articles**
* Planningboard interface & basic interactions
* Swimlane Assignment Types
* Planningboard Widget Parameters
**Support Tickets**
* [#6681](https://support.nextedy.com/helpdesk/tickets/6681)
* [#6688](https://support.nextedy.com/helpdesk/tickets/6688)
**Source Code**
* `licenseReadonly.cy.ts`
* `Config.java`
* `AssignmentMode.java`
* `widget.vm`
* `PlanningBoardWidget.java`
# Toolbar Controls
Source: https://learn.nextedy.com/planningboard/reference/ui-elements/toolbar
The Nextedy PLANNINGBOARD toolbar is located in the upper-left corner of the board area.
***
## Toolbar Button Reference
The following table lists every toolbar button in the order they appear. All buttons are toggle or action controls — they do not require widget parameter configuration to be visible unless noted.
| Button | Label | Type | Description |
| -------------------- | -------------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Collapse all | **Collapse all** | Action | Collapses all swimlanes at once, hiding their card rows and showing only the swimlane header. Equivalent to clicking each swimlane's individual collapse control. |
| Expand all | **Expand all** | Action | Expands all collapsed swimlanes, restoring their card rows. Individual swimlane collapse state is reset. |
| Refresh | **Refresh data** | Action | Reloads board data from the server. Use after making changes in Polarion that are not yet reflected on the board, or after another user has modified planned items. |
| Toggle Resource Load | **Toggle Resource Load visualization** | Toggle | Shows or hides capacity bars in each swimlane and Plan column, indicating the current load per assignee. Must be configured via widget parameters to produce meaningful values (see [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters)). |
| Show Unplanned | **Show Unplanned** | Toggle | Shows or hides the Unplanned sidebar on the right side of the board. The sidebar holds work items not yet assigned to a Plan. See [Unplanned Sidebar](/planningboard/reference/ui-elements/sidebar) for full details. |
| Create New Plan | **Create New Plan** | Action | Creates a new Plan (board column) from the configured template, using the New Plan widget parameters (Template ID, Parent ID, Plan Name/ID Pattern, Duration). See [Creating Plans](/planningboard/guides/planning/creating-plans). |
| Prioritize | **Prioritize** | Toggle | Enables Prioritization mode on the board. In this mode, cards can be reordered within swimlanes to set planning priority. Drag-and-drop scheduling is blocked while Prioritize is active. |
| Show Dependencies | **Show Dependencies** | Toggle | Displays all dependency links between cards simultaneously across the entire board. This is a board-wide view; for link visibility on a single card, use the Show Links quick action on the card. Requires dependency display to be enabled via widget parameters. |
***
## Toolbar Icon Reference
The icons below correspond to each toolbar button in the order they appear:
***
## Collapse and Expand Controls
Collapse and expand operate at two levels:
* **Toolbar level** — **Collapse all** and **Expand all** apply to every swimlane simultaneously.
* **Swimlane level** — Individual swimlane headers can be clicked to collapse or expand that swimlane independently. See [Swimlane Controls](/planningboard/reference/ui-elements/swimlane-controls).
***
## Show Dependencies vs. Show Links
Two separate mechanisms exist for viewing dependencies between cards. They operate at different scopes:
| Mechanism | Scope | Location | Activation |
| --------------------- | ----------------------------------------- | ----------------- | ----------------------------------- |
| **Show Dependencies** | All cards on the board simultaneously | Toolbar | Toolbar toggle button |
| **Show Links** | Single selected card and its linked cards | Card quick action | Hover over card → quick action icon |
When **Show Dependencies** is active, all cards not involved in any link are hidden and all dependency links are drawn across the board. When **Show Links** is used from a card, only that card's linked cards remain visible and all others are hidden.
**Widget parameter prerequisite**
The **Show Dependencies** toolbar button requires that dependency display is enabled in the widget configuration. If the button is absent or non-functional, check the relevant widget parameter. See [UI and Display Parameters](/planningboard/reference/widget-parameters/ui-parameters).
***
## Toggle Resource Load Visualization
The **Toggle Resource Load visualization** button shows or hides capacity bars on the board. Capacity bars appear in swimlane rows and Plan column headers to indicate how much capacity has been consumed relative to available capacity.
* When toggled **on**, each swimlane cell and Plan column header displays a progress bar reflecting the current load.
* When toggled **off**, capacity bars are hidden and the board displays cards only.
Capacity bar behavior depends on the capacity mode configured in widget parameters:
| Capacity Mode | Bars shown at | Description |
| --------------- | ----------------- | ---------------------------------------------------------------------- |
| Single capacity | Plan column level | One bar per column, shared across all swimlanes |
| Multi-capacity | Per swimlane cell | Each swimlane cell shows its own bar keyed to that resource's capacity |
| User capacity | Per-user swimlane | Capacity derived from each user's defined capacity |
**Hovering over a capacity bar**
When you hover over a capacity bar in a Plan column header, a tooltip appears with detailed capacity information for that Plan. This tooltip is only available when capacity is configured. See [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters).
***
## Prioritize Mode
When **Prioritize** is active:
* Cards within each swimlane can be reordered by dragging to set planning priority.
* Drag-and-drop scheduling (moving a card from the Unplanned sidebar onto the board, or between Plan columns) is **blocked** while Prioritize is active.
* The board remains read-only for plan assignment operations until Prioritize is toggled off.
Prioritization affects item sort order within swimlanes. The default sort order when Prioritize is off is: resource name → start date → priority or custom sort field → ID as tiebreaker.
**Prioritize mode blocks drag-and-drop scheduling**
While Prioritize mode is active, you cannot drag cards between columns or from the Unplanned sidebar. Toggle Prioritize off before reassigning items to Plans.
***
## Show Unplanned Sidebar
The **Show Unplanned** button toggles the Unplanned sidebar that appears on the right side of the board. The sidebar holds all work items that match the board's query but are not yet assigned to a Plan.
* When hidden, the full horizontal width of the browser window is available for the board area.
* The sidebar preference is not automatically saved between sessions.
For full sidebar reference including filtering, search, and drag-and-drop behavior, see [Unplanned Sidebar](/planningboard/reference/ui-elements/sidebar).
***
## Refresh Data
The **Refresh data** button reloads the board's data from the Polarion server without reloading the entire page. Use it when:
* Another user has made changes to planned items and you want to see the current state.
* You have made changes in Polarion directly (e.g., via the work item editor) and want the board to reflect them.
* After a save operation in the Work Item Properties sidebar, the board preserves scroll and swimlane position. A manual refresh will reload all data from the server.
***
## Toolbar Layout Diagram
***
## Related Reference Pages
* [Unplanned Sidebar](/planningboard/reference/ui-elements/sidebar) — full reference for the Unplanned sidebar panel
* [Card Quick Actions](/planningboard/reference/ui-elements/card-quick-actions) — card-level actions including Show Links, Add Link, and Unplan
* [Swimlane Controls](/planningboard/reference/ui-elements/swimlane-controls) — individual swimlane expand/collapse and other per-row controls
* [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) — widget parameters controlling capacity bar behavior
* [UI and Display Parameters](/planningboard/reference/widget-parameters/ui-parameters) — widget parameters for dependency display and other UI options
* [Assignment Modes](/planningboard/reference/assignment-modes/index) — how swimlanes are populated (affects what the Resource Load visualization shows)
**KB Articles**
* Planningboard interface & basic interactions
**Source Code**
* `unplanned_sidebar.js`
* `enum-rows-filter-folder-scope.cy.ts`
* `widget.vm`
* `viewLicense.vm`
* `license-panel.js`
# Advanced Parameters
Source: https://learn.nextedy.com/planningboard/reference/widget-parameters/advanced-parameters
Advanced parameters give you low-level control over Nextedy PLANNINGBOARD widget behaviour: the scripting hook, instance identity, rendering mode, and item-load ceiling.
For the full parameter surface, see the [Widget Parameters](/planningboard/reference/widget-parameters/index) reference index.
***
## Parameters
### Instance and Rendering
| Name | Type | Default | Description |
| --------- | --------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `pbId` | `string` | `""` | Unique identifier for this Planningboard instance. Required when two or more board widgets appear on the same Polarion page — each board must have a distinct `pbId` so the client can distinguish them. |
| `inView` | `boolean` | `false` | When `true`, renders the board in *view mode*: a modal parameter-editor overlay is shown instead of rendering the board inline as a standalone page. Use `false` (the default) for a standard embedded board widget. |
| `version` | `string` | `""` | Version string appended to the board's iframe `src` URL for cache-busting. Ensures users receive the latest board code after a Planningboard upgrade. Set automatically by the widget renderer; you do not normally need to set this manually. |
***
### Scripting Hook
| Name | Type | Default | Description |
| ----------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `advScript` | `string` | `""` | Advanced JavaScript code to execute in the Planningboard context. The script is exposed as `window.__pbAdvScript` and runs after the board initialises. Use this for custom board-level logic that cannot be achieved through widget parameters alone. See [Scripting API](/planningboard/reference/api/scripting-api) for the API surface available to scripts. |
**Advanced use only**
`advScript` executes arbitrary JavaScript in the Polarion page context. Incorrect scripts can break board rendering or interfere with Polarion navigation. Test in a non-production environment before deploying.
***
### Item Loading
| Name | Type | Default | Description |
| ---------- | -------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `maxItems` | `number` | `1000` | Maximum number of work items loaded into the board. If your query matches more items than this ceiling, the board silently truncates the result set. Increase only when necessary — very large item sets affect initial load time. |
**Performance**
The default `maxItems` value of `1000` is a balance between completeness and rendering performance. Boards with hundreds of cards across many swimlanes may feel sluggish; narrow your work-item query rather than raising `maxItems`.
***
### Sidebar Fields
| Name | Type | Default | Description |
| --------------- | ---------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `sidebarFields` | `string[]` | `[]` | Array of Polarion field IDs to display in the Work Item Properties sidebar when a card is clicked. If empty, the board falls back to a default field set (title, status, plannedIn). Individual users can further personalise visible fields using the gear icon in the sidebar — those per-user additions apply to all work items of the same type for that user only. |
**Example — configuring sidebar fields:**
```json theme={null}
["title", "status", "plannedIn", "assignee", "priority", "description"]
```
Field IDs must match the exact Polarion field identifiers for your project. Custom fields are referenced by their custom field ID.
**Sidebar field configuration scope**
`sidebarFields` sets the *default* fields presented to all users of this board instance. Per-user customisation (via the gear icon) layered on top is user-scoped and does not affect the widget parameter.
***
### Unplanned Sidebar Hierarchy
| Name | Type | Default | Description |
| ----------------------------- | -------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `PARAMETER_US_DEPTH` | `number` | See application | Controls how many levels of parent work items are loaded when building the hierarchy in the unplanned sidebar. Higher values show deeper parent chains but increase load time and memory usage. |
| `PARAMETER_PARENTS_LINK_ROLE` | `string` | See application | Specifies which Polarion link role defines parent-child relationships for the unplanned sidebar hierarchy. Only link roles registered in the Polarion project configuration are valid. Incorrect or missing values result in a flat (non-hierarchical) unplanned sidebar. |
**Depth trade-offs:**
| Depth Value | Effect |
| ----------- | ------------------------------------------------------------------------------------------------------------------- |
| `1` | Loads only direct parents — fast, minimal memory |
| `2` | Loads grandparents — supports two-level feature/story hierarchies |
| `3+` | Deep hierarchies — use only when the project structure requires it; performance degrades with each additional level |
**Performance with deep hierarchies**
Each additional depth level multiplies the number of parent work items fetched. On large projects with thousands of items, `PARAMETER_US_DEPTH` values above `2` can significantly increase board load time.
***
## Parameter Visibility and Page Parameters
By default, Planningboard widget parameters are accessible through the gear icon on the embedded widget. There is no built-in option to permanently display the parameter controls above the board without user interaction.
**Verify in application**
Whether Polarion page parameters (`$pageParameters.xxx`) can be used to drive Planningboard widget values dynamically is not confirmed in the current source context. Based on ticket evidence, Planningboard swimlane configuration does **not** support Polarion page parameters for dynamic team filtering — a static workaround (separate Planningboard page per team configured with hardcoded swimlane values) is the supported approach. See [Swimlanes (Rows) Parameters](/planningboard/reference/widget-parameters/swimlanes-parameters) for swimlane configuration options.
***
## Configuration Example
The following example shows a widget instance with a unique `pbId`, a 500-item cap, custom sidebar fields, and an `advScript` that logs initialisation to the browser console.
```properties theme={null}
pbId = sprint-board-q3
inView = false
maxItems = 500
sidebarFields = ["title","status","plannedIn","assignee","storyPoints"]
advScript = console.log('Planningboard sprint-board-q3 initialised');
```
**Scenario:** A sprint Planningboard embedded on a LiveDoc page alongside a Gantt widget. Setting `pbId = sprint-board-q3` prevents the two widgets from sharing client state. `maxItems = 500` keeps load time acceptable for a project with a large backlog. The sidebar exposes story points alongside the standard fields so planners do not need to open the work item form.
***
## Parameter Interaction Diagram
***
## Related References
* [Widget Parameters](/planningboard/reference/widget-parameters/index) — full parameter index
* [Work Items Parameters](/planningboard/reference/widget-parameters/work-items-parameters) — query, sort, and dependency configuration
* [Plans (Columns) Parameters](/planningboard/reference/widget-parameters/plans-parameters) — plan type, count, and column link
* [Swimlanes (Rows) Parameters](/planningboard/reference/widget-parameters/swimlanes-parameters) — assignment types and row configuration
* [Scripting API](/planningboard/reference/api/scripting-api) — JavaScript API available to `advScript`
* [Config Script API](/planningboard/reference/api/config-script-api) — configuration scripting reference
**KB Articles**
* Planningboard Widget Parameters
* Planningboard: Customizable Statistics and Capacity Indicators
* Planningboard interface & basic interactions
**Support Tickets**
* [#6607](https://support.nextedy.com/helpdesk/tickets/6607)
* [#6546](https://support.nextedy.com/helpdesk/tickets/6546)
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
**Source Code**
* `widget.vm`
* `PlanningBoardWidgetRenderer.java`
* `PlanningBoardWidget.java`
* `Config.java`
* `planningboard.js`
# Capacity Parameters
Source: https://learn.nextedy.com/planningboard/reference/widget-parameters/capacity-parameters
Capacity parameters control how Nextedy PLANNINGBOARD calculates and visualizes effort and resource load.
These parameters work together. Enabling `capacityLoad` activates column-level bars; adding `multiCapacityLoad` moves to per-swimlane-cell bars; adding `userCapacityLoad` draws capacity from the Teams Service rather than from plan totals. See the [Configuration Properties — Capacity Properties](/planningboard/reference/configuration-properties/capacity-properties) page for system-wide capacity settings that complement these per-widget parameters.
***
## Capacity Load Parameters
| Parameter | Type | Default | Description |
| ------------------- | --------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `capacityLoad` | `boolean` | `false` | Enables capacity/load visualization. When `true`, progress bars appear in each plan column showing total allocated effort versus plan capacity. Requires effort data on work items (see `capacityField` or time-tracking fields). |
| `multiCapacityLoad` | `boolean` | `false` | Enables per-swimlane-cell capacity bars. Each cell in the board grid shows its own capacity progress for the intersecting resource and plan. Takes effect only when `capacityLoad` is also `true`. |
| `userCapacityLoad` | `boolean` | `false` | Enables user-level capacity loading. Draws per-user total capacity from the Teams Service rather than deriving it from plan capacity values. Requires `useTeamsService = true`. |
| `capacityField` | `string` | *(none)* | Custom field ID containing the effort or capacity value for each work item (for example, a story points field). When set, Planningboard reads this field instead of the default time-tracking fields (`remainingEstimate` / `initialEstimate`). Write the exact field ID as configured in Polarion — wrong casing fails silently. |
| `hoursPerDay` | `number` | `8` | Working hours per day used to convert time-tracking values to comparable units. Affects how `remainingEstimate` and `initialEstimate` are scaled when `capacityField` is not set. |
| `useTeamsService` | `boolean` | `false` | Enables integration with the Planningboard Teams Service. Required for `userCapacityLoad`. When enabled, team member lists, total user capacities, and team assignments are sourced from the Teams Service instead of directly from Polarion plan data. |
***
## Effort Calculation
When `capacityLoad` is enabled, Planningboard calculates three effort values per work item:
| Value | Calculation | Notes |
| ------------ | ------------------------------- | ---------------------------------------------------------------------------------------------- |
| `effort` | Total effort from the work item | From `capacityField` if set; otherwise derived from `initialEstimate` scaled by `hoursPerDay` |
| `effortDone` | Completed portion | For resolved/done work items: equals `effort`. For open items: derived from time already spent |
| `effortTodo` | Remaining portion | `effort − effortDone`. For resolved items: `0`. |
The capacity bar displays allocated effort (sum of `effort` across items in the swimlane/plan cell) against the plan's configured capacity value.
**Capacity values are set per plan**
The capacity value for each plan column is set separately — either via the Teams Service or directly through the REST API endpoint `POST /capacity` (see [REST API](/planningboard/reference/api/rest-api)). Without a capacity value configured on a plan, the capacity bar shows effort consumed but cannot display a percentage or "over/under" state.
***
## Capacity Modes: Column-Level vs Cell-Level
Use `multiCapacityLoad` when different resources have different individual capacities and you need to track load per person per plan rather than per plan in aggregate.
**Multi-assignee capacity is not supported**
When a work item has multiple assignees, the effort is not distributed across swimlanes. The full effort value is attributed to the primary assignee only. This is a known limitation compared to Nextedy GANTT. See [Swimlanes (Rows) Parameters](/planningboard/reference/widget-parameters/swimlanes-parameters) for related swimlane assignment constraints.
***
## Teams Service Integration
The Teams Service provides per-user and per-team capacity data that overrides plan-level capacity values when `useTeamsService = true` and `userCapacityLoad = true`.
| Parameter | Type | Default | Description |
| ----------------- | --------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `useTeamsService` | `boolean` | `false` | Activates the Teams Service integration. Must be `true` to use `userCapacityLoad` and to have team member lists sourced from the service. |
| `selectedTeam` | `string` | *(none)* | ID of the team to filter by when the Teams Service is active. Restricts displayed swimlanes to members of the specified team only. Leave empty to show all teams. |
When the Teams Service is enabled, the user capacity data model tracks:
| Field | Description |
| ------------------- | -------------------------------------------------------------------------------------- |
| `totalCapacity` | Total capacity configured for the user (hours or effort units, from the Teams Service) |
| `allocatedCapacity` | Sum of effort assigned to the user across planned work items |
| `remainingCapacity` | Automatically calculated: `totalCapacity − allocatedCapacity` |
The capacity bar tooltip (visible on hover over a plan column's capacity bar) shows this breakdown when the Teams Service is active.
**Capacity tooltip**
Hovering over a capacity bar shows a detailed tooltip with total, allocated, and remaining capacity. This tooltip is only available when `capacityLoad` is enabled via widget parameters.
***
## Configuration Example
The following example configures a board with per-swimlane capacity bars, story points as the effort unit, and the Teams Service providing user capacity totals.
```properties theme={null}
# Enable capacity visualization
capacityLoad=true
multiCapacityLoad=true
# Use story points field instead of time tracking
capacityField=storyPoints
# Teams Service for per-user capacity
useTeamsService=true
userCapacityLoad=true
# 8-hour working day (default, shown for clarity)
hoursPerDay=8
```
In this configuration:
* Each board cell (resource × plan intersection) shows its own capacity bar.
* Effort is read from the `storyPoints` custom field on each work item.
* Total capacity per user is sourced from the Teams Service, not from plan-level values.
* The capacity tooltip on hover shows total / allocated / remaining per user.
***
## Parameter Dependencies
**Whitespace sensitivity**
Capacity configuration parameters are whitespace-sensitive. Do not include leading or trailing spaces around `=` or around field ID values (for example, `capacityField=storyPoints`, not `capacityField = storyPoints`). Whitespace causes the value to be read as empty.
***
## Limitations
* **No multi-assignee effort distribution.** When a work item is assigned to multiple users, the full effort is attributed to the primary assignee only — it is not split across swimlane rows. This is a known gap relative to Nextedy GANTT's capacity model.
* **Sub-item effort is not aggregated into parent swimlane rows.** Effort on child work items does not roll up to a parent swimlane. The capacity bar reflects only items directly in the swimlane.
* **`PARENT` assignment mode does not support capacity normalization.** When `assignmentMode` is `PARENT`, the `planCellsMode` (used by capacity normalization) is not supported. Capacity bars are unavailable in parent-mode boards.
* **Plan capacity must be set separately.** Planningboard does not auto-derive plan capacity from date ranges or team size. Without a capacity value on the plan, the bar displays effort consumed only — no percentage or over-capacity indicator.
***
## Related Pages
* [Plans (Columns) Parameters](/planningboard/reference/widget-parameters/plans-parameters) — configure plan columns and the `Show Capacity Load` option
* [Swimlanes (Rows) Parameters](/planningboard/reference/widget-parameters/swimlanes-parameters) — configure swimlane assignment and how resources map to rows
* [Configuration Properties — Capacity Properties](/planningboard/reference/configuration-properties/capacity-properties) — system-wide capacity defaults
* [Teams Service API](/planningboard/reference/api/teams-service-api) — Teams Service endpoints for user capacity data
* [Assignment Modes](/planningboard/reference/assignment-modes/index) — overview of all assignment modes and their capacity support
**KB Articles**
* Planningboard Widget Parameters
* Planningboard: Customizable Statistics and Capacity Indicators
* Planningboard interface & basic interactions
**Support Tickets**
* [#4714](https://support.nextedy.com/helpdesk/tickets/4714)
* [#6607](https://support.nextedy.com/helpdesk/tickets/6607)
* [#6777](https://support.nextedy.com/helpdesk/tickets/6777)
**Source Code**
* `PlanningBoardWidget.java`
* `planningboard.js`
* `widget.vm`
* `PlanningBoardDataService.java`
* `Config.java`
# Widget Parameters
Source: https://learn.nextedy.com/planningboard/reference/widget-parameters/index
Widget parameters configure each Nextedy PLANNINGBOARD instance embedded in a Polarion LiveDoc or Wiki page.
## Parameter Reference Pages
[**Plans (Columns) Parameters**](/planningboard/reference/widget-parameters/plans-parameters) — Parameters that control which Plans appear as columns on the board, including Plan queries, Plans mode selection, and Plan range filtering.
[**Swimlanes (Rows) Parameters**](/planningboard/reference/widget-parameters/swimlanes-parameters) — Parameters that define how work items are grouped into swimlanes: the swimlane assignment type, sort order, and filtering rules.
[**Work Items Parameters**](/planningboard/reference/widget-parameters/work-items-parameters) — Parameters that specify which work items are loaded onto the board, including work item type filters and item queries.
[**Capacity Parameters**](/planningboard/reference/widget-parameters/capacity-parameters) — Parameters for configuring capacity bars per swimlane, the capacity field used for effort, and capacity normalization behaviour.
[**UI and Display Parameters**](/planningboard/reference/widget-parameters/ui-parameters) — Parameters controlling card content, board appearance, and highlighting rules (for example, items planned after their due date).
[**SAFe Parameters**](/planningboard/reference/widget-parameters/safe-parameters) — Parameters specific to SAFe planning modes, including SAFe Sprints, Program Increments, and Solution Trains.
[**Advanced Parameters**](/planningboard/reference/widget-parameters/advanced-parameters) — Scripting hooks and low-level override parameters for custom card rendering, item scripts, and configuration scripts.
Capacity configuration parameters are whitespace-sensitive. Copy parameter values exactly as shown in the reference pages — leading or trailing spaces can produce unexpected results.
## Common Tasks
* Configure a Plan query to select which Plans appear: [Plans (Columns) Parameters](/planningboard/reference/widget-parameters/plans-parameters)
* Set up swimlanes by assignee, parent item, or enumeration field: [Swimlanes (Rows) Parameters](/planningboard/reference/widget-parameters/swimlanes-parameters)
* Enable and tune capacity bars: [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters)
* Customise which fields appear on cards: [UI and Display Parameters](/planningboard/reference/widget-parameters/ui-parameters)
* Add scripting hooks for advanced board logic: [Advanced Parameters](/planningboard/reference/widget-parameters/advanced-parameters)
**KB Articles**
* Planningboard Widget Parameters
* Planningboard: Customizable Statistics and Capacity Indicators
* Planningboard interface & basic interactions
**Support Tickets**
* [#6607](https://support.nextedy.com/helpdesk/tickets/6607)
* [#6546](https://support.nextedy.com/helpdesk/tickets/6546)
* [#6705](https://support.nextedy.com/helpdesk/tickets/6705)
**Source Code**
* `PlanningBoardWidget.java`
* `widget.vm`
* `PlanningBoardWidgetRenderer.java`
* `Config.java`
* `planningboard.js`
# Plans (Columns) Parameters
Source: https://learn.nextedy.com/planningboard/reference/widget-parameters/plans-parameters
The **Plans (Columns) Parameters** control which Polarion Plans are displayed as columns on the Nextedy PLANNINGBOARD, how many past and future plans appear, how plans are linked, and whether capacity load is enabled.
See also: [Widget Parameters](/planningboard/reference/widget-parameters/index) | [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) | [Plans Modes](/planningboard/reference/plans-modes/index)
***
## Overview
Each column on the board corresponds to one Polarion Plan. The parameters in this group determine which Plans are loaded, in what order, and what supplementary information (capacity, links) is attached to each column header.
***
## Core Properties
| Parameter | Type | Default | Description |
| -------------- | ------------- | -------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `plansMode` | string (enum) | `PROJECT_PLANS` | Determines the type of Plans loaded as columns. See [Plans Mode options](#plans-mode-options) below. |
| `plansQuery` | string | `None` | Lucene query to filter which Plans are displayed as columns. When empty, all Plans of the selected type in the project are candidates. |
| `lastPlans` | number | `1` | Number of past (completed) Plans to show to the left of today. |
| `nextPlans` | number | `5` | Number of future (upcoming) Plans to show to the right of today. |
| `capacityLoad` | boolean | `false` | When `true`, enables visualization of the capacity load for each Plan column as a capacity bar. Requires capacity to be configured; see [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters). |
| `planLink` | string | `/polarion/#/project/${plan.objectId.projectId}/plan?id=${plan.objectId.itemId}` | URL template for the link opened when clicking a column header. Supports `${plan.*}` variable substitution. |
***
## Plans Mode Options
The `plansMode` parameter selects how Plans are sourced and organized as columns.
| Value | Description |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `PROJECT_PLANS` | Standard Polarion Plans from the current project, filtered by `plansQuery`. This is the default mode and the most commonly used. |
| `SAFE_SPRINTS` | SAFe iteration Plans (sprints) from the current program. The plans query is automatically set to `template.id:iterationPlan`. Requires a Polarion SAFe Solution configuration. |
| `SAFE_PFL_SPRINTS` | SAFe iteration Plans (sprints) at portfolio level, spanning multiple programs within a solution portfolio. Requires a Polarion SAFe Solution configuration. |
| `SAFE_PIS` | SAFe Program Increments as columns. Configuration UI differs from `PROJECT_PLANS` — additional SAFe-specific fields appear. Requires Polarion SAFe Solution. |
| `SAFE_SOLUTION` | SAFe Solution Train level Plans. For portfolio-level planning. Requires Polarion SAFe Solution. |
**SAFe Plans Modes**
When `plansMode` is set to a SAFe variant, the widget configuration panel shows different fields than the **Project Plans** (`PROJECT_PLANS`) mode. If you need a SAFe Plans mode, contact Nextedy support for configuration guidance.
For full details on each mode, see [Plans Modes](/planningboard/reference/plans-modes/index).
***
## Controlling How Many Plans Are Shown
The `lastPlans` and `nextPlans` parameters control the visible window of Plans around the current date.
| Parameter | Type | Default | Description |
| ----------- | ------ | ------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `lastPlans` | number | `1` | Number of past Plans to display. Increasing this value loads more historical Plans and may affect performance on large projects. |
| `nextPlans` | number | `5` | Number of future Plans to display. |
**Performance note**
Loading a large number of Plans increases the amount of data fetched and rendered. Keep the `lastPlans` + `nextPlans` total to a reasonable range for your team size and project. Excessive Plan counts also increase the number of work items loaded against the `maxItems` limit.
**Example — show 2 past iterations and 4 upcoming:**
```properties theme={null}
lastPlans = 2
nextPlans = 4
```
***
## Plans Query
When `plansMode` is set to **Project Plans** (`PROJECT_PLANS`), the `plansQuery` parameter accepts a Lucene query string to restrict which Plans appear as columns.
| Parameter | Type | Default | Description |
| ------------ | ------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `plansQuery` | string | `None` | Lucene query filtering Plans. When empty, all Plans of the selected template type in the current project are candidates, limited to the `lastPlans` / `nextPlans` window. |
**Example — show only Plans with a specific template type:**
```properties theme={null}
plansQuery = template.id:iteration
```
**Example — show Plans matching a name pattern:**
```properties theme={null}
plansQuery = name:Sprint*
```
***
## Capacity Load
Enabling `capacityLoad` adds a capacity bar to each Plan column header, showing how loaded that Plan is relative to its defined capacity.
| Parameter | Type | Default | Description |
| ------------------- | ------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `capacityLoad` | boolean | `false` | Show the capacity bar for each Plan column. |
| `multiCapacityLoad` | boolean | `false` | Enable per-swimlane (per-resource) capacity bars within each column, rather than a single column-level bar. See [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters). |
| `userCapacityLoad` | boolean | `false` | Enable per-user capacity loading when using the Teams service. See [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters). |
**Viewing the capacity tooltip**
When `capacityLoad` is enabled, hovering over a Plan column's capacity bar displays a detailed tooltip with capacity breakdown figures. This tooltip is only visible if capacity has been configured for that Plan.
For full capacity configuration details, see [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters).
***
## Assign to Parent Plan
When a work item is dragged onto the board and planned into a child Plan (for example, an Iteration under a Version), the `Assign to Parent Plan` option controls whether the item is also automatically planned into the parent Plan.
| UI Label | Property | Type | Default | Description |
| --------------------- | -------------------- | ------- | -------- | -------------------------------------------------------------------------------------------------------------- |
| Assign to Parent Plan | *(widget parameter)* | boolean | disabled | When enabled, planning a work item into a child Plan also plans it into that Plan's parent Plan automatically. |
**Behavior with this option disabled** — a work item dragged into Iteration 4 is planned only in Iteration 4.
**Behavior with this option enabled** — the same item is also planned into Version 1.0 (Iteration 4's parent Plan) automatically.
**Verify in application**
The exact widget-parameter key name for the Assign to Parent Plan option is not exposed in the available source context. Configure this option through the widget's configuration panel in Polarion.
***
## Report Link (Column Header Link)
The `planLink` parameter defines the URL that opens when a user clicks on a Plan column header. The URL template supports variable substitution using `${plan.*}` placeholders.
| Parameter | Type | Default | Description |
| ---------- | ------ | -------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| `planLink` | string | `/polarion/#/project/${plan.objectId.projectId}/plan?id=${plan.objectId.itemId}` | URL template for the column-header link. Supports `${plan.objectId.projectId}` and `${plan.objectId.itemId}` variables. |
**Available template variables:**
| Variable | Description |
| ---------------------------- | -------------------------------------- |
| `${plan.objectId.projectId}` | The Polarion project ID of the Plan. |
| `${plan.objectId.itemId}` | The Plan's item ID within its project. |
**Example — link to a custom Wiki report page parameterised by Plan:**
```properties theme={null}
planLink = /polarion/#/project/${plan.objectId.projectId}/wiki/SOME_REPORT?plan=${plan.objectId.itemId}
```
This link opens when the user clicks the column header for that Plan. The `${plan.objectId.projectId}` and `${plan.objectId.itemId}` values are substituted at render time.
***
## New Plan Creation
The **New Plan** section of the widget parameters enables creating new Plans directly from the Planningboard toolbar. When enabled, a **+** button appears in the toolbar.
### New Plan Properties
| Parameter | Type | Default | Description |
| ----------------- | ------ | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `plansTemplateId` | string | `None` | The Polarion Plan template ID used when creating new Plans (for example, `iteration` or `release`). Must match a valid template ID in the project. |
### Plan Naming Patterns
New Plans are named and identified using pattern strings with `{planNum}` and `{teamName}` / `{teamId}` placeholders.
| Pattern Parameter | Available Placeholders | Description |
| ----------------- | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| Plan Name Pattern | `{planNum}`, `{teamName}` | Display name of the new Plan as it appears in the column header. |
| Plan ID Pattern | `{planNum}`, `{teamId}` | ID assigned to the new Plan. Must be unique across the project. The `{planNum}` placeholder is required for auto-numbering to work. |
**Placeholder reference:**
| Placeholder | Used In | Description |
| ------------ | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `{planNum}` | Name pattern, ID pattern | Auto-incremented integer. The system extracts the last plan number from the most recent Plan matching the template and increments by 1. Defaults to `1` if no prior Plans are found. |
| `{teamName}` | Name pattern | The team's display name. Used when Teams are enabled and multiple Plans are created per run (one per team). |
| `{teamId}` | ID pattern | The team's identifier. Used to make each team's Plan ID unique. |
**Example — create iteration Plans without Teams:**
```properties theme={null}
plansTemplateId = iteration
Plan Name Pattern = Iteration {planNum}
Plan ID Pattern = Iteration_{planNum}
```
When the user clicks **+**, the system finds the last existing Plan matching `template.id:iteration` in the project, extracts the number from its ID, increments it, and proposes the next Plan name and ID for confirmation.
**Example — create Plans with Teams enabled:**
```properties theme={null}
Plan Name Pattern = Sprint {planNum} - {teamName}
Plan ID Pattern = Sprint_{planNum}_{teamId}
```
### Parent Plan and Duration
| UI Label | Description |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Parent ID | The ID of an existing Plan under which new Plans are created. Useful when the project has multiple Versions but new iterations should always go under a specific one. |
| New Plan Duration | Duration of the newly created Plan (for example, `2w` for 2 weeks). |
### Last Plan Query and Sort
These parameters control how the system finds the "last" existing Plan when computing the next auto-number.
| UI Label | Description |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Last Plan Query | Lucene query to find the last Plan. When empty, the system searches for the latest Plan of the same template type in the same project. |
| Last Plan Sort | Field used to decide which Plan from the query is "last". When empty, Plans are sorted by `dueDate` descending (the Plan with the latest due date is treated as the last one). |
### Teams
When **Enable Teams** is turned on, the New Plan feature creates one Plan per configured team in a single operation.
| UI Label | Description |
| ------------ | ---------------------------------------------------------------------------------------------------------------- |
| Enable Teams | When enabled, new Plans are created for each configured team using the `{teamId}` and `{teamName}` placeholders. |
| Teams | List of team name/ID pairs used when creating Plans with Teams enabled. |
**Pattern defaults when using Teams**
The Plan Name Pattern and Plan ID Pattern are predefined with `{teamName}` / `{teamId}` when Teams are enabled. If you are **not** using Teams, update these patterns to remove the team placeholders — otherwise the literal placeholder text appears in Plan names.
***
## Configuration Example
The following example shows a **Project Plans** (`PROJECT_PLANS`) configuration that displays 2 past iterations and 3 upcoming iterations, enables the capacity bar, and links column headers to a custom report page.
```properties theme={null}
# Plans (Columns) — example configuration
plansMode = PROJECT_PLANS
plansQuery = template.id:iteration
lastPlans = 2
nextPlans = 3
# Capacity
capacityLoad = true
# Column header link — opens a custom Wiki report for the selected Plan
planLink = /polarion/#/project/${plan.objectId.projectId}/wiki/SPRINT_REPORT?plan=${plan.objectId.itemId}
# New Plan creation
plansTemplateId = iteration
# Plan Name Pattern = Iteration {planNum}
# Plan ID Pattern = Iteration_{planNum}
```
This setup renders three future iteration columns and two past ones on the board. Each column header is clickable and opens the `SPRINT_REPORT` Wiki page filtered to that Plan. The capacity bar appears on each column.
***
## Limitations
* **Page parameters not supported in Plans configuration.** Planningboard Plans column configuration does not evaluate Polarion page parameters (such as `$pageParameters.xxx`) at runtime. Plans must be selected via static `plansQuery` values or the `lastPlans` / `nextPlans` window.
* **SAFe Plans modes require support configuration.** The **SAFe Sprints in Program** (`SAFE_SPRINTS`), **SAFe Sprints in Portfolio** (`SAFE_PFL_SPRINTS`), **SAFe Program Increments in Program** (`SAFE_PIS`), and **SAFe Program Increments in Solution** (`SAFE_SOLUTION`) modes depend on a correctly configured Polarion SAFe Solution. The configuration UI changes based on the selected mode. Contact Nextedy support for SAFe-specific setup guidance.
* **`lastPlans` + `nextPlans` affects performance.** Each additional Plan column increases data fetched. Large windows on busy projects may exceed the `maxItems` limit or produce slow load times.
***
## Related Parameters
| Topic | Reference |
| -------------------------------- | ---------------------------------------------------------------------------------------------- |
| Swimlane (row) configuration | [Swimlanes (Rows) Parameters](/planningboard/reference/widget-parameters/swimlanes-parameters) |
| Work item query and card content | [Work Items Parameters](/planningboard/reference/widget-parameters/work-items-parameters) |
| Capacity bar details | [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) |
| Plans mode details | [Plans Modes](/planningboard/reference/plans-modes/index) |
| Project Plans mode | [Project Plans](/planningboard/reference/plans-modes/project-plans) |
| SAFe Sprints mode | [SAFe Sprints](/planningboard/reference/plans-modes/safe-sprints) |
| SAFe Program Increments mode | [SAFe Program Increments](/planningboard/reference/plans-modes/safe-pis) |
| SAFe Solution Trains mode | [SAFe Solution Trains](/planningboard/reference/plans-modes/safe-solutions) |
| All widget parameters | [Widget Parameters](/planningboard/reference/widget-parameters/index) |
**KB Articles**
* Planningboard Widget Parameters
* Planningboard interface & basic interactions
* Planningboard: Customizable Statistics and Capacity Indicators
**Support Tickets**
* [#6607](https://support.nextedy.com/helpdesk/tickets/6607)
* [#6546](https://support.nextedy.com/helpdesk/tickets/6546)
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
**Source Code**
* `PlanningBoardWidget.java`
* `widget.vm`
* `Config.java`
* `PlanningBoardWidgetRenderer.java`
* `PlanningBoardApiServlet.java`
# SAFe Parameters
Source: https://learn.nextedy.com/planningboard/reference/widget-parameters/safe-parameters
Reference for all widget parameters that control SAFe (Scaled Agile Framework) integration in Nextedy PLANNINGBOARD.
## Plans Mode Selection
The `plansMode` parameter is the primary switch for SAFe integration. Setting it to a SAFe value changes which additional configuration fields are shown and which Plans are loaded as columns.
| Parameter | Type | Default | Description |
| ----------- | --------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `plansMode` | `string` (enum) | `PROJECT_PLANS` | Determines how plans are loaded and displayed as columns. Set to a SAFe value to activate SAFe-specific fields and behaviors. See [Plans Modes](/planningboard/reference/plans-modes/index) for full mode reference. |
### Available SAFe Plans Mode Values
| Value | Mode Name | Description |
| ------------------ | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `SAFE_SPRINTS` | SAFe Sprints (Program) | Loads SAFe iteration plans (sprints) from the current program. Plans query is automatically set to `template.id:iterationPlan`. Requires a Polarion SAFe Solution. |
| `SAFE_PFL_SPRINTS` | SAFe Sprints (Portfolio) | Loads sprint-level plans at portfolio level, spanning multiple programs within a solution portfolio. Requires a Polarion SAFe Solution. |
| `SAFE_PIS` | SAFe Program Increments (Program) | Loads Program Increment plans at Agile Release Train level. Reflects PI planning cadence (typically 8–12 week increments). Requires a Polarion SAFe Solution. |
| `SAFE_SOLUTION` | SAFe Solution Trains | Loads Program Increment plans at Solution level, coordinating multiple ARTs. Requires a Polarion SAFe Solution at portfolio level. |
**Plans Type determines which configuration fields appear**
When `plansMode` is set to a SAFe value, the widget parameter editor shows different fields than it does for Project Plans. In particular, the Scope, Query, and Type fields present under Project Plans are replaced by SAFe-specific fields. If you see an unexpected configuration UI, verify your Plans Type selection first.
***
## SAFe Program Increment Parameter
This parameter is shown only when Plans Type is set to SAFe Sprints in Program (`SAFE_SPRINTS`) or SAFe Sprints in Portfolio (`SAFE_PFL_SPRINTS`).
| Parameter | Type | Default | Description |
| ------------------------------ | -------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Program Increment Parameter ID | `string` | None | References a Polarion page parameter that identifies which Program Increment (PI) to scope the board to. Must match a Page Parameter defined on the same Polarion page. When set, the board filters sprints to those belonging to the specified PI. |
**Page Parameters must be created explicitly**
The Program Increment Parameter ID field references a Polarion page parameter by name — it does not create one. You must define the page parameter on the Wiki or LiveDoc page first, then enter its ID here. If the parameter is missing or the ID is wrong, no plans load. See the ticket insight: SAFe configuration errors most commonly trace back to missing or misreferenced Page Parameters.
***
## Assignment Mode — SAFe Swimlanes
These parameters control how swimlanes are grouped when using a SAFe assignment mode. Set `assignmentMode` to one of the SAFe values to activate SAFe-based row grouping.
| Parameter | Type | Default | Description |
| ---------------- | --------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `assignmentMode` | `string` (enum) | `ASSIGNEE` | Determines how work items are grouped into swimlanes. Set to a SAFe value to use SAFe-based row grouping. See [Assignment Modes](/planningboard/reference/assignment-modes/index) for full reference. |
### SAFe Assignment Mode Values
| Value | Mode Name | Description |
| ----------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `SAFE_TEAM` | SAFe Team Mode | Displays one swimlane per SAFe team within the current program. Teams are discovered from the Polarion SAFe Solution data. Requires Polarion SAFe Solution. See [SAFe Team Mode](/planningboard/reference/assignment-modes/safe-team-mode). |
| `SAFE_TRAIN_TEAM` | SAFe Train Team Mode | Displays swimlanes for teams within a specific Agile Release Train (ART), filtered by ART ID. See [SAFe Train Team Mode](/planningboard/reference/assignment-modes/safe-train-team-mode). |
| `SAFE_PROGRAMS` | SAFe Programs Mode | Displays swimlanes for SAFe programs within a solution train. Used for portfolio-level planning. Requires Polarion SAFe Solution at portfolio level. See [SAFe Programs Mode](/planningboard/reference/assignment-modes/safe-programs-mode). |
### SAFe Assignment Mode Parameters
| Parameter | Type | Default | Description |
| -------------------- | --------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `safeTeamField` | `string` | `safeTeam` | Custom field ID that stores the SAFe Team assignment on work items. Used when Assignment Type is set to Program / Solution Teams (SAFe) (`SAFE_TEAM`) or Agile Release Train Teams (SAFe) (`SAFE_TRAIN_TEAM`). Must match the exact field ID in your Polarion project configuration. |
| `safeProgramField` | `string` | `safeProgram` | Custom field ID that stores the SAFe Program assignment on work items. Used when Assignment Type is set to Programs (SAFe) (`SAFE_PROGRAMS`). Must match the exact field ID in your Polarion project configuration. |
| `showEmptySwimlanes` | `boolean` | `false` | When `true`, all SAFe teams or programs appear as swimlanes even if no work items are currently assigned to them. When `false`, only swimlanes with at least one card are shown. |
| `swimlaneSort` | `string` | `alphabetical` | Determines the sort order of swimlanes. Applied when using any SAFe assignment mode. |
**SAFe field IDs are whitespace-sensitive**
The values of `safeTeamField` and `safeProgramField` must exactly match the custom field IDs in your Polarion project, including casing. A mismatch produces empty swimlanes with no error message.
***
## SAFe Plan Cells Mode
When using SAFe sprints or stemming-based planning, items can be locked to specific plan-resource intersections (cells) rather than moved freely across plans.
| Parameter | Type | Default | Description |
| --------------- | --------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `planCellsMode` | `boolean` | `false` | When `true`, enables plan cells mode. Work items belong to specific plan-resource cells. Applies when `plansMode` is a SAFe value or when stemming is enabled. |
**Verify in application**
The exact runtime behavior of `planCellsMode` in each SAFe plans mode combination should be verified against the live product, as interactions between `planCellsMode`, `plansMode`, and `assignmentMode` are complex.
***
## SAFe Parent Sync
When work items are assigned to a team in a SAFe mode, Planningboard can automatically sync those items to the correct Team Program Increment plan.
| Parameter | Type | Default | Description |
| ------------------- | --------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Sync to Parent Plan | `boolean` | — | When enabled, planned work items are also automatically planned to the parent Plan of the currently added Plan. Shown only when Plans Type is set to Project Plans (`PROJECT_PLANS`); hidden for SAFe plans modes. |
**SAFe parent sync is automatic in SAFe modes**
The `syncSAFEParentsFromChildren` behavior — automatically syncing SAFe User Stories to the correct Team Program Increment plan when team assignment changes — is an automatic behavior in SAFe plans modes, not a separately configurable parameter. It triggers when a work item's team assignment changes and remaps the plan ID based on the team assignment.
***
## Capacity Parameters in SAFe Contexts
Capacity calculation parameters apply in SAFe modes as in standard modes, but their interaction with SAFe plan structures has specific behavior.
| Parameter | Type | Default | Description |
| ------------------- | --------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `capacityLoad` | `boolean` | `false` | Enables capacity loading calculations for resources. When used with SAFe team swimlanes, capacity is tracked per team. See [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters). |
| `multiCapacityLoad` | `boolean` | `false` | Enables per-swimlane capacity tracking across multiple plans simultaneously. See [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters). |
| `userCapacityLoad` | `boolean` | `false` | Enables user-level capacity loading when using the Teams Service. Only meaningful when `useTeamsService` is `true`. |
| `useTeamsService` | `boolean` | `false` | Enables integration with the Polarion Teams Service for team capacity, user capacity, and team member data. When enabled, overrides `plan.capacity` values with Teams Service data. |
| `selectedTeam` | `string` | None | ID of the currently selected team for filtering and capacity display. Used when `useTeamsService` is `true`. |
| `hoursPerDay` | `number` | `8` | Number of working hours per day used in capacity calculations. Applies across all plans modes including SAFe. |
| `capacityField` | `string` | None | Custom field ID containing capacity values (e.g., story points, hours). When set, overrides time-tracking fields for capacity calculation. |
See [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) for the full capacity configuration reference.
***
## Configuration Example
The following example shows a board configured for SAFe Program Increment planning at the program level, with teams as swimlanes.
```text theme={null}
SAFe PI Board — Program Level
plansMode = SAFE_SPRINTS
Program Increment = PI_2025_Q3 (via Page Parameter)
assignmentMode = SAFE_TEAM
safeTeamField = safeTeam
safeProgramField = safeProgram
showEmptySwimlanes = false
capacityLoad = true
useTeamsService = false
hoursPerDay = 8
```
This configuration produces a board where:
* Columns are SAFe iteration plans (sprints) within Program Increment `PI_2025_Q3`
* Rows (swimlanes) are SAFe teams sourced from the Polarion SAFe Solution
* Only teams with assigned cards are shown (`showEmptySwimlanes = false`)
* Capacity bars are shown per swimlane per sprint
For a portfolio-level board showing Programs as swimlanes across Solution Train PIs:
```text theme={null}
SAFe Solution Train Board — Portfolio Level
plansMode = SAFE_SOLUTION
assignmentMode = SAFE_PROGRAMS
safeProgramField = safeProgram
showEmptySwimlanes = true
capacityLoad = false
```
***
## Level-by-Level Configuration Summary
Different SAFe hierarchy levels require different combinations of `plansMode` and `assignmentMode`.
***
## Limitations
* Planningboard swimlane configuration does not support Polarion page parameters (e.g. `$pageParameters.xxx`) for dynamic team filtering. Workarounds include configuring static swimlanes using link roles, or creating one Planningboard page per team.
* Custom Team work item types are not supported for SAFe swimlane configuration. Only Nextedy's standard Team work item type with the required custom fields (`safeTeam`, `safeProgram`) is supported. Nextedy GANTT (25.5.0+) supports custom team types if that is a requirement.
* SAFe configuration is highly context-dependent: the configuration UI changes based on `plansMode` selection. If your board is showing unexpected configuration fields, verify the Plans Type selection first.
* Multi-assignee capacity distribution and sub-item effort distribution are not supported in SAFe modes (consistent with general Planningboard capacity limitations vs. Nextedy GANTT).
***
## Related Reference Pages
* [Plans Modes](/planningboard/reference/plans-modes/index) — full reference for all `plansMode` values
* [SAFe Sprints](/planningboard/reference/plans-modes/safe-sprints) — `SAFE_SPRINTS` mode details
* [SAFe Program Increments](/planningboard/reference/plans-modes/safe-pis) — `SAFE_PIS` mode details
* [SAFe Solution Trains](/planningboard/reference/plans-modes/safe-solutions) — `SAFE_SOLUTION` mode details
* [SAFe Team Mode](/planningboard/reference/assignment-modes/safe-team-mode) — `SAFE_TEAM` assignment mode
* [SAFe Train Team Mode](/planningboard/reference/assignment-modes/safe-train-team-mode) — `SAFE_TRAIN_TEAM` assignment mode
* [SAFe Programs Mode](/planningboard/reference/assignment-modes/safe-programs-mode) — `SAFE_PROGRAMS` assignment mode
* [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) — capacity configuration reference
* [Plans (Columns) Parameters](/planningboard/reference/widget-parameters/plans-parameters) — full plans column configuration
* [Swimlanes (Rows) Parameters](/planningboard/reference/widget-parameters/swimlanes-parameters) — full swimlane configuration
**KB Articles**
* Planningboard Widget Parameters
* Planningboard: Customizable Statistics and Capacity Indicators
* Planningboard interface & basic interactions
**Support Tickets**
* [#5879](https://support.nextedy.com/helpdesk/tickets/5879)
* [#6607](https://support.nextedy.com/helpdesk/tickets/6607)
* [#6546](https://support.nextedy.com/helpdesk/tickets/6546)
**Source Code**
* `Config.java`
* `PlanningBoardWidget.java`
* `widget.vm`
* `PlanningBoardWidgetRenderer.java`
* `PlanningBoardWidgetDependenciesProcessor.java`
# Swimlanes (Rows) Parameters
Source: https://learn.nextedy.com/planningboard/reference/widget-parameters/swimlanes-parameters
The swimlanes (rows) parameters control how Nextedy PLANNINGBOARD groups work items into horizontal rows.
Swimlane parameters are configured in the **Widget Parameters** panel under the **Swimlanes (Rows)** section.
***
## Assignment Type
The **Assignment Type** is the primary swimlane parameter. It determines how work items are mapped to swimlane rows.
| Parameter | Type | Default | Description |
| ---------------- | ------ | ---------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `assignmentMode` | string | `ASSIGNEE` | Determines how work items are grouped into swimlane rows. See [Assignment Mode Values](#assignment-mode-values) for all options. |
### Assignment Mode Values
| Value | UI Label | Description |
| ----------------- | -------------------------------- | ------------------------------------------------------------------------------------------------------ |
| `ASSIGNEE` | Users (Assignee) | Each swimlane represents a project user, grouped by their assigned role. |
| `PARENT` | Parent Item | Each swimlane represents a parent work item (e.g., a Feature). Items appear under their linked parent. |
| `ENUM` | Enumeration Field | Each swimlane represents a value from a custom enumeration field on the work item. |
| `PROJECT` | Project | Each swimlane represents a Polarion project. Used for cross-project planning. |
| `SAFE_TEAM` | Program / Solution Teams (SAFe) | Swimlanes correspond to SAFe teams. Requires SAFe configuration. |
| `SAFE_TRAIN_TEAM` | Agile Release Train Teams (SAFe) | Swimlanes correspond to Agile Release Train teams. Requires SAFe configuration. |
| `SAFE_PROGRAMS` | Programs (SAFe) | Swimlanes correspond to SAFe Programs. Requires SAFe configuration. |
| `none` | No Swimlanes | Swimlane grouping is disabled. All items appear in a single unified view. |
***
## Users (Assignee) Parameters
Applies when `assignmentMode` is set to **Users (Assignee)** (`ASSIGNEE`).
| Parameter | Type | Default | Description |
| ---------------------- | ------- | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `userRole` | string | See application | Defines which Polarion project role is used to determine which users appear as swimlanes. For example, `project_user` displays all users who hold that role in the project. |
| `reportLink` | string | (empty) | Optional URL template for a link that opens when a user clicks the swimlane label. Supports the `${r.objectId.itemId}` variable for the resource (user) identifier. |
| `showEmptySwimlanes` | boolean | `false` | When `true`, swimlanes for users with no assigned work items are shown. When `false`, only swimlanes containing at least one card are displayed. |
| `swimlaneSort` | string | `alphabetical` | Sort order for swimlanes. See [Swimlane Sort Options](#swimlane-sort-options). |
| `collapsibleSwimlanes` | boolean | `true` | Enables individual swimlane collapse/expand by the user. |
### Report Link Example (Assignee Mode)
```
/polarion/#/project/PlanningBoard/wiki/SOME_REPORT?user=${r.objectId.itemId}
```
The `${r.objectId.itemId}` placeholder is substituted with the user ID of the swimlane's assignee.
### Example: Assignee Mode Configuration
The `project_user` role is configured in **Administration > User Management > Roles**. Users who hold this role in the project (e.g., Alex Seller, Carl User) each receive their own swimlane.
***
## Parent Item Parameters
Applies when `assignmentMode` is set to **Parent Item** (`PARENT`).
| Parameter | Type | Default | Description |
| ---------------------- | ------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `parentWorkItemType` | string | `None` | Specifies which work item type to use as the parent. Filters the set of possible parent swimlanes to items of this type only. |
| `parentRole` | string | See application | The link role that defines the parent–child relationship (e.g., `implements`). Used to determine which parent item a work item belongs to. |
| `parentQuery` | string | (empty) | Optional Lucene query to filter which parent items appear as swimlanes. Leave empty to show all parents of the configured type. |
| `filterParents` | string | `No` | Whether to limit visible parent swimlanes. Set to `Yes` to restrict swimlanes to parents matched by `parentQuery`. |
| `swimlaneSort` | string | `alphabetical` | Sort order of parent item swimlanes. See [Swimlane Sort Options](#swimlane-sort-options). As of Planningboard 25.9.0, parent swimlanes can be sorted by any custom property, including priority. |
| `reportLink` | string | (empty) | Optional URL template for a link that opens when a user clicks the swimlane label. |
| `showEmptySwimlanes` | boolean | `false` | When `true`, parent swimlanes with no child items are shown. |
| `collapsibleSwimlanes` | boolean | `true` | Enables individual swimlane collapse/expand. |
**Parent Item Swimlane Constraint**
When using Parent Item mode, work items can only be placed under their **actual linked parent**. You cannot freely choose a different row. If a card is dragged to an incorrect swimlane, Planningboard automatically moves it to its correct parent row once dropped. This preserves data integrity of parent–child links.
***
## Enumeration Field Parameters
Applies when `assignmentMode` is set to **Enumeration Field** (`ENUM`).
| Parameter | Type | Default | Description |
| ---------------------- | -------------------- | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `enumFieldId` | string | `None` | The Polarion field ID of the enumeration custom field to use for swimlane grouping (e.g., `team`, `severity`). Must be a valid field ID on the selected work item type. |
| `rowsFilter` | string (multi-value) | (empty — show all) | Limits which enumeration values appear as swimlane rows. When empty, all values defined for that field are shown. Select specific values to display only those rows. |
| `reportLink` | string | (empty) | Optional URL template for a report link on the swimlane label. |
| `showEmptySwimlanes` | boolean | `false` | When `true`, rows for enum values with no matching work items are shown. |
| `collapsibleSwimlanes` | boolean | `true` | Enables individual swimlane collapse/expand. |
### Rows Filter Behavior
* **Empty filter (default):** All enumeration values defined for the field and work item type are displayed as rows.
* **Selected values:** Only the chosen enum values appear as swimlane rows. Work items whose field value is not in the selected set do not appear on any row.
* **Multi-enum fields:** A work item with multiple enum values assigned to the field can appear in multiple swimlane rows simultaneously.
* **Type-dependent values:** Available enum values in the filter depend on the selected work item type. Different types may have different enumeration configurations for the same field ID.
### Example: Enumeration Field Mode
Field ID `team` is configured as an enumeration custom field in the Polarion project. Setting `enumFieldId` to `team` creates one swimlane per team value.
***
## Project Parameters
Applies when `assignmentMode` is set to **Project** (`PROJECT`).
| Parameter | Type | Default | Description |
| ---------------------- | ------- | ------- | ------------------------------------------------------------------------------- |
| `reportLink` | string | (empty) | Optional URL template for a project-specific report link on the swimlane label. |
| `showEmptySwimlanes` | boolean | `false` | When `true`, swimlanes for projects with no work items are shown. |
| `collapsibleSwimlanes` | boolean | `true` | Enables individual swimlane collapse/expand. |
Use Project mode for cross-project planning boards where the board must display items from multiple Polarion projects simultaneously.
***
## SAFe Assignment Type Parameters
Applies when `assignmentMode` is set to **Program / Solution Teams (SAFe)** (`SAFE_TEAM`), **Agile Release Train Teams (SAFe)** (`SAFE_TRAIN_TEAM`), or **Programs (SAFe)** (`SAFE_PROGRAMS`).
**Verify in application**
SAFe swimlane types require dedicated SAFe configuration in your Polarion environment. Contact Nextedy support for setup guidance before configuring these modes.
| Parameter | Type | Default | Description |
| ---------------------- | ------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `safeTeamField` | string | `safeTeam` | Custom field ID that stores the SAFe Team assignment on work items. Used when `assignmentMode` is set to **Program / Solution Teams (SAFe)** (`SAFE_TEAM`) or **Agile Release Train Teams (SAFe)** (`SAFE_TRAIN_TEAM`). |
| `safeProgramField` | string | `safeProgram` | Custom field ID that stores the SAFe Program assignment on work items. Used when `assignmentMode` is set to **Programs (SAFe)** (`SAFE_PROGRAMS`). |
| `showEmptySwimlanes` | boolean | `false` | When `true`, SAFe team or program swimlanes with no work items are shown. |
| `collapsibleSwimlanes` | boolean | `true` | Enables individual swimlane collapse/expand. |
For more detail on SAFe assignment modes, see the [SAFe Team Mode](/planningboard/reference/assignment-modes/safe-team-mode), [SAFe Train Team Mode](/planningboard/reference/assignment-modes/safe-train-team-mode), and [SAFe Programs Mode](/planningboard/reference/assignment-modes/safe-programs-mode) reference pages.
***
## No Swimlanes Parameters
Applies when `assignmentMode` is set to **No Swimlanes** (`none`).
When No Swimlanes is selected, all swimlane grouping is disabled. All work items appear in a single unified planning area. There are no per-row parameters to configure in this mode.
Use this mode when you want to focus on column-level (Plan) organization without horizontal grouping — for example, for high-level release overviews or quick board views.
***
## Swimlane Sort Options
The `swimlaneSort` parameter applies to Assignee, Parent Item, and Enumeration Field assignment modes and controls the vertical ordering of swimlane rows.
| Value | Description |
| ---------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `alphabetical` | Rows are sorted alphabetically by their label. This is the default. |
| Custom property (e.g., `priority`) | As of Planningboard 25.9.0, Parent Item swimlanes can be sorted by any custom property on the parent work item type, such as `priority`. Enter the field ID directly. |
**Sort Coupling**
Swimlane sort order is coupled to the work item sort order within each lane. Reordering swimlanes may affect how cards are arranged within those lanes. This is a known characteristic of the current sort implementation.
***
## Common Parameters (All Assignment Types)
The following parameters apply regardless of the selected assignment type.
| Parameter | Type | Default | Description |
| ---------------------- | ------- | -------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `showEmptySwimlanes` | boolean | `false` | Controls whether swimlanes containing no work items are displayed. When `true`, all possible lanes are visible even if empty. |
| `swimlaneSort` | string | `alphabetical` | Vertical ordering of swimlane rows. |
| `collapsibleSwimlanes` | boolean | `true` | Enables users to collapse/expand individual swimlanes to reduce visual complexity on large boards. |
***
## Report Link Parameter
The `reportLink` parameter is available on all assignment types that have a named resource (Assignee, Parent Item, Enumeration Field, Project). It adds a clickable link to each swimlane label that opens an external report or page.
The link URL is a template string that can reference the swimlane's associated resource:
| Variable | Applies to | Description |
| ------------------------- | --------------- | ----------------------------------------------------- |
| `${r.objectId.itemId}` | Assignee (user) | The user ID of the swimlane's assignee. |
| `${r.objectId.projectId}` | All | The project ID associated with the swimlane resource. |
### Report Link Example
```
/polarion/#/project/PlanningBoard/wiki/SOME_REPORT?user=${r.objectId.itemId}
```
This opens a Wiki page at `SOME_REPORT`, passing the current swimlane's user as a page parameter.
***
## Page Parameters for Dynamic Swimlane Filtering
Planningboard supports Polarion page parameters (`$pageParameters.xxx`) for dynamic swimlane filtering.
**Limitation — String Entry Only**
Page parameters in swimlane configuration are accepted as **string type** only, requiring manual text entry. An enum picker dropdown for page parameters is not currently available and is under investigation. Plan your configuration accordingly.
### Requirement: Team Work Item Type ID
When using swimlane filtering with Nextedy Team work items, the Team work item type ID **must** be exactly `team`. Custom Team work item type IDs are not supported in Planningboard (unlike Nextedy Gantt, which supports custom Team work item type IDs from version 25.5.0 onwards).
### Multi-Team Deployment Options
| Approach | Description | Limitation |
| -------------------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------- |
| Separate board page per team | Configure one Planningboard page per team with hardcoded swimlane settings. | Requires maintaining multiple pages. |
| Dynamic page parameter filtering | Pass a team filter via `$pageParameters.xxx` as a string value. | Manual string entry only; no dropdown picker. |
| Nextedy Gantt with custom Team WI type | Use Gantt (25.5.0+) as the primary planning tool for teams using custom Team work item type IDs. | Planningboard does not support custom Team WI type IDs. |
***
## Configuration Example
The following widget parameter configuration sets up a Planningboard with Parent Item swimlanes, sorted by `priority`, showing only parents matched by a query, with a report link.
```properties theme={null}
# Swimlanes (Rows)
assignmentMode=PARENT
parentWorkItemType=feature
parentRole=implements
parentQuery=status:open
filterParents=Yes
swimlaneSort=priority
showEmptySwimlanes=false
collapsibleSwimlanes=true
reportLink=/polarion/#/project/${r.objectId.projectId}/wiki/FEATURE_REPORT?feature=${r.objectId.itemId}
```
This configuration:
1. Groups work items into swimlanes by their linked parent Feature.
2. Restricts visible swimlanes to open Features only (`status:open`).
3. Sorts parent swimlanes by the `priority` custom field (available from Planningboard 25.9.0).
4. Hides empty parent swimlanes.
5. Adds a report link on each swimlane label pointing to a Feature-specific report page.
***
## Swimlane Board Layout Diagram
***
## Limitations
* **Custom Team work item type IDs** are not supported in swimlane configuration. The Team work item type must use the exact ID `team`. Gantt (25.5.0+) supports custom Team work item type IDs as an alternative.
* **Page parameters for swimlane filtering** accept string type only. An enum picker dropdown is not currently available (under investigation).
* **Parent Item swimlane sorting** by custom property is available from Planningboard 25.9.0. Earlier versions support only alphabetical sorting.
* **Swimlane sort order is coupled to item sort order** within each lane. Changing the swimlane sort may affect card ordering within those swimlanes.
* **No multi-assignee swimlane support.** Work items with multiple assignees are assigned to a single swimlane based on the primary assignee. This is a known gap versus Nextedy Gantt's capacity model.
***
## Related Reference
* [Assignment Modes](/planningboard/reference/assignment-modes/index) — detailed reference for each assignment mode
* [Assignee Mode](/planningboard/reference/assignment-modes/assignee-mode)
* [Parent Item Mode](/planningboard/reference/assignment-modes/parent-mode)
* [Enumeration Field Mode](/planningboard/reference/assignment-modes/enum-mode)
* [Project Mode](/planningboard/reference/assignment-modes/project-mode)
* [No Swimlanes Mode](/planningboard/reference/assignment-modes/no-swimlanes-mode)
* [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) — configure capacity bars on swimlanes
* [Plans (Columns) Parameters](/planningboard/reference/widget-parameters/plans-parameters) — configure the columns of the board
* [Swimlane Controls](/planningboard/reference/ui-elements/swimlane-controls) — collapse/expand and toolbar interactions
* [Widget Parameters](/planningboard/reference/widget-parameters/index) — overview of all widget parameter groups
**KB Articles**
* Planningboard Widget Parameters
* Swimlane Assignment Types
* Planningboard interface & basic interactions
**Support Tickets**
* [#6681](https://support.nextedy.com/helpdesk/tickets/6681)
* [#6546](https://support.nextedy.com/helpdesk/tickets/6546)
* [#6309](https://support.nextedy.com/helpdesk/tickets/6309)
**Source Code**
* `PlanningBoardWidget.java`
* `licenseReadonly.cy.ts`
* `enum-rows-filter.cy.ts`
* `AssignmentMode.java`
* `widget.vm`
# UI and Display Parameters
Source: https://learn.nextedy.com/planningboard/reference/widget-parameters/ui-parameters
This page is a complete reference for the Nextedy PLANNINGBOARD widget parameters that control the board's visual presentation, sidebar behavior, toolbar availability, and card display.
## Parameter overview
***
## Sidebar fields
When a user clicks a card, the **Work Item Properties** sidebar opens on the right. The fields shown there are controlled by the `sidebarFields` parameter.
| Name | Type | Default | Description |
| --------------- | ------- | ------- | ------------------------------------------------------------------------------------------------ |
| `sidebarFields` | `array` | `[]` | Array of Polarion field IDs displayed in the Work Item Properties sidebar when a card is opened. |
### Behavior
* The default value is an empty array (`[]`). When no fields are configured, the sidebar falls back to application-level defaults (confirmed as `title`, `status`, and `plannedIn` from the source).
* Users can additionally personalize their own sidebar view via the **Select Fields** button (gear icon) inside the sidebar — this is per-user, per-work-item-type, and does not override the widget parameter.
* Saving changes in the sidebar preserves the user's swimlane position and scroll location; the board does not jump back to the top.
### Configuration example
```properties theme={null}
sidebarFields = title, description, assignee, status, plannedIn, severity
```
**Field ID casing**
Use the exact Polarion field ID as it appears in project configuration. Wrong casing fails silently — the field is omitted from the sidebar without an error message.
***
## Board rendering mode
| Name | Type | Default | Description |
| -------- | --------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `inView` | `boolean` | `false` | When `true`, renders the board in **view mode**: widget parameters are editable via a modal overlay instead of the standard inline parameter editor. When `false`, the board renders as a standalone widget with its own parameter editor. |
| `pbId` | `string` | `""` | Unique identifier for this board instance. Required when embedding multiple Planningboard widgets on the same Polarion page to prevent ID collisions. |
### Notes on `inView`
* In view mode the board is rendered inside an iframe with a modal editor overlay for parameters.
* If a page hosts only one Planningboard widget, `inView` can remain `false`.
### Notes on `pbId`
* When two or more Planningboard widgets appear on the same LiveDoc or Wiki page, each must have a distinct `pbId` value.
* The value is appended to the iframe `src` URL and used in DOM element IDs.
**Multiple boards on one page**
If you place more than one Planningboard widget on the same page without setting a unique `pbId` for each, the boards may interfere with each other's state. Always set distinct `pbId` values in multi-board layouts.
### Configuration example
```properties theme={null}
pbId = sprint-board-2
inView = false
```
***
## Dependency visualization
The **Show Dependencies** toolbar button reveals dependency arrows between cards. The arrows are drawn only for the link roles configured here.
| Name | Type | Default | Description |
| --------------------- | -------- | ------- | ---------------------------------------------------------------------------------- |
| `dependencyLinkRoles` | `string` | — | Polarion link role ID whose links are displayed as dependency arrows on the board. |
### Behavior
* If `dependencyLinkRoles` is not set, the **Show Dependencies** toolbar button has no effect — no arrows are drawn.
* The card-level **Show Links** quick action (hover over a card) uses the same link role to highlight related cards and hide unrelated ones.
* Setting this parameter also enables the **Add Link** quick action on cards.
**Enable Show Dependencies in the toolbar**
The **Show Dependencies** toolbar button is only functional when `dependencyLinkRoles` is configured. Document the intended link role ID from your Polarion project (for example, `depends_on`) and set it here.
### Configuration example
```properties theme={null}
dependencyLinkRoles = depends_on
```
***
## Unplanned sidebar hierarchy
The **Unplanned section** on the right of the board shows cards not yet assigned to a Plan. For team leads and project managers working with feature hierarchies, the sidebar can load parent items to provide context.
| Name | Type | Default | Description |
| ----------------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `usDepth` | `number` | — | Number of parent levels to load above unplanned work items in the sidebar hierarchy. Controls how many ancestor levels are fetched and displayed. |
| `parentsLinkRole` | `string` | — | Polarion link role ID used to traverse the parent-child relationship when building the unplanned sidebar hierarchy. |
### Behavior of `usDepth`
* A value of `0` or leaving the parameter unset shows only the work items themselves, with no parent context.
* A value of `1` loads the immediate parent of each unplanned item.
* Higher values load deeper ancestors but increase the number of API calls. On large boards with many unplanned items, deep hierarchies may noticeably increase load time.
### Behavior of `parentsLinkRole`
* Set this to the link role that defines the parent relationship in your Polarion project (for example, `parent` or `is_parent_of`).
* If left unset, no parent hierarchy is loaded regardless of the `usDepth` value.
**Performance guidance**
Start with `usDepth = 1` for most planning boards. Only increase the depth if your planning workflow requires visibility into grandparent items. Each additional level multiplies the number of items fetched for hierarchy rendering.
### Configuration example
```properties theme={null}
usDepth = 1
parentsLinkRole = parent
```
***
## Version and cache busting
| Name | Type | Default | Description |
| --------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `version` | `string` | `""` | Version string appended to the iframe `src` URL for cache busting. Ensures that users load the latest board code after a Planningboard update. This value is injected automatically by Planningboard and does not need to be set manually. |
**Verify in application**
The `version` parameter is managed automatically by Planningboard. It is listed here for completeness. Do not set it manually in widget parameters.
***
## Advanced script execution
| Name | Type | Default | Description |
| ----------- | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `advScript` | `string` | `""` | JavaScript code executed in the Planningboard context. The script is exposed as `window.__pbAdvScript` and runs after board initialization. |
### Usage notes
* Intended for advanced customization scenarios only. Consult the [Scripting API](/planningboard/reference/api/scripting-api) and [Config Script API](/planningboard/reference/api/config-script-api) for the available scripting surface.
* Incorrect scripts may break board initialization. Test in a non-production environment before deploying.
* Do not expose sensitive data in script content — the value is embedded in the page HTML.
**Advanced use only**
The `advScript` parameter exposes raw JavaScript execution inside the board context. Use it only when the standard widget parameters do not cover your customization requirement. Always refer to the [Scripting API](/planningboard/reference/api/scripting-api) for supported methods and properties.
### Configuration example
```javascript theme={null}
// advScript value — applied as a Polarion widget parameter
// Example: log the board configuration on load
console.log("Board config loaded", window.__pbConfig);
```
***
## Configuration example — complete UI parameters block
The following example shows a representative configuration for a sprint Planningboard used by a single Scrum team. Iterations are columns, assignees are swimlanes. The sidebar shows key fields, dependencies use the `depends_on` link role, and parent context is one level deep in the unplanned sidebar.
```properties theme={null}
# Sidebar: fields visible when a card is clicked
sidebarFields = title, description, assignee, status, plannedIn, storyPoints
# Dependency arrows in the board
dependencyLinkRoles = depends_on
# Unplanned sidebar: load one level of parent items
usDepth = 1
parentsLinkRole = parent
# Board instance identity (only needed if multiple boards on one page)
pbId = sprint-board
# Rendering mode
inView = false
```
***
## Toolbar controls reference
The following toolbar controls are affected by the UI parameters described on this page. See [Toolbar Controls](/planningboard/reference/ui-elements/toolbar) for the full toolbar reference.
| Toolbar Button | Requires Parameter |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------- |
| **Show Dependencies** | `dependencyLinkRoles` must be set |
| **Show Unplanned** | Unplanned sidebar always available; `usDepth` and `parentsLinkRole` affect its hierarchy |
| **Prioritize** | No UI parameter — enabled via [Work Items Parameters](/planningboard/reference/widget-parameters/work-items-parameters) |
| **Toggle Resource Load** | Controlled via [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) |
***
## Known limitations
* **Parameter visibility**: There is no built-in option to display widget parameters permanently above the board without clicking the gear icon. Parameters are only accessible through the standard Polarion widget parameter editor. There is no confirmed workaround for permanently exposing parameters above the widget.
* **Sidebar fields per work-item type**: The `sidebarFields` parameter applies globally to all work item types shown on the board. Per-type sidebar field sets are not supported at the widget parameter level; individual users can add type-specific fields using the gear icon inside the sidebar, but these additions are user-local.
***
## Related pages
* [Widget Parameters](/planningboard/reference/widget-parameters/index) — overview of all parameter groups
* [Work Items Parameters](/planningboard/reference/widget-parameters/work-items-parameters) — query, sort, and type filters
* [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) — capacity bar configuration
* [Swimlanes (Rows) Parameters](/planningboard/reference/widget-parameters/swimlanes-parameters) — swimlane assignment types
* [Toolbar Controls](/planningboard/reference/ui-elements/toolbar) — toolbar button reference
* [Unplanned Sidebar](/planningboard/reference/ui-elements/sidebar) — unplanned section reference
* [Card Quick Actions](/planningboard/reference/ui-elements/card-quick-actions) — hover actions on cards
* [Scripting API](/planningboard/reference/api/scripting-api) — advanced scripting surface
**KB Articles**
* Planningboard Widget Parameters
* Planningboard: Customizable Statistics and Capacity Indicators
* Planningboard interface & basic interactions
**Support Tickets**
* [#6607](https://support.nextedy.com/helpdesk/tickets/6607)
* [#4714](https://support.nextedy.com/helpdesk/tickets/4714)
**Source Code**
* `widget.vm`
* `PlanningBoardWidgetRenderer.java`
* `PlanningBoardWidget.java`
* `Config.java`
* `viewSetup.vm`
# Work Items Parameters
Source: https://learn.nextedy.com/planningboard/reference/widget-parameters/work-items-parameters
The Work Items parameters control which work items appear on the Nextedy PLANNINGBOARD, how they are sorted, which link roles visualize dependencies, and what fields display in the sidebar when a card is opened.
***
## Parameter reference
### Scope and query
| Parameter | Type | Default | Description |
| ------------- | ------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Scope` | string | — | Defines the project scope for the current board. Restricts the set of work items the board loads to the specified Polarion project. |
| `Query type` | enum | — | Specifies whether the query is a Lucene query or another supported type. |
| `Query` | string | `NOT *:*` | Lucene query to filter which work items are displayed on the board. Only work items matching this query are loaded. |
| `Add Planned` | boolean | — | When enabled, all work items that are already planned are loaded in addition to those matched by the `Query`. Useful when you want to show the full planned set alongside a filtered unplanned set. |
| `maxItems` | number | `1000` | Maximum number of work items loaded into the board in a single request. Reduce this value on large projects to improve load performance. |
| `wiType` | string | — | Work item type filter (for example, `task`, `story`, `feature`). When set, only work items of the specified type are shown on the board. |
**Query syntax**
The `Query` parameter accepts standard Polarion Lucene syntax. An empty or `NOT *:*` query loads no work items by default. Provide a valid query to populate the board. Example: `type:story AND NOT status:done`.
**maxItems and performance**
The default `maxItems` limit is `1000`. Loading large numbers of work items increases initial render time. Tune this value alongside your query to keep board load times acceptable.
***
### Sorting
| Parameter | Type | Default | Description |
| --------- | ------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Sort by` | string | — | Defines how cards are ordered within each swimlane. The board applies sort priority in the following order: (1) resource/assignee name, (2) start date, (3) the configured sort field or priority (if prioritization is enabled), (4) work item ID as a tiebreaker. |
**Sort order and swimlane coupling**
The swimlane sort order is coupled to the item sort order. Changing the sort field affects the order of cards within every swimlane simultaneously.
***
### Dependencies
| Parameter | Type | Default | Description |
| ------------------ | --------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Dependency Roles` | string (link role ID) | — | Specifies which Polarion work item link roles are visualized as dependency lines on the board. Set to the ID of the link role(s) that represent blocking or ordering relationships between cards. |
When `Dependency Roles` is configured, the **Show Dependencies** toolbar button becomes active. Clicking it reveals all dependency arrows between cards simultaneously across the board.
**Dependency visibility requires configuration**
The **Show Dependencies** toolbar control is only functional when `Dependency Roles` is set. Without a configured link role, the toolbar button has no effect.
***
### Sidebar fields
| Parameter | Type | Default | Description |
| ---------------- | ------------------ | ------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Sidebar Fields` | array of field IDs | `title`, `status`, `plannedIn` | Defines which work item fields appear in the **Work Item Properties** sidebar when a card is clicked. Accepts a comma-separated list of Polarion field IDs. |
The sidebar opens when a user clicks any card on the board. It displays the fields listed in `Sidebar Fields` by default. Users can additionally personalize their own sidebar view using the gear icon (Select Fields button) — these personal additions apply only to that user and affect all work items of the same type.
**Sidebar scroll position**
When changes are saved in the sidebar, the Planningboard preserves the swimlane and scroll position. The board does not jump back to the top after saving.
**Common field IDs for sidebar configuration:**
| Field ID | Description |
| ------------- | ------------------------------------------- |
| `title` | Work item title (default) |
| `status` | Current workflow status (default) |
| `plannedIn` | Plans the work item is planned in (default) |
| `assignee` | Assigned user(s) |
| `priority` | Work item priority |
| `severity` | Work item severity |
| `description` | Full description text |
| `dueDate` | Due date |
**Verify in application**
The exact set of available field IDs depends on your Polarion project's custom field configuration. Verify field IDs against your project's work item type definitions.
***
### Unplanned sidebar hierarchy
| Parameter | Type | Default | Description |
| ----------------------------- | --------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `PARAMETER_US_DEPTH` | number | — | Controls how many levels of parent work items are loaded in the unplanned sidebar hierarchy. Higher values load deeper parent chains but may impact performance on large projects. |
| `PARAMETER_PARENTS_LINK_ROLE` | string (link role ID) | — | Specifies which link role defines parent-child relationships used to build the hierarchy tree in the unplanned sidebar. |
The unplanned sidebar groups cards by parent hierarchy when these parameters are set. The sidebar header shows a counter of the form "X out of Y work items" reflecting active filters.
**Hierarchy depth and performance**
Setting a high `PARAMETER_US_DEPTH` value on projects with deep work item hierarchies increases the number of Polarion queries during load. Start with depth `1` or `2` and increase only if the hierarchy display is required.
***
## Unplanned sidebar filtering
The unplanned sidebar supports several filter modes, all accessible without leaving the board:
| Filter | How to access | Behavior |
| ------------------- | ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| By assignee or team | Click the funnel icon | Shows only cards assigned to the selected resource. Mutually exclusive with query filtering — applying a resource filter clears the active query filter. |
| By query | Click the funnel icon → select a predefined query | Shows only cards matching the selected query. Mutually exclusive with resource filtering — applying a query filter clears the active resource filter. |
| Hide resolved items | Click the upper-right toggle | Removes work items in a resolved state from the unplanned list. |
| Filter columns | **Filter columns** toggle | Hides verified work items that are already planned from the unplanned section. |
| Text search | Search field | Case-insensitive real-time search across card content and parent names. Combines with other active filters. |
Clearing filters (the clear button) removes resource and query filters but does not affect the text search or the resolved-items toggle.
**Predefined queries for the sidebar**
Queries available in the funnel filter are configured in the **Queries** section of the widget parameters (separate from the main work items `Query` parameter). See the Queries section in the [Widget Parameters reference](/planningboard/reference/widget-parameters/index) for details.
***
## Configuration example
The following example shows a representative Work Items parameter configuration for a Scrum project using story-type work items, dependency visualization via a `blocks` link role, and a custom sidebar showing priority and due date alongside the defaults.
```text theme={null}
Widget Parameter Configuration — Work Items
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Scope : MyProject
Query type : Lucene
Query : type:story AND NOT status:done
Add Planned : enabled
maxItems : 500
wiType : story
Sort by : priority
Dependency Roles : blocks
Sidebar Fields : title, status, plannedIn, priority, dueDate
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Result:
- Board loads up to 500 stories not in "done" status
- Already-planned stories also appear on the board
- Cards sorted by priority within each swimlane
- "blocks" link role lines shown via Show Dependencies toolbar
- Sidebar shows: Title, Status, Planned In, Priority, Due Date
```
***
## Related parameters
Work Items parameters interact with the following parameter groups:
| Parameter group | Relationship |
| ---------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [Plans (Columns) Parameters](/planningboard/reference/widget-parameters/plans-parameters) | Plans determine which columns cards can be dragged into. The `Add Planned` option loads work items already assigned to those Plans. |
| [Swimlanes (Rows) Parameters](/planningboard/reference/widget-parameters/swimlanes-parameters) | The swimlane assignment type determines which field (assignee, enum, parent, etc.) routes cards to rows. |
| [Capacity Parameters](/planningboard/reference/widget-parameters/capacity-parameters) | Capacity bars per swimlane reflect the work items loaded by this query. Adjust `maxItems` and `Query` to control the set of items contributing to capacity. |
| [Advanced Parameters](/planningboard/reference/widget-parameters/advanced-parameters) | Advanced scripting parameters can further customize card rendering and item behavior beyond what the standard Work Items parameters expose. |
***
## Limitations
* **Page parameters not supported in work item queries.** Planningboard query parameters (including `Scope` and `Query`) do not support Polarion page parameters (`$pageParameters.xxx`) for dynamic substitution. Use separate Planningboard pages per configuration rather than parameterized page-level filtering.
* **Work items with status Verified are locked.** Cards in a Verified status that have been placed on the board cannot be moved or unplanned via drag-and-drop.
* **Sidebar field personalization is per user, per work item type.** Fields added by a user via the gear icon in the sidebar apply to that user only and affect all work items of the same type across all boards they access.
* **`Sort by` and swimlane sort are coupled.** The sort field configured here affects card ordering inside every swimlane simultaneously; independent sort order per swimlane is not available.
**KB Articles**
* Planningboard Widget Parameters
* Planningboard: Customizable Statistics and Capacity Indicators
* Planningboard interface & basic interactions
**Support Tickets**
* [#6607](https://support.nextedy.com/helpdesk/tickets/6607)
* [#6174](https://support.nextedy.com/helpdesk/tickets/6174)
* [#6546](https://support.nextedy.com/helpdesk/tickets/6546)
**Source Code**
* `PlanningBoardWidget.java`
* `PlanningBoardWidgetRenderer.java`
* `widget.vm`
* `Config.java`
* `unplanned_sidebar.js`
# Powersheet Architecture
Source: https://learn.nextedy.com/powersheet/concepts/architecture
Nextedy POWERSHEET is an app for Siemens Polarion ALM that acts as a standalone view on top of Polarion data, accessible from Polarion documents.
This page explains the architectural layers, how data flows between them, and how security is enforced -- giving you the mental model needed to reason about configuration changes, troubleshoot loading behavior, and plan data model design.
## High-Level Architecture
The diagram above captures the key insight: there is no external database, no middleware cache, no separate service to operate. Powersheet runs in-process inside Polarion. YAML configuration and work item data both reside in the same Polarion SVN repository. When you edit a cell in the sheet, the write goes directly to Polarion's work item API -- not to an intermediary.
## No Separate Data Store
This is the single most important architectural concept to internalize. Unlike tools that synchronize data to an external database, Powersheet works entirely within Polarion:
* **Work items** are the rows in the sheet. They are standard Polarion work items, queryable and editable through any Polarion interface.
* **Link roles** connect work items across entity types. Powersheet reads and writes these native Polarion links -- it does not maintain its own relationship tables.
* **Custom fields** on work items store property values. Powersheet columns bind to these fields through the data model.
* **YAML files** stored in the project SVN repository define what data to show and how to present it. They are version-controlled alongside the rest of the project.
The data model does not store data. It defines the *structure* of the data -- which entity types exist, how they relate, and what properties they expose. All actual data lives in Polarion as work items and links. Deleting a data model YAML file does not delete any work items or links.
This design means that anything you do in a Powersheet is immediately visible in Polarion's native views and vice versa. There is no synchronization lag, no import/export step, and no risk of data divergence between the sheet and the underlying platform.
## Three-Tier Architecture
### Server Extension
The server extension runs as a Java plugin inside the Polarion application server process. It handles four responsibilities:
| Responsibility | What It Does |
| ---------------------------- | -------------------------------------------------------------------------------------- |
| **Query translation** | Converts client data requests into Polarion Lucene queries to retrieve work items |
| **Metadata generation** | Reads data model YAML and produces a typed metadata schema for the client |
| **Save operations** | Processes cell edits, new work item creation, and link management via the Polarion API |
| **Configuration management** | Loads, parses, and serves YAML configuration files from the SVN repository |
The server extension registers four administration pages within Polarion at **Administration > Nextedy Powersheet**:
* **Data Models** -- file manager for data model YAML files
* **Sheet Configurations** -- file manager for sheet configuration YAML files
* **Setup** -- initial setup and configuration
* **License** -- license status and management
These pages are available at project, project group, and repository (global) scope, following Polarion's standard administration hierarchy.
### Client Application
The client application runs in the user's browser and renders the interactive sheet. It receives the parsed configuration and typed metadata from the server, then builds the sheet UI with:
* **Hierarchical row expansion** based on the data model's expansion paths
* **Inline cell editing** with type-aware editors (text, dropdowns, reference pickers)
* **Column filtering and sorting** including multi-column sort
* **Row grouping** by column values with collapsible headers
* **Copy and paste** with level-aware restrictions that prevent cross-hierarchy paste errors
* **Keyboard shortcuts** for common operations (add row, export, freeze columns, grouping)
The client uses a data guard mechanism that blocks rendering until the metadata system has fully initialized. This prevents displaying an empty sheet while data is still loading -- a common source of confusion when network latency is high.
### Configuration Layer
All behavior in Powersheet is driven by two types of YAML files:
| File Type | Purpose | Scope |
| ----------------------- | ----------------------------------------------------------------- | --------------------------------------- |
| **Data model** | Entity types, properties, relationships, cardinality, constraints | Shared across sheets in a project |
| **Sheet configuration** | Columns, views, formatters, column groups, data sources | Per-document or shared across documents |
The data model acts as a semantic abstraction layer over Polarion's native work item types and link roles. You can reuse the same sheet configuration across projects that have different Polarion type setups -- only the data model mapping needs to change.
The sheet configuration is assigned to a document through a custom field on the Polarion LiveDoc. When a user opens that document, Powersheet reads the assigned configuration and renders the sheet accordingly.
A single sheet configuration can be referenced by multiple documents. This is valuable when you have several LiveDocs that should present data in the same tabular format but from different document scopes.
For a deeper comparison, see [Data Model vs Sheet Configuration](/powersheet/concepts/data-model-vs-sheet-config).
## Data Flow: Loading a Sheet
The following diagram traces the sequence from the moment a user opens a Powersheet document to the fully rendered sheet.
The load sequence in detail:
1. **Document opens** -- The document's custom field identifies which sheet configuration to use
2. **Server loads YAML** -- The server reads the sheet configuration and the referenced data model from the SVN repository
3. **Metadata generation** -- The server generates a typed metadata schema from the data model and sends it along with the configuration to the client
4. **Client initializes** -- The client builds columns from the configuration, sets up type-aware editors, and prepares the sheet structure
5. **Data query execution** -- The client issues queries that the server translates to Polarion Lucene queries, expanding along configured expansion paths to load related entities at each level
6. **Sheet renders** -- All rows, columns, formatting, and grouping are applied
After initial load, the configuration and metadata remain cached in the client. Subsequent user actions (editing cells, adding rows, creating links) interact directly with the server API, which writes through to the Polarion data layer. No YAML reload occurs during normal editing -- you only need to refresh the page when you change the configuration itself.
## Security Architecture
Powersheet runs entirely inside the customer's Polarion environment. It adds no independent authentication system and no external network exposure -- its servlets run within Polarion's web container and are reachable only through an authenticated Polarion session. Security is a **shared responsibility** between the Polarion platform and Powersheet.
**Handled by Polarion** -- user authentication and authorization (roles, permissions, project access), session management, HTTPS/TLS, Content Security Policy, CSRF protection on state-changing operations, network and OS/JVM/database hardening, central logging, secure secrets storage through the User Account Vault, and the SQL/Lucene query restrictions that are on by default since Polarion 2410. Powersheet relies on these and never bypasses or replaces them.
**Handled by Powersheet** -- correct and secure use of the Polarion APIs, respecting the authenticated user context, safe rendering of user-controlled data, conservative default query and processing limits, and keeping regular usage clearly separated from privileged configuration.
### Authentication
Powersheet has no login screen of its own; it requires an active Polarion session. Users authenticate through Polarion's standard mechanisms (SSO, LDAP, or local accounts) before the widget loads.
### Permission Enforcement
Every data operation goes through the Polarion API, which applies the user's project, work item, and field-level permissions -- if a user lacks write permission on a work item, the server rejects the save regardless of what the client UI allows. Powersheet maintains no access-control lists of its own. Client-side cues (read-only columns, workflow-locked and calculated fields) give immediate UI feedback but are never the sole enforcement; the server independently validates every write.
### Privileged, Scriptable Configuration
Powersheet configuration is centrally managed and treated as privileged, because it can include advanced or scriptable behavior:
* **Storage** -- configuration lives in the Polarion SVN repository (the project's `.polarion` location). Polarion's default permission schemes restrict write access to these paths to administrators; regular users have no write access.
* **Management** -- configuration is edited through administration interfaces intended for users with at least **Project Administrator** privileges (**Administration > Nextedy Powersheet**).
* **Regular users** work with Powersheet data through the configured views but cannot modify configuration or inject custom logic.
* **Scripting** -- customization can use server-side JavaScript, client-side JavaScript, or server-side Velocity, all with access to the Polarion Open/Rendering APIs and Nextedy APIs. It is restricted to trusted roles and is not sandboxed beyond that role restriction.
### Safe Rendering
Administrator-configured rendering contexts (custom cell renderers, top-panel content, formulas, and other template-driven output) control how work item data is displayed; their safety depends on the Polarion API the configuration uses:
* **Rendering API** (e.g. `$workItem.title.render`) performs built-in HTML sanitization and is recommended for all administrator-configurable rendering.
* **Open API / raw access** (e.g. `$workItem.title`) returns unsanitized content; when it is used, the administrator must escape the output -- for example `$esc.html($workItem.title)` on LiveDocs and LiveReport Pages.
Client-side cues and server-side permission enforcement work together, but only the server decides: even if a client-side restriction were bypassed, the Polarion API rejects unauthorized changes. Because configuration and scripting are admin-only and stored in permission-controlled SVN, you never need to duplicate Polarion's permission rules in Powersheet.
## Configuration Scoping
Powersheet configuration operates at three levels, following Polarion's standard administration hierarchy:
| Scope | Location | Use Case |
| ----------------------- | ---------------------- | ---------------------------------------------- |
| **Repository (global)** | Global administration | Organization-wide defaults, shared data models |
| **Project group** | Group administration | Shared configurations for related projects |
| **Project** | Project administration | Project-specific models and sheet layouts |
Project-level configurations supplement global ones. A project can reference a global data model while defining its own sheet configurations, or vice versa. This enables organizations to maintain a standard entity model centrally while allowing individual projects to customize their column layouts.
For details on how global and project-level configurations interact, see [Global vs Project-Specific Configuration](/powersheet/concepts/global-vs-project-specific).
## Where Each Component Lives
Understanding the physical location of each component clarifies what is deployed, what is configured, and what is stored:
| Component | Location | Changed By |
| ------------------------------- | -------------------------------------------------------- | ------------------------------- |
| Server extension (Java plugin) | Polarion server installation | Deployment/upgrade |
| Client application (JavaScript) | Served by the plugin, runs in browser | Deployment/upgrade |
| Data model YAML | `.polarion/nextedy/models/` in project SVN | Administrator edits |
| Sheet configuration YAML | `.polarion/nextedy/sheet-configurations/` in project SVN | Administrator edits |
| Work item data | Polarion project repository | User edits in sheet or Polarion |
| License | Polarion administration | License key entry |
Start with the simplest possible configuration -- a single entity type with a few columns -- and extend incrementally. Jumping straight to complex multi-entity models with many relationships is a common source of hard-to-diagnose errors during initial setup.
## Related Pages
* [Core Components](/powersheet/concepts/core-components) -- Detailed look at each building block
* [Data Model vs Sheet Configuration](/powersheet/concepts/data-model-vs-sheet-config) -- Why two YAML files exist and how they divide responsibilities
* [Model-Driven Design](/powersheet/concepts/model-driven-design) -- How the data model shapes the entire sheet experience
* [Polarion Integration](/powersheet/concepts/polarion-integration) -- How Powersheet extends the Polarion platform
* [Global vs Project-Specific Configuration](/powersheet/concepts/global-vs-project-specific) -- Configuration inheritance and scoping
* [YAML Configuration System](/powersheet/concepts/yaml-configuration) -- How configuration files are discovered and loaded
# Core Components
Source: https://learn.nextedy.com/powersheet/concepts/core-components
Nextedy POWERSHEET provides a structured, configurable sheet interface over Siemens Polarion ALM data.
## The four-component model
Every working powersheet setup relies on four collaborating elements. Each one can be configured independently, but they must reference each other correctly at runtime.
The diagram shows the dependency flow: the data model sits at the top because every other component ultimately depends on the entity types and relationships it defines. The sheet configuration references the data model. Both Powersheet Drive and individual LiveDoc documents reference sheet configurations.
## Data model
The **data model** is a YAML file that creates a semantic layer between Polarion's native work item types and the structured entities that Powersheet works with. Think of it as a "lens" placed over the raw Polarion data -- it does not create new work item types or modify existing ones. Instead, it maps them into a typed hierarchy that Powersheet can navigate, query, and enforce rules upon.
A data model declares three things:
* **Entity types** (`domainModelTypes`): each entry names an entity type and maps it to a Polarion work item type via the `polarionType` property. Entity types also declare their available `properties` -- the fields that can appear as columns in the sheet.
* **Relationships**: connections between entity types that specify the `from` and `to` entity types, the `cardinality` (one-to-one, one-to-many, many-to-one, or many-to-many), the `storage` mechanism (typically `linkedWorkItems` using Polarion's native link system), and the `linkRole` that identifies which Polarion link role stores the connection. Each relationship creates a pair of navigation properties -- a `direct` property on the source entity and a `back` property on the target entity -- enabling traversal in both directions.
* **Constraints**: optional rules that filter which work items appear in `pick` dialogs (picker constraints), controlling what users can select. Picker constraints can filter by `document` properties such as `moduleFolder`, `moduleName`, `type`, or `component`. The `component` constraint supports dynamic context references like `$context.source.document.component` for runtime-resolved filtering.
Data models are managed in **Administration > Nextedy Powersheet > Data Models** and can be scoped to a specific project or shared globally across all projects.
A common misconception is that the data model determines which columns appear in the sheet. It does not -- the data model defines *what data exists and how it connects*. Which columns are visible, how they are labeled, and how they behave is the responsibility of the sheet configuration.
### The standard RTM example
Throughout this documentation, the standard Requirements Traceability Matrix (RTM) example is used to illustrate concepts. It defines five entity types linked in a chain:
`UserNeed` --> `SystemRequirement` --> `DesignRequirement` --> `Hazard` --> `RiskControl`
Each arrow represents a relationship with defined cardinality, link role, and navigation properties. This hierarchy models a typical regulated-industry traceability chain from high-level needs through system-level requirements, design artifacts, and risk management entities.
For a complete YAML reference of this model, see [Example Models Reference](/powersheet/reference/example-models/index).
## Sheet configuration
The **sheet configuration** is a separate YAML file that controls what users see and how they interact with the data. While the data model defines the data landscape, the sheet configuration defines the data *presentation*. It references entity types and navigation properties from the data model and specifies:
* **Columns**: each column is identified by a binding path -- a dot-separated key that maps to a data model property or navigates through a relationship. For example, `title` binds to a direct property, while `systemRequirements.systemRequirement.severity` traverses a relationship to reach a property on a related entity. Each column definition supports properties including `title` (display header), `width` (pixel width), `minWidth` (minimum responsive width), `visible` (default visibility), `formatter` (conditional styling reference), `columnGroup` (visual grouping assignment), `multiItem` (for one-to-many relationship columns), and `isReadOnly` (edit protection).
* **Sources**: data source definitions that connect the sheet to its data model. Each source specifies a `model` reference (the data model name), a `query` (which entity type to load as the root), and an `expand` tree (which relationships to follow when fetching data). The expand tree determines the depth and breadth of hierarchical data loading.
* **Views**: named presets that control which columns are visible for a given analysis perspective. Multiple views can exist within a single sheet configuration, allowing users to switch between different column sets without creating separate configurations.
* **Column groups** (`columnGroups`): visual groupings that cluster related columns under a shared header. Each group has a `groupName`, optional `groupStyle` and `headerStyle` for color theming, and a `collapseTo` property that specifies which column remains visible when the group is collapsed.
* **Sort order** (`sortBy`): default sort configuration specifying the column and direction (`asc` or `desc`) for initial row ordering.
Sheet configurations are managed in **Administration > Nextedy Powersheet > Sheet Configurations** and follow the same project or global scoping as data models.
The `sources[].model` property in the sheet configuration must match the exact name of the data model, not the default `rtm`. A mismatch here is one of the most common first-time configuration errors -- the sheet will fail to load metadata and display no data.
## Powersheet Drive
**Powersheet Drive** is a sidebar navigation panel that gives users a central place to discover and open all powersheet documents in their project. It queries for Polarion documents that have the `nextedySheetConfig` custom field populated and presents them in a drive-style navigator.
Powersheet Drive becomes available once the `powersheet` topic is added to the project's navigation views in Polarion administration. From the user's perspective, it functions like a file browser scoped to powersheet documents, showing document names, folder paths, and the assigned configuration.
**Verify in application**
The query used by Powersheet Drive to discover documents is configurable via project properties. The default behavior finds all documents with the `nextedySheetConfig` field populated.
## LiveDoc (document entry point)
Each powersheet is anchored to a Polarion **LiveDoc** -- a standard Polarion module document. What makes a LiveDoc into a powersheet document is the presence of the `nextedySheetConfig` custom field, which holds the identifier of a sheet configuration file. When a user opens this document through Powersheet Drive, the application reads the configuration reference, loads the associated data model, executes the data query, and renders the interactive sheet.
The `PowersheetService` handles document management operations: creating new powersheet documents, duplicating from templates, and retrieving document metadata. When creating a document, the service assigns the appropriate module type (defaulting to the type containing `powersheet`), sets the configuration reference, and generates document URLs in the format `/polarion/#/project/{projectId}/powersheet?_document={path}&_title={title}`. Starting with Powersheet 26.7.2, these system parameters carry an underscore prefix; the older bare `document` and `documentTitle` names still open existing links. See [URL Parameters](/powersheet/concepts/url-parameters#system-parameters).
Documents can also include an "Open with Nextedy Powersheet" button via a Velocity macro, providing bidirectional navigation between the standard LiveDoc view and the sheet view.
## How the components connect at runtime
When a user opens a powersheet document, the loading sequence follows a deterministic chain:
The key steps in detail:
1. The user selects a document from Powersheet Drive (or navigates directly to the document URL)
2. The application reads the `nextedySheetConfig` custom field value from the LiveDoc to identify which sheet configuration to use
3. The sheet configuration YAML is loaded and parsed, extracting column definitions, source configurations, views, and formatters
4. The `sources[].model` property in the sheet configuration identifies the data model by name; the data model YAML is loaded and its entity types are translated into a metadata structure
5. A data guard component monitors initialization state and blocks rendering until the metadata system is ready. Once ready, the data source query executes (expanding relationships as defined in the source `expand` tree), columns are resolved against entity metadata, and the interactive sheet renders
| Component | Managed in | References |
| ------------------- | -------------------------------------------------------------- | ---------------------------------------------------- |
| Data model | **Administration > Nextedy Powersheet > Data Models** | Polarion work item types, link roles |
| Sheet configuration | **Administration > Nextedy Powersheet > Sheet Configurations** | Data model (by name) |
| LiveDoc | Project documents | Sheet configuration (via `nextedySheetConfig` field) |
| Powersheet Drive | **Administration > Portal > Topics** | Documents with `nextedySheetConfig` set |
## Separation of concerns
The split between the data model and the sheet configuration is a deliberate architectural decision. It enables two important patterns:
**One data model, many sheet configurations.** A single data model defining the RTM entity hierarchy can serve multiple sheet configurations -- one for requirements review (showing requirement-focused columns), another for risk analysis (showing hazard and risk control columns), and a third for traceability auditing (showing link completeness columns). All three sheets share the same underlying entity types and relationships.
**One project, many data models.** A project can host multiple data models for unrelated concerns. A requirements traceability data model and a risk management data model can coexist, each with its own entity types, relationships, and sheet configurations.
This separation also means that changes to presentation (adding a column, creating a new view, adjusting column widths) never require modifications to the data structure. And changes to the data structure (adding a new entity type, defining a new relationship) do not automatically affect existing sheets -- columns must be explicitly added to display new data.
When starting a new Powersheet setup, begin with the simplest possible configuration: a data model with a single entity type and a sheet configuration with a few columns. Validate that the basic setup loads correctly before adding relationships, expansion paths, and additional entity types. This incremental approach significantly reduces misconfiguration errors during initial setup.
For a detailed comparison of what belongs in which file, see [Data Model vs Sheet Configuration](/powersheet/concepts/data-model-vs-sheet-config). For practical tutorials on building each component, see the [Getting Started](/powersheet/getting-started/index) section. For the complete YAML property reference, see the [Sheet Configuration Reference](/powersheet/reference/sheet-config/index) and [Data Model Reference](/powersheet/reference/data-model/index).
# Data Model vs Sheet Configuration
Source: https://learn.nextedy.com/powersheet/concepts/data-model-vs-sheet-config
One of the most important design decisions in Nextedy POWERSHEET is the separation between the **data model** and the **sheet configuration**.
This page explains what each file does, why they are separate, and how they connect at runtime to produce the sheets you see in Siemens Polarion ALM.
## Two files, two concerns
Think of the data model as a **blueprint** and the sheet configuration as a **floor plan**. The blueprint defines the structural elements that exist -- walls, beams, doors -- while the floor plan decides which rooms to show, how to arrange the furniture, and what view each window offers. You can redesign a room without re-engineering the building, and you can reuse the same structural elements in many different room layouts.
At its simplest, the distinction is:
| | Data Model | Sheet Configuration |
| ------------------ | ----------------------------------------------------- | -------------------------------------------------------------- |
| **Purpose** | Defines what data exists | Defines how data is displayed |
| **Contains** | Entity types, relationships, constraints | Columns, sources, views, formatters |
| **YAML root keys** | `domainModelTypes`, `relationships` | `columns`, `sources`, `views`, `formatters` |
| **Managed in** | **Administration > Nextedy Powersheet > Data Models** | **Administration > Nextedy Powersheet > Sheet Configurations** |
| **Scope** | Project or Global | Project or Global |
The data model describes the **structure** of your data: what entity types exist, what properties they have, how they relate to each other, and what Polarion work item types they map to. The sheet configuration describes the **presentation**: which columns appear, what data source to query, how to expand relationships for display, and how to format cells conditionally.
## Why separate files?
The separation enables several important patterns that would be impossible -- or at least impractical -- with a monolithic configuration.
### One data model, many sheet configurations
A single data model -- for example, one defining `UserNeed`, `SystemRequirement`, `DesignRequirement`, `Hazard`, and `RiskControl` -- can power multiple sheet configurations. A requirements engineer might use a sheet that focuses on `UserNeed` to `SystemRequirement` traceability. A safety engineer might use a different sheet showing `Hazard` to `RiskControl` coverage. Both sheets reference the same data model, so entity types and relationships stay consistent.
This is the most compelling reason for separation: **the data model is shared infrastructure, while sheet configurations are team-specific views**.
### Independent change cycles
Data models change infrequently -- typically when a project adds a new entity type or relationship. Sheet configurations change regularly as teams adjust column visibility, add formatters, or create new views for different analysis perspectives. Keeping them separate means everyday column tweaks do not risk breaking the underlying data structure.
### Scope flexibility
Both files can be scoped at the project level or the global level. A global data model can define a company-wide entity structure, while individual projects customize their sheet configurations to show only the columns relevant to their workflow. See [Global vs Project-Specific Configuration](/powersheet/concepts/global-vs-project-specific) for details on scope resolution.
## What the data model defines
The data model YAML file has two primary sections: `domainModelTypes` and `relationships`.
### Entity types and Polarion mapping
Each entity type maps to a Polarion work item type via the `polarionType` property:
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
description:
severity:
SystemRequirement:
polarionType: sys_req
properties:
description:
severity:
DesignRequirement:
polarionType: des_req
properties:
description:
```
The key on the left (`UserNeed`) is the **entity type name** used throughout Powersheet -- in sources, columns, and expansion paths. The `polarionType` value (`user_need`) is the Polarion work item type ID that this entity maps to. These are not interchangeable. A common error is using the Polarion type ID where the entity type name is expected, or vice versa.
Always use the entity type name (e.g., `UserNeed`) in sheet configuration `sources` and `columns`. The Polarion type ID (e.g., `user_need`) belongs only in the `polarionType` field of the data model. Mixing them causes silent query failures.
The `properties` section declares which fields are available for each entity type. These property names become the basis for column binding paths in the sheet configuration.
### Relationships
Relationships connect entity types with direction, cardinality, storage mechanism, and navigation property names:
```yaml theme={null}
relationships:
- from: UserNeed
to: Chapter
cardinality: many-to-one
storage: linkedWorkItems
linkRole: parent
direct:
name: chapter
back:
name: userNeeds
- from: SystemRequirement
to: UserNeed
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds
back:
name: systemRequirements
```
Key properties:
* **`from` / `to`** -- The source and target entity types. Must match keys in `domainModelTypes`.
* **`cardinality`** -- How many instances can be linked: `many-to-one`, `one-to-many`, or `many-to-many`.
* **`storage`** -- How the link is persisted in Polarion. `linkedWorkItems` is the only supported storage mechanism, using Polarion's native link mechanism.
* **`linkRole`** -- The Polarion link role name (must exist in the project's link role configuration).
* **`direct` / `back`** -- Navigation property names for forward and reverse traversal.
The navigation property names (`direct.name` and `back.name`) are the bridge between the data model and the sheet configuration. They appear in the sheet configuration's `expand` clauses and column binding paths.
For a deeper exploration of relationships and navigation, see [Entity Types and Relationships](/powersheet/concepts/entity-types-and-relationships) and [Navigation Properties](/powersheet/concepts/navigation-properties).
### Constraints
The data model can also define constraints that control picker behavior when users create or link entities:
```yaml theme={null}
domainModelTypes:
SystemRequirement:
polarionType: sys_req
constraints:
pick:
document:
moduleFolder: Requirements
component: $context.source.document.component
```
Constraints like `pick.document.moduleFolder` filter which work items appear in picker dialogs. The `$context.source.document.component` syntax dynamically resolves to the current document's component, enforcing component-scoped relationships. See [Process Constraints](/powersheet/concepts/process-constraints) for the full constraint model.
## What the sheet configuration defines
The sheet configuration YAML has several top-level sections: `sources`, `columns`, `views`, `formatters`, `styles`, `columnGroups`, and `sortBy`.
### Sources: what data to load
Sources define how Powersheet queries the server API for data. Each source specifies the data model to use, an entity type to query, and navigation properties to expand:
```yaml theme={null}
sources:
- id: user_needs
model: rtm
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: systemRequirement
```
The `model` value identifies which data model this source references -- this is the explicit connection point between the sheet configuration and the data model. The `query.from` value must match an entity type name from the referenced data model (not a Polarion type ID). The `expand` entries use navigation property names defined in the data model's `relationships` section.
Sources can also define an `entityFactory` to set default property values when creating new entities:
```yaml theme={null}
sources:
- id: user_needs
model: rtm
query:
from: UserNeed
entityFactory:
Status: Planned
```
Support experience shows that new users who jump straight to complex multi-level expansions encounter hard-to-diagnose errors. Start with a single source with no expansions, verify it works, then add `expand` entries one level at a time.
### Columns: how data appears
Columns define the visual layout of the sheet. Each column key is a **binding path** -- a dot-separated path that traces through navigation properties to reach a data property:
```yaml theme={null}
columns:
title:
title: Title
hasFocus: true
width: 300
chapter:
title: Chapter
display: title
list:
search:
- title
systemRequirements.systemRequirement.title:
title: SysReq Title
isReadOnly: true
```
The binding path determines what data appears in the column:
* **`title`** -- A direct property on the root entity type
* **`chapter`** -- A scalar navigation property (many-to-one); `display` specifies which property of the referenced entity to show
* **`systemRequirements.systemRequirement.title`** -- A deep path through a many-to-many relationship (association entity `systemRequirements` to target entity `systemRequirement`, then its `title` property)
### Column properties at a glance
| Property | Type | Default | Purpose |
| ------------- | ----------------- | ------------ | ----------------------------------------------------------------------------- |
| `title` | string | binding path | Display label for the column header |
| `width` | number or string | `'*'` | Column width in pixels or relative (`'2*'`) |
| `minWidth` | number | `150` | Minimum column width |
| `visible` | boolean | `true` | Whether the column is shown by default |
| `isReadOnly` | boolean | `false` | Prevents user editing |
| `isRequired` | boolean | `false` | Validates before save |
| `hasFocus` | boolean | `false` | Receives initial focus for new rows |
| `hasUrl` | boolean | -- | Displays a link to the Polarion work item |
| `multiItem` | boolean | `false` | Enables multi-item picker without creating a new level |
| `formatter` | string | -- | References a conditional formatting rule |
| `value` | string | -- | JavaScript expression that computes the column's content |
| `valueType` | string | `string` | Result type of a `$`-prefixed column's `value`: `string`, `number`, or `date` |
| `render` | string | -- | Custom renderer or JavaScript expression |
| `groupBy` | boolean or object | `false` | Groups rows by this column's values |
| `frozen` | boolean | -- | Freezes the column for horizontal scrolling |
| `aggregate` | string | -- | Aggregate function: `sum`, `avg`, `min`, `max`, `count` |
| `columnGroup` | string | -- | Assigns column to a visual group |
For the complete column property reference, see [Sheet Configuration Reference](/powersheet/reference/sheet-config/index).
### Views: named column presets
Views let you define named column visibility presets without duplicating the entire sheet configuration:
```yaml theme={null}
views:
Without V&V:
columns:
validationTestCases.validationTestCase:
visible: false
systemRequirements.systemRequirement.verificationTestCases.verificationTestCase:
visible: false
```
Each view extends the base column configuration by overriding specific properties (typically `visible`). One view can be marked as the default with `default: true`. If no default view is specified, the base configuration (called "Default view") is applied when the document loads.
See [Views as Analysis Perspectives](/powersheet/concepts/views-as-perspectives) for the conceptual model behind views.
### Formatters, styles, and column groups
The sheet configuration also controls visual presentation through:
* **`formatters`** -- Conditional formatting rules that evaluate a JavaScript expression against each row and apply a style when the condition is true
* **`styles`** -- Named style definitions with CSS-like properties (`color`, `backgroundColor`, `textDecoration`)
* **`columnGroups`** -- Visual groupings with shared header styling and optional collapse behavior via `collapseTo`
* **`sortBy`** -- Default client-side sort order specifying `columnId` and `direction`
## How they connect at runtime
When a Powersheet document loads, the following sequence occurs:
1. **Configuration resolution** -- The server loads the sheet configuration YAML associated with the document (determined by the document's sheet config custom field)
2. **Data model loading** -- The server API loads the data model referenced by each source's `model` field, building the metadata that describes entity types, properties, and relationships
3. **Source queries** -- For each source, the client query framework issues queries using `query.from` to identify the root entity type, then expands navigation properties as specified in `expand`
4. **Column binding** -- Each column's binding path is resolved against the metadata. The path is walked through navigation properties until the target data property is reached
5. **Rendering** -- The sheet renders with the resolved data, applying formatters, styles, views, and column groups
The critical connection point is the **navigation property name**. When a sheet configuration declares `expand: [{ name: systemRequirements }]`, the metadata system looks up `systemRequirements` in the data model's relationship definitions to determine the target entity type, cardinality, and link role. When a column binding path starts with `systemRequirements.systemRequirement.title`, the same metadata resolves each segment of the path.
## How cardinality affects the connection
The cardinality defined in the data model relationship determines how the sheet configuration must reference it. This is where the two files' concerns meet most concretely:
| Cardinality | Data Model | Source Expand | Column Binding | UI Behavior |
| ---------------------- | ------------------------------- | ------------------------------------------------------------- | -------------------------------------- | ----------------------------- |
| **N:1** (many-to-one) | `direct.name: chapter` | `- name: chapter` | `chapter`, `chapter.title` | Single-value reference picker |
| **1:N** (one-to-many) | `back.name: userNeeds` | `- name: userNeeds` | `userNeeds` (new level) | Child rows (new sheet level) |
| **M:N** (many-to-many) | `back.name: systemRequirements` | `- name: systemRequirements` then `- name: systemRequirement` | `systemRequirements.systemRequirement` | Multi-item reference picker |
For many-to-many relationships, the expand pattern requires two levels -- first the association collection, then the target entity -- and the column binding path mirrors this two-segment structure. For many-to-one relationships, a single navigation property name suffices.
See [Link Cardinality](/powersheet/concepts/link-cardinality) for a deeper exploration of how cardinality affects sheet behavior.
## Common misconceptions
### "I can define columns for any Polarion field"
Columns can only reference properties and navigation properties that exist in the data model. If a Polarion custom field is not declared in the entity type's `properties` section, it will not be available for column binding. The data model acts as a filter -- it determines the boundary of what data is accessible.
### "Entity type names and Polarion type IDs are the same thing"
They are distinct. The entity type name (`SystemRequirement`) is chosen by the administrator and can be anything meaningful. The Polarion type ID (`sys_req`) must match an existing work item type in Polarion. They connect through the `polarionType` field. In sources and columns, always use the entity type name.
### "I need a separate data model for each sheet configuration"
Multiple sheet configurations can (and typically do) share the same data model. The data model defines the full data landscape; each sheet configuration selects a subset to display. This is by design -- it keeps the entity type and relationship definitions consistent across all views.
### "Changing a column definition will affect my data"
Sheet configuration changes are purely presentational. Changing a column's `title`, `width`, `visible`, or `formatter` does not alter any data in Polarion. The data model and Polarion's link roles are the only configurations that affect data structure. This is why it is safe to experiment with sheet configurations without risk to your data.
## Practical guidelines
**When to modify the data model:**
* Adding a new entity type to your data landscape
* Defining a new relationship between existing entity types
* Adding a new property that needs to be queryable or editable
* Changing picker constraints for entity creation
**When to modify the sheet configuration:**
* Adding or removing visible columns
* Changing column widths, titles, or sort order
* Creating new views for different stakeholders
* Adding conditional formatting rules
* Adjusting source queries or expansion depth
**When to modify both:**
* Introducing a completely new entity type that needs to appear in the sheet -- define it in the data model first, then add sources and columns in the sheet configuration
Start with the simplest possible configuration: one source with a single entity type, a few columns showing basic properties, no expansions. Verify it loads correctly. Then add one expansion at a time, checking at each step. This approach makes it easy to identify which change caused an error if something goes wrong.
## Further reading
* [Entity Types and Relationships](/powersheet/concepts/entity-types-and-relationships) -- Deep dive into data model entity definitions
* [Navigation Properties](/powersheet/concepts/navigation-properties) -- How navigation property names work across both files
* [Hierarchy and Traceability](/powersheet/concepts/hierarchy-and-traceability) -- How expansion paths create hierarchical views
* [YAML Configuration System](/powersheet/concepts/yaml-configuration) -- YAML syntax and structure conventions
* [Model-Driven Design](/powersheet/concepts/model-driven-design) -- The philosophy behind separating data structure from presentation
* [Source Configuration](/powersheet/concepts/source-configuration) -- Detailed guide to configuring data sources
***
# Document Rules
Source: https://learn.nextedy.com/powersheet/concepts/document-rules
In Nextedy POWERSHEET, **document rules** are constraints within the data model that bind entity types to specific Polarion documents, document types, or module folders.
Think of document rules as a filing system for a regulated office: each type of document has its designated drawer, and the rules ensure that nobody accidentally files a safety hazard report in the requirements drawer. Polarion itself does not enforce this discipline -- Powersheet adds it through the data model's constraint mechanism.
## Why Document Rules Matter
Siemens Polarion ALM organizes work items inside LiveDoc documents, but it does not natively restrict which work item types belong in which documents. A `systemRequirement` work item can be created in any document, and a `userNeed` can end up in a design specification. In regulated industries following standards like ISO 26262 or Automotive SPICE, this structural freedom introduces risk: auditors expect clear separation between requirement types, and traceability gaps emerge when items scatter across uncontrolled locations.
Document rules in the data model act as **process guardrails**. They do not alter Polarion's underlying data storage -- they control what Powersheet queries, displays, and permits through the sheet interface. This distinction is important: a `SystemRequirement` work item that exists in an unexpected document is not deleted or moved by a document rule. Instead, the rule simply prevents it from appearing in the sheet, being selected in a picker, or being the default location for new items of that type.
**Data model scope**
Document rules are defined per entity type in the data model YAML (`domainModelTypes`), not in the sheet configuration. This means they apply consistently across every sheet configuration that uses the same data model, regardless of column layout or view settings.
## The Three Constraint Stages
Document rules operate through three **constraint stages**, each controlling a different aspect of how entities interact with documents. These stages are defined within the `constraints` block on an entity type.
### Stage Cascading
A critical concept is that constraint stages **cascade upward**:
* **`pick`** inherits from `load`. If you define `load` constraints but no `pick` constraints, the pick stage uses the load constraints automatically.
* **`create`** inherits from both `load` and `pick`. If no explicit `create` constraints exist, the system falls back to `pick` constraints (which themselves may have fallen back to `load`).
This cascading means you often only need to define the `load` stage. The pick and create stages will inherit its document rules unless you need different behavior at those stages.
**Cascading fallback order**
The fallback chain is: `create` -> `pick` -> `load`. If you define only `load` document rules, all three stages use them. If you define `load` and `pick`, the create stage inherits from `pick` (not `load`). Define explicit `create` constraints only when new items should go to a different location than where picker results come from.
### Load Stage
A `load` constraint with document rules filters the initial data query so that only work items residing in matching documents appear in the sheet:
```yaml theme={null}
domainModelTypes:
SystemRequirement:
polarionType: systemRequirement
constraints:
load:
document:
type: systemSpecification
```
This ensures the sheet query only returns `SystemRequirement` items from documents whose type is `systemSpecification`. Items of the same Polarion work item type in other documents are excluded from the display.
### Pick Stage
Pick constraints scope the item picker dialog. When a user links a relationship to a `UserNeed`, the picker shows only items matching the pick constraints:
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: userNeed
constraints:
pick:
document:
moduleFolder: Requirements
type: needsDocument
```
When another entity type references `UserNeed` through a relationship, the picker dialog will only show user needs from `needsDocument`-type documents in the `Requirements` folder. This prevents users from accidentally linking to items in unrelated documents.
### Create Stage
Create constraints determine the default document location when a user creates a new entity through the sheet:
```yaml theme={null}
domainModelTypes:
DesignRequirement:
polarionType: designOutput
constraints:
create:
document:
moduleFolder: Design
moduleName: Design Specification
```
When a user creates a new `DesignRequirement` item, Powersheet automatically places it in the `Design Specification` document within the `Design` folder. Without this constraint, new items might be created in the currently active document, which may not be the intended location.
## Document Filter Properties
All three constraint stages support the same set of document filter properties within the `document` block:
| Property | What It Filters | Example Value |
| ----------------------- | --------------------------------------------------------------------------------------- | ------------------------------------ |
| `document.moduleFolder` | Restricts to work items within a specific Polarion module folder (space) | `Requirements` |
| `document.moduleName` | Restricts to work items within a specific document by exact name match | `System Specification` |
| `document.type` | Restricts to work items in documents of a specific Polarion document type | `systemSpecification` |
| `document.component` | Restricts by the document's component property; supports dynamic `$context` expressions | `$context.source.document.component` |
These properties can be combined within a single `document` block. When multiple properties are specified, they act as an AND condition -- all criteria must match for a document to qualify.
```yaml theme={null}
constraints:
load:
document:
moduleFolder: Requirements
type: systemSpecification
component: Braking
```
This loads only `systemSpecification`-type documents from the `Requirements` folder that belong to the `Braking` component.
## Dynamic Document Scoping with Context
For projects where document assignments vary by component, subsystem, or other runtime context, document rules support **`$context` expressions**. These expressions resolve dynamically based on the current document, source entity, or query parameters rather than being hardcoded in the data model.
The most common pattern scopes constraints to the same component as the source entity's document:
```yaml theme={null}
constraints:
pick:
document:
component: $context.source.document.component
```
This ensures that when picking related items, only entities from documents with the **same component value** as the source entity's document are shown. In multi-component projects -- where each component has its own requirement, design, and test documents -- this prevents cross-component linking mistakes.
**When to use dynamic scoping**
Use `$context.source.document.component` when your project structure mirrors a component hierarchy. For example, if the Braking subsystem has its own `System Specification` and `Design Specification` documents, dynamic scoping ensures that requirements in the Braking specification only link to design items in the Braking design document -- without needing separate entity types or data models per component.
The query manager resolves `$context` expressions at runtime by injecting the current document's properties (such as `document.id`, `document.moduleFolder`, and `document.component`) into the query parameters. This resolution happens transparently before the query is sent to the server.
## Combining Document Rules Across Entity Types
In a full RTM data model, each entity type typically has its own document rules. Consider a standard requirements traceability hierarchy:
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: userNeed
constraints:
load:
document:
type: needsDocument
SystemRequirement:
polarionType: systemRequirement
constraints:
load:
document:
type: systemSpecification
DesignRequirement:
polarionType: designOutput
constraints:
load:
document:
type: designSpecification
create:
document:
moduleFolder: Design
moduleName: Design Specification
Hazard:
polarionType: hazard
constraints:
pick:
document:
component: $context.source.document.component
```
Each entity type is scoped to its appropriate document type. The `DesignRequirement` type adds an explicit `create` stage to control where new items land. The `Hazard` type uses dynamic component scoping for its picker.
## Comparison Operators in Constraints
Beyond simple equality matching, constraints support several **comparison operators** that provide more flexible filtering:
| Operator | Behavior | Example |
| ------------ | ------------------------------------------------ | -------------------------------------- |
| `equals` | Exact match (default when no operator specified) | `type: systemSpecification` |
| `contains` | Substring match | `moduleName: { contains: "Spec" }` |
| `in` | Matches any value in a list | `type: { in: [sysSpec, designSpec] }` |
| `startsWith` | Prefix match | `moduleFolder: { startsWith: "Req" }` |
| `endsWith` | Suffix match | `moduleName: { endsWith: "Document" }` |
These operators are useful when document naming follows a pattern rather than exact conventions, or when a single constraint needs to match multiple document types.
## Logical Operators
Within the `document` block, constraints support **OR logic** for combining alternative conditions. Multiple criteria at the same level are joined with AND logic by default. To express OR conditions, the constraint system allows alternative document blocks:
```yaml theme={null}
constraints:
pick:
document:
moduleFolder: Requirements
type: needsDocument
```
All properties within the same `document` block are evaluated as AND. If no `create` constraints are defined, the system falls back to `pick` constraints for the create stage, ensuring consistent behavior without redundant configuration.
**Conflicting constraints**
When composing multiple constraints, be careful that the combined conditions do not produce an empty result set. For example, constraining to `moduleFolder: Design` AND `type: needsDocument` might match no documents if your needs documents reside in the `Requirements` folder. Test constraint combinations by checking what the picker shows before committing the configuration.
## Common Misconceptions
**"Document rules move work items between documents."**
They do not. Document rules only affect what Powersheet loads, displays in pickers, and uses as the target for new items. A work item's actual document location in Polarion is unchanged by document rules.
**"I need to define all three stages."**
Due to cascading inheritance, defining only the `load` stage is often sufficient. The `pick` and `create` stages inherit from it automatically. Define separate stages only when you need different behavior -- for example, loading broadly but creating in a specific document.
**"Document rules replace Polarion permissions."**
Document rules are a data model concern, not a security mechanism. They guide the sheet interface but do not override Polarion's native permission model. A user with Polarion permissions to edit a document outside the constraint scope could still modify items through Polarion's standard interface, just not through Powersheet.
## Relationship to Other Concepts
Document rules are one layer of the broader constraint system in Powersheet. They work alongside other concepts to create a complete enforcement model:
* **[Process Constraints](/powersheet/concepts/process-constraints)** define validation rules beyond document scoping, such as field-level restrictions and workflow enforcement.
* **[Link Cardinality](/powersheet/concepts/link-cardinality)** controls how many relationships of a given type are permitted -- while document rules control *where* the related entities can come from.
* **[Entity Types and Relationships](/powersheet/concepts/entity-types-and-relationships)** define the structural foundation that document rules operate upon.
* **[Navigation Properties](/powersheet/concepts/navigation-properties)** determine how relationships are traversed; document rules determine which items are reachable during that traversal.
For practical setup instructions, see the [Data Model Guides](/powersheet/guides/data-model/index). For the full constraint property reference, see the [Data Model Reference](/powersheet/reference/data-model/index).
***
# Dynamic Value Expressions
Source: https://learn.nextedy.com/powersheet/concepts/dynamic-expressions
Nextedy POWERSHEET configurations support **dynamic value expressions** — values that are resolved at runtime based on the current context.
This concept page explains *why* dynamic expressions exist, *how* the two expression notations differ, and *what mental model you need* to reason about them effectively. For step-by-step configuration instructions, see the relevant [How-To Guides](/powersheet/guides/index).
## Why Dynamic Expressions Matter
Consider a data model where `DesignRequirement` entities link to `SystemRequirement` entities. Without dynamic expressions, a constraint that filters design requirements to a specific component would need to be hardcoded:
```yaml theme={null}
constraints:
load:
document:
component: "Braking"
```
This works for one document but breaks the moment you open a different component's requirements. Dynamic expressions solve this by letting the configuration *ask the runtime* for the correct value:
```yaml theme={null}
constraints:
load:
document:
component: $context.source.document.component
```
Now the same configuration works across every component — Braking, Steering, Powertrain — because the filter value is resolved from the source entity's actual document at the moment the sheet loads.
The same principle applies throughout sheet configuration: filtering queries by the current document, calculating column values from other properties, rendering custom HTML in cells, controlling how navigation properties are displayed, and conditionally styling rows based on data thresholds.
## Two Notations, Two Worlds
Powersheet uses two distinct expression notations. Each belongs to a different configuration file type, and they are **not interchangeable**.
| Notation | Syntax | Configuration File | Evaluation Model |
| ---------------------- | ------------------------ | -------------------------------------------------------------- | ------------------------------ |
| **Context expression** | `$context.property.path` | Data model YAML (constraints) | Simple property path traversal |
| **Dynamic value** | `() => expression` | Sheet configuration YAML (where, value, render, display, etc.) | JavaScript arrow function |
If you are editing a **data model** YAML file (`domainModelTypes`, `relationships`), use `$context`. If you are editing a **sheet configuration** YAML file (`sources`, `columns`, `formatters`), use `() =>`.
### Context Expressions: Property Path Traversal
Context expressions (`$context.property.path`) are **declarative lookups**. Think of them as a pointer into a data structure — no logic, no computation, just "go to this address and return what you find."
Powersheet resolves a `$context` expression by walking the dot-separated segments at runtime. The expression `$context.source.document.component` means: start at the context object, navigate to `source`, then `document`, then read the `component` property.
This simplicity is intentional. Data model constraints define structural rules about *which* entities can relate to each other. They should be predictable and side-effect-free. A constraint that runs arbitrary JavaScript could introduce subtle bugs across the entire traceability structure.
**Available paths for `$context`:**
| Path | Description | Example Value |
| --------------------------------------- | ------------------------------------ | ----------------------------------- |
| `$context.source.type` | Source entity's work item type | `"sys_req"` |
| `$context.source.document.id` | Source entity's document ID | `"Requirements/SRS"` |
| `$context.source.document.moduleName` | Source entity's document module name | `"UserNeedSpecification"` |
| `$context.source.document.moduleFolder` | Source entity's document folder | `"Requirements"` |
| `$context.source.document.component` | Source entity's document component | `"Braking"` |
| `$context.source.document.type` | Source entity's document type | `"systemRequirementsSpecification"` |
| `$context.source.document.title` | Source entity's document title | `"System Requirements"` |
Dynamic constraints with `$context` are evaluated **per-row**. If your sheet displays system requirements from multiple components, each row resolves `$context.source.document.component` independently. Row A might resolve to "Braking" while Row B resolves to "Steering."
### Dynamic Values: JavaScript Arrow Functions
Dynamic values (`() => expression`) bring full JavaScript expressiveness to sheet configuration. They can access multiple context properties, perform calculations, construct strings, render HTML, control display values for navigation properties, and apply conditional logic.
The `() =>` syntax is a JavaScript arrow function that receives a `context` object. At runtime, Powersheet evaluates the function and uses the returned value:
```yaml theme={null}
# A computed column that multiplies two properties
value: "() => context.entity.count * context.entity.rate"
# A where clause that scopes results to the current document
where:
document.moduleName:
"==": "() => context.document.moduleName"
```
Because these are real JavaScript functions, you have access to standard JavaScript capabilities: string interpolation, array methods, Date objects, arithmetic, and conditional (ternary) operators.
## The Context Object
Both expression notations draw from a shared runtime **context object**. Understanding its structure is the key to writing correct expressions. The context is hierarchical — properties are progressively available depending on where the expression is evaluated.
```text theme={null}
context
|-- parameters URL and configuration parameters (key-value pairs)
| +-- {paramName} e.g. context.parameters.client
|-- sources All configured data source definitions
|-- document Current document information
| +-- title, type, id, moduleName, moduleFolder, component
|-- project Current project
| +-- id, name e.g. context.project.name (name may be absent on older backends)
|-- entity Current entity (per-cell contexts only)
| +-- {propertyName} e.g. context.entity.severity
|-- source Parent/source entity — the level navigated from
| +-- {propertyName} e.g. context.source.document.component
|-- row The whole row across every navigation level
| +-- entities[] e.g. context.row.entities[0]
|-- value Current cell's display value
+-- item Deprecated alias of context.entity
```
**Not all properties are available everywhere.** The context is scoped based on where the expression runs:
| Usage Location | `.document` | `.project` | `.parameters` | `.entity` | `.value` | `.source` | `.row` |
| :----------------------- | :---------- | :--------- | :------------ | :-------- | :------- | :-------- | :----- |
| `where` | Yes | Yes | Yes | — | — | — | — |
| `entityFactory` | Yes | Yes | Yes | — | — | — | — |
| `value` (bound column) | Yes | Yes | Yes | Yes | — | — | — |
| `value` (unbound column) | Yes | Yes | Yes | Yes | — | Yes | Yes |
| `render` / `renderers` | Yes | Yes | Yes | Yes | Yes | — | — |
| `formatter` | Yes | Yes | Yes | Yes | Yes | — | — |
| `display` | Yes | Yes | Yes | Yes | Yes | Yes | — |
`context.item` is deprecated because it's ambiguous — in some cell expressions it's the entity, in others the whole row. Use `context.entity` or `context.row` instead; each always means exactly one thing.
Think of this as a funnel: at the query level (`where`), there is no "current item" yet — the query *finds* items. At the cell level (`value`, `render`, `display`), each expression runs in the context of a specific entity and cell value.
Referencing `context.entity` inside a `where` clause will return `undefined` because the entity has not been resolved yet at query time. Similarly, `context.document` is not available in `render` expressions. Always consult the availability table above when writing expressions.
**A computed column starts from no cell value.**
`context.value` is the value already in the cell, so it is `undefined` inside a `value` expression — the expression is what produces that value. Read what you need from `context.entity` instead. Only an unbound column reaches `context.source` and `context.row`; a bound `value` column is evaluated from the entity alone.
## Where Each Notation Is Used
### Context Expressions in Data Model Constraints
Context expressions appear exclusively in data model constraint definitions — the rules that control which entities can be loaded or picked when navigating relationships.
```yaml theme={null}
relationships:
- from: DesignRequirement
to: SystemRequirement
back:
name: designRequirements
constraints:
load:
document:
component: $context.source.document.component
```
This constraint says: when expanding `SystemRequirement` to show linked `DesignRequirement` entities, only load those from documents matching the source's component. The constraint is structural — it shapes what data appears in the sheet.
For more on how constraints work in the data model, see [Process Constraints](/powersheet/concepts/process-constraints) and [Entity Types and Relationships](/powersheet/concepts/entity-types-and-relationships).
### Dynamic Values in Sheet Configuration
Dynamic values appear across several sheet configuration properties, each serving a different purpose:
| Property | Purpose | Persists Data? |
| ----------------------------------- | --------------------------------------------------------------------------------------------- | -------------- |
| `sources.query.where` | Filter which entities appear in the sheet | No |
| `sources.expand[].query.where` | Filter a nested / expanded level (subquery) — same predicates and context as the root `where` | No |
| `sources.entityFactory` | Set initial property values for newly created items | Yes |
| `columns.*.value` (bound key) | Compute a column's content from other properties | **Yes** |
| `columns.*.value` (unbound `$` key) | Compute a column's content with no property behind it | No |
| `columns.*.render` | Custom HTML rendering for cell display | No |
| `columns.*.display` | Override the display value for navigation properties | No |
| `renderers.*` | Named renderer definitions reusable across columns | No |
| `formatters.*.expression` | Boolean condition for conditional styling | No |
**`value` is about data; `render` is about appearance.**
On a column bound to a real property, `value` **writes the computed result back to the data source** — it changes persisted data. `render` only affects visual display; it styles whatever the cell already holds and cannot supply content of its own.
When you need a computed value that is never stored, neither one is the answer: prefix the column's binding key with `$` so the column is **unbound** — it has no property behind it, computes on read, and leaves the work item untouched. The prefix, not `render`, is what decides whether the result is stored.
### Formatter Expressions: The Exception
Formatter expressions use a simplified syntax that differs from both `$context` and `() =>`:
```yaml theme={null}
formatters:
criticalHighlight:
expression: "context.entity.Probability <= 99"
style: warningStyle
```
Notice: no `() =>` prefix, no `$context` prefix. The expression is evaluated directly as a boolean condition. This is a deliberate design choice — formatters only need to answer "does this condition match?" and the simplified syntax makes that intent clear.
## Common Expression Patterns
### Controlling How Navigation Properties Display
The most common use of `() =>` is the `display` property on navigation columns — it controls *which* field of a linked entity appears in the cell. For columns that show a referenced document, `display: titleOrName` is the typical choice; for columns that show a chapter or section reference, use `display: title`:
```yaml theme={null}
columns:
document:
binding: source.document
display: "() => context.value.titleOrName"
chapter:
binding: source.chapter
display: "() => context.value.title"
```
Because `display` runs in a cell context, `context.value` is the linked entity itself, and the arrow function picks the human-readable label without mutating any data. This pattern keeps the underlying binding intact (so navigation, sorting, and saving still work against the real entity) while letting each column choose the most meaningful label.
### Scoping a Query to the Current Document
A common `where` pattern is to restrict a sheet to entities that live in the same document as the powersheet widget. Use `context.document.moduleName` so the query follows whichever document the user has open:
```yaml theme={null}
sources:
- id: requirements
query:
from: SystemRequirement
where:
document.moduleName:
"==": "() => context.document.moduleName"
```
The widget then shows requirements from the current document only — without any per-document configuration.
### Calculating Derived Values
A `value` expression can reference any property on the current entity. Bound to a real property, the result is stored:
```yaml theme={null}
columns:
total:
value: "() => context.entity.count * context.entity.rate"
```
Prefixed with `$`, the same expression produces a column that is shown but never stored — declare its result type with `valueType`, since there is no property metadata to take one from:
```yaml theme={null}
columns:
$riskScore:
title: Risk Score
value: "() => context.entity.Probability * context.entity.Severity"
valueType: number
```
Either way the column is read-only: its content comes from the expression, not from what a user types. See [Add a Computed Column](/powersheet/guides/sheet-configuration/add-computed-column).
### Dynamic Initial Values
When users create new entities from within the sheet, `entityFactory` sets sensible defaults — often by inheriting from the current document:
```yaml theme={null}
entityFactory:
component: "() => context.document.component"
```
### Custom Cell Rendering
Renderers produce HTML for rich cell content:
```yaml theme={null}
renderers:
linkedItems: "() => context.value.map((item) => `${item.name} `).join(', ')"
```
### Date Comparisons
JavaScript Date objects work naturally in where clauses:
```yaml theme={null}
where:
DueDate:
">": "() => new Date().toISOString()"
```
Date values must be in the correct format for the target data type. For Polarion date fields, `.toISOString()` produces the expected format.
## Mental Model: Static Structure vs Dynamic Behavior
The two expression types reflect a fundamental architectural division in Powersheet:
* The **data model** defines *what exists* — entity types, relationships, cardinality rules. It is the structural blueprint. Context expressions (`$context`) fit here because they are declarative property lookups that shape data boundaries.
* The **sheet configuration** defines *how things look and behave* — column layout, formatting, calculations, rendering, and the labels shown for navigation properties. Dynamic values (`() =>`) fit here because they need the full expressiveness of runtime computation.
This separation means you can change how data is *displayed* (sheet config) without affecting how data is *structured* (data model), and vice versa. The data model remains a stable foundation that multiple sheet configurations can build upon.
For deeper exploration of this separation, see [Data Model vs Sheet Configuration](/powersheet/concepts/data-model-vs-sheet-config) and [Model-Driven Design](/powersheet/concepts/model-driven-design).
## Quick Reference
| I want to... | Notation | Example |
| ----------------------------------------- | ---------- | ------------------------------------------------------------------ |
| Filter relationships by source document | `$context` | `component: $context.source.document.component` |
| Show a document reference in a column | `() =>` | `display: "() => context.value.titleOrName"` |
| Show a chapter reference in a column | `() =>` | `display: "() => context.value.title"` |
| Scope query to the current document | `() =>` | `"==": "() => context.document.moduleName"` |
| Compute a column and store the result | `() =>` | `value: "() => context.entity.count * context.entity.rate"` |
| Compute a column without storing anything | `() =>` | `$total:` with `value: "() => …"` and `valueType: number` |
| Render custom HTML in a cell | `() =>` | `render: "() => '' + context.value + ' '"` |
| Set default value for new items | `() =>` | `entityFactory: { component: "() => context.document.component" }` |
| Conditionally style a cell | expression | `expression: "context.entity.Risk > 50"` |
## Further Reading
* [URL Parameters](/powersheet/concepts/url-parameters) — feed `context.parameters` from the URL into any `() =>` value (filters, defaults, computed columns, the sheet name)
* [Server-Side Filtering](/powersheet/concepts/server-side-filtering) — how a `() =>` value in a `where` scopes the query on the server so only the matching slice loads
* [Process Constraints](/powersheet/concepts/process-constraints) — how constraints control entity loading and picking in the data model
* [YAML Configuration System](/powersheet/concepts/yaml-configuration) — the overall configuration architecture that expressions plug into
* [Data Model vs Sheet Configuration](/powersheet/concepts/data-model-vs-sheet-config) — why the two configuration files exist and how they interact
* [Navigation Properties](/powersheet/concepts/navigation-properties) — how expansion paths and the `display` property work together
* [Add a Computed Column](/powersheet/guides/sheet-configuration/add-computed-column) — the practical guide to `value`, the `$` unbound marker, and `valueType`
* [Sheet Configuration Guides](/powersheet/guides/sheet-configuration/index) — practical step-by-step instructions for configuring columns, formatters, and queries
* [Customization Guides](/powersheet/guides/customization/index) — hands-on guides for custom fields and conditional formatting
# Entity Types and Relationships
Source: https://learn.nextedy.com/powersheet/concepts/entity-types-and-relationships
The data model in Nextedy POWERSHEET is built on two foundational concepts: **entity types** define the categories of objects in your traceability structure, and **relationships** define how those objects connect.
Think of the data model as an architect's blueprint. The blueprint defines which rooms exist (entity types) and how corridors connect them (relationships). The sheet then renders this blueprint as an interactive, navigable hierarchy where engineers can trace requirements to risks, link design decisions to test cases, and manage complex traceability chains -- all within a single configurable view.
## Entity Types: The Building Blocks
An **entity type** represents a category of work item in your engineering process. In the data model YAML, entity types are declared under the `domainModelTypes` section. Each entity type maps to a Polarion work item type and declares which properties (fields) are visible in the sheet.
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
description:
severity:
component:
```
In this example, `UserNeed` is the entity type name used throughout Powersheet configuration. It maps to the `user_need` Polarion work item type and exposes three properties for display and editing in the sheet.
Key aspects of entity types:
| Property | Purpose |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `polarionType` | Maps the domain entity to a Polarion work item type ID. If omitted, the entity type name itself is used as the Polarion type. |
| `properties` | Declares which Polarion fields are exposed in the sheet. Each key maps to a work item custom field or built-in field. A null value means the property exists with default configuration. |
| `constraints` | Optional rules for `load`, `create`, and `pick` behavior (see [Process Constraints](/powersheet/concepts/process-constraints)). |
**Entity type names use PascalCase**
Entity type names in `domainModelTypes` must be single words without spaces or special characters. Use PascalCase: `UserNeed`, `SystemRequirement`, `DesignRequirement`. These names become the identifiers used in relationships, queries, and expansion paths throughout your configuration.
### Why Entity Types Matter
Entity types serve as the translation layer between Polarion's flat work item storage and the structured data model that Powersheet uses to build hierarchical views. Without entity types, Powersheet would have no way to know that a `user_need` work item type should appear as a top-level requirement, or that a `hazard` work item type represents a risk that traces back to a system requirement.
This translation layer is what enables Powersheet to present the same underlying Polarion data in fundamentally different ways. A requirements traceability matrix, a risk analysis sheet, and a design verification view can all draw from the same project data -- the data model defines which entity types participate and how they relate.
### Multiple Polarion Types per Entity
A single entity type can map to multiple Polarion work item types. The `polarionType` property accepts either a single string or an array:
```yaml theme={null}
domainModelTypes:
Requirement:
polarionType:
- sys_req
- des_req
```
When an entity maps to multiple types, the sheet handles type selection during creation and filtering during queries. This is useful when you want to treat several related Polarion types as a single logical category in your data model -- for example, grouping system requirements and design requirements under a unified `Requirement` entity type.
### Entity Type Properties
Properties declared on an entity type control which fields are visible and editable in the sheet. Each property key corresponds to a Polarion work item field (built-in or custom). When a property is declared with a null value, it uses default configuration:
```yaml theme={null}
domainModelTypes:
SystemRequirement:
polarionType: sys_req
properties:
description:
severity:
priority:
verificationMethod:
```
Properties do more than expose fields. They become the vocabulary that columns, formatters, and queries use to reference data. When you configure a column with a binding path like `systemRequirements.systemRequirement.severity`, you are navigating through relationships and accessing a declared property. If `severity` is not declared in the entity type's `properties`, it will not be available in the sheet.
## Relationships: The Connections
**Relationships** define how entity types connect to each other. Each relationship specifies a source and target entity type, a cardinality pattern, a storage mechanism, and navigation properties that enable traversal in both directions.
```yaml theme={null}
relationships:
- from: UserNeed
to: SystemRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: systemRequirements
back:
name: userNeeds
```
Every relationship has two sides:
* **`direct`** -- The forward navigation property, created on the `from` entity type. In the example above, navigating from `UserNeed` to its related `SystemRequirement` items uses the property named `systemRequirements`.
* **`back`** -- The reverse navigation property, created on the `to` entity type. Navigating from `SystemRequirement` back to its originating `UserNeed` items uses the property named `userNeeds`.
This bidirectional design means you can build sheets that start from either end of a relationship. A requirements traceability matrix might start from `UserNeed` and expand into `SystemRequirement` items (using the `direct` navigation). A reverse traceability view might start from `SystemRequirement` and expand back to `UserNeed` items (using the `back` navigation).
**Navigation property naming convention**
By convention, singular names (like `chapter`) indicate many-to-one relationships (one target), while plural names (like `systemRequirements`) indicate one-to-many or many-to-many relationships (multiple targets). This naming convention is not enforced by the system but makes configurations easier to read and maintain.
## Cardinality: How Many Can Connect
**Cardinality** defines the multiplicity of a relationship -- how many instances of each entity type can participate. Powersheet supports three cardinality patterns, and each one determines how the relationship appears in the sheet, how sources expand data, and how columns bind to navigation properties.
### Many-to-One (N:1)
Each instance of the `from` entity belongs to exactly one instance of the `to` entity. This is the simplest relationship pattern.
**Example:** Each `UserNeed` belongs to exactly one `Chapter`.
```yaml theme={null}
relationships:
- from: UserNeed
to: Chapter
cardinality: many-to-one
storage: linkedWorkItems
linkRole: parent
direct:
name: chapter
back:
name: userNeeds
```
In the sheet, a many-to-one relationship renders as a **single-value reference picker**. The `chapter` column shows one value and allows selecting a different `Chapter` entity. You can also display properties of the referenced entity using dot notation:
```yaml theme={null}
columns:
chapter:
title: Chapter
display: title
list:
search:
- title
chapter.title:
title: Chapter Title
isReadOnly: true
```
The column `chapter` provides a picker for selecting the parent chapter. The column `chapter.title` displays the title of the linked chapter as a read-only field.
### One-to-Many (1:N)
Each instance of the `to` entity has multiple instances of the `from` entity. This is the reverse view of a many-to-one relationship -- same underlying link, different perspective.
**Example:** Each `Chapter` has multiple child `UserNeed` items.
```yaml theme={null}
sources:
- id: chapters
query:
from: Chapter
expand:
- name: userNeeds
```
In the sheet, a one-to-many relationship creates **child rows** -- a new hierarchy level that expands beneath the parent row. The `expand` clause in the source configuration tells Powersheet to load the related items and nest them under their parent.
```yaml theme={null}
columns:
title:
title: Chapter
hasFocus: true
userNeeds:
title: User Need
hasFocus: true
```
The `userNeeds` column represents the expanded child level. No dot notation is needed because the expand directly opens the child level in the sheet hierarchy.
### Many-to-Many (M:N)
Both sides of the relationship can have multiple instances. This is the most complex pattern and uses an **association entity** as an intermediate layer.
**Example:** `UserNeed` items linked to multiple `SystemRequirement` items and vice versa.
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: systemRequirement
```
The source expand is two levels deep: first `systemRequirements` (the association collection), then `systemRequirement` (the actual target entity). Column bindings use dot notation to reach through the association:
```yaml theme={null}
columns:
title:
title: Title
hasFocus: true
systemRequirements.systemRequirement:
title: System Requirement
list:
search:
- objectId
- title
createNew: true
systemRequirements.systemRequirement.title:
title: SysReq Title
hasFocus: true
```
The column `systemRequirements.systemRequirement` acts as a **multi-item reference picker**, allowing users to link multiple system requirements to a single user need.
### Cardinality Summary
| Cardinality | Source expand | Column binding | UI behavior |
| ----------- | ------------------------------------------------------------- | -------------------------------------- | -------------------------------- |
| **N:1** | `- name: chapter` | `chapter`, `chapter.title` | Single-value reference picker |
| **1:N** | `- name: userNeeds` | `userNeeds` | Child rows (new hierarchy level) |
| **M:N** | `- name: systemRequirements` then `- name: systemRequirement` | `systemRequirements.systemRequirement` | Multi-item reference picker |
**Many-to-many requires two-level expand**
A common mistake is to use a single-level expand for many-to-many relationships. The association entity is an intermediate layer that must be expanded separately. If you write `expand: [name: systemRequirements]` without the nested expand to `systemRequirement`, the sheet will show the association objects rather than the target entities.
## Storage Mechanisms
The `storage` property determines how Powersheet persists relationships in Polarion. The only supported storage mechanism is `linkedWorkItems`, which uses Polarion's native link mechanism. The relationship is stored as a typed link between work items, identified by the `linkRole` property.
The `linkRole` must match a link role defined in the Polarion project configuration. Common link roles include `parent`, `refines`, `decomposes`, `verifies`, and `mitigates`.
## The Three-Layer Connection
Entity types and relationships form just the first layer. Understanding how the three configuration layers connect is essential for building working sheets:
1. **Data model** -- Defines entity types and relationships with navigation property names
2. **Sources** -- Define how to query and expand those relationships using the navigation property names
3. **Columns** -- Define how to display the resulting data using binding paths that follow the navigation property chain
The navigation property names defined in `direct` and `back` are the glue. The same name appears in the data model relationship, the source `expand` clause, and the column binding path. If any layer uses a different name, the chain breaks.
For a deeper exploration of how sources connect to data model navigation properties, see [Source Configuration](/powersheet/concepts/source-configuration). For the reference of all relationship properties, see [Data Model Reference](/powersheet/reference/data-model/index).
## A Complete Example
Bringing all concepts together, here is a minimal but complete data model that demonstrates entity types, relationships across multiple cardinality patterns, and the standard RTM entities:
```yaml theme={null}
domainModelTypes:
Chapter:
polarionType: heading
UserNeed:
polarionType: user_need
properties:
description:
severity:
SystemRequirement:
polarionType: sys_req
properties:
description:
severity:
DesignRequirement:
polarionType: des_req
properties:
description:
relationships:
- from: UserNeed
to: Chapter
cardinality: many-to-one
storage: linkedWorkItems
linkRole: parent
direct:
name: chapter
back:
name: userNeeds
- from: SystemRequirement
to: UserNeed
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds
back:
name: systemRequirements
```
This model defines four entity types and two relationships. `Chapter` entities group `UserNeed` items (many-to-one), while `SystemRequirement` and `UserNeed` share a many-to-many traceability link. Each relationship declares both `direct` and `back` navigation properties, enabling sheets to traverse the hierarchy from either direction.
**Start simple and extend**
New users should begin with a minimal single-entity configuration and extend gradually. Jumping straight to complex multi-entity models with multiple relationship types leads to hard-to-diagnose errors. Add one entity type and one relationship at a time, verifying each addition works correctly in the sheet before adding the next.
## Common Misconceptions
**"Every entity type needs properties"** -- Not true. An entity type can be declared with no properties at all. It will still participate in relationships and appear in the sheet hierarchy. Properties only need to be declared for fields you want to expose as columns.
**"Relationships are always bidirectional"** -- While Powersheet creates navigation properties in both directions (`direct` and `back`), not every sheet needs to use both. A sheet starting from `UserNeed` may only use the `direct` navigation to `SystemRequirement` without ever traversing the `back` direction.
**"The second linked column works the same as the first"** -- When a sheet has two different entity types linked to the same parent (for example, design outputs and design verifications both linked to system requirements), the second linked column must be declared with `multiItem: true` in the sheet configuration. This is a non-obvious requirement that frequently blocks new users during initial setup. See [Multi-Item Columns](/powersheet/reference/sheet-config/multi-item-columns) for details.
## Next Steps
* [Navigation Properties](/powersheet/concepts/navigation-properties) -- How navigation properties enable expansion paths and column bindings
* [Link Cardinality](/powersheet/concepts/link-cardinality) -- Detailed cardinality rules and their impact on sheet behavior
* [Data Model vs Sheet Configuration](/powersheet/concepts/data-model-vs-sheet-config) -- How data model and sheet configuration complement each other
* [Configure a Relationship](/powersheet/guides/data-model/configure-relationship) -- Step-by-step guide to adding relationships
# Configuration Hierarchy
Source: https://learn.nextedy.com/powersheet/concepts/global-vs-project-specific
Nextedy POWERSHEET uses YAML as the single configuration language for both data models and sheet configurations.
## The Configuration Hierarchy
Powersheet configuration operates at three scope levels, each with its own storage location in the Polarion repository:
| Scope | Storage Location | Visibility | When to Use |
| ----------------------- | ------------------------------------- | ---------------------------- | -------------------------------------------- |
| **Repository (Global)** | Global configuration directory | All projects in the instance | Shared standards, common traceability models |
| **Project Group** | Group-level configuration directory | All projects in the group | Division or program-level customizations |
| **Project** | Project-level configuration directory | Only the specific project | Project-unique layouts, experiments |
This three-tier structure applies equally to both **data models** (entity types and relationships) and **sheet configurations** (column layout, views, formatters, sources).
Think of it like CSS specificity: the most specific scope wins. A project-level configuration always takes precedence over a global one when both are candidates for the same document.
## The Two Configuration Layers
Powersheet relies on two distinct YAML files that serve complementary roles. Think of it like a blueprint: the **data model** defines *what types of rooms exist and how they connect*, while the **sheet configuration** defines *how each room looks and what furniture it contains*.
**Data model** (`domainModelTypes`, `relationships`) -- Defines the semantic layer: entity types -- for example, `UserNeed`, `SystemRequirement`, and `DesignRequirement` in an RTM model -- their properties, and how they relate to each other. Managed through **Administration > Nextedy Powersheet > Data Models**. One data model can be shared across many sheet configurations.
**Sheet configuration** (`columns`, `views`, `styles`, `sources`) -- Defines the presentation layer: which columns appear, how they are styled, what data sources to query, and what views are available. Stored as a YAML file associated with a specific powersheet document via the `nextedySheetConfig` custom field.
**Reusability through separation**
Because the data model and sheet configuration are separate files, you can reuse the same data model across different sheet configurations. For example, one RTM model can power both a requirements traceability sheet and a risk analysis sheet -- each with different columns and views.
## Why a Layered Hierarchy Matters
In enterprise environments, multiple Polarion projects often share the same engineering methodology. A medical device program might have separate projects for hardware, software, and system integration, but all three follow the same traceability model -- for example, `UserNeed` to `SystemRequirement` to `DesignRequirement` to `Hazard` to `RiskControl`. Without a global scope, administrators would need to duplicate identical data models and sheet configurations in every project.
The hierarchy addresses three organizational realities:
**Consistency at scale.** A global data model ensures that all projects use the same entity types, relationship definitions, and property names. When compliance auditors review traceability across projects, the structure is uniform.
**Local flexibility.** Individual projects may need to map entity types to different Polarion work item types (different `polarionType` values), add project-specific columns, or experiment with new layouts before standardizing.
**Incremental rollout.** New configurations can be tested at project level, promoted to project group level once proven, and eventually elevated to global scope for organization-wide adoption.
## What Gets Scoped: The Two Configuration Layers
Powersheet manages two distinct types of configuration files, and both follow the same scoping rules:
### Data Models
Data models define entity types, their properties, relationships, and cardinality. A global data model establishes the canonical traceability structure. Project-specific data models can:
* Map the same entity types to different Polarion work item types via `polarionType`
* Add relationships unique to a single project
* Define project-specific constraints for picker filtering (e.g., restricting `moduleFolder` or `type` in the `pick` section)
When a sheet configuration references a data model by name through its `sources` section, Powersheet resolves that name against both global and project-level directories.
### Sheet Configurations
Sheet configurations define columns, column groups, views, formatters, sort order, and source expansion paths. A global sheet configuration provides a standard layout; project-specific configurations can modify column visibility, add custom columns, or define different conditional formatting rules.
The `SheetConfigEnumProvider` dynamically discovers available configuration files and presents them in the picker on each Powersheet document:
* **Global configurations**: ID starts with `/`, display name includes a `(Global)` suffix
* **Project-specific configurations**: ID is the filename without path, display name is the filename without extension
All discovered configurations from both scopes appear together in the same picker list.
## How Configuration Resolution Works
Understanding the resolution process is critical for predicting which configuration a document will use. Here is the sequence:
1. **A Powersheet document loads.** The document has a custom field (`nextedySheetConfig`) that stores the selected sheet configuration identifier.
2. **The configuration service resolves the identifier.** If the identifier starts with `/`, the service looks in the global configuration directory. Otherwise, it looks in the project-specific directory.
3. **The sheet configuration references a data model by name.** The `sources.model` property in the YAML points to a model name (not a file path).
4. **The model is resolved.** Powersheet scans both global and project-specific model directories. If a model with the same name exists at both levels, the project-specific model takes precedence for that project.
**Common Misconfiguration**
The `sources.model` property must match the **name** of the model file, not a default value like `rtm`. New users frequently leave this as the default, causing the sheet to fail to connect to the correct data model. Always verify that the model name in your sheet configuration matches an actual model file at either the global or project level.
### The Picker Experience
When a user opens a Powersheet document and selects a configuration, the picker shows a combined list:
| Display Name | Source | ID Format |
| ----------------------- | ----------------- | ---------------- |
| `rtm-standard (Global)` | Global directory | `/rtm-standard` |
| `medical-rtm (Global)` | Global directory | `/medical-rtm` |
| `project-custom` | Project directory | `project-custom` |
| `pilot-layout` | Project directory | `pilot-layout` |
The `(Global)` suffix is the visual signal that a configuration is shared. Project-specific files appear by filename alone.
**No Default Configuration**
Powersheet does not define a default sheet configuration. Each document must have a configuration explicitly selected. If the `nextedySheetConfig` field is empty, the document will not render a sheet.
## Administration at Each Scope Level
Powersheet integrates into Polarion's native administration interface, adding pages under **Administration > Nextedy Powersheet** for:
* **Data Models** -- manage data model YAML files
* **Sheet Configurations** -- manage sheet configuration YAML files
* **Setup** -- initial Powersheet configuration
* **License** -- license management
Each administration page is available at all three scope levels: project, project group, and repository (global). The scope is determined by where the administrator navigates in Polarion's administration hierarchy before opening the Powersheet section.
The embedded file manager interface supports creating, editing, and deleting YAML files within the selected scope. When editing at repository scope, changes affect all projects that reference global configurations.
## Propagating Changes Across Projects
One of the key advantages of global configurations is centralized updates. When you modify a global data model or sheet configuration, every project that references it picks up the change on next load -- no per-project edits required.
However, this also means that a breaking change in a global configuration can affect every project simultaneously. Consider these strategies:
**Staged rollout.** Create a new version of the configuration at project level first. Test it in a pilot project. Once validated, promote it to global scope.
**Naming conventions.** Use versioned names for global configurations (e.g., `rtm-v2`, `rtm-v3`) so that projects can opt in to new versions at their own pace rather than being forced into an immediate upgrade.
**Project-level overrides as safety nets.** If a project has unique needs that might conflict with global changes, define a project-specific configuration. It will always take precedence over the global one, insulating the project from upstream changes.
**Project Group Scope**
The project group scope provides a middle ground. If your organization uses Polarion project groups to organize related projects (e.g., all projects in a product line), you can define configurations at the group level. These override global configurations but are themselves overridden by project-level configurations.
## Configuration Hierarchy Decision Matrix
Use this matrix to decide where to place your configuration files:
| Question | If Yes | If No |
| -------------------------------------------------- | ----------------------------- | --------------------------- |
| Will more than one project use this configuration? | Global or Project Group | Project |
| Does it define a standard traceability model? | Global | Project Group or Project |
| Is it an experiment or prototype? | Project | Promote later if successful |
| Does it need to override a global standard? | Project (same name overrides) | Use global as-is |
| Is it specific to a product line or division? | Project Group | Global or Project |
## The Role of Project-Specific Properties
Beyond YAML configuration files, Powersheet reads project-level properties from Polarion's configuration system. These properties control runtime behavior and are always project-specific (not subject to the global/project hierarchy):
| Property | Purpose | Default Behavior |
| ---------------------------- | ------------------------------------------------------------------- | ---------------------------------------------------------- |
| Powersheet document query | Lucene query identifying which documents appear in Powersheet Drive | Searches for documents with `nextedySheetConfig` populated |
| Sheet configuration field ID | Custom field linking documents to their configuration | `nextedySheetConfig` |
| Open button title | Text displayed on the "Open in Powersheet" button | Customizable per project for branding |
| Template document query | Query to identify template documents for duplication | Same as document query by default |
These properties are configured through Polarion's standard project properties mechanism, separate from the YAML file management interface.
## Common Misconceptions
**"Project configurations inherit from global and merge."** This is not how it works. Powersheet does not merge a global model with a project model. If a project defines its own model file with the same name, the entire project-level file replaces the global one for that project. There is no property-level merging.
**"I need to copy the global configuration to customize it."** Not necessarily. You can create a completely new project-specific configuration with a different name. The document's `nextedySheetConfig` field determines which configuration is used -- you simply select the project-specific one instead of the global one.
**"Global configurations are read-only."** Global configurations are fully editable at repository scope in the administration interface. However, editing them requires repository-level administration access, which is typically restricted to system administrators.
## Configuration Editor Scopes
Beyond the repository-level hierarchy (global, project group, project), the configuration editor exposes three additional scope levels within a single document:
* **Instance** -- A per-document override. Changes at this level apply only to the specific Powersheet document being edited.
* **Template** -- Template-level defaults. When a document is created from a template, it inherits these settings.
* **Default** -- The global baseline from the YAML file itself.
This layered approach means teams can share a base configuration while allowing individual documents to override specific settings without modifying the shared file.
**Configuration is YAML, not JSON**
Although some internal field names reference JSON for historical reasons, all user-facing configuration files use YAML syntax. The configuration editor supports both formats and can convert between them, with YAML as the preferred language.
## Key YAML Patterns
### Columns Use Dot-Notation Binding Paths
Column keys in the sheet configuration use dot-separated paths that trace the expansion path through entity relationships:
```yaml theme={null}
columns:
title:
title: Title
width: 200
systemRequirements.systemRequirement.title:
title: System Req Title
width: 180
```
The binding path `systemRequirements.systemRequirement.title` means: follow the `systemRequirements` expansion, select the `systemRequirement` entity, and display its `title` property.
### Styles and Anchors Reduce Repetition
YAML anchors (`&`) and aliases (`*`) allow you to define a style once and reuse it across multiple columns:
```yaml theme={null}
styles:
readOnlyStyle:
backgroundColor: 'grey100'
columns:
outlineNumber:
title: "#"
width: 80
header:
style: darkgrey
```
Powersheet provides predefined header styles such as `red`, `blue`, `green`, `purple`, and their variants (`darkred`, `lightblue`, etc.) that map to the built-in design token palette.
### Column Groups Organize Related Columns
The `columnGroups` section visually groups related columns under a shared header with optional collapse behavior:
```yaml theme={null}
columnGroups:
epic:
groupName: Epics
groupStyle: darkgreen
headerStyle: green
collapseTo: title
```
## Practical Example: Multi-Project Setup
Consider an organization with three projects sharing a medical device traceability model:
* **Global data model** (`medical-rtm`): Defines `UserNeed`, `SystemRequirement`, `DesignRequirement`, `Hazard`, and `RiskControl` entity types with standard relationships
* **Global sheet configuration** (`medical-standard`): Standard column layout with traceability columns, risk assessment groups, and compliance views
* **Project HW** uses `medical-standard (Global)` as-is
* **Project SW** uses `medical-standard (Global)` but adds a project-specific data model that maps `DesignRequirement` to a different Polarion work item type
* **Project Integration** defines its own `integration-layout` sheet configuration with additional cross-reference columns, while still using the global `medical-rtm` data model
Each project selects its configuration through the document-level picker. The global configurations provide the baseline, and projects customize only what they need.
## Related Pages
* [YAML Configuration System](/powersheet/concepts/yaml-configuration) -- how YAML configuration files are structured and parsed
* [Data Model vs Sheet Configuration](/powersheet/concepts/data-model-vs-sheet-config) -- understanding the two configuration layers
* [Source Configuration](/powersheet/concepts/source-configuration) -- how sources reference data models by name
* [Powersheet Architecture](/powersheet/concepts/architecture) -- where configuration fits in the overall system
* [Core Components](/powersheet/concepts/core-components) -- the building blocks that consume configuration
* [Creating Your First Sheet Configuration](/powersheet/getting-started/first-sheet-configuration) -- hands-on tutorial for building your first sheet configuration
* [Creating Your First Data Model](/powersheet/getting-started/first-data-model) -- step-by-step tutorial for data model setup
For practical guidance on working with configurations at different scopes, see:
* [Assign Configuration to Document](/powersheet/guides/sheet-configuration/assign-config-to-document) -- selecting a configuration for a Powersheet document
* [Administration Guides](/powersheet/guides/administration/index) -- managing configurations across projects
# Hierarchy and Traceability
Source: https://learn.nextedy.com/powersheet/concepts/hierarchy-and-traceability
Nextedy POWERSHEET is well-suited for organizations that manage structured hierarchical data -- whether tracing requirements across abstraction levels, managing risk analyses, or organizing any domain with nested parent-child structure.
## The Traceability Challenge
Polarion stores traceability as individual links between work items. While each link is correct in isolation, understanding the full chain -- from a user need through system requirements to design requirements to hazards to risk controls -- requires mentally assembling dozens of separate work item views. This is like reading a book one sentence at a time from different chapters: technically possible, but practically unusable for analysis.
Powersheet solves this by rendering the entire traceability chain as a single hierarchical sheet, where parent-child nesting shows the relationships and every level is editable in place.
## How Hierarchy Maps to the Data Model
The hierarchy displayed in a Powersheet sheet is defined by two configuration layers working together:
1. **Data model** -- defines entity types (e.g., `UserNeed`, `SystemRequirement`, `DesignRequirement`) and the `relationships` between them, including cardinality, storage mechanism, and navigation property names
2. **Sheet configuration** -- defines which columns to show, how to sort and group rows, and which `sources` with `expand` clauses to use for loading related entities
The data model provides the structural skeleton. The sheet configuration decides which parts of that skeleton to display and how.
## Row Levels and Expansion Paths
When a sheet loads data, it starts with a root entity type (defined by `sources[].query.from`) and follows **expansion paths** to load related entities. Each expansion creates a new row level in the hierarchy:
* **Level 0 (upstream)** -- the root entity (e.g., `UserNeed`). Always present, with no back reference.
* **Level 1 (downstream)** -- first-level related entities (e.g., `SystemRequirement`), loaded by expanding a navigation property.
* **Level 2+** -- deeper related entities (e.g., `DesignRequirement`), loaded by nested expansions.
Each downstream level maintains a **back reference** to its parent navigation property, preserving the parent-child relationship for rendering and editing.
```yaml theme={null}
sources:
- id: rtm
title: Requirements Traceability
model: rtm
query:
from: UserNeed
expand:
- name: systemRequirements
title: System Requirements
expand:
- name: designRequirements
title: Design Requirements
```
The nested `expand` structure mirrors the hierarchy you want to see in the sheet. Each `name` must reference a navigation property defined in the data model `relationships` section.
## Cardinality and Row Nesting
The `cardinality` of each relationship determines how many child rows appear beneath a parent:
| Cardinality | Behavior in Sheet |
| -------------- | ----------------------------------------------------------------------------------- |
| `one-to-many` | Parent row expands to show multiple child rows |
| `many-to-one` | Multiple parent rows share a single child reference |
| `many-to-many` | Parent row expands to multiple children; children may appear under multiple parents |
| `one-to-one` | Parent row has exactly one child row |
Most traceability relationships use `one-to-many` or `many-to-many`, as requirements typically refine into multiple downstream items and can be traced to multiple upstream sources.
**Practical Rule**
The `one-to-many` cardinality is the most common for traceability chains. A single `UserNeed` typically decomposes into multiple `SystemRequirement` items, each of which may decompose into multiple `DesignRequirement` items.
## Column Binding Paths Across Levels
Columns in the sheet configuration use dot-separated **binding paths** that traverse navigation properties to reach properties on related entities. The binding path determines which row level the column belongs to:
```yaml theme={null}
columns:
# Level 0: UserNeed properties
title:
title: User Need
width: 250
hasFocus: true
# Level 1: SystemRequirement properties
systemRequirements.systemRequirement.title:
title: System Requirement
width: 200
# Level 2: DesignRequirement properties
systemRequirements.systemRequirement.designRequirements.designRequirement.title:
title: Design Requirement
width: 200
```
## Relationships and Polarion Link Roles
Every relationship in the data model maps to a Polarion **link role** via the `linkRole` property. The link role must exist in your Polarion project configuration. The `storage` property (typically `linkedWorkItems`) specifies that the relationship is persisted using Polarion's native work item linking mechanism.
```yaml theme={null}
relationships:
- from: UserNeed
to: SystemRequirement
cardinality: one-to-many
storage: linkedWorkItems
linkRole: refines
direct:
name: systemRequirements
back:
name: userNeed
```
**Entity Names vs Work Item Types**
The `from` and `to` values in relationships must reference `domainModelTypes` names -- not Polarion work item type IDs. This is a common source of configuration errors.
## Constraints and Scoping
Entity types can define `constraints` that scope which items appear at each level of the hierarchy. Constraints support three operations:
* **`load`** -- filters which entities are loaded and displayed
* **`create`** -- restricts where new entities can be created (by document folder, name, or type)
* **`pick`** -- filters which entities appear in relationship pickers
These constraints ensure that the traceability hierarchy reflects your process requirements -- for example, ensuring that `SystemRequirement` items can only be picked from documents of a specific type.
**Verify in application**
The interaction between constraints defined at the entity type level and constraints defined on navigation properties should be verified against your specific data model, as constraint resolution follows a layered evaluation approach.
## Related Pages
* [Navigation Properties](/powersheet/concepts/navigation-properties) -- how traversal between entity types works
* [Entity Types and Relationships](/powersheet/concepts/entity-types-and-relationships) -- defining the data model structure
* [Link Cardinality](/powersheet/concepts/link-cardinality) -- understanding relationship multiplicity
* [Process Constraints](/powersheet/concepts/process-constraints) -- enforcing rules through data model constraints
* [Model-Driven Design](/powersheet/concepts/model-driven-design) -- why the data model drives the sheet behavior
# Concepts
Source: https://learn.nextedy.com/powersheet/concepts/index
Nextedy POWERSHEET is built on a set of interconnected design principles that separate data structure from presentation and enforce process rules through configuration.
## Architecture and Design
**[Powersheet Architecture](/powersheet/concepts/architecture)** -- How the server extension, client application, and YAML configuration layers fit together inside Siemens Polarion ALM.
**[Core Components](/powersheet/concepts/core-components)** -- The four building blocks of every powersheet: data model, sheet configuration, Powersheet Drive, and the document entry point.
**[Model-Driven Design](/powersheet/concepts/model-driven-design)** -- Why Powersheet uses a declarative data model to abstract Polarion work item types and link roles into a portable configuration layer.
## Configuration
**[Data Model vs Sheet Configuration](/powersheet/concepts/data-model-vs-sheet-config)** -- Understanding the separation between what data exists (data model) and how it is displayed (sheet configuration).
**[Configuration Hierarchy](/powersheet/concepts/global-vs-project-specific)** -- How YAML configuration files are discovered and loaded, scoping rules for global vs project-specific storage, and key YAML patterns used in sheet configurations.
## Data Modeling
**[Entity Types and Relationships](/powersheet/concepts/entity-types-and-relationships)** -- Defining `domainModelTypes`, mapping them to Polarion work item types, and declaring relationships with `from`, `to`, `cardinality`, and `linkRole`.
**[Navigation Properties](/powersheet/concepts/navigation-properties)** -- How `direct` and `back` create traversable paths used in expansion paths and column binding paths.
**[Link Cardinality](/powersheet/concepts/link-cardinality)** -- The meaning of `one-to-one`, `many-to-one`, `one-to-many`, and `many-to-many` cardinality values and how they affect the sheet UI.
**[Hierarchy and Traceability](/powersheet/concepts/hierarchy-and-traceability)** -- How expansion paths let you navigate multi-level entity hierarchies such as, for example, `UserNeed` to `SystemRequirement` to `DesignRequirement` in an RTM model.
## Constraints and Rules
**[Process Constraints](/powersheet/concepts/process-constraints)** -- Enforcing engineering methodology through `load`, `create`, and `pick` constraints that go beyond what Polarion provides natively.
**[Document Rules](/powersheet/concepts/document-rules)** -- Restricting where work items can be created or selected using `moduleFolder`, `moduleName`, `type`, and `component` constraints.
## Platform Integration
**[Polarion Integration](/powersheet/concepts/polarion-integration)** -- How Powersheet embeds inside Polarion, registers administration pages, and stores configuration in SVN.
**[Admin AI Assistant](/powersheet/concepts/admin-ai-assistant)** -- The documentation-grounded chat in the configuration editor: how it stays grounded in the documentation, what it needs to be available, and the browser-based authentication flow behind it.
**Where to start**
If you are new to Powersheet, begin with [Powersheet Architecture](/powersheet/concepts/architecture) and [Core Components](/powersheet/concepts/core-components) to build a mental model of the system. Then move to [Entity Types and Relationships](/powersheet/concepts/entity-types-and-relationships) to understand the data model that drives everything else.
## See Also
* [Getting Started](/powersheet/getting-started/index) -- Hands-on tutorials for your first data model and sheet configuration
* [Reference](/powersheet/reference/index) -- Complete YAML property reference for data models and sheet configurations
* [FAQ](/powersheet/faq/index) -- Answers to common configuration and setup questions
# Link Cardinality
Source: https://learn.nextedy.com/powersheet/concepts/link-cardinality
In Nextedy POWERSHEET, **link cardinality** defines how many instances of one entity type can be related to another.
## Why Cardinality Matters
Siemens Polarion ALM allows any work item to link to any number of other work items through link roles. This open-ended flexibility means Polarion itself does not enforce limits like "a hazard must link to at least one risk control" or "a system requirement should derive from exactly one user need."
Powersheet's data model introduces cardinality as a semantic layer on top of Polarion's link roles. Think of it like database schema design: just as a relational database enforces foreign key constraints, Powersheet's cardinality settings enforce relationship multiplicity in the user interface.
## Cardinality Options
The `cardinality` property on a relationship definition accepts the following supported values:
| Cardinality | From Side | To Side | Typical Use Case |
| -------------- | --------- | -------- | ------------------------------------------------------- |
| `many-to-one` | Multiple | Single | Many design reqs derive from one system req |
| `one-to-many` | Single | Multiple | One user need decomposes into many system reqs |
| `many-to-many` | Multiple | Multiple | Hazards linked to multiple risk controls and vice versa |
**one-to-one is not currently supported**
Although `one-to-one` appears conceptually in the diagram above, it is not a supported cardinality value in the current Powersheet data model. Use `many-to-one` when you need a single-valued reference on the "from" side, or model uniqueness through validation rather than cardinality.
## How Cardinality Is Defined
Cardinality is set on each relationship in the `relationships` array of the data model YAML:
```yaml theme={null}
relationships:
- from: UserNeed
to: SystemRequirement
cardinality: one-to-many
storage: linkedWorkItems
linkRole: refines
direct: systemRequirements
back: userNeed
```
In this example, one `UserNeed` can link to many `SystemRequirement` items (one-to-many). The `direct` becomes a collection-valued property on `UserNeed`, while `back` becomes a single-valued property on `SystemRequirement`.
## Impact on the User Interface
Cardinality directly controls the sheet's editing behavior:
* **Single-value relationships** (the "one" side) display a single-select picker. The user can choose exactly one target entity.
* **Multi-value relationships** (the "many" side) display a multi-select picker. The user can select multiple related entities.
**Cardinality is directional**
A `many-to-one` relationship means the "from" entity can reference exactly one "to" entity, but the "to" entity can be referenced by many "from" entities. The navigation property on the "from" side is single-valued; the navigation property on the "to" side (via `back`) is collection-valued.
## Cardinality and Polarion Link Roles
Polarion link roles are inherently many-to-many -- any work item can create any number of links using a given role. Powersheet's cardinality setting does not change this at the Polarion level; instead, it enforces the constraint at the UI and validation level within the sheet.
This means:
* If a relationship is defined as `many-to-one`, the sheet will present a single-value picker and prevent users from creating additional links through the powersheet
* Links created outside Powersheet (via Polarion's native UI) are not retroactively constrained
**Verify in application**
The exact enforcement behavior for cardinality violations (whether existing extra links are hidden or shown with a warning) may vary. Test with your configuration to confirm.
## Common RTM Cardinality Pattern
A typical Requirements Traceability Matrix uses the following cardinality chain:
| From | To | Cardinality | Link Role |
| ------------------- | ------------------- | -------------- | ----------- |
| `UserNeed` | `SystemRequirement` | `one-to-many` | `refines` |
| `SystemRequirement` | `DesignRequirement` | `one-to-many` | `refines` |
| `Hazard` | `RiskControl` | `many-to-many` | `mitigates` |
This creates a hierarchy where each upstream requirement can decompose into multiple downstream items, while hazard-to-control relationships remain flexible.
## Related Pages
* [Entity Types and Relationships](/powersheet/concepts/entity-types-and-relationships) -- How entity types and relationships are structured
* [Process Constraints](/powersheet/concepts/process-constraints) -- Additional rules for loading, creating, and picking entities
* [Creating Your First Data Model](/powersheet/getting-started/first-data-model) -- Hands-on tutorial for setting up cardinality
***
# Model-Driven Design
Source: https://learn.nextedy.com/powersheet/concepts/model-driven-design
Nextedy POWERSHEET follows a **model-driven design** pattern: the structure and behavior of every sheet is determined by a declarative YAML data model rather than imperative code.
## The design principle
In a model-driven system, configuration files describe **what** should happen, not **how** it should happen. The data model declares entity types, their properties, and their relationships. The Powersheet runtime reads this declaration and automatically generates the metadata, queries, pickers, and validation rules needed to render and edit the data.
This is the opposite of a code-driven approach where each new entity type or relationship would require custom development. With Powersheet, adding a new entity type is a YAML change, not a code change.
Think of it like a building blueprint. The blueprint (data model) specifies which rooms exist, how they connect, and what each room contains. The construction crew (Powersheet runtime) reads the blueprint and builds everything accordingly. If you want to add a new room, you update the blueprint rather than writing new construction instructions from scratch.
## The three configuration layers
Powersheet's model-driven architecture rests on three distinct configuration layers that work together. Understanding how they connect is essential for building effective sheets.
| Layer | File | Purpose |
| ----------------------- | --------------------------- | --------------------------------------------------- |
| **Data model** | `model.yaml` | Defines entity types, properties, and relationships |
| **Sheet configuration** | `powersheet.yaml` | Defines columns, views, formatters, and sources |
| **Polarion project** | Link roles, work item types | Provides the underlying data infrastructure |
The data model sits between Polarion and the sheet configuration. It maps Polarion's native concepts (work item types, link roles, custom fields) into a consistent vocabulary of entity types and navigation properties. The sheet configuration then references that vocabulary without needing to know the Polarion-level details.
The navigation property names are the thread that connects these layers. A relationship defined in the data model creates a named navigation property. The sheet sources use that same name to expand into related data. The sheet columns use it to bind and display values. If any layer uses a different name, the connection breaks.
## From YAML to metadata
When a powersheet document is opened, the data model YAML is processed through a metadata generation pipeline. Each `domainModelTypes` entry becomes an entity type with:
* A primary key property (`objectId`)
* A `polarionType` property linking to the Polarion work item type
* Built-in properties: `title`, `icon`, and automatically added document and project navigation properties
* Custom properties from the `properties` section, each mapped to Polarion work item fields
Here is a minimal data model showing how entity types are declared:
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
description:
severity:
SystemRequirement:
polarionType: sys_req
properties:
description:
severity:
```
Each key under `domainModelTypes` (like `UserNeed`) becomes the entity type name used throughout the rest of the configuration. The `polarionType` maps it to the corresponding Polarion work item type. Properties listed under `properties` become available as columns in the sheet.
### Relationships and navigation properties
Relationships define how entity types connect to each other. Each relationship specifies:
* **`from` / `to`** -- the source and target entity types
* **`cardinality`** -- the multiplicity (many-to-one, one-to-many, many-to-many)
* **`storage`** -- how the link is persisted in Polarion (`linkedWorkItems` is the only supported storage mechanism)
* **`linkRole`** -- the Polarion link role that implements the connection
* **`direct` / `back`** -- the navigation property names for forward and reverse traversal
```yaml theme={null}
relationships:
- from: SystemRequirement
to: UserNeed
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds
back:
name: systemRequirements
```
In this example, the relationship creates two navigation properties:
* `direct.name: userNeeds` -- navigate from a `SystemRequirement` to its linked `UserNeed` items
* `back.name: systemRequirements` -- navigate from a `UserNeed` to its linked `SystemRequirement` items
**Use direct/back syntax**
The `direct` and `back` object notation is the current relationship syntax. Each contains a `name` field specifying the navigation property. This syntax replaced an earlier flat format and is the only supported approach.
### Built-in entity types
Two built-in entity types are always available regardless of the data model configuration:
| Entity type | Purpose |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `Document` | Represents Polarion modules (LiveDocs). Exposes properties like `moduleName`, `moduleFolder`, `title`, `titleOrName`, `titleWithSpace`, and `allowedWITypes` |
| `Project` | Represents Polarion projects. Automatically linked to all work item entity types |
These built-in types enable features like document-scoped filtering in picker constraints and project-level navigation without any explicit configuration.
## The mapping layer
A key advantage of model-driven design is that the data model acts as a **mapping layer** between Polarion's native data structures and the Powersheet view. This is significant because:
* **Different projects can have different Polarion type names** for the same conceptual entity. The data model normalizes these: one project's `sys_requirement` and another's `systemReq` can both map to a `SystemRequirement` entity type in the data model.
* **Link roles vary between projects.** The data model abstracts them behind navigation property names, so the sheet configuration remains identical.
* **A single sheet configuration can be reused across projects** that share the same data model structure but differ in Polarion-level details.
**Why two separate files?**
This mapping layer is why the data model and sheet configuration are separate files. The data model handles project-specific Polarion mappings. The sheet configuration handles presentation and interaction. You can pair one data model with multiple sheet configurations, or update the Polarion mappings without touching the column layout.
## How cardinality shapes the sheet
The `cardinality` of a relationship determines how data flows through sources, how columns bind to properties, and what users see in the sheet. This is perhaps the most important concept for understanding how model-driven design translates into a working UI.
| Cardinality | Model definition | Source expand | Column binding | UI behavior |
| ----------- | ------------------------------------------------------------ | ------------------------------------------------------------- | -------------------------------------- | -------------------------------- |
| **N:1** | `cardinality: many-to-one`, `direct.name: chapter` | `- name: chapter` | `chapter`, `chapter.title` | Single-value reference picker |
| **1:N** | Reverse of N:1, `back.name: userNeeds` | `- name: userNeeds` | `userNeeds` | Child rows (new hierarchy level) |
| **M:N** | `cardinality: many-to-many`, `back.name: systemRequirements` | `- name: systemRequirements` then `- name: systemRequirement` | `systemRequirements.systemRequirement` | Multi-item reference picker |
### Many-to-one: scalar references
When an entity has a many-to-one relationship (each `UserNeed` belongs to exactly one `Chapter`), the navigation property is scalar. The source expands it with a single name, and columns can either display a picker for the reference or read through to display properties of the referenced entity:
```yaml theme={null}
columns:
chapter:
title: Chapter
display: title
list:
search:
- title
chapter.title:
title: Chapter Title
isReadOnly: true
```
### One-to-many: hierarchical expansion
The reverse side of a many-to-one relationship is one-to-many. This is where Powersheet's hierarchical nature becomes visible. When a `Chapter` expands into its `userNeeds`, each child `UserNeed` appears as a nested row under the parent. The expand creates a new level in the sheet hierarchy.
### Many-to-many: association entities
Many-to-many relationships use an **association entity** between the two types. The source expand goes through two levels -- first the association collection, then the target entity. The column binding uses dot-notation to reach through:
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: systemRequirement
columns:
systemRequirements.systemRequirement:
title: System Requirement
list:
search:
- objectId
- title
createNew: true
```
The two-level expand (`systemRequirements` then `systemRequirement`) and the dot-notation column key (`systemRequirements.systemRequirement`) are the telltale signs of a many-to-many relationship. When a sheet has two different work item types linked to the same parent entity, the second linked column must declare `multiItem: true` in the sheet configuration.
**Reading a column key**
A dot-separated column key like `systemRequirements.systemRequirement.title` reads as: "Starting from the current entity, follow the `systemRequirements` navigation property (association collection), then follow `systemRequirement` (target entity), then display the `title` property." Each segment maps to a relationship or property defined in the data model.
## Constraints and picker filtering
The data model also drives **picker constraints** -- rules that filter which items appear when a user selects a related entity. Constraints can restrict picker results by:
* **Document location** (`moduleFolder`, `moduleName`) -- limit selections to items in specific spaces
* **Document type** (`type`) -- only show items from documents of a certain type
* **Component** (`component`) -- scope selections to the same component as the source entity using `$context.source.document.component`
```yaml theme={null}
domainModelTypes:
SystemRequirement:
polarionType: sys_req
constraints:
pick:
document:
moduleFolder: Requirements
type: requirements_specification
```
This constraint means that when a user picks a `SystemRequirement` in the sheet, the picker only shows items from documents in the `Requirements` space that have the `requirements_specification` document type. The runtime applies these filters automatically based on the model declaration.
**Verify in application**
Dynamic context references like `$context.source.document.component` resolve at runtime based on the current entity's document context. The exact behavior depends on the project's component configuration in Polarion.
## Why model-driven design matters
The model-driven approach delivers several practical benefits that become increasingly valuable as configurations grow in complexity:
**Consistency across the organization.** Because the data model is a single YAML file shared across sheet configurations, all sheets that reference the same model use identical entity definitions, relationship rules, and navigation properties. Changes propagate automatically.
**Separation of concerns.** Polarion administrators manage work item types and link roles. Data model authors map those to a clean entity vocabulary. Sheet designers compose columns and views without worrying about Polarion internals. Each role works at the appropriate level of abstraction.
**Reduced configuration errors.** New users frequently encounter issues when jumping straight to complex multi-entity configurations. The model-driven pattern encourages an incremental approach: define one entity type, verify it works, then add relationships one at a time. Each addition is a self-contained YAML block that can be validated independently.
**Reusability across projects.** A well-designed data model can serve multiple Polarion projects by updating only the `polarionType` and `linkRole` mappings. The sheet configurations, sources, and column bindings remain unchanged because they reference entity type names and navigation properties, not Polarion-specific identifiers.
For a detailed comparison of the data model and sheet configuration files, see [Data Model vs Sheet Configuration](/powersheet/concepts/data-model-vs-sheet-config). To understand how entity types and relationships are structured in practice, see [Entity Types and Relationships](/powersheet/concepts/entity-types-and-relationships). For hands-on configuration guidance, see the [Data Model Guides](/powersheet/guides/data-model/index).
# Navigation Properties
Source: https://learn.nextedy.com/powersheet/concepts/navigation-properties
Nextedy POWERSHEET uses **navigation properties** to connect entity types within a data model, enabling the sheet to traverse relationships and display hierarchical data across multiple levels.
## What Navigation Properties Are
A **navigation property** is a named reference on an entity type that points to one or more related entities of a different type. When you define a relationship between two entity types in your data model, Powersheet automatically generates navigation properties on both sides of the relationship. These properties become the building blocks for column binding paths in your sheet configuration and for expansion paths in your data sources.
For example, when you define a relationship from `UserNeed` to `SystemRequirement`, two navigation properties are created:
* A **forward (direct) property** on `UserNeed` pointing to its related `SystemRequirement` entities
* A **backward (back) property** on `SystemRequirement` pointing back to the originating `UserNeed`
Navigation properties do not store data themselves. They are computed references that Powersheet resolves at runtime by querying Polarion link roles. The data model simply gives these traversal paths a name so that sheet configurations and source expansion paths can reference them consistently.
## How Navigation Properties Are Defined
Navigation properties are defined exclusively in the `relationships` section of the data model YAML. Each relationship entry creates a pair of navigation properties using `direct` and `back` notation:
```yaml theme={null}
relationships:
- from: UserNeed
to: SystemRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: refines
direct:
name: systemRequirements
back:
name: userNeed
```
The `direct` block defines the forward navigation property -- created on the `from` entity type (`UserNeed` in this example). The `back` block defines the reverse navigation property -- created on the `to` entity type (`SystemRequirement`). The property names you choose here become the segments used in binding paths and expansion paths throughout your sheet configuration.
**Naming Convention**
Navigation property names follow camelCase convention. Use a **plural** form for the "many" side of a relationship (e.g., `systemRequirements`) and a **singular** form for the "one" side (e.g., `chapter`). This naming convention signals the expected cardinality and makes configurations more readable.
## Directionality: Direct vs Back
Every relationship in a data model is inherently directional. Understanding which direction you are traversing is essential for building correct expansion paths and column bindings.
**Direct** (forward): Follows the relationship from the `from` entity to the `to` entity. If a `UserNeed` relates to a `SystemRequirement`, the direct navigation property on `UserNeed` points toward `SystemRequirement`.
**Back** (reverse): Follows the relationship in the opposite direction. The back navigation property on `SystemRequirement` points back toward `UserNeed`.
An analogy helps here: imagine a one-way street sign between two neighborhoods. The `direct` property lets you travel in the direction the sign points. The `back` property lets you travel in the opposite direction. Both directions are always available -- the data model creates doorways in both directions for every relationship.
| Direction | Defined on | Points to | Typical naming |
| --------- | ------------------ | ------------------ | ---------------------------------------- |
| `direct` | `from` entity type | `to` entity type | Plural if collection, singular if scalar |
| `back` | `to` entity type | `from` entity type | Plural if collection, singular if scalar |
The direction you choose in your source expansion determines which entity type serves as the root of your hierarchy and which entities appear as child rows.
## How Cardinality Shapes Navigation Properties
The `cardinality` of a relationship determines whether a navigation property resolves to a single entity (scalar) or a collection of entities. This distinction has direct consequences for how the sheet renders data and how you write column bindings.
### Many-to-One (N:1)
In a many-to-one relationship, the direct navigation property is **scalar** -- it points to exactly one entity. For example, each `UserNeed` belongs to exactly one `Chapter`:
```yaml theme={null}
relationships:
- from: UserNeed
to: Chapter
cardinality: many-to-one
storage: linkedWorkItems
linkRole: parent
direct:
name: chapter
back:
name: userNeeds
```
Here, `chapter` is a scalar property on `UserNeed` (each user need has one chapter), while `userNeeds` is a collection property on `Chapter` (each chapter has many user needs). In the sheet, a scalar navigation property renders as a single-value reference picker, while its reverse collection side expands into child rows.
**Source and column usage:**
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: chapter
columns:
title:
title: Title
hasFocus: true
chapter:
title: Chapter
display: title
list:
search:
- title
chapter.title:
title: Chapter Title
isReadOnly: true
```
The column `chapter` provides a single-value reference picker. The column `chapter.title` is a read-only display of the referenced Chapter's title field.
### One-to-Many (1:N)
One-to-many is the reverse perspective of many-to-one. If you query from `Chapter` and expand `userNeeds`, each chapter row gains child rows for its user needs. The `back` property `userNeeds` acts as the collection side:
```yaml theme={null}
sources:
- id: chapters
query:
from: Chapter
expand:
- name: userNeeds
columns:
title:
title: Chapter
hasFocus: true
userNeeds:
title: User Need
hasFocus: true
```
The expand follows the `userNeeds` navigation property to load all related `UserNeed` entities as child rows under each chapter. No dot-notation is needed -- the expand directly opens the child level.
### Many-to-Many (M:N)
Many-to-many relationships introduce an important concept: the **association entity**. Because both sides of the relationship are collections, Powersheet uses a two-level navigation path to traverse from one entity type to another through the association.
```yaml theme={null}
relationships:
- from: SystemRequirement
to: UserNeed
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds
back:
name: systemRequirements
```
When expanding a many-to-many relationship in your sources, you specify two nested levels:
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: systemRequirement
```
The first level (`systemRequirements`) reaches the association entity. The second level (`systemRequirement`) reaches the actual target entity. This two-level pattern is reflected in column binding paths as well: `systemRequirements.systemRequirement`.
**Two-Level Expansion Required for M:N**
Many-to-many relationships always require a two-level expansion in your sources configuration. If you only expand one level, you will reach the association entity but not the actual target entity, resulting in empty or incorrect column data.
## The Three Layers: Model, Source, Columns
Navigation properties form the connective tissue between three configuration layers. Understanding how these layers reference each other is fundamental to working with Powersheet.
**Data model** defines the relationships and assigns navigation property names via `direct.name` and `back.name`. This layer answers: "What entities exist and how are they related?"
**Sources** use navigation property names in `expand` blocks to tell Powersheet which related entities to load. This layer answers: "What data should the sheet fetch?"
**Columns** use dot-notation binding paths built from navigation property names to display specific fields of related entities. This layer answers: "What should the user see?"
| Layer | Uses navigation properties for | Example |
| ---------- | ---------------------------------------- | ----------------------------- |
| Data model | Defining named traversal paths | `direct: { name: chapter }` |
| Sources | Specifying which relationships to expand | `expand: [{ name: chapter }]` |
| Columns | Building binding paths to display data | `chapter.title` as column key |
The names must match exactly across all three layers. If your model defines `direct.name: chapter` but your column references `chapters.title`, the binding will fail silently and the column will appear empty.
**Name Consistency Is Critical**
A single typo in a navigation property name can cause an entire column or expansion level to silently produce no data. Always verify that the names in your `relationships` block, `sources.expand`, and `columns` keys match exactly.
## Dot-Notation Binding Paths
Column keys in your sheet configuration use **dot-notation** to traverse navigation properties and access fields on related entities. Each dot-separated segment corresponds to one navigation property traversal.
Consider a three-level hierarchy: `UserNeed` relates to `SystemRequirement`, which relates to `DesignRequirement`:
```yaml theme={null}
columns:
title:
title: User Need
systemRequirements.systemRequirement:
title: System Requirement
systemRequirements.systemRequirement.designRequirements.designRequirement:
title: Design Requirement
```
The path `systemRequirements.systemRequirement.designRequirements.designRequirement` traverses two relationships:
1. `systemRequirements.systemRequirement` -- from `UserNeed` through the association to `SystemRequirement`
2. `designRequirements.designRequirement` -- from `SystemRequirement` through the association to `DesignRequirement`
Each pair of segments represents one many-to-many hop. To access a specific field on the target entity, append the property name: `systemRequirements.systemRequirement.severity` displays the severity field of the related `SystemRequirement`.
The depth of your dot-notation path determines the **row level** in the sheet hierarchy. Root entity columns have no dots (level 0). First-level navigation adds one or two segments (level 1). Each additional relationship hop adds another level.
**Verify in application**
Deep navigation paths (three or more relationship hops) may impact query performance depending on the volume of linked work items. Test with representative data sets before deploying deeply nested configurations to production.
## Scalar vs Collection Navigation Properties
The distinction between scalar and collection navigation properties determines how the sheet renders data and which UI controls are available:
**Scalar properties** (from the "one" side of a relationship) resolve to a single entity. In the sheet, these render as:
* A reference picker allowing the user to select one related entity
* Read-only display of a related entity's field when accessed via dot-notation (e.g., `chapter.title`)
**Collection properties** (from the "many" side of a relationship) resolve to multiple entities. In the sheet, these render as:
* Child rows that expand underneath the parent row, creating a new hierarchy level
* Multi-item reference pickers when the column is configured with `multiItem: true`
The cardinality table below summarizes the relationship between model definitions and sheet behavior:
| Cardinality | Direct property | Back property | Source expand | Column binding | UI behavior |
| ----------- | ------------------------ | ------------------------ | -------------------------------------------------------- | -------------------------------------- | ----------------------- |
| **N:1** | Scalar (`chapter`) | Collection (`userNeeds`) | `- name: chapter` | `chapter`, `chapter.title` | Single-value ref picker |
| **1:N** | Collection (`userNeeds`) | Scalar (`chapter`) | `- name: userNeeds` | `userNeeds` (child rows) | New grid level |
| **M:N** | Collection | Collection | Two-level: `systemRequirements` then `systemRequirement` | `systemRequirements.systemRequirement` | Multi-item ref picker |
## Built-In Navigation Properties
Every entity type in Powersheet automatically receives two built-in navigation properties, regardless of what you define in the `relationships` section:
| Property | Target | Description |
| ---------- | ---------- | --------------------------------------------------- |
| `document` | `Document` | Links the entity to its containing Polarion LiveDoc |
| `project` | `Project` | Links the entity to its Polarion project |
These built-in properties support filtering, expansion, and foreign key lookups without any explicit configuration in the data model. You can use them in column bindings (e.g., `document.title`) and in picker constraints to scope entity selection by document or project.
## Common Misconceptions
**"I can define navigation properties directly on entity types."** Navigation properties are created exclusively through the `relationships` block. You cannot declare them inline within an entity type definition. The `properties` section of an entity type is for data fields (like `description`, `severity`) -- not for navigation.
**"Navigation properties store links."** Navigation properties do not store anything. The actual link data is persisted through Polarion's native link mechanism (specified by `storage: linkedWorkItems` and `linkRole`). Navigation properties are runtime-resolved references that query these links.
**"Navigation properties are the same as Polarion link roles."** A link role is the storage mechanism in Polarion; a navigation property is the named accessor that Powersheet creates on top of that link role. Multiple relationships can use the same link role but create different navigation properties with different names.
**"Singular names mean one-to-one relationships."** The naming convention (singular vs plural) is a readability guideline, not a technical constraint. Powersheet determines cardinality from the `cardinality` field, not from the property name. However, following the convention consistently prevents confusion when reading configurations.
**"I only need to expand one level for many-to-many."** Many-to-many relationships always require two expansion levels in sources -- one for the association and one for the target entity. A single-level expansion will only reach the association, leaving target entity columns empty.
## Relationship to Other Concepts
Navigation properties connect to several other areas of the Powersheet configuration system:
* [Entity Types and Relationships](/powersheet/concepts/entity-types-and-relationships) defines the structural context in which navigation properties exist
* [Link Cardinality](/powersheet/concepts/link-cardinality) determines whether a navigation property is scalar or a collection, affecting both UI rendering and expansion patterns
* [Source Configuration](/powersheet/concepts/source-configuration) uses navigation properties in `expand` blocks to load related data
* [Hierarchy and Traceability](/powersheet/concepts/hierarchy-and-traceability) is the architectural goal that navigation properties enable -- building multi-level views across entity types
* [Data Model vs Sheet Configuration](/powersheet/concepts/data-model-vs-sheet-config) explains where navigation properties fit across the two configuration files
For practical guidance on configuring data models with navigation properties, see the [Data Model Guides](/powersheet/guides/data-model/index). For column binding syntax and expansion path setup, see the [Sheet Configuration Guides](/powersheet/guides/sheet-configuration/index).
# Polarion Integration
Source: https://learn.nextedy.com/powersheet/concepts/polarion-integration
Nextedy POWERSHEET is not a standalone application -- it runs inside Siemens Polarion ALM.
This page explains the integration architecture -- *why* Powersheet works the way it does inside Polarion, and what that means for configuration, security, and day-to-day use.
## No Separate Data Store
The most important architectural decision in Powersheet is that it stores **nothing outside Polarion**. Every piece of data you see in a Powersheet sheet is a Polarion work item, every relationship is a Polarion link role, and every configuration file lives in Polarion's SVN repository.
Think of Powersheet as a specialized lens over data that already exists in Polarion. When you open a sheet, Powersheet reads the data model and sheet configuration from SVN, translates your view into Polarion Lucene queries, and renders the results as an interactive hierarchical sheet. When you save changes, those changes are written directly to Polarion work items through Polarion's own APIs.
This means:
* **No data synchronization** -- there is no ETL process or replication lag between Powersheet and Polarion. The sheet always shows the current state of your work items.
* **No backup complexity** -- backing up Polarion backs up everything Powersheet needs.
* **No migration burden** -- if you stop using Powersheet, your work items and links remain exactly as they were in Polarion.
Because Powersheet reads and writes Polarion data directly, any change made in a Powersheet sheet is immediately visible in Polarion's standard work item views, LiveDocs, and reports -- and vice versa.
## How Powersheet Embeds in Polarion
Powersheet registers itself as a web application within Polarion's embedded application server at startup. The plugin descriptor makes all Powersheet endpoints available through Polarion's standard web infrastructure. From the user's perspective, Powersheet appears as a native page within the Polarion web interface -- it shares the same browser session, the same navigation chrome, and the same URL structure.
Every request to Powersheet passes through Polarion's authentication layer. Users do not need separate login credentials -- if they are authenticated in Polarion, they can access Powersheet. This also means Polarion's session management, SSO integration, and session timeout policies all apply automatically.
## Configuration Storage in SVN
All Powersheet configuration -- data models and sheet configurations -- lives as YAML files in Polarion's SVN repository. This is a deliberate design choice with several consequences:
**Version control is built in.** Every change to a data model or sheet configuration is tracked as an SVN revision. You can view the change history, compare versions, and revert to a previous configuration using standard Polarion tools.
**Project isolation is natural.** Each Polarion project has its own SVN directory tree, so project-level configurations are automatically scoped. Global configurations reside in a shared `_global` location, providing defaults that any project can inherit or override.
**Deployment is instant.** When you save a configuration change through the administration pages, it is written to SVN and takes effect on the next sheet load. There is no build step, no deployment pipeline, and no server restart required.
**Configuration storage path**
Data models and sheet configurations are stored under the `.polarion/nextedy/` directory within each project's SVN structure. Global configurations use the same path under the `_global` project. The administration interface manages these files automatically -- you do not need to interact with SVN directly.
For a detailed comparison of global and project-level configuration scope, see [Global vs Project-Specific Configuration](/powersheet/concepts/global-vs-project-specific).
## Administration Interface
Powersheet extends Polarion's native administration interface rather than providing a separate management console. This means administrators work in the same environment they already know, with the same permission controls and the same navigation patterns.
The administration pages are available at three scope levels:
| Scope | Access Path | What It Controls |
| ----------------- | ------------------------------------------------------------- | ------------------------------------------------ |
| **Global** | **Administration > Nextedy Powersheet** (repository-wide) | Default configurations available to all projects |
| **Project Group** | **Administration > Nextedy Powersheet** (project group level) | Configurations shared by projects in a group |
| **Project** | **Administration > Nextedy Powersheet** (project level) | Configurations specific to one project |
Within each scope, the administration interface provides:
| Admin Page | Purpose |
| ------------------------ | --------------------------------------------------------------------------------------------- |
| **Data Models** | Create and edit data model YAML files that define entity types, relationships, and properties |
| **Sheet Configurations** | Manage sheet configuration YAML files that control column layout, formatting, and behavior |
| **Setup** | Initial Powersheet configuration and system settings |
| **License** | License key management and status |
The administration pages embed a file manager interface that lets you create, edit, rename, and delete YAML configuration files directly in the browser. Changes are saved to SVN immediately.
## Document-Centric Model
Every Powersheet sheet is anchored to a Polarion LiveDoc document. This is not an arbitrary constraint -- it reflects a deliberate design principle: a sheet is a **view** of a document's structured content, not a free-floating report.
The connection between a document and its sheet configuration works through a custom field:
1. The Polarion document has a `nextedySheetConfig` custom field.
2. This field references the sheet configuration file to use (either by file path or by enum selection).
3. When Powersheet opens the document, it reads this field and loads the corresponding YAML configuration from SVN.
The configuration field supports both string values (direct file paths) and enum options. When configured as an enum, Polarion provides a dropdown picker that scans available configuration files at both global and project scope, making it easy for document authors to assign the right configuration.
**Common setup mistake**
The `nextedySheetConfig` field must reference the configuration **ID**, not the display name. Using the display name is a frequent source of "configuration not found" errors during initial setup. See [Troubleshooting](/powersheet/guides/troubleshooting/index) for resolution steps.
The document URL follows the pattern `#/project/{projectId}/powersheet?document={folder/name}`, which means you can bookmark, share, and link to specific Powersheet documents just like any other Polarion page.
## Entity Type and Work Item Mapping
Powersheet introduces the concept of **entity types** as an abstraction layer over Polarion work item types. Rather than working directly with Polarion work item types in your sheet configuration, you define entity types in the data model and map them to their corresponding Polarion types:
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: userNeed
properties:
title:
severity:
SystemRequirement:
polarionType: systemRequirement
properties:
title:
status:
```
This indirection is valuable because:
* **Naming independence** -- your data model can use names that make sense in your engineering context (`UserNeed`, `Hazard`, `RiskControl`) regardless of what the Polarion work item types are called internally.
* **Property filtering** -- the data model exposes only the properties that matter for your traceability analysis, hiding irrelevant Polarion fields from the sheet.
* **Relationship modeling** -- the data model defines how entity types relate to each other using Polarion link roles, with explicit cardinality and navigation direction.
When Powersheet executes a query, the server API translates entity type references into Polarion Lucene queries scoped to the mapped `polarionType`. Properties resolve to Polarion custom fields and built-in fields. Relationships resolve to Polarion link roles with the `direct` and `back` navigation directions.
For deep coverage of how entity types and relationships work, see [Entity Types and Relationships](/powersheet/concepts/entity-types-and-relationships) and [Navigation Properties](/powersheet/concepts/navigation-properties).
## Sidebar Navigation with Powersheet Drive
Powersheet registers a navigation extension that adds **Powersheet Drive** as a topic in the Polarion sidebar. This provides a centralized document browser -- users can see all Powersheet documents in the current project at a glance, without navigating through Polarion's folder hierarchy.
By default, Powersheet Drive lists all documents that have a `nextedySheetConfig` field value. The query that controls which documents appear can be customized through a project property:
```
com.powersheet.powersheetDocumentQuery=type:powersheet OR HAS_VALUE:templateDoc.KEY
```
This flexibility means you can:
* Show only documents of a specific document type
* Include template documents for easy duplication
* Filter by custom criteria using Polarion Lucene syntax
Powersheet Drive also supports **template documents**. When templates are included in the query results, users can duplicate them to create new Powersheet documents with a preconfigured sheet configuration already assigned.
## Security and Permission Inheritance
Powersheet relies on Polarion's security model rather than implementing an identity or access-control layer of its own. Security is a **shared responsibility**: Polarion provides the controls and Powersheet is responsible for using them correctly -- see [Security Architecture](/powersheet/concepts/architecture#security-architecture) for that split in full. This has practical implications at several levels:
**Authentication:** Powersheet uses Polarion's authentication realm. If your Polarion instance uses LDAP, SAML, or another SSO provider, Powersheet respects it automatically. There are no separate user accounts to manage.
**Project access:** Users can only open Powersheet documents in projects they have access to. Polarion's project role assignments control who can view or edit.
**Work item permissions:** When Powersheet renders a sheet, it respects Polarion's work item-level permissions. If a user cannot edit a specific work item type in Polarion, they cannot edit it in Powersheet either.
**Property-level control:** The data model adds a finer-grained layer through entity metadata annotations. Properties can be marked as `isReadOnly` in the server metadata, controlling whether a column is editable in the sheet. These annotations complement (but do not override) Polarion's native permission model.
**Configuration access:** Sheet configuration and the data model are privileged. They live in the Polarion SVN repository (the project's `.polarion` location), where Polarion's default permission schemes restrict write access to administrators, and they are edited through **Administration > Nextedy Powersheet**. Because configuration can include server-side JavaScript, client-side JavaScript, or Velocity, it is restricted to trusted roles and is not sandboxed beyond that role restriction -- treat it as administrative code.
**Verify in application**
The interaction between Polarion's native permissions and Powersheet's data model property annotations depends on your specific configuration. Test your permission setup to confirm the expected read/write behavior for each user role.
For details on how permissions flow through Powersheet, see [User Roles and Permissions](/powersheet/concepts/user-roles-and-permissions), and [Product Security](/overview/security-and-privacy/product-security) for the cross-product model.
## Revision and Baseline Support
Powersheet supports opening documents at historical revisions and baselines. When a `revision` parameter is specified in the URL, Powersheet loads the document state as it existed at that point in time.
Historical views are inherently **read-only** -- users can inspect past states of their traceability data without any risk of accidental modification. This is particularly valuable in regulated environments where teams need to demonstrate the state of requirements or risk analyses at specific milestones.
Because Powersheet reads directly from Polarion's data store, revision support requires no additional infrastructure. Polarion's own revision mechanism (backed by SVN for documents and the work item history for field values) provides the temporal data that Powersheet renders.
## The Integration Mental Model
If you are coming from standalone spreadsheet or database tools, the most important mental shift is this: Powersheet does not own data. It does not import, export, replicate, or cache your work items. It provides a **configurable, hierarchical view** directly over Polarion's native data structures.
This means:
* Changes propagate instantly in both directions
* Polarion reports, dashboards, and LiveDocs always reflect edits made in Powersheet
* Existing Polarion workflows, notifications, and automations continue to work
* Standard Polarion backup and disaster recovery procedures cover Powersheet completely
The only artifacts Powersheet adds to your Polarion environment are YAML configuration files in SVN and the `nextedySheetConfig` custom field on documents.
## Related Pages
* [Powersheet Architecture](/powersheet/concepts/architecture) -- Technical architecture of the server and client layers
* [Core Components](/powersheet/concepts/core-components) -- How configuration, data, and rendering components connect
* [Data Model vs Sheet Configuration](/powersheet/concepts/data-model-vs-sheet-config) -- The two configuration files and their distinct roles
* [Global vs Project-Specific Configuration](/powersheet/concepts/global-vs-project-specific) -- Scope management for configurations
* [User Roles and Permissions](/powersheet/concepts/user-roles-and-permissions) -- How Polarion permissions flow through Powersheet
***
# Powersheet vs. Risksheet
Source: https://learn.nextedy.com/powersheet/concepts/powersheet-vs-risksheet
How Nextedy POWERSHEET and Nextedy RISKSHEET differ, when to use each, and how the two complement each other inside Siemens Polarion ALM.
**Goal:** Understand the key differences between Powersheet and Risksheet, when to use each product, and how they complement each other.
Nextedy offers two interactive grid products for Siemens Polarion ALM: **Powersheet** and **Risksheet**. Both render a spreadsheet-like editing experience directly inside Polarion, and both store their data as standard Polarion work items -- but they solve different problems and are configured in fundamentally different ways.
## Core Purpose
**Powersheet** is a general-purpose hierarchical sheet app for Polarion. It is designed to manage any structured, multi-level data model -- requirements traceability, test planning, task boards, custom domain models -- across any domain or industry. You define what data to show and how to structure it through YAML configuration files.
**Risksheet** is purpose-built for risk analysis workflows. It targets safety engineers and cybersecurity analysts performing FMEA, HARA, TARA, STRIDE, or CVSS assessments in regulated industries such as automotive (ISO 26262), medical devices (ISO 14971), and cybersecurity (ISO/SAE 21434). It includes risk-specific capabilities -- risk rating scales, RPN formulas, risk matrices, and risk review workflows -- that are not present in general-purpose grids.
## Shared Foundation
Despite their different goals, the two products rest on the same Polarion-native foundation, which is why they complement each other so cleanly:
* **Native Polarion work items and links.** Neither product keeps a separate datastore. Every row, and every relationship between rows, is a standard Polarion work item or link -- so the data inherits Polarion versioning, audit history, permissions, queries, and suspect-link propagation, and stays visible in the Polarion tracker.
* **Polarion-inherited security.** Both authenticate through Polarion and enforce project roles and field-level permissions on the server, regardless of what the grid shows on the client.
* **SVN-stored configuration with instant deployment.** Both keep their configuration in the project's SVN repository and apply changes the next time a sheet is opened -- no build step and no server restart.
## Configuration Model
This is the most significant architectural difference between the two products.
### Powersheet: three-layer YAML architecture
Powersheet separates its configuration into three distinct layers:
1. **Data model** -- A YAML file that defines the semantic layer: which Polarion work item types, link roles, and document types are exposed as structured entity types and relationships. The data model also enforces process constraints such as link cardinality rules.
2. **Sheet configuration** -- A separate YAML file that defines how the data model data is displayed: which columns appear, how rows expand to show related entities, which views are available, and how editing behaves.
3. **Document entry point** -- A Polarion LiveDoc that references a sheet configuration. One sheet configuration can be reused across many documents and even across projects with different Polarion type IDs (as long as each project has its own data model mapping).
This separation means you can standardize a single sheet layout across an entire organization and adapt it to local Polarion configurations purely by adjusting the data model -- without touching the sheet configuration.
The data model is a semantic abstraction layer: entity types and relationships carry their own names and map onto Polarion work item types and link roles -- a single entity type can even span several Polarion types. Powersheet resolves columns, queries, pickers, and validation through this vocabulary rather than against raw Polarion type IDs, which is what makes one sheet configuration portable across projects.
### Risksheet: single JSON configuration per document
Risksheet is configured through a `risksheet.json` file attached directly to each LiveDoc document (or inherited from a template document). This single JSON file controls the entire grid: columns, JavaScript formulas, cell decorators, CSS styles, enumeration dropdowns, hierarchical row levels, and link role bindings.
The configuration-driven design makes Risksheet highly flexible within the risk analysis domain, but it is intentionally scoped to that domain. There is no concept of a separate data model layer.
## Data Scope
**Risksheet** roots each grid in a **single Polarion LiveDoc** -- its main (row) work items all come from that one document, and it cannot aggregate root data across documents. It can, however, still display *linked* items one level up (upstream references) and one level down (mitigation and task items), and those linked items may live in other documents.
**Powersheet** supports **expansion paths** -- configuration-defined traversals that follow link roles to pull in related entities from across the data model. A single powersheet can display a root entity alongside its linked children, traceability targets, and associated test cases in one view, even when those entities span different document types.
## Typical Use Cases
| Scenario | Recommended Product |
| ----------------------------------------------------------- | ------------------------------------------------- |
| FMEA, HARA, TARA, STRIDE, or CVSS analysis | **Risksheet** |
| Requirements traceability matrix (RTM) | **Powersheet** |
| System decomposition and allocation | **Powersheet** |
| Multi-level task and planning boards | **Powersheet** |
| Risk register integrated with broader traceability | **Powersheet** (with risk data model) or **both** |
| Audit-ready risk analysis with RPN and color-coded matrices | **Risksheet** |
## Capability Comparison
The table below compares the two grids feature by feature. A check (✓) means the capability is available today; a dash (—) means it is not yet supported. The **Mid-term roadmap** column flags gaps that are planned for an upcoming release.
| Capability | Risksheet | Powersheet | Details | Mid-term roadmap |
| ------------------------------------------ | :-------: | :--------: | ---------------------------------------------------------------------------------------------------- | :--------------: |
| Excel-like editing | ✓ | ✓ | | |
| Filtering | ✓ | ✓ | | |
| Searching | ✓ | ✓ | | |
| Single work item picker | ✓ | ✓ | | |
| Multi work item picker | ✓ | ✓ | | |
| Deep structures (more than two levels) | — | ✓ | Risksheet can go only one level deep; Powersheet can manage data from any number of levels. | |
| Multi-dimension | — | ✓ | Risksheet shows linked items one level up and down; Powersheet can add references at any depth. | |
| Enum | ✓ | ✓ | | |
| Multi-enum | ✓ | — | Powersheet does not yet support multi-enum custom fields. | ✓ |
| Manage workflow status | ✓ | — | Powersheet does not yet support changing workflow status. | ✓ |
| Compare | ✓ | — | Powersheet can open data from a revision; baseline compare is not available yet. | |
| Export to PDF | ✓ | — | Powersheet cannot export to PDF yet. | ✓ |
| Export to Excel | ✓ | ✓ | | |
| Merge based on cell value | ✓ | — | Powersheet structure is derived from work items, not yet value-driven merged cells. | |
| Granular permissions | ✓ | ✓ | | |
| Data from multiple documents at root level | — | ✓ | Risksheet shows root (row) work items from a single document only. | |
| Review mode for changes before save | — | ✓ | Powersheet presents local unsaved changes before they are committed. | |
| Review comments (approvals) | ✓ | — | Powersheet does not yet provide a review mode for content approval. | |
| Data routing | — | ✓ | Powersheet can automatically pick the right target document based on data constraints. | |
| Computed / formula columns | ✓ | ✓ | Risksheet evaluates JavaScript formulas (RPN, ASIL, CVSS); Powersheet uses dynamic expressions. | |
| Server-rendered columns | ✓ | ✓ | Read-only columns rendered by Velocity templates that can traverse links and call Polarion services. | |
| Saved views / perspectives | ✓ | ✓ | Named column-visibility presets, switched without reloading data or losing edits. | |
| Conditional cell styling | ✓ | ✓ | Value-driven cell styling -- Risksheet cell decorators, Powersheet formatters. | |
**Two senses of "review."** The two products use the word *review* for different things. Powersheet's review mode previews local unsaved changes before they are committed, whereas Risksheet's review features support content approval -- comment-based, work-item-based, or approval-based workflows. They solve different problems and are not equivalent.
## Licensing and Integration
Risksheet and Powersheet are **licensed independently**, and each is fully functional on its own -- neither product requires the other. Owning both does not mean paying for Active Users twice: Active Users are counted once across the two products, and read-only access to the second product is covered by its bundled Connect license.
Each product is complete on its own -- you are not missing core functionality by running just one. When both are installed and Powersheet holds a valid production license, Risksheet transparently switches to an enhanced configuration that **adds** extra capabilities on top of what it already does -- no manual configuration required, and evaluation or trial Powersheet licenses do not trigger it. Owning both mainly opens up more possibilities and changes how licensing is applied; it does not switch on features that were otherwise missing.
## Summary
| | Powersheet | Risksheet |
| -------------------------- | -------------------------------------------------------- | ------------------------------------------------------------------------ |
| **Primary use case** | General-purpose hierarchical data management | Risk analysis (FMEA, HARA, TARA, STRIDE, CVSS) |
| **Configuration format** | YAML (data model + sheet config) | JSON (`risksheet.json`) |
| **Configuration layers** | Three (data model, sheet config, document) | One (document-attached JSON) |
| **Cross-document data** | Yes, via expansion paths | Root rows from one document; linked items may span documents |
| **Risk-specific features** | No (general columns only) | Yes -- RPN formulas, risk rating scales, risk matrices, review workflows |
| **Config reuse** | Single sheet config shared across many documents | Template inheritance via template documents |
| **License** | Separate | Separate |
| **Runtime integration** | Adds extra Risksheet capabilities when both are licensed | Benefits from Powersheet when both are licensed |
If your primary need is structured risk analysis with industry-standard rating scales and calculated risk metrics, start with **Risksheet**. If you need a flexible, model-driven grid for managing any type of Polarion work item relationships -- including but not limited to risk -- start with **Powersheet**.
## See Also
* [Migrate from Risksheet to Powersheet](/powersheet/guides/migration/migrate-from-risksheet) -- Step-by-step transition of an existing project, converting the data model, sheet configurations, and document bindings
* [Data Model vs Sheet Configuration](/powersheet/concepts/data-model-vs-sheet-config) -- The configuration separation that underpins Powersheet's flexibility
* [Core Components](/powersheet/concepts/core-components) -- The building blocks of every powersheet
# Process Constraints
Source: https://learn.nextedy.com/powersheet/concepts/process-constraints
Siemens Polarion ALM provides a flexible work item system that intentionally leaves structural rules unenforced.
This page explains why constraints exist, how the three constraint stages interact through cascading, what properties you can constrain, and how dynamic context expressions enable adaptive filtering at runtime.
## Why Constraints Exist
Consider a regulated engineering environment: user needs must live in a stakeholder requirements document, system requirements belong in a system specification, and design outputs go into a design document. Polarion itself does not enforce these structural rules -- it stores the data, but it does not prevent a user from placing a system requirement in the wrong document or linking a hazard to an unrelated test case.
Process constraints in Nextedy POWERSHEET act as **guardrails**: they do not alter what Polarion can store, but they control what Powersheet will display in the sheet, offer in picker dialogs, and permit as a target location when creating new items.
Think of constraints as a building's access control system. The building itself (Polarion) has rooms and hallways connecting them, but the access system (constraints) determines which doors open for which people and which rooms are available for new meetings. The physical structure is unchanged, but the behavior is governed.
**Guardrails, not walls**
Constraints operate at the Powersheet application layer. Users with direct Polarion access can still create or link items outside these rules. Constraints guide correct behavior within the sheet experience; they complement (but do not replace) Polarion workflow rules or link role restrictions.
## The Three Constraint Stages
The data model supports three categories of constraints, each operating at a different point in the data lifecycle:
### Load Constraints
**`constraints.load`** filters which entities are retrieved when the sheet initially queries Polarion. This operates at the query level, reducing the result set before data ever reaches the client application.
A load constraint typically uses document properties to scope entity retrieval:
```yaml theme={null}
domainModelTypes:
SystemRequirement:
polarionType: systemRequirement
constraints:
load:
document:
type: systemSpecification
```
With this constraint, only system requirements residing in documents of type `systemSpecification` are loaded into the sheet. Items in other document types are invisible to Powersheet, as though they do not exist.
### Pick Constraints
**`constraints.pick`** restricts which existing items appear in picker dialogs when users create or modify relationships. This is critical for preventing incorrect traceability links -- without pick constraints, a user could link a system requirement to an item from an unrelated document or project space.
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: userNeed
constraints:
pick:
document:
moduleFolder: Requirements
type: needsDocument
```
When a user opens the picker to select a `UserNeed`, only items from the `Requirements` folder in documents of type `needsDocument` appear as candidates.
### Create Constraints
**`constraints.create`** controls where new work items are placed when users create them through the sheet. By specifying a `document` constraint with `moduleFolder`, `moduleName`, or `type`, you route new items to the correct location automatically.
```yaml theme={null}
domainModelTypes:
DesignRequirement:
polarionType: designOutput
constraints:
create:
document:
moduleFolder: Design
type: designSpecification
```
When a user creates a new `DesignRequirement` through the sheet, Powersheet automatically places it in a document matching the `Design` folder and `designSpecification` type. The user does not need to manually choose a target location.
## Stage Cascading and Fallback
One of the most important aspects of the constraint system is **stage cascading**. The three stages form an inheritance chain:
1. **`load`** is the base stage -- it stands alone with no inheritance
2. **`pick`** inherits all `load` constraints (combined with AND logic)
3. **`create`** inherits both `load` and `pick` constraints
This cascading behavior means that a single `load` constraint automatically scopes all three user interactions. If you constrain `load` to filter by `document.type: systemSpecification`, then the picker and create dialogs also respect that filter without requiring explicit `pick` or `create` blocks.
**Fallback behavior**
If no `create` constraints are explicitly defined for an entity type, the system falls back to using `pick` constraints for the create stage. This means defining only `load` and `pick` is often sufficient -- the `create` behavior inherits from both. However, if you need create to target a *different* location than what pick allows, you must define `create` constraints explicitly.
**Practical implication:** Start with the most restrictive stage you need. If a load constraint covers your needs, you may not need pick or create blocks at all. Add them only when the three stages require different scoping rules.
| Scenario | Minimum constraints needed |
| --------------------------------------- | ------------------------------------------------- |
| Same filter for all interactions | `load` only |
| Different picker scope than loaded data | `load` + `pick` |
| Create targets a specific document | `load` + `create` (or `load` + `pick` + `create`) |
| Each stage has unique rules | All three explicitly defined |
## Document-Based Constraint Properties
All three constraint stages share a common set of document-level filter properties:
| Property | Description | Example value |
| ----------------------- | --------------------------------------------------------------- | ------------------------------------ |
| `document.moduleFolder` | Restricts to a specific Polarion module folder (space) | `Requirements` |
| `document.moduleName` | Restricts to a specific document by exact name | `System Specification` |
| `document.type` | Restricts to documents of a specific Polarion document type | `systemSpecification` |
| `document.id` | Restricts by full document ID in `folder/name` format | `Requirements/Stakeholder Needs` |
| `document.title` | Restricts by document display title | `Stakeholder Requirements` |
| `document.component` | Restricts by document component; supports `$context` references | `$context.source.document.component` |
## Comparison Operators
Constraint values are not limited to exact matching. Powersheet provides five comparison operators that give you flexible filtering patterns:
| Operator | Meaning | Example |
| ------------ | ------------------------------------------------ | -------------------------------------- |
| `equals` | Exact match (default when no operator specified) | `type: systemSpecification` |
| `contains` | Value contains the substring | `moduleName: {contains: "Spec"}` |
| `in` | Value matches any item in a list | `type: {in: [systemSpec, designSpec]}` |
| `startsWith` | Value starts with the prefix | `moduleFolder: {startsWith: "Req"}` |
| `endsWith` | Value ends with the suffix | `moduleName: {endsWith: "Document"}` |
When you write a plain string value (like `type: systemSpecification`), it is interpreted as an `equals` comparison. Use the object syntax with an explicit operator key when you need other matching behavior.
## Logical Operators: AND and OR
By default, multiple properties within a `document` block are combined with **AND** logic -- all conditions must be true for an item to match.
```yaml theme={null}
constraints:
pick:
document:
moduleFolder: Requirements
type: needsDocument
```
This means the item must be in the `Requirements` folder AND in a document of type `needsDocument`.
Powersheet also supports **OR** logic inside the document block, allowing you to match items that satisfy any one of several conditions. This is useful when valid items can come from multiple document types or folders.
**Constraint composition**
When combining multiple constraints with OR logic, be careful about conflicting conditions. Two constraints that individually match different sets of items may produce an empty result if their intersection is empty. Test complex constraint compositions in a development environment before deploying to production.
## Dynamic Context References
Constraints support runtime context expressions using the `$context` prefix. These expressions are resolved dynamically when the constraint is evaluated, allowing the filter to adapt based on the current document or entity.
The most common pattern is **component-scoped filtering**:
```yaml theme={null}
constraints:
pick:
document:
component: $context.source.document.component
```
This ensures that when a user opens a picker to select a related entity, only items from documents sharing the same component value as the source entity's document are offered. This is particularly useful in large projects where multiple components (subsystems, variants, or product lines) coexist and traceability must remain within component boundaries.
Other available context references include:
| Expression | Resolves to |
| ------------------------------------ | ------------------------------------------------ |
| `$context.source.document.component` | Component of the source entity's parent document |
| `$context.document.id` | Full ID of the current document |
**Verify in application**
The exact set of `$context` expressions available may vary by Powersheet version. Test context-based constraints in your environment to confirm behavior before relying on them in production configurations.
## Constraint Composition: A Complete Example
The following data model excerpt shows constraints applied to a standard RTM hierarchy. Each entity type is scoped to its correct document location, with pick constraints ensuring traceability links stay within the proper boundaries:
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: userNeed
constraints:
load:
document:
type: stakeholderRequirements
pick:
document:
moduleFolder: Requirements
SystemRequirement:
polarionType: systemRequirement
constraints:
load:
document:
type: systemSpecification
create:
document:
moduleFolder: Design
type: systemSpecification
DesignRequirement:
polarionType: designOutput
constraints:
load:
document:
type: designSpecification
create:
document:
moduleFolder: Design
type: designSpecification
Hazard:
polarionType: hazard
constraints:
pick:
document:
moduleFolder: Risks
component: $context.source.document.component
```
In this configuration:
* **`UserNeed`** items are loaded only from stakeholder requirements documents, and pickers further restrict to the `Requirements` folder
* **`SystemRequirement`** items load from system specifications, and new items are created in the `Design` folder within system specification documents
* **`DesignRequirement`** follows a similar pattern, scoped to design specifications
* **`Hazard`** pick constraints ensure risk-related linking stays within the same component, enforcing component-level traceability
## How Constraints Relate to Other Concepts
Constraints work in concert with several other data model concepts to enforce your engineering process:
* **[Link Cardinality](/powersheet/concepts/link-cardinality)** controls *how many* links are allowed between entity types, while constraints control *which items* are visible, selectable, and creatable
* **[Document Rules](/powersheet/concepts/document-rules)** define broader document-level governance that applies regardless of entity type
* **[Entity Types and Relationships](/powersheet/concepts/entity-types-and-relationships)** define the structural connections that constraints then filter and scope
* **[Navigation Properties](/powersheet/concepts/navigation-properties)** use the `direct` and `back` directions that constraints influence when loading related entities
Together, these mechanisms form a layered governance model: the data model defines what entities exist and how they relate, cardinality limits the number of connections, and constraints ensure those connections stay within the correct structural boundaries.
## Common Misconceptions
**"Constraints block Polarion from storing data."** They do not. Constraints operate at the Powersheet application layer. A user with direct Polarion access or another tool can still create items outside the constraint boundaries. Constraints govern the Powersheet experience, not the underlying Polarion data store.
**"I need all three stages defined for every entity type."** In most cases, you only need `load` constraints. Thanks to cascading, `pick` inherits from `load` and `create` inherits from both. Define additional stages only when their scoping rules differ from the inherited behavior.
**"OR logic means I can match anything."** While OR broadens the filter, all constraints within a stage are still composed together. Two OR branches with contradictory conditions can still produce an empty result set. Always verify composed constraints against real data.
For practical guidance on implementing constraints in your data model, see [Creating Your First Data Model](/powersheet/getting-started/first-data-model) and the [Data Model Guides](/powersheet/guides/data-model/index).
***
# Server-Side Filtering
Source: https://learn.nextedy.com/powersheet/concepts/server-side-filtering
How Nextedy POWERSHEET runs query filters on the server while expanding, so a sheet loads only the slice of Siemens Polarion ALM data it needs instead of fetching everything and filtering in the browser.
A Powersheet filter runs on the server while the query executes -- not in the browser after the data has arrived. Every level of a sheet, the root query and each expanded level, can carry a `where` that narrows what that level returns, so only the matching slice is fetched. On a large dataset this is the difference between a responsive sheet and one that stalls while loading everything before it can show anything.
## Server-side filtering, not client-side filtering
The distinction matters as data grows:
* **Client-side filtering** loads the full result set and then hides rows. The server still reads and transfers everything.
* **Server-side filtering** injects the condition into the query `where` *before* it runs. Polarion returns only the rows that match, so the large dataset is never fetched -- the sheet stays fast and the server stays light.
For example, on a requirements traceability sheet you can show every Chapter and Requirement but only the Electrical design requirements beneath them: the non-Electrical rows are never pulled to the browser at all.
## Filter the root query or any expand level
Add a `query.where` to the level you want to slice. Levels without one behave exactly as before:
```yaml theme={null}
sources:
- id: rtm
query:
from: Chapter
where:
title: { contains: Draft } # (optional) root-level filter
expand:
- name: requirements
expand:
- name: requirement
query:
where:
type: Electrical # subquery: only Electrical children load
```
A subquery `where` applies to **its own level only** -- ancestor rows are unaffected -- and works on every relationship type, scalar (N:1, 1:1) and collection (1:N, M:N) alike. For a many-to-many chain, put the `where` on the leaf level (for example `requirements.requirement`), not the junction. Multiple keys in one `where` are combined with AND, and filters can be nested at several levels, each scoping its own. For the full schema of an expand node's `where`, see the [expand clause reference](/powersheet/reference/query-api/expand-clause#expand-subquery-filtering); for the operator vocabulary (`eq`, `contains` as a whole-word token match, `ne`, `in`, `and` / `or`), see [Predicates](/powersheet/reference/query-api/predicates).
## The filter value can be static or come from the URL
A filter condition does **not** have to reference a URL parameter. The value can be a literal (`type: Electrical`), pinning the slice directly in the configuration. A [URL parameter](/powersheet/concepts/url-parameters) is simply one way to *supply* that value at load time: swap the literal for a `() =>` [dynamic expression](/powersheet/concepts/dynamic-expressions) that reads `context.parameters`, and one configuration serves many slices instead of one config per slice.
```yaml theme={null}
query:
where:
type: "() => context.parameters.domain" # from ?domain=…
```
Now `?domain=HW` and `?domain=SW` on the same sheet return different slices, with no duplicate configurations. A static condition and a parameter-driven one can sit side by side -- the fixed part always applies, the dynamic part varies with the URL:
```yaml theme={null}
query:
where:
and:
- postmitigationAP: { in: [M, H] } # always applied
- postmitigationAP: { eq: "() => context.parameters.pmap" } # from ?pmap=
```
See [URL Parameters](/powersheet/concepts/url-parameters) for how values reach `context.parameters`, and [Open a Scoped Sheet with URL Parameters](/powersheet/guides/sheet-configuration/parametrize-sheet-url) for the end-to-end task.
## When a filter value is missing
Filtering degrades optimistically rather than failing:
* A `where` condition whose value resolves to nothing has that single condition **dropped**, and the level loads unfiltered.
* An [`applyCurrentDocumentTo`](/powersheet/reference/query-api/document-filtering) scope resolved from a missing value is likewise **removed**, so the sheet loads unscoped rather than empty.
A malformed `() => …` expression is different: it fails loudly during query construction instead of silently producing a filterless query.
## Pickers follow the filter
A subquery `where` on an expand level also constrains that level's **reference picker**: only candidates that satisfy the same filter are offered, so a value you pick will not vanish on the next load -- what you save is what you get. For a many-to-many chain the picker carries the leaf level's filter (for example `requirement`), not the junction level, since the junction filter cannot apply to a candidate that is not linked yet. Where a target type also has a data-model [pick constraint](/powersheet/guides/customization/configure-picker-filters), the two combine with AND -- a candidate must satisfy both.
## New rows inherit the filter
**New rows satisfy the filter they were created under**
Creating an item at a filtered level pre-fills the fields the filter pins by **equality**, so the new row satisfies the filter it was created under instead of disappearing on the next load. Only equality seeds a default (`type: Electrical` or `type: { eq: … }`) -- fuzzy operators (`contains`, `in`, `ne`, `or`) pin no single value and seed nothing. An explicit [`entityFactory`](/powersheet/reference/sheet-config/sources) default always wins over a filter-derived one, and a subquery scoped to the current document also creates the new item in that document.
## Related
Where filter values can come from: named values read from the sheet's URL into `context.parameters`.
Step-by-step: filter the root query and an expanded level, then drive them from a shareable URL.
The expand node schema, including the `query.where` subquery filter and its picker behaviour.
`applyCurrentDocumentTo` -- scoping a level to the current LiveDoc on the server.
# Source Configuration
Source: https://learn.nextedy.com/powersheet/concepts/source-configuration
Every Nextedy POWERSHEET sheet begins with a question: *what data should appear?* The `sources` array in a sheet configuration answers that question.
## Sources as the Data Pipeline
Think of sources as the plumbing between your data model and the sheet surface. The data model declares what entity types exist and how they relate. The columns define what users see. Sources sit in between, translating domain relationships into concrete data queries.
A sheet configuration's root structure includes `sources` alongside `columns`, `views`, `renderers`, `formatters`, `styles`, and `sortBy`. While columns control presentation and formatters control appearance rules, sources control *what data enters the sheet in the first place*.
## Anatomy of a Source
Each source is an object in the `sources` array with the following parts:
| Property | Required | Purpose |
| ----------------- | -------- | ------------------------------------------------------- |
| `id` | Yes | Unique identifier referenced by other settings |
| `model` | Yes | Data model the source binds to (typically `rtm`) |
| `query` | Yes | Defines which entity type to fetch and optional filters |
| `expand` | No | Specifies which navigation properties to traverse |
| `entityFactory` | No | Default property values for newly created records |
| `name` or `title` | No | Human-readable label for the source |
The `id` is a user-defined string that acts as a reference key. It connects the source to the rest of the sheet configuration. Choose descriptive identifiers that reflect the entity type being queried -- for example, `user_needs` rather than `source1`.
The `model` property binds the source to a specific data model -- almost always `rtm`, the Requirements Traceability Model that declares your entity types and relationships. Without `model`, Powersheet has no way to resolve the `from` entity type or the navigation properties used in `expand`. Treat `model` as a required field alongside `id` and `query`.
### The Query Object
The `query` property controls data retrieval:
* **`from`** (required) -- The entity type name from your data model. This tells Powersheet which type of work items to load. For example, `from: UserNeed` fetches all entities of type `UserNeed` as defined in your `domainModelTypes`.
* **`where`** (optional) -- A filter predicate that narrows the result set. The predicate value can be static or dynamic. Dynamic values use the `() =>` notation to evaluate JavaScript expressions at runtime. This is particularly useful for date-based filtering or parameterized queries.
* **`take`** (optional) -- Limits the number of records returned.
* **`orderBy`** (optional) -- Controls server-side ordering of results.
**Dynamic Filters with Expressions**
Source queries support **dynamic value expressions** using `() => expression` syntax. For example, to filter for future dates only: `">": "() => new Date().toISOString()"`. You can also inject widget parameters: `"==": "() => context.parameters.client"`. See [Dynamic Value Expressions](/powersheet/concepts/dynamic-expressions) for the full reference on the context object and expression patterns.
### The Expand Property
The `expand` property is where source configuration connects most directly to the data model. Each entry in the `expand` array specifies a **navigation property name** -- the same name defined in the data model's relationship `direct.name` or `back.name` fields.
Expansion can be nested, letting you traverse multi-level hierarchies:
```yaml theme={null}
sources:
- id: user_needs
model: rtm
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: systemRequirement
```
In this example, the source starts from `UserNeed` entities, expands into the `systemRequirements` association, and then further into each `systemRequirement` target entity. Each expansion level corresponds to a new row level in the sheet.
**Expansion Depth Affects Performance**
Every expansion level triggers additional data retrieval. Deeply nested expansions -- three or more levels -- increase load time and memory usage. Design your sources to expand only the levels your sheet actually displays.
## How Cardinality Shapes Sources
The relationship cardinality defined in your data model dictates the expand pattern and, by extension, the column binding syntax and UI behavior. This is one of the most important concepts to internalize.
### Many-to-One (N:1)
When a relationship is `many-to-one` -- for example, many `UserNeed` entities belong to one `Chapter` -- the source uses the **direct** navigation property name (singular form). The expand entry is a single level:
```yaml theme={null}
expand:
- name: chapter
```
In the columns section, this produces a **scalar navigation property**: `chapter` renders as a single-value reference picker, and `chapter.title` lets you display a read-only property of the referenced entity. The key insight is that N:1 relationships do not create new row levels -- they add reference columns to the existing level.
### One-to-Many (1:N)
The reverse relationship -- one `Chapter` has many `UserNeed` children -- uses the **back** navigation property name (plural form):
```yaml theme={null}
expand:
- name: userNeeds
```
This creates a **new row level** in the sheet. When the user expands a `Chapter` row, the child `UserNeed` rows appear beneath it. The column binding for the child level uses the navigation property name directly (e.g., `userNeeds`) without dot notation.
### Many-to-Many (M:N)
Many-to-many relationships are the most complex case. They involve an **association entity** that sits between the two related types. The source expand requires two levels -- one for the association, one for the target entity:
```yaml theme={null}
expand:
- name: systemRequirements
expand:
- name: systemRequirement
```
The column binding mirrors this two-level structure: `systemRequirements.systemRequirement`. The association layer (`systemRequirements`, plural) is the collection of links, while the target layer (`systemRequirement`, singular) is the actual entity. In the UI, this pattern produces a multi-item reference picker.
**Naming Convention Matters**
The navigation property names in your source `expand` must exactly match the `direct.name` or `back.name` values in your data model relationships. A mismatch between the model and the source configuration is one of the most common causes of empty sheets. See [Entity Types and Relationships](/powersheet/concepts/entity-types-and-relationships) and [Link Cardinality](/powersheet/concepts/link-cardinality) for details on how relationships define these names.
## Entity Factory: Defaults for New Records
The `entityFactory` property defines default values that Powersheet assigns when a user creates a new record from within the sheet. This is useful for enforcing consistent initial states:
```yaml theme={null}
sources:
- id: user_needs
model: rtm
query:
from: UserNeed
entityFactory:
Status: "Draft"
Priority: "Medium"
```
When a user adds a new `UserNeed` row, the `Status` field automatically populates with "Draft" and `Priority` with "Medium". Without `entityFactory`, new records would have empty fields (or whatever defaults the underlying platform provides).
Entity factories also support dynamic value expressions:
```yaml theme={null}
entityFactory:
Client: "() => context.parameters.client"
```
This makes the factory value depend on the widget parameters passed to the sheet at load time, enabling context-sensitive defaults. Entity factories can be defined at any expansion level, not just the root source. Each `expand` entry can carry its own `entityFactory` for the child level.
## Multiple Sources
A sheet configuration can define multiple sources in the `sources` array. Each source gets its own `id`, `model`, query, and expansion tree. This allows a single sheet to display data from different root entity types side by side or in separate sections.
```yaml theme={null}
sources:
- id: user_needs
model: rtm
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: systemRequirement
- id: hazards
model: rtm
query:
from: Hazard
expand:
- name: riskControls
expand:
- name: riskControl
```
Each source operates independently -- it runs its own query and builds its own expansion tree. The columns section then references bindings from any of the configured sources.
## The Three-Layer Connection
The relationship between data model, sources, and columns follows a strict chain:
1. **Data model** declares entity types (e.g., `UserNeed`, `SystemRequirement`) and relationships with navigation property names (e.g., `direct.name: chapter`, `back.name: systemRequirements`).
2. **Sources** reference those navigation property names in `expand` entries and the entity type names in `query.from`, binding to the data model via the `model` property. The source does not redefine the relationships -- it activates specific paths from the data model.
3. **Columns** use dot-separated binding paths built from the same navigation property names. The binding path `systemRequirements.systemRequirement.title` means: traverse the `systemRequirements` association, reach the `systemRequirement` entity, and display its `title` property.
If the data model changes a navigation property name, both the source and the column bindings must update to match. This tight coupling is intentional -- it ensures that the sheet always reflects the actual data structure.
**Verify in application**
The interplay between model, source, and column configuration is best verified by loading the sheet in the Powersheet widget and confirming that expansions and column data appear as expected.
## Common Misconceptions
**"Sources define the schema."** Sources do not define entity types or properties -- the data model does. Sources only specify which parts of the model to query and expand. If you need to add a new entity type, modify the data model first, then add a source entry.
**"More expand levels means richer data."** Each expand level adds a data-loading step. Expanding four or five levels deep may produce impressive hierarchy trees but comes at a performance cost. Most practical sheets use one to three expansion levels.
**"The `id` must match the entity type name."** The source `id` is a free-form string. While it is good practice to use a descriptive name that hints at the entity type (e.g., `user_needs` for `UserNeed`), there is no technical requirement for the `id` to match the `from` value.
**"Dynamic where clauses run on the server."** The `() =>` expressions in `where` predicates are evaluated on the client side before the query is sent. This means the expression has access to the browser context (including widget parameters) but cannot reference server-side variables directly.
## Putting It All Together
Consider a requirements traceability sheet that displays `UserNeed` entities at the root, their linked `SystemRequirement` entities as children, and further nested `DesignRequirement` entities at the third level:
```yaml theme={null}
sources:
- id: user_needs
model: rtm
query:
from: UserNeed
entityFactory:
Status: "Draft"
expand:
- name: systemRequirements
expand:
- name: systemRequirement
expand:
- name: designRequirements
expand:
- name: designRequirement
columns:
title:
title: User Need
hasFocus: true
systemRequirements.systemRequirement:
title: System Requirement
list:
search:
- objectId
- title
createNew: true
systemRequirements.systemRequirement.title:
title: SysReq Title
hasFocus: true
systemRequirements.systemRequirement.designRequirements.designRequirement:
title: Design Requirement
systemRequirements.systemRequirement.designRequirements.designRequirement.title:
title: DesReq Title
hasFocus: true
```
In this configuration, each column binding mirrors the source expansion path. The `systemRequirements` and `designRequirements` segments are association-level navigation properties (M:N), while `systemRequirement` and `designRequirement` are the target entity-level properties. This pattern -- expanding through the association layer then into the entity -- is the standard approach for M:N relationships in Powersheet.
## Related Topics
For practical steps on configuring sources in your own sheets, see the [Sheet Configuration Guides](/powersheet/guides/sheet-configuration/index). To understand the data model relationships that sources reference, see [Entity Types and Relationships](/powersheet/concepts/entity-types-and-relationships) and [Link Cardinality](/powersheet/concepts/link-cardinality). For a side-by-side comparison of the model and sheet configuration layers, see [Data Model vs Sheet Configuration](/powersheet/concepts/data-model-vs-sheet-config). For details on the `() =>` expression syntax used in `where` clauses and entity factories, see [Dynamic Value Expressions](/powersheet/concepts/dynamic-expressions). To read values from the sheet's URL into the configuration, see [URL Parameters](/powersheet/concepts/url-parameters); to scope a source on the server so only the matching slice loads, see [Server-Side Filtering](/powersheet/concepts/server-side-filtering).
# URL Parameters
Source: https://learn.nextedy.com/powersheet/concepts/url-parameters
How Nextedy POWERSHEET reads named values from a sheet's URL into context.parameters, so one configuration can be driven -- filters, new-row defaults, computed columns, even the sheet name -- from shareable, bookmarkable links against Siemens Polarion ALM.
A Powersheet reads every value from its own URL query string into `context.parameters`, where the sheet configuration can pick it up. Because the values live in the URL, a view can be bookmarked, shared with a colleague, or reloaded and resolves to the same thing every time -- without editing the stored configuration. You get a different view by changing the URL, not the configuration.
This mirrors how the built-in `revision` parameter lets you [share a specific historical snapshot](/powersheet/guides/queries/query-baseline-revision) by URL.
## Reading a parameter
You do **not** have to declare a parameter to read it -- every value present on the URL is automatically available under `context.parameters.`, keyed by the name you gave it in the URL. Read one through the [dynamic value expression](/powersheet/concepts/dynamic-expressions) `() => …` form:
```yaml theme={null}
where:
component: "() => context.parameters.device" # from ?device=…
```
For a URL ending `…&device=laptop`, `context.parameters.device` resolves to the string `laptop`. Declaring the parameter (see below) is only needed for defaults and the required gate.
## URL parameters work anywhere a `() =>` value is accepted
`context.parameters` is a plain map, and it is available in **every** place that accepts a `() => …` dynamic value -- not only query filters. The same `() => context.parameters.` expression works across the [source configuration](/powersheet/concepts/source-configuration):
| Surface | Example use |
| ---------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| Query `where` (root or an [expand subquery](/powersheet/concepts/server-side-filtering)) | Scope which rows load on the server. |
| `entityFactory` defaults | Seed a new row with the slice it was created in. |
| Computed column (`value`) | Fold a URL value into a calculated cell. |
| Cell `render` | Reflect a URL value in custom cell HTML. |
| `constraints.applyCurrentDocumentTo` | Choose (dynamically) which entity type is scoped to the current document. |
| [Header](/powersheet/reference/sheet-config/sheet-header) `title` / `subtitle` / `icon` | State which slice is on screen -- a label, project name, or icon driven by a URL value. |
Which context object is available in each of these places is documented under [Dynamic Value Expressions](/powersheet/concepts/dynamic-expressions); this page is about getting values *into* `context.parameters` from the URL. Feeding a URL value into a query `where` is how a sheet is scoped on the server -- see [Server-Side Filtering](/powersheet/concepts/server-side-filtering) for that mechanism.
### Also in server-rendered properties
Starting with Powersheet 26.7.2, the same URL parameters also reach [server-rendered properties](/powersheet/reference/server-rendering/context-variables). A `serverRender` Velocity template reads them through `$context.parameters.` -- the server-side counterpart of the client-side `() => context.parameters.` form. Use it to compute a value on the server that depends on a URL parameter, for example narrowing a computed column to the slice named in the URL. Read the parameter with Velocity's quiet reference (`$!context.parameters.`) so a missing parameter renders blank rather than printing the literal reference text. See [Context Variables](/powersheet/reference/server-rendering/context-variables) for the full details and a worked example.
## Declaring parameters
You declare a parameter only when you want to control what happens if it is absent -- require it, or give it a default. The top-level `parameters` block is a map keyed by parameter name (the same shape as `columns` and `views`):
```yaml theme={null}
parameters:
device: # required -- the sheet won't open without ?device=…
required: true
approval: # optional -- this value is used when ?approval is absent
default: approved
```
| Field | Effect |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `required: true` | No URL value and no `default` -- the sheet refuses to open and shows a message (see below). |
| `default: ` | Used when the parameter is absent from the URL. A `required` parameter that also has a `default` is satisfied by the default and will not block. |
## Guiding the user when a required parameter is missing
A bare "missing parameter" error is a dead end. Add `ifMissing` to turn the block into a way out -- a message and an optional link to a page where the user can pick a valid value:
```yaml theme={null}
parameters:
device:
required: true
ifMissing:
message: "Pick a device to load its requirements."
button:
label: "Back to the overview"
url: "() => `${context.polarionBaseUrl}/polarion/#/project/${context.project.id}/wiki/Index`"
```
The block dialog then shows your message and a button that opens `button.url` in the same tab. The button appears only when `button.url` is set; `button.label` falls back to a generic label when omitted. All three of `message`, `button.label`, and `button.url` accept the `() =>` dynamic form, so both the label and the destination can be computed from context. Document administrators additionally see an **Open Configuration** button. If several required parameters are missing at once, the dialog lists them all and shows the message of the first one that declares an `ifMissing`.
## What happens when a value is missing
| Situation | Result |
| --------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| Declared `required`, no `default` | The sheet does not open; the user sees the message (and the optional `ifMissing` link). |
| Declared optional with a `default` | The `default` value is used. |
| Referenced but not declared, and absent | The condition that uses it is dropped -- that filter quietly disappears and the level loads unfiltered. |
**A broken expression fails loudly**
A parameter that has no value degrades gracefully (the condition is dropped). This is distinct from a malformed `() => …` expression, which raises an error during query construction rather than silently producing a filterless query.
## System parameters
Powersheet carries its own navigation and UI state in URL parameters too. Starting with Powersheet 26.7.2, these **system parameters** all begin with an underscore (`_`), which keeps them out of the way of your own parameter names:
| Parameter | Purpose |
| ----------- | --------------------------------------------------------------------------------------------- |
| `_project` | Current Polarion project. |
| `_document` | Current [document](/powersheet/reference/query-api/document-filtering). |
| `_revision` | [Historical revision](/powersheet/reference/query-api/baseline-and-revision-queries) to load. |
| `_title` | Document title carried from the Polarion link. |
| `_view` | Saved [view](/powersheet/reference/sheet-config/views) to apply on load, by view id. |
Reserve the leading underscore for Powersheet: **do not give your own parameters names beginning with `_`.** Powersheet also writes an internal `_version` cache-buster onto the URL; you never set it yourself.
**Older links keep working**
Before 26.7.2 these parameters had no underscore (`document`, `revision`, `documentTitle`). Those bare names are still honored for links saved in Polarion documents, wikis, and bookmarks, so existing links open exactly as before. When both the underscored and the legacy bare name are present, the underscored one wins.
Because system parameters are now underscore-prefixed, a parameter you name `document` (or any former reserved name) no longer collides with navigation state: it arrives verbatim in `context.parameters.document` and does not affect which document the sheet loads.
**Context fields are unchanged**
The typed context fields your configuration already reads -- `context.project`, `context.document`, `context.revision`, `context.documentTitle` -- keep their names and behavior. The underscore rename applies to the URL only, so existing sheet configurations need no edits.
## Related
The main thing URL parameters drive: filtering a sheet on the server so only the matching slice loads.
Step-by-step: reference a parameter, build the shareable URL, and gate required values.
The `parameters` block schema, reserved names, and the full configuration surface.
The `() => …` syntax and the context object that `context.parameters` is read from.
# User Roles and Permissions
Source: https://learn.nextedy.com/powersheet/concepts/user-roles-and-permissions
Nextedy POWERSHEET operates as an embedded application within Siemens Polarion ALM, which means its permission model is not a standalone access control system.
This page explains how Polarion's native permission layers interact with Powersheet's configuration and runtime behavior, and where administrators should focus their attention when setting up role-based access.
## The Permission Inheritance Principle
Think of Powersheet as a window into Polarion data. Just as a glass window lets you see what is on the other side but does not change what is actually there, Powersheet displays and edits work items through Polarion's own data layer. The permissions governing who can see and modify those work items are determined by Polarion, not by Powersheet itself.
This means:
* A user who cannot read a certain work item type in Polarion will not see those items in a Powersheet view
* A user who lacks write permission on a field in Polarion will be unable to save changes to that field through the sheet
* Project-level role assignments in Polarion carry directly into what a user experiences in Powersheet
**No Separate Login**
Powersheet does not maintain its own user database or authentication system. Users are authenticated by Polarion, and their identity flows through to every Powersheet operation.
## Polarion's Role-Based Access Control
Polarion uses a role-based access control (RBAC) system with two layers: **global roles** and **project roles**. Both layers affect what a user can do inside Powersheet.
### Global Roles
Global roles apply across the entire Polarion instance. The most relevant global roles for Powersheet are:
| Global Role | Powersheet Impact |
| -------------------- | ------------------------------------------------------------------------------------------------------- |
| **Administrator** | Full access to all projects and configurations, including data model and sheet configuration YAML files |
| **User** | Standard access governed by project-level role assignments |
| **Guest / External** | Typically read-only; cannot save changes through the sheet |
### Project Roles
Within each Polarion project, users are assigned one or more project-level roles. These roles determine fine-grained permissions on work item types, fields, and operations.
Common project roles that affect Powersheet behavior:
| Project Role | Typical Permissions | Powersheet Effect |
| -------------------- | -------------------------------- | ---------------------------------------------------------- |
| Project Admin | Full project control | Can modify data models, sheet configurations, and all data |
| Project Member | Read/write on most work items | Can view and edit sheet data within their permission scope |
| Reviewer | Read-only on documents and items | Can view sheets but not save changes |
| External Stakeholder | Limited read access | May see only certain entity types in the sheet |
**Role Assignment Is Per-Project**
A user who is a Project Admin in one project may be a Reviewer in another. Powersheet respects this boundary — the same user will have full editing capabilities in the first project's sheets and read-only access in the second.
## How Permissions Affect Sheet Operations
Powersheet operations map to Polarion permission checks at several levels. Understanding these mappings helps explain why a user might be able to perform some actions in a sheet but not others.
### Viewing Data
When a sheet loads, Powersheet queries Polarion for work items matching the sheet's source configuration and expansion paths. Polarion's query engine automatically filters results based on the current user's read permissions. If a user lacks read access to a particular work item type (for example, `Hazard` items in a safety project), those rows simply will not appear in the sheet.
This filtering is transparent — the sheet displays only what the user is authorized to see, without error messages for items that were filtered out.
### Editing and Saving
When a user modifies a cell and triggers a save operation, Powersheet sends the change to Polarion's server API. Polarion validates that the current user has write permission on the specific field of the specific work item being modified. If the user lacks permission, the save operation will be rejected.
Key behaviors during save:
* **Field-level granularity**: A user might be able to edit the `severity` field on a `Hazard` but not the `status` field, depending on workflow and field-level permissions
* **Workflow constraints**: Even with write permission, Polarion workflow rules may prevent certain state transitions
* **Link role permissions**: Creating or removing links between entity types (for example, linking a `RiskControl` to a `Hazard`) requires permission on both the source and target work items, as well as permission to modify the relevant link role
For more details on how save operations are processed, see [Save Operations Guides](/powersheet/guides/save-operations/index).
### Configuration Access
Modifying data model YAML files and sheet configuration YAML files is an administrative action. These files are stored in the project's SVN repository under the `.polarion/nextedy/` directory structure.
Access to configuration requires:
* **SVN write access** to the project's configuration directory
* **Project administration privileges** in Polarion, typically granted through the Project Admin role
* Access to the **Administration > Nextedy Powersheet** menu in the Polarion UI
**Configuration Changes Affect All Users**
Unlike data edits that affect individual work items, changes to data models and sheet configurations affect every user who opens that sheet. Always coordinate configuration changes with your team.
## License State Override
Before any role-based permission check applies, Powersheet evaluates the **license state** of the Powersheet installation. The license state acts as a global override layer that sits above all roles and project permissions.
| License State | Effect |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| **Valid** | Normal operation — role-based permissions apply as described below |
| **Invalid / Expired** | Global read-only mode — all users, including administrators, lose write access. Sheets can be viewed but no data can be saved or modified. |
When the license is invalid or expired, Powersheet forces read-only mode regardless of the user's Polarion role assignments. This means a Project Admin with full write permissions in Polarion will still be unable to save changes through Powersheet until the license is restored. The sheet UI may display a license warning banner.
**License overrides all roles**
An expired or invalid license forces every user into read-only mode. If users report that save operations are failing across all projects simultaneously, check the license state before investigating role assignments.
To verify or update the license, see [Update Powersheet](/powersheet/guides/administration/update-powersheet).
## The Three Permission Tiers
In practice, Powersheet users fall into three broad permission tiers based on how Polarion's RBAC maps to sheet functionality.
### Tier 1 — Viewer
Users with read-only project access. They can:
* Open sheets and browse entity hierarchies through expansion paths
* Switch between named views to see different column presets
* Sort, filter, and search within their visible data
* Export visible data where export functionality is available
They cannot modify any data or configuration.
### Tier 2 — Editor
Users with project write access on relevant work item types and fields. They can do everything a Viewer can, plus:
* Edit cell values directly in the sheet
* Save changes to work item fields they have write permission on
* Create, modify, or remove links between entity types (subject to link role permissions)
* Trigger workflow transitions where their role permits
### Tier 3 — Administrator
Users with project administration privileges. They can do everything an Editor can, plus:
* Modify data model YAML files (entity types, relationships, cardinality)
* Create and modify sheet configuration YAML files (columns, formatters, binding paths)
* Manage views (named column visibility presets)
* Configure process constraints and validation rules
For guidance on administrative tasks, see [Administration Guides](/powersheet/guides/administration/index).
## Views and Permission Boundaries
Views in Powersheet — named column visibility presets that allow different analysis perspectives — are available to all users who can access the sheet. Views do not add or restrict data access; they simply control which columns are visible in the current layout.
This is an important distinction: a view labeled "Safety Analysis" that shows risk-related columns does not grant access to risk data that the user could not already see. If a user lacks read permission on `Hazard` entity types, those columns will be empty regardless of the view selected.
For more on how views work, see [Views as Analysis Perspectives](/powersheet/concepts/views-as-perspectives).
## Common Misconceptions
### "Powersheet has its own permission system"
Powersheet does not maintain a separate permission layer. Every access check is delegated to Polarion. If a user reports unexpected access restrictions in a sheet, the investigation should start in Polarion's project role and permission configuration, not in Powersheet's YAML files.
### "Hiding a column hides the data"
Removing a column from a sheet configuration or a view makes the data invisible in that particular sheet layout, but it does not restrict access to the underlying work item field. Users can still see and edit that field through Polarion's native work item editor, other sheets, or the Polarion API. Column visibility is a presentation concern, not a security mechanism.
### "Data model restrictions limit data access"
The data model defines which entity types and relationships Powersheet knows about and can navigate. If an entity type is not in the data model, Powersheet will not display it — but this is a configuration scope decision, not an access control mechanism. The underlying data remains accessible through Polarion's standard interfaces.
**Verify in application**
The exact behavior of permission enforcement during save operations, including error messaging and partial-save handling, may vary by Polarion version and Powersheet release. Test your specific permission configurations in a non-production environment before rolling out to users.
## Practical Implications for Configuration
When designing sheet configurations, keep these permission-related principles in mind:
**Match sheet scope to audience roles.** If a sheet is intended for reviewers who have read-only access, avoid including editable columns that will produce save errors. Instead, consider creating separate sheet configurations for different permission tiers — a read-oriented view for reviewers and an edit-oriented configuration for project members.
**Use Polarion's field-level permissions for sensitive data.** If certain fields (for example, cost estimates or proprietary risk assessments) should be visible only to specific roles, configure those restrictions in Polarion's permission settings rather than relying on column visibility in Powersheet.
**Test with representative user accounts.** When setting up a new sheet configuration, log in as users with different project roles to verify that the sheet behaves correctly at each permission level. Pay particular attention to save operations and link creation, where permission gaps are most likely to surface.
**Document role requirements.** For each sheet configuration you deploy, maintain a note of which Polarion project roles are expected to use it and whether they need read-only or read-write access. This helps onboarding and troubleshooting.
For step-by-step configuration guidance, see [Sheet Configuration Guides](/powersheet/guides/sheet-configuration/index) and [Data Model Guides](/powersheet/guides/data-model/index).
## Relationship to Process Constraints
Powersheet's process constraints (validation rules that enforce data quality during save operations) operate alongside Polarion's permissions but serve a different purpose. Permissions answer "is this user allowed to modify this field?" while constraints answer "is the proposed value acceptable?"
A user might have full write permission on a field but still be prevented from saving by a constraint that enforces a required value or a specific format. These two mechanisms are complementary that enforces a required value or a specific format. These two mechanisms are complementary — permissions gate who can act, and constraints gate what actions are valid.
For more on how constraints work, see [Process Constraints](/powersheet/concepts/process-constraints).
## Summary
Powersheet's permission model is deliberately simple: it defers entirely to Polarion's role-based access control. This design means there is no separate permission system to learn, configure, or maintain. The trade-off is that effective Powersheet access management requires a solid understanding of Polarion's project roles, field-level permissions, and workflow rules — the same skills needed to administer any Polarion project.
| Concern | Where to Configure |
| ---------------------------------- | ----------------------------------------------------- |
| Who can see which work items | Polarion project roles and work item type permissions |
| Who can edit which fields | Polarion field-level permissions and workflow rules |
| Who can modify sheet configuration | Polarion project administration role + SVN access |
| Which columns appear in the sheet | Sheet configuration YAML and views |
| What values are valid during save | Process constraints in Powersheet configuration |
# Views as Analysis Perspectives
Source: https://learn.nextedy.com/powersheet/concepts/views-as-perspectives
Nextedy POWERSHEET allows a single sheet configuration to present multiple faces of the same underlying data through **views**.
## The lens analogy
Imagine a large table of engineering data laid out on a desk. The table itself does not change -- the same rows, the same relationships, the same values. Now imagine placing different colored filters over that table. One filter highlights requirement traceability columns and hides risk columns. Another reveals verification and validation test case columns while concealing design-level detail. A third shows everything. Each filter is a **view** -- a named perspective that selects which columns to show and which to suppress.
The critical insight is that views are **not separate sheets**. They are overlays on a single sheet configuration. When you switch from one view to another, the data does not reload, the hierarchy does not change, and any unsaved edits remain intact. Only the column visibility toggles.
Each view points to the same underlying data. Switching views does not reload or requery -- it toggles column visibility.
## How views relate to the base configuration
Every sheet configuration has an implicit **Base View**. This is the column layout defined directly in the top-level `columns` section of the sheet configuration YAML. The Base View represents the full set of columns and their default visibility. If no `views` section exists, or if no named view has been selected by the user, the Base View is what the sheet displays. It is labeled "Default view" in the user interface unless you explicitly name it.
Named views, defined in the `views` section of the YAML, are **extensions of the Base View**, not replacements. A named view does not need to redeclare every column -- it only overrides the properties it wants to change. In practice, this almost always means toggling `visible` to `true` or `false` for specific columns. The binding paths used in a view must match the binding paths defined in the Base View's `columns` section; a view cannot introduce columns that do not exist in the base configuration.
**Views extend, they do not replace**
A view only needs to declare the columns whose visibility (or other properties) differ from the Base View. Every column not mentioned in a view inherits its default state from the base `columns` definition.
### Naming the Base View
You can give the Base View a display name by defining an empty view in the `views` section:
```yaml theme={null}
views:
Full Traceability: {}
```
This creates a view named "Full Traceability" that behaves identically to the base configuration. It provides a human-friendly label in the view switcher instead of the generic "Default view".
## View structure in YAML
Views are defined under the `views` key at the root level of the sheet configuration. Each view is a named object whose `columns` property lists the binding paths to override:
```yaml theme={null}
views:
Without V&V:
columns:
validationTestCases.validationTestCase:
visible: false
systemRequirements.systemRequirement.verificationTestCases.verificationTestCase:
visible: false
systemRequirements.systemRequirement.designRequirements.designRequirement.verificationTestCases.verificationTestCase:
visible: false
```
In this example, the "Without V\&V" view hides all verification and validation test case columns across multiple levels of the hierarchy while leaving every other column in its base state. The binding paths (`validationTestCases.validationTestCase`, etc.) must exactly match those declared in the base `columns` section.
### Setting a default view
Any view can be marked as the view that loads automatically when a user first opens the sheet:
```yaml theme={null}
views:
Requirements Only:
default: true
columns:
hazard:
visible: false
riskControls.riskControl:
visible: false
```
When `default` is set to `true`, this view is applied during initialization instead of the Base View. If no view has `default: true`, the Base View is used. Only one view should be marked as default; if multiple views declare `default: true`, the behavior is undefined and may vary.
## View properties reference
Views support a focused subset of the properties available on base columns:
| Property | Type | Purpose |
| --------------------------- | ------- | --------------------------------------------------------------------- |
| `default` | boolean | When `true`, this view loads on initialization. Default: `false` |
| `columns` | object | Subset of base column binding paths with overridden properties |
| `columns.` | object | Override object for a specific column, identified by its binding path |
| `columns..visible` | boolean | Show or hide the column in this view |
The `columns` within a view use the same binding path notation as the base `columns` section -- dot-separated paths that follow navigation properties through the data model hierarchy (e.g., `systemRequirements.systemRequirement.title`).
Views currently control column **visibility**. They share the same configuration options as base columns, but in practice `visible` is the primary property used in view overrides. Other column properties like `width` or `title` can theoretically be set per view, but visibility toggling is the intended and most common use case.
## Why views matter: analysis perspectives
In a real-world project, a single traceability matrix may contain dozens of columns spanning entity types across the full requirements chain (`UserNeed` through `SystemRequirement`, `DesignRequirement`, `Hazard`, and `RiskControl`). Different roles need different subsets of this information:
* A **requirements engineer** working on allocation may want to see `UserNeed` properties alongside `SystemRequirement` properties, but has no need for risk or test columns
* A **safety engineer** performing a risk assessment wants `Hazard` and `RiskControl` columns in focus, with requirement columns collapsed or hidden
* A **test engineer** preparing verification plans needs the test case columns visible and requirement details reduced to identifiers only
* A **project manager** reviewing overall coverage wants a broad view showing key status fields across all entity types
Without views, each of these perspectives would require a separate sheet configuration pointing to the same data model and the same data sources. That approach leads to configuration duplication, maintenance burden, and divergence risk. Views eliminate this problem by keeping a single source of truth for columns, sources, and data while allowing each audience to focus on what matters to them.
## The mental model: one sheet, many lenses
The following table captures the key distinction between views and other approaches to displaying different subsets of data:
| Approach | Data sources | Column definitions | Maintenance cost |
| ----------------------------- | --------------------- | --------------------------------------- | -------------------------------------------------- |
| Separate sheet configurations | Duplicated per config | Duplicated per config | High -- changes must propagate to all copies |
| Single config, no views | Shared | Single set, all visible | Low config, but cluttered for users |
| Single config with views | Shared | Single set, visibility toggled per view | Low -- one base config, lightweight view overrides |
Views occupy the efficient middle ground. They avoid duplication while still providing focused, role-appropriate presentations of the data.
**Views do not filter rows**
A common misconception is that views can show or hide specific *rows* or entity types. Views operate exclusively at the column level. If you need to filter which rows appear, use source query `where` clauses or client-side column filters (the `filter` property on individual columns). See [Source Configuration](/powersheet/concepts/source-configuration) for query-level filtering.
## Views and column groups
Views interact naturally with **column groups** (`columnGroups`). When a view hides all columns within a particular column group, the group header also disappears from the sheet. When a view reveals columns within a group, the group header reappears. This means you can use column groups to organize related columns under a common header, and then use views to show or hide entire groups at once by toggling the visibility of their member columns.
For example, if a column group named "Test Cases" contains three test-related columns, a view that sets all three to `visible: false` effectively hides the entire group. No special group-level visibility setting is needed -- the group's visibility follows its columns.
This interaction between views and column groups creates a powerful organizational pattern:
1. Define column groups in the base configuration to cluster related columns (requirements, tests, risks)
2. Define views that toggle visibility of entire groups by listing their member columns
3. Users switch views to reveal or hide logical sections of the sheet
## Practical patterns
### The "progressive disclosure" pattern
Define views that progressively reveal more columns:
* **Overview** -- shows only key identifiers and status fields across all entity types
* **Detailed** -- adds description, priority, and assignment columns
* **Full** -- shows every column, including metadata and audit fields
This pattern works well for onboarding new users who might be overwhelmed by a fully expanded sheet.
### The "role-based" pattern
Define views named after the roles that use them:
* **Requirements Engineer** -- `UserNeed` and `SystemRequirement` columns prominent, test and risk columns hidden
* **Safety Engineer** -- `Hazard` and `RiskControl` columns visible, design columns hidden
* **Reviewer** -- status, owner, and approval columns visible across all entity types
Role-based views make the sheet self-documenting. A user switching to their role's view instantly sees a tailored workspace.
### The "phase-based" pattern
In projects that follow lifecycle phases, views can align with project milestones:
* **Requirements Phase** -- focuses on allocation and decomposition columns
* **Design Phase** -- reveals design requirement and architecture columns
* **Verification Phase** -- shows test case and test result columns
Each phase view keeps historical columns accessible (just hidden) while foregrounding the currently active work.
## Common misconceptions
**"Switching views reloads the data."** It does not. View switching is a client-side operation that toggles column visibility. The data remains loaded in memory. Unsaved changes, scroll position, and expanded rows are preserved.
**"I need a separate sheet configuration for each team."** In most cases, a single sheet configuration with well-designed views achieves the same result with far less maintenance. Reserve separate configurations for cases where the *data sources* or *expansion paths* differ, not just the visible columns.
**"Views can change the column order."** Views control visibility, not column ordering. The column order is determined by the sequence in which columns are declared in the base `columns` section. If you need a different column sequence, that requires a separate sheet configuration.
**"A view can add columns that are not in the base configuration."** A view's `columns` property must reference binding paths that already exist in the base `columns` section. A view cannot introduce new binding paths or new columns -- it can only modify properties of existing ones.
## Relationship to other concepts
Views are one layer in the Powersheet configuration stack. Understanding where they fit helps avoid over-engineering at the wrong layer:
* **Data model** defines what data exists and how entity types connect -- see [Entity Types and Relationships](/powersheet/concepts/entity-types-and-relationships)
* **Sheet configuration** (base) defines all available columns, sources, and layout -- see [Data Model vs Sheet Configuration](/powersheet/concepts/data-model-vs-sheet-config)
* **Views** control which columns are visible for a given perspective (this page)
* **Column groups** organize columns into collapsible visual sections -- see [Core Components](/powersheet/concepts/core-components)
* **Source configuration** controls which data is loaded and how the hierarchy expands -- see [Source Configuration](/powersheet/concepts/source-configuration)
For practical guidance on creating and managing views in your sheet configuration, see the [Sheet Configuration Guides](/powersheet/guides/sheet-configuration/index). For the complete YAML reference of view properties, see the [Sheet Configuration Reference](/powersheet/reference/sheet-config/index).
# Working Sessions and Save Behavior
Source: https://learn.nextedy.com/powersheet/concepts/working-sessions
When you open a Nextedy POWERSHEET document in Siemens Polarion ALM, you begin a **working session** -- a period of interactive editing where changes accumulate locally in the browser before being committed to Polarion with an explicit save.
This page explains the session lifecycle, the explicit save model, how concurrent editing is handled, and what recovery options exist when things go wrong.
## The Explicit Save Model
Powersheet uses an **explicit save** model, not auto-save. Every edit you make -- changing a cell value, adding a row, deleting a row, creating a link -- is captured in a local change buffer within your browser session. Nothing is written to Polarion until you click **Save**.
Think of this like a text editor with an unsaved document indicator. You can make dozens of changes, undo some of them, review what you have modified, and only persist when you are satisfied. The alternative -- auto-saving every keystroke to the server -- would be impractical in a regulated engineering environment where each save creates a revision in Polarion's audit trail.
This model has several important implications:
* **Navigating away discards unsaved changes.** If you close the browser tab, navigate to a different page, or refresh the browser, your local change buffer is lost. There is no draft recovery or local persistence.
* **Each save creates Polarion revisions.** Every saved modification produces an auditable revision in Polarion's version history, which is critical for compliance in regulated industries.
* **Undo only works before saving.** The undo/redo stack (`Ctrl+Z` / `Ctrl+Y`) tracks operations within the current session. Once changes are saved, the stack is cleared. Reverting a saved change requires using Polarion's native revision history.
**No auto-save**
Powersheet does not auto-save. If you have been editing for an extended period, save regularly to avoid losing work. A good practice is to save after completing each logical group of changes -- for example, after updating all fields on a set of related requirements.
## Session Lifecycle
A working session starts when Powersheet loads data and ends when you navigate away or close the browser. During this lifecycle, several phases occur.
### Loading Phase
When you open a powersheet document, the client application requests metadata and data from the server:
1. **Configuration loading** -- the server reads the data model and sheet configuration YAML files
2. **Metadata generation** -- the server produces a typed schema describing entity types, properties, relationships, and constraints
3. **Data query** -- the server translates the sheet's source configuration into Polarion Lucene queries and returns matching work items
4. **Client rendering** -- the browser renders the sheet with loaded data, applying column definitions, formatters, and conditional styling
At this point the session is live. The sheet displays a snapshot of the data as it existed at query time.
### Editing Phase
During the editing phase, all changes are local:
| Operation | What Happens Locally | What Happens on Server |
| ------------- | --------------------------------------------------- | ---------------------- |
| Edit a cell | Value stored in change buffer, row marked modified | Nothing |
| Add a row | New entity created in local state with temporary ID | Nothing |
| Delete a row | Row marked for deletion in change buffer | Nothing |
| Create a link | Relationship staged in change buffer | Nothing |
| Undo/redo | Change buffer entries reverted or re-applied | Nothing |
The **Save** button activates only when the change buffer contains at least one pending operation. The toolbar displays a count of changed rows when review mode is active.
### Save Phase
When you click **Save**, Powersheet executes a structured commit sequence:
1. **Validation** -- all pending changes are checked against data model constraints, including required fields, cardinality rules, and process constraints
2. **Dependency ordering** -- entities are sorted so that items referenced by links are saved before the links themselves
3. **Server commit** -- each entity is saved to Polarion via the server API, creating work items, updating fields, and establishing links
4. **Confirmation** -- on success, the change buffer and undo stack are cleared, and the sheet refreshes to show the persisted state
If any validation error occurs, the save is blocked and the error is reported. You must resolve the issue before the save can proceed.
**Save is atomic per entity**
The save operation processes entities one by one in dependency order. If an error occurs partway through, entities already saved remain persisted. This is not a database transaction that rolls back entirely -- partially saved states are possible, though rare. Always review validation results before saving.
### Session End
A session ends when you navigate away from the document, close the browser tab, or refresh the page. There is no session timeout that automatically saves your work. Unsaved changes are lost silently.
## The Change Buffer
The change buffer is the central data structure of a working session. It acts as a local transaction log, recording every operation in sequence. Understanding what the change buffer tracks helps explain behaviors like undo granularity and review mode filtering.
The change buffer records:
* **Cell edits** -- the original value and the new value for each modified cell, enabling undo
* **Row additions** -- new entities with temporary IDs and their initial field values
* **Row deletions** -- which existing entities are marked for removal
* **Link operations** -- staged relationship changes (new links, removed links)
The undo/redo mechanism walks this log backward and forward. Each atomic user action (one cell edit, one row addition) is one undo step. You cannot undo "half" of a cell edit.
**Review mode** uses the change buffer to filter the sheet display. When review mode is active, only rows with pending changes are shown. This gives you a focused view of what will be sent to the server when you save. Modified cells show visual indicators so you can verify each change.
**Review before saving**
In regulated environments, enabling review mode before saving is a best practice. It reduces the risk of accidentally persisting unintended changes, especially in large sheets with hundreds of rows where a stray edit might go unnoticed.
## Concurrent Editing
In any multi-user environment, the question arises: what happens when two users edit the same sheet -- or the same work item -- at the same time? Powersheet handles this through a **last-write-wins** model at the Polarion level, combined with session-level isolation.
### Session Isolation
Each browser session operates independently. When User A and User B open the same powersheet document, they each receive their own snapshot of the data at load time. Their change buffers are completely separate. Neither user sees the other's unsaved changes.
### Last-Write-Wins
Because Powersheet does not maintain its own data store (all data lives in Polarion), concurrent save operations are resolved by Polarion's native behavior. If User A saves a change to a work item's `severity` field and User B subsequently saves a different value to the same field, User B's value overwrites User A's. There is no merge dialog or conflict detection within Powersheet itself.
This has practical implications:
* **Non-overlapping edits are safe.** If two users edit different fields on the same work item, or different work items entirely, their saves do not interfere with each other.
* **Overlapping edits follow last-write-wins.** If two users modify the same field on the same work item, the last save prevails. The earlier save is overwritten without warning.
* **Stale data is possible.** After User A saves, User B's sheet still shows the data from their original snapshot. User B does not automatically see User A's changes until they refresh the page.
**Coordinate in shared sheets**
In team environments, communicate with colleagues when working on the same documents. Adopting conventions -- such as assigning ownership of specific entity types or document sections to individual team members -- reduces the risk of conflicting edits. Refreshing the page before starting a new editing session ensures you are working with current data.
### Refresh to Synchronize
To see changes made by other users (or by other Polarion tools), you must **reload the page**. Powersheet does not poll the server for updates or push real-time notifications. The data you see in the sheet reflects the state at the time the page was loaded (or last refreshed).
This behavior is consistent with the broader Polarion architecture, where LiveDoc pages and reports also display point-in-time snapshots rather than live-updating views.
## Handling Errors and Recovery
### Validation Errors
If the save operation encounters a validation error -- for example, a required field is empty or a constraint is violated -- the save is blocked. The error is displayed in the sheet, and you must resolve the issue before the save can proceed.
Validation errors do not discard your changes. The change buffer remains intact, and you can fix the problematic field and retry the save. See [Handle Validation Errors](/powersheet/guides/save-operations/handle-validation-errors) for detailed steps.
### Error State
In rare cases, an unexpected error during save can place the sheet in an **error state**. When this happens, further save operations are blocked with a message indicating that the application has encountered an error. The recommended recovery is to reload the browser page.
**Reload loses unsaved changes**
If the sheet enters an error state and you need to reload, any unsaved changes in your change buffer are lost. This is another reason to save frequently -- smaller, more frequent saves reduce the amount of work at risk if an error occurs.
### Browser and Network Issues
Because all unsaved changes exist only in the browser's memory, several common scenarios can cause data loss:
| Scenario | Impact | Recovery |
| -------------------------- | ----------------------------------------- | ----------------------------------------------------- |
| Browser tab closed | Unsaved changes lost | Re-open document, re-apply changes manually |
| Browser crash | Unsaved changes lost | Re-open document, re-apply changes manually |
| Network disconnection | Save operation fails | Restore network, retry save (change buffer preserved) |
| Session timeout (Polarion) | Next save fails with authentication error | Log in again, reload page (unsaved changes lost) |
| Page refresh | Unsaved changes lost | Re-apply changes manually |
Network disconnections are the most recoverable scenario -- if the browser stays open, your change buffer remains intact. Once the network is restored, you can retry the save without losing work.
## Why Explicit Save Matters
The explicit save model is a deliberate architectural choice that aligns with the regulated engineering context where Powersheet is typically deployed.
**Auditability.** In environments governed by ISO 26262, Automotive SPICE, or similar standards, every change to a requirement or risk assessment must be traceable. Auto-saving every keystroke would create an excessive revision history, making it difficult to distinguish intentional decisions from typing corrections. The explicit save model ensures that each revision represents a completed, reviewed set of changes.
**Batch coherence.** Engineering changes often span multiple related fields and entities. A system requirement update might involve changing the title, updating the verification status, and adjusting a linked hazard's risk level. The explicit save model lets you make all related changes before committing them together, ensuring that the Polarion revision history shows a coherent state rather than intermediate half-finished updates.
**Undo safety.** The ability to undo changes before saving provides a safety net that auto-save cannot offer. If you accidentally delete a row or overwrite a field, `Ctrl+Z` restores the previous state immediately. With auto-save, such mistakes would require navigating Polarion's revision history to recover.
**Save frequency guideline**
Balance between saving too frequently (creating noise in the revision history) and too infrequently (risking data loss). A practical approach: save after completing each logical unit of work, such as updating all properties of a single entity type or finishing a set of related traceability links.
## Common Misconceptions
**"Powersheet auto-saves my work."** It does not. Every edit is local until you explicitly click Save. Closing the browser without saving discards all pending changes.
**"Other users can see my changes in real time."** They cannot. Each session is isolated. Other users see the state of the data at the time they loaded the page. They must refresh to see your saved changes.
**"If the save fails, I lose everything."** Not necessarily. Validation errors keep your change buffer intact -- you fix the issue and retry. Only browser-level events (closing, crashing, refreshing) destroy the change buffer.
**"Undo works after saving."** It does not. The undo stack is cleared when a save completes. To revert a saved change, use Polarion's native revision history on the affected work item.
**"Saving locks the work items for other users."** It does not. Powersheet does not acquire locks during save. Multiple users can save to the same work items, with last-write-wins resolution at the Polarion level.
## Related Pages
* [Powersheet Architecture](/powersheet/concepts/architecture) -- how the client, server, and Polarion data layer interact
* [Process Constraints](/powersheet/concepts/process-constraints) -- validation rules that can block save operations
* [Update a Work Item](/powersheet/guides/save-operations/update-work-item) -- step-by-step editing and saving workflow
* [Handle Validation Errors](/powersheet/guides/save-operations/handle-validation-errors) -- resolving errors that prevent saving
* [Create a Work Item](/powersheet/guides/save-operations/create-work-item) -- adding new entities with constraint enforcement
# YAML Configuration System
Source: https://learn.nextedy.com/powersheet/concepts/yaml-configuration
Nextedy POWERSHEET uses a declarative YAML-based configuration system that separates *what you want to see* from *how the system retrieves it*.
This page explains the architecture of the configuration system, how its layers interact, and why the design works the way it does. For practical setup instructions, see the [Sheet Configuration Guides](/powersheet/guides/sheet-configuration/index). For a primer on YAML syntax itself, see [YAML Primer for Powersheet](/powersheet/concepts/yaml-primer).
## Two Configuration Files, Two Responsibilities
Every Powersheet deployment relies on two distinct YAML files that serve complementary purposes:
| File | Responsibility | Analogy |
| ----------------------- | ------------------------------------------------------------------------------------------------ | ----------------- |
| **Data model** | Defines *what exists* — entity types, their properties, and how they relate to each other | A database schema |
| **Sheet configuration** | Defines *what to show* — which columns to display, how to format them, and where to get the data | A report template |
This separation is intentional. A single data model can power many different sheet configurations, each offering a different perspective on the same underlying data. Think of it like a relational database: you define the schema once, then write as many queries and views as you need.
The data model defines the vocabulary; the sheet configuration uses that vocabulary to compose a specific view.
## Anatomy of a Sheet Configuration
A sheet configuration file is organized into several top-level sections, each controlling a distinct aspect of the rendered sheet:
```yaml theme={null}
# Top-level sections of a sheet configuration
columnGroups: # Visual grouping of related columns
sortBy: # Default sort order
columns: # Column definitions with binding paths
views: # Named visibility presets
formatters: # Conditional styling rules
styles: # Reusable CSS class definitions
sources: # Data retrieval and expansion paths
```
### Columns: The Core Building Block
The `columns` section is where most configuration effort goes. Each entry maps a **binding path** — a dot-separated property reference from the data model — to display settings:
```yaml theme={null}
columns:
title:
title: "Title"
width: 300
hasFocus: true
systemRequirements.systemRequirement.title:
title: "System Requirement"
width: 250
columnGroup: sysReq
multiItem: true
display: title
```
The first column (`title`) references a simple property on the root entity. The second column (`systemRequirements.systemRequirement.title`) follows a navigation path through a relationship defined in the data model: from the root entity, through the `systemRequirements` relationship, to the `systemRequirement` entity type, and finally to its `title` property.
**Binding Paths Are Data Model References**
Every column key in the sheet configuration must correspond to a valid path through the data model. If a binding path references an entity type or relationship that does not exist in the data model, the column will fail to render. The data model acts as the contract that the sheet configuration relies on.
### Column Groups: Visual Organization
Column groups cluster related columns under a shared header with consistent styling. They are purely visual — they do not affect data retrieval:
```yaml theme={null}
columnGroups:
sysReq:
groupName: "System Requirements"
groupStyle: blue
headerStyle: blue
collapseTo: systemRequirements.systemRequirement.title
```
The `collapseTo` property specifies which column remains visible when the group is collapsed, giving users a compact summary view.
### Views: Named Perspectives
Views let administrators define named column visibility presets. A single sheet configuration can offer multiple analysis perspectives — for example, a "Risk Focus" view that hides requirement columns and emphasizes risk-related fields, or a "Full Traceability" view that shows everything:
```yaml theme={null}
views:
riskFocus:
columns:
hazards.hazard.severity:
visible: true
systemRequirements.systemRequirement.title:
visible: false
fullTraceability:
columns:
hazards.hazard.severity:
visible: true
systemRequirements.systemRequirement.title:
visible: true
```
Views override the default `visible` property of columns. Users switch between views at runtime without modifying the underlying configuration. For more on how views shape analysis workflows, see [Views as Analysis Perspectives](/powersheet/concepts/views-as-perspectives).
### Formatters and Styles: Conditional Presentation
Formatters apply conditional styling rules to cells based on their values. A formatter definition pairs an expression (the condition) with a style (the visual effect):
```yaml theme={null}
formatters:
severityHighlight:
expression: "value === 'Critical'"
style: criticalStyle
styles:
criticalStyle:
backgroundColor: "#ffebee"
color: "#c62828"
```
Setting a column's `isReadOnly` property to `true` or applying a read-only formatter prevents user editing regardless of permissions. This is useful for computed or derived columns that should only be viewed, not modified.
### Sources: Where Data Comes From
The `sources` section defines which entity types to load as root items, what query filters to apply, and how to expand related entities. Sources connect the sheet configuration to live Polarion data through the data model:
```yaml theme={null}
sources:
- type: UserNeed
query: "type:userneed AND NOT HAS_VALUE:resolution"
expand:
- systemRequirements.systemRequirement
- systemRequirements.systemRequirement.designRequirements.designRequirement
```
Each expansion path follows relationships defined in the data model, loading related entities at successive levels of the hierarchy. For a deeper understanding of how sources drive data loading, see [Source Configuration](/powersheet/concepts/source-configuration).
## Configuration Storage and Discovery
Powersheet configurations are stored in the Polarion repository (SVN) and can exist at two scopes:
* **Global configurations** are stored in a shared repository location, available to all projects. Their identifiers start with `/` and display with a "(Global)" suffix in the selection UI.
* **Project-specific configurations** are stored within a project's repository space. Their identifiers use the filename without a path prefix.
When an administrator assigns a sheet configuration to a Polarion document, a custom field (`nextedySheetConfig`) stores the configuration file reference. Powersheet dynamically discovers all available configuration files at both scopes and presents them as selectable options through the **Administration > Nextedy Powersheet** interface.
**No Default Configuration**
Users must explicitly select a configuration for each Powersheet document. There is no automatic default assignment — this is deliberate, because every document's data model and column needs differ. The system does include a bundled `powersheet.yaml` as a starter template, accessible through the built-in configuration editor.
## Configuration Scoping: Instance, Template, Default
The configuration editor supports three levels of scope that allow fine-grained override control:
| Scope | Purpose | Precedence |
| ------------ | ------------------------------------------------------------ | ---------- |
| **Instance** | Per-document overrides for a specific Powersheet | Highest |
| **Template** | Shared configuration template used across multiple documents | Middle |
| **Default** | Global fallback defaults | Lowest |
This layered approach means you can define a standard configuration template that multiple documents share, while still allowing individual documents to override specific settings. The scope control can be enabled, disabled, or disallowed at the administrator level, preventing end users from making scope changes when organizational consistency is required.
## How Configuration Becomes a Sheet
Understanding the runtime flow helps clarify why the configuration is structured the way it is:
1. **Load** — Powersheet reads the YAML configuration from the repository location stored in the document's custom field. If the file cannot be read or parsed, an error is surfaced (YAML parse errors are logged but do not crash the application).
2. **Validate against data model** — Column binding paths are resolved against the data model. Each dot-separated segment must match a known property or navigation path. Unresolvable paths produce rendering failures for those specific columns.
3. **Fetch metadata** — The metadata system translates entity types and relationships from the data model into a queryable schema that the client uses for data retrieval.
4. **Execute sources** — Source definitions trigger queries against Polarion, filtered by the specified query expressions. Expansion paths are followed to load related entities at each hierarchy level.
5. **Render** — Columns are laid out according to their defined widths, groups, and visibility settings. Formatters evaluate their expressions against cell values and apply styles. Views determine which columns are visible in the current perspective.
## The Data Model as Contract
The data model is not just a separate file — it is the **contract** that all sheet configurations must honor. It defines:
* **Entity types** via `domainModelTypes` — each mapping a logical name (like `UserNeed` or `SystemRequirement`) to a Polarion work item type through the `polarionType` property
* **Properties** — the fields available on each entity type, which become valid column binding targets
* **Relationships** — the navigation paths between entity types, including cardinality (one-to-one vs. one-to-many) and direction (direct vs. back)
When a sheet configuration references `systemRequirements.systemRequirement.title`, the data model must define: (1) a relationship called `systemRequirements` on the root entity, (2) that relationship's target entity type `SystemRequirement`, and (3) a `title` property on that entity type.
For deeper coverage of data model concepts, see [Model-Driven Design](/powersheet/concepts/model-driven-design) and [Entity Types and Relationships](/powersheet/concepts/entity-types-and-relationships).
## Common Misconceptions
**Configuration Complexity vs. Incremental Approach**
A frequent source of support issues is attempting to build a complex multi-entity configuration from scratch. The recommended approach is to **start with a minimal single-entity setup** — one source, a few columns — verify it renders correctly, and then add complexity incrementally. Each addition (a new relationship path, a column group, a formatter) can be validated independently before moving on.
**"Changing the data model automatically updates sheet configurations."** It does not. The data model defines what is *possible*; sheet configurations define what is *shown*. If you add a new entity type to the data model, no existing sheet configuration will display it until you explicitly add columns and sources that reference it.
**"Column keys are display labels."** Column keys are binding paths — they follow the data model's property and relationship structure. The `title` property within each column definition controls the display label. Two columns can have the same display title but different binding paths.
**"Global configurations override project configurations."** They coexist as separate options in the selection list. A global configuration is simply one that is *available* to all projects. There is no inheritance or override relationship between global and project-specific configurations — a document uses exactly one configuration file.
## Configuration Editor
Powersheet includes a built-in YAML editor accessible through the Polarion interface. The editor provides:
* **Syntax-aware editing** with support for both YAML and JSON content languages
* **JSON Schema validation** that checks your configuration against the expected structure
* **Language conversion** — content can be switched between JSON and YAML representations
* **Scope awareness** — the editor shows which scope level (instance, template, or default) you are editing
* **History** — links to revision history for tracking configuration changes over time
The editor supports optional Vim keybinding mode and line wrapping toggles, with preferences persisted in the browser. Theme styling adapts to match the Powersheet product branding.
## Relationship to Other Concepts
The YAML configuration system is the foundation that connects most other Powersheet concepts:
* **[Core Components](/powersheet/concepts/core-components)** — explains the runtime subsystems that consume the configuration
* **[Data Model vs Sheet Configuration](/powersheet/concepts/data-model-vs-sheet-config)** — dives deeper into the separation of concerns between the two file types
* **[Navigation Properties](/powersheet/concepts/navigation-properties)** — details how dot-notation binding paths traverse relationships
* **[Hierarchy and Traceability](/powersheet/concepts/hierarchy-and-traceability)** — shows how expansion paths in sources build multi-level views
* **[Global vs Project-Specific Configuration](/powersheet/concepts/global-vs-project-specific)** — covers storage scopes and sharing strategies
* **[Dynamic Value Expressions](/powersheet/concepts/dynamic-expressions)** — explains how `$context` expressions in sources are resolved at runtime
For hands-on guidance, the [Data Model Guides](/powersheet/guides/data-model/index) and [Sheet Configuration Guides](/powersheet/guides/sheet-configuration/index) walk through practical setup scenarios step by step.
# YAML Primer for Powersheet
Source: https://learn.nextedy.com/powersheet/concepts/yaml-primer
Nextedy POWERSHEET configuration is built entirely on YAML files.
## What Is YAML?
YAML (YAML Ain't Markup Language) is a human-readable data serialization format. Unlike JSON, which uses braces and brackets, or XML, which uses angle-bracket tags, YAML relies on indentation and simple punctuation to express structure. This makes it especially well suited for configuration files that engineers need to read, review, and modify by hand.
Think of YAML like a well-organized outline. Each level of indentation represents a deeper level of nesting, just as sub-bullets sit beneath their parent bullet in a document outline. The result is configuration that reads almost like natural language.
**Why Powersheet uses YAML**
YAML was chosen because it supports comments, multi-line strings, and anchors — features that are essential when managing complex sheet configurations shared across teams. A complete Powersheet sheet configuration typically fits on a single screen, which would not be practical in XML.
## Core YAML Concepts
### Key-Value Pairs
The most basic YAML structure is a key-value pair, separated by a colon and a space:
```yaml theme={null}
name: RTM Configuration
version: 2
enabled: true
```
The colon-space separator is mandatory. Omitting the space after the colon is the single most common YAML syntax error. In Powersheet configuration, keys like `name`, `label`, and `width` all follow this pattern.
### Nesting with Indentation
YAML uses consistent indentation (spaces, never tabs) to express hierarchy. Each nested level adds the same number of spaces — typically two:
```yaml theme={null}
column:
key: systemRequirement.title
label: System Requirement
width: 250
```
Here, `key`, `label`, and `width` are properties of `column`. This hierarchical nesting maps directly to how Powersheet organizes column definitions within a sheet configuration.
**Tabs will break your configuration**
YAML does not allow tab characters for indentation. Always configure your editor to insert spaces. Mixed tabs and spaces produce parsing errors that can be difficult to diagnose because they are invisible in most editors.
### Lists (Sequences)
Lists use a dash followed by a space at the same indentation level:
```yaml theme={null}
sources:
- type: UserNeed
model: rtm-model
- type: SystemRequirement
model: rtm-model
```
Each `- ` introduces a new list item. In Powersheet, lists appear throughout configuration — the `sources` array defines which entity types a sheet queries, the `columns` array defines which columns appear, and the `views` array defines named column presets.
### Strings and Quoting
Most strings in YAML do not need quotes:
```yaml theme={null}
label: Risk Control Status
```
However, you must quote strings that contain special characters or could be misinterpreted:
```yaml theme={null}
# These need quotes
description: "Status: active"
pattern: "true"
query: "type:systemRequirement AND status:approved"
```
The general rule: if your value contains a colon followed by a space, or if it looks like a boolean (`true`, `false`, `yes`, `no`) or a number but you intend it as text, wrap it in quotes. Powersheet Lucene query strings almost always need quoting because they contain colons and special operators.
### Comments
Comments start with `#` and continue to the end of the line:
```yaml theme={null}
# Data model for automotive safety RTM
domainModelTypes:
- name: UserNeed # Maps to Polarion 'userNeed' type
polarionType: userNeed
```
Comments are invaluable in Powersheet configurations for documenting why a particular column is configured a certain way, or noting which Polarion work item type an entity maps to. Unlike JSON, which forbids comments entirely, YAML makes it easy to keep configuration self-documenting.
## YAML Structures in Powersheet
Powersheet uses two primary YAML files. Understanding how standard YAML structures map to these files builds a mental model for reading and writing any configuration.
### Maps of Maps (Nested Objects)
Data model entity types use deeply nested maps to describe properties and their metadata:
```yaml theme={null}
domainModelTypes:
- name: SystemRequirement
polarionType: systemRequirement
properties:
- property: title
type: string
- property: severity
type: enum
```
Each entity type is a map within a list. Each entity type contains a `properties` key whose value is itself a list of maps. This pattern — lists of maps containing lists of maps — is the most common structure in Powersheet YAML.
### Dot-Separated Binding Paths
Powersheet uses a convention that extends standard YAML: **binding paths** expressed as dot-separated strings within the `key` field of column definitions:
```yaml theme={null}
columns:
- key: systemRequirement.title
label: Requirement Title
- key: systemRequirement.designRequirements.designRequirement.status
label: Design Status
```
These paths are not YAML syntax — they are Powersheet-specific conventions interpreted at runtime. The dots denote traversal through entity relationships defined in the data model. Understanding that these are plain YAML strings (not nested YAML keys) avoids confusion when reading complex column configurations.
For a deeper explanation of how binding paths relate to the data model, see [Navigation Properties](/powersheet/concepts/navigation-properties) and [Data Model vs Sheet Configuration](/powersheet/concepts/data-model-vs-sheet-config).
### Multi-Line Strings
YAML supports multi-line strings using the pipe (`|`) or folded (`>`) syntax:
```yaml theme={null}
description: |
This sheet configuration displays
the full requirements traceability
matrix for automotive safety projects.
```
The pipe preserves line breaks exactly as written. The folded style (`>`) joins lines with spaces, creating flowing paragraphs. In Powersheet, multi-line strings are most commonly used in description fields and in Lucene query strings that span multiple lines.
## Common Pitfalls
Understanding these common mistakes saves significant debugging time when working with Powersheet YAML files.
| Pitfall | Symptom | Fix |
| ------------------------------ | -------------------------------------------- | ------------------------------------------------------- |
| Tab characters in indentation | Parser error, configuration fails to load | Configure editor to use spaces only |
| Missing space after colon | Key-value pair treated as single string | Always use `key: value` with a space |
| Inconsistent indentation depth | Child properties attach to wrong parent | Use exactly 2 spaces per nesting level |
| Unquoted special characters | Colons, brackets, or booleans misinterpreted | Quote strings containing `:`, `{`, `[`, `true`, `false` |
| Trailing whitespace | Invisible characters cause diff noise | Enable "trim trailing whitespace" in editor |
**Validating YAML before applying**
Before uploading a modified configuration to Polarion, validate the YAML syntax using an online YAML validator or your editor's built-in linting. A single indentation error can prevent the entire sheet from loading, and Powersheet's error messages may point to a downstream effect rather than the root cause.
## YAML Anchors and Aliases
YAML provides a reuse mechanism through **anchors** (`&`) and **aliases** (`*`). An anchor marks a block of YAML for reuse, and an alias references it elsewhere:
```yaml theme={null}
# Define a reusable column style
_styles:
highlight: &highlight-style
backgroundColor: "#fff3e0"
fontWeight: bold
columns:
- key: hazard.severity
label: Severity
style: *highlight-style
- key: hazard.probability
label: Probability
style: *highlight-style
```
This avoids duplicating the same style definition across multiple columns. When the style needs to change, you update it in one place. The leading underscore on `_styles` is a convention indicating the key exists only for anchor definitions and is not processed directly by Powersheet.
**Verify in application**
The extent of anchor and alias support may vary depending on the YAML parser version used by your Polarion installation. Test anchor-based configurations in a non-production project first.
## Data Types in YAML
YAML automatically infers data types, which can occasionally produce surprises:
```yaml theme={null}
# Interpreted as boolean (not string)
enabled: true
# Interpreted as integer (not string)
width: 200
# Interpreted as float (not string)
ratio: 1.5
# Interpreted as string
label: System Requirement
# Careful: interpreted as boolean!
value: yes # becomes true
value: "yes" # stays as the string "yes"
```
In Powersheet configurations, the most frequent data-type issue involves boolean-like strings. If a column label, enum option, or description contains words like `yes`, `no`, `true`, `false`, `on`, or `off`, always wrap them in quotes to prevent YAML from converting them to booleans.
## How YAML Maps to Powersheet Concepts
The following table connects YAML structures to the Powersheet concepts they represent:
| YAML Structure | Powersheet Concept | Example Key |
| ----------------------------- | ---------------------------------------- | ------------------ |
| Top-level list of maps | Entity type definitions | `domainModelTypes` |
| Nested list of maps | Relationships between entities | `relationships` |
| List of maps with `key` field | Column definitions | `columns` |
| Map with named entries | Style definitions | `styles` |
| List of strings | View column visibility | `views[].columns` |
| Dot-separated string value | Binding path across entity relationships | `columns[].key` |
For the complete structure of each YAML file, see the [Sheet Configuration Reference](/powersheet/reference/sheet-config/index) and [Data Model Reference](/powersheet/reference/data-model/index).
## Editor Setup Recommendations
Choosing the right editor configuration prevents the majority of YAML errors:
* **Indentation:** Set tab width to 2 spaces and enable "insert spaces" mode
* **Syntax highlighting:** Use a YAML-aware editor or install a YAML plugin for syntax coloring and bracket matching
* **Linting:** Enable a YAML linter that flags tab characters, inconsistent indentation, and duplicate keys
* **Schema validation:** Some editors support JSON Schema for YAML, which can validate Powersheet-specific keys and structures as you type
**Keep a known-good reference**
When learning Powersheet YAML, keep a working configuration file open alongside the one you are editing. Comparing structure side by side is the fastest way to spot indentation or nesting errors. The [Example Models Reference](/powersheet/reference/example-models/index) provides several complete, validated configurations.
## Next Steps
With a solid understanding of YAML fundamentals, you are ready to explore how Powersheet applies these concepts in practice:
* [YAML Configuration System](/powersheet/concepts/yaml-configuration) explains how the two configuration files interact at runtime
* [Data Model vs Sheet Configuration](/powersheet/concepts/data-model-vs-sheet-config) clarifies the boundary between what the data model defines and what the sheet configuration controls
* [Entity Types and Relationships](/powersheet/concepts/entity-types-and-relationships) shows how `domainModelTypes` and `relationships` work together
* [Sheet Configuration Guides](/powersheet/guides/sheet-configuration/index) provide step-by-step instructions for building and modifying configurations
# Configuration FAQ
Source: https://learn.nextedy.com/powersheet/faq/configuration
Common questions about configuring Nextedy POWERSHEET in Siemens Polarion ALM, including administration access, editor features, and configuration scopes.
Where do I find the Powersheet configuration pages in Polarion?
What scopes does the configuration editor support?
How does a Powersheet document find its configuration file?
# Data Model FAQ
Source: https://learn.nextedy.com/powersheet/faq/data-model
Common questions about configuring the Nextedy POWERSHEET data model — entity types, relationships, cardinality, and expansion paths in Siemens Polarion ALM.
**Terminology**
In Powersheet, the YAML file defining entity types and relationships is called the **data model** (formerly "domain model"). "Entity type" refers to data model concepts; "work item type" refers to the underlying Polarion type.
What is a data model and why do I need one?
How do I define entity types in the data model?
What relationship cardinalities are supported?
Should I start with a complex or simple data model?
# Frequently Asked Questions
Source: https://learn.nextedy.com/powersheet/faq/index
Find quick answers to common questions about Nextedy POWERSHEET.
***
Powersheet is a hierarchical sheet application for Polarion that provides configurable tabular views over complex work item hierarchies. It enables Excel-like editing and traceability directly inside Polarion, letting teams manage requirements traceability matrices, risk analyses, and structured data without leaving their ALM environment. For a full introduction, see [Getting Started](/powersheet/getting-started/index).
Powersheet serves systems engineers, requirements managers, quality engineers, and safety engineers who work with Polarion. Skill levels range from end users who view and edit data in sheets to administrators who configure data models and sheet configurations. It is particularly useful for teams managing structured hierarchical data in regulated industries — from requirements traceability matrices (RTM) to risk management workflows.
A **data model** defines entity types, their properties, and the relationships between them — it maps Powersheet entity types to Polarion work item types and establishes navigable links via link roles. A **sheet configuration** defines how data from the data model is displayed: column layout, widths, formatters, views, sorting, and expansion paths. Both are YAML files stored in the project SVN.
| Aspect | Data Model | Sheet Configuration |
| ------------ | ----------------------------------- | -------------------------------- |
| Purpose | Entity types and relationships | Column layout and display |
| Key sections | `domainModelTypes`, `relationships` | `columns`, `sources`, `views` |
| Scope | Shared across multiple sheets | Specific to one sheet view |
| Controls | Data structure and navigation paths | Visual presentation and behavior |
For details on each, see the [Data Model Reference](/powersheet/reference/data-model/index) and [Sheet Configuration Reference](/powersheet/reference/sheet-config/index).
Powersheet maps data model entity types to Polarion work item types via the `polarionType` property. Relationships between entity types are stored using Polarion link roles, with `direct` and `back` navigation directions defined in the data model. When users load a sheet, Powersheet queries Polarion for work items matching the source configuration and displays them according to the column definitions. Save operations write changes back to Polarion work items through the server API.
Data models can be defined at the **global** scope (accessible from `_global`) and referenced by sheet configurations in any project. This lets you maintain a single data model definition used by multiple projects. Note that while the data model definition itself can be shared globally, each sheet still queries data within a single Polarion project scope — cross-project querying is not supported.
**Project-scoped queries**
Even when using a globally defined data model, each sheet's source configuration queries work items within the project where the sheet is embedded. Cross-project query scoping is not a supported feature.
Powersheet supports ISO 15288 (systems engineering), Automotive SPICE, ISO 26262 (via RTM traceability), and general requirements management processes. The standard RTM example uses the entity hierarchy `UserNeed` > `SystemRequirement` > `DesignRequirement` > `Hazard` > `RiskControl` to demonstrate traceability across these domains. For industry-specific models, see the [Example Models Reference](/powersheet/reference/example-models/index).
Begin with the simplest possible configuration and extend incrementally. Create a data model with one or two entity types and a basic sheet configuration with a few columns. Verify each step works before adding complexity — this avoids hard-to-diagnose errors that arise from multi-level hierarchies with many-to-many relationships on a first attempt. See [Getting Started](/powersheet/getting-started/index) for a guided walkthrough.
**Incremental approach**
Start with a single entity type, a handful of columns, and one source definition. Add relationships, expansion paths, column groups, and formatters one at a time. Test after each addition.
Master-downstream is the hierarchical display pattern where master items (such as `UserNeed`) expand to show their related downstream items (such as `SystemRequirement`). The sheet automatically merges cells for master-level columns to span all downstream rows, providing visual grouping. Users can add or remove items at both levels, and undo/redo is fully supported across all operations.
Review mode is a toggle in the sheet toolbar that filters the view to show only modified, added, or removed rows. It lets users focus on changes they have made before saving, reducing the risk of unintended modifications. Review mode displays counts of changed items and works alongside the standard save validation.
Check the [Troubleshooting Guides](/powersheet/guides/troubleshooting/index) for step-by-step error resolution, or browse the [Troubleshooting FAQ](/powersheet/faq/troubleshooting) for quick answers. For configuration-specific questions, see the [Configuration FAQ](/powersheet/faq/configuration) and [Sheet Configuration FAQ](/powersheet/faq/sheet-configuration). If your issue is not covered in the documentation, submit a support ticket through the [Nextedy support portal](https://support.nextedy.com/support/tickets/new).
## License Status and Behavior
Powersheet communicates its license state through four severity levels:
| Status | Icon | Meaning | Effect on Users |
| --------- | ---- | ---------------------- | ----------------------------------------- |
| `OK` | ✅ | Valid license | All features enabled |
| `INFO` | ℹ️ | Informational notice | Full functionality with a banner message |
| `WARNING` | ⚠️ | License issue detected | Limited functionality; action recommended |
| `INVALID` | ❌ | No valid license | Entire sheet forced into read-only mode |
When the status is anything other than `OK`, a message in the license panel explains the specific issue, such as an approaching expiration date or exceeded user count.
The license panel renders as a non-blocking banner at the bottom of the Powersheet viewport. It displays the current license state -- including trial, expired, or invalid conditions -- and provides a link to obtain or renew a license from Nextedy. The banner does not prevent you from viewing the sheet, but editing capabilities may be restricted depending on the severity level.
When the license status reaches `INVALID`, Powersheet enforces a global `readOnly` flag across the entire application. All data editing, configuration changes, and save operations are disabled for every user in the project. The effective read-only state is determined by combining the license status with user permissions -- if either the license is invalid or the user lacks write permissions, the sheet becomes read-only.
**Project-wide impact**
An invalid license affects **all users** in the project, not just administrators. Plan license renewals before expiration to avoid disrupting active workflows.
## License Management
Contact Nextedy support and provide your Polarion server details (hostname, environment type, and Polarion version). Nextedy will generate a time-limited evaluation license file that you can apply through the Polarion administration interface. Evaluation licenses typically provide full functionality for a fixed trial period.
Navigate to **Administration > Nextedy Powersheet > License** in the Polarion administration interface. The license management page is available at the project, project group, and repository (global) scope levels. From this page you can view the current license status, see expiration details, and apply new license files.
Contact Nextedy support with your server information and current license details before the expiration date. Once you receive the renewal file, apply it through **Administration > Nextedy Powersheet > License** in Polarion. The new license takes effect immediately without requiring a server restart.
**Verify in application**
The exact renewal workflow may vary depending on your organization's agreement with Nextedy. Contact your account representative for specific renewal procedures and pricing.
## Permissions and Access Control
Powersheet enforces a three-layer access model. Each layer must grant access for the user to have full capabilities:
1. **License layer** -- The license status sets the baseline. An `INVALID` license forces read-only mode for everyone, regardless of other permissions.
2. **Polarion role layer** -- The user's Polarion project role determines what actions are available in the platform (viewing, editing, administering).
3. **Powersheet permission layer** -- Powersheet checks specific capability flags fetched from the server at load time:
* **Document administration** -- `read` to view sheet configuration, `write` to modify it
* **Model administration** -- `read` to view the data model, `write` to modify it
The final effective permission is the intersection of all three layers. For example, a user with full Polarion write permissions will still be read-only if the license is `INVALID`.
Your effective permissions are determined by Powersheet at load time based on your Polarion user role combined with the current license status. If you cannot edit data or access configuration settings, verify two things with your Polarion administrator: (1) that you have the appropriate project role assigned, and (2) that the license status is `OK`. See the [Configuration FAQ](/powersheet/faq/configuration) for additional permission-related troubleshooting.
Powersheet fetches permissions from the server when the sheet loads. If your Polarion role is changed while you have a sheet open, the change will not take effect until you reload the page. Save any pending edits before asking your administrator to change your role, then refresh the browser to pick up the new permissions.
## Product Registration
Powersheet registers as a product within the Polarion server during initialization. The registration includes identity metadata (product name and version), a license status provider for real-time license checks, and an authorization checker that determines whether the current user can access Powersheet. This registration process is automatic and requires no manual configuration beyond applying a valid license file.
**Configuration file access**
Powersheet also registers a file supplier under the identifier `sheet_configuration`, which enables storage and retrieval of YAML sheet configurations from the project repository. This is why sheet configurations appear under **Administration > Nextedy Powersheet** in the Polarion UI.
## Administration Access
Powersheet administration pages are integrated into Polarion's standard administration interface under the **Administration > Nextedy Powersheet** section. From there you can access:
* **Data Models** -- manage data model YAML files
* **Sheet Configurations** -- manage sheet configuration YAML files
* **Setup** -- initial Powersheet setup and configuration
* **License** -- license management
These pages are available at project, project group, and repository (global) scope levels.
Powersheet supports two configuration scopes for both data models and sheet configurations. **Global configurations** are stored at the repository level and are available to all projects -- they appear with a "(Global)" suffix in the configuration picker. **Project-specific configurations** are stored within an individual project and are only available in that project context. Project configurations supplement or override global ones.
**Configuration strategy**
Use global configurations for organization-wide standards, then create project-specific configurations only when a project needs deviations from the global defaults.
## Configuration Editor
The built-in configuration editor supports three scopes for managing configuration files:
| Scope | Description |
| ---------- | ---------------------------------------------------- |
| `instance` | Per-instance override for a specific document |
| `template` | Template-level configuration shared across documents |
| `default` | Global defaults applied when no override exists |
The scope control can be `ENABLED`, `DISALLOWED`, or `DISABLED` depending on your permissions and the current editing context.
Yes. The configuration editor can attach a JSON Schema to validate your YAML content as you type. This provides real-time feedback on configuration errors, missing required fields, and invalid property values. The schema is auto-generated from the data model definition, ensuring that your configuration references valid Polarion prototypes and entity types.
The editor supports both YAML and JSON as configuration languages. You can switch between them, and the content is automatically converted when you change the language setting. By default, the editor uses YAML (`lang: yaml`). Your language preference is saved in your browser and persists across sessions.
**Verify in application**
Additional editor features such as line wrapping and keyboard mode preferences are available in the editor toolbar.
## Sheet Configuration Assignment
Each Powersheet document has a custom field (`nextedySheetConfig`) that references a sheet configuration YAML file. Powersheet scans both the global and project-specific configuration directories for available YAML files and populates a picklist from which you select the desired configuration. If no configuration is selected, the document uses a bundled default configuration (`powersheet.yaml`).
Yes. Sheet configurations are stored as standalone YAML files in the repository, independent of any specific document. Multiple Powersheet documents can reference the same configuration file through their `nextedySheetConfig` custom field. This is the recommended approach for maintaining consistency across related documents in a project.
You can change a document's sheet configuration by updating the `nextedySheetConfig` custom field on the document, either through the Polarion work item editor or programmatically. You can also edit the configuration YAML directly through **Administration > Nextedy Powersheet > Sheet Configurations**, which will affect all documents referencing that configuration.
See [Creating Your First Sheet Configuration](/powersheet/getting-started/first-sheet-configuration) for a guided walkthrough.
## Data Model Basics
The **data model** is a YAML configuration file that defines the semantic layer between Polarion's native work item types and Powersheet's sheet views. It maps Polarion types, link roles, and custom fields into structured entity types and relationships that Powersheet uses for querying, displaying, and editing data. Without a data model, Powersheet cannot understand which work items to load or how they relate to each other.
See the [Data Model Reference](/powersheet/reference/data-model/index) for the complete property reference.
Data models are managed through the Polarion administration interface at **Administration > Nextedy Powersheet > Data Models**. You can create both global models (available to all projects) and project-specific models. Multiple models can coexist, and each sheet configuration references a specific model by name.
The three configuration layers are connected through navigation property names:
* **Data model** defines entity types and relationships (with `direct` and `back` navigation names)
* **Sources** define how to query and expand those relationships (using the navigation names)
* **Columns** define how to display the resulting data (using dot-notation binding paths)
The cardinality of a relationship determines the expand pattern and column binding syntax. See the [Sheet Configuration Reference](/powersheet/reference/sheet-config/index) for column binding details.
## Entity Types and Properties
Entity types are defined in the `domainModelTypes` section of the YAML file using **map format only** — each key is the entity type name, and the value contains its configuration. The `polarionType` property maps the entity type to a Polarion work item type.
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
description:
severity:
SystemRequirement:
polarionType: sys_req
properties:
description:
severity:
```
**Map format only**
The `domainModelTypes` section must use **map format** (keyed by type name). Array format is not supported and will not work.
Each entry under `properties` defines a field exposed in the Powersheet sheet. Properties are listed as keys under the entity type. Key property attributes include:
| Attribute | Purpose | Default |
| ----------------- | ---------------------------- | -------------- |
| `name` | Client-facing property name | Required |
| `serverName` | Polarion field name override | Same as `name` |
| `customFieldName` | Polarion custom field ID | -- |
| `readable` | Can be read by users | `true` |
| `updatable` | Can be modified by users | `true` |
| `scalar` | Single value vs. collection | `true` |
| `enumValues` | Valid enum option IDs | -- |
Use `serverName` to alias Polarion field names to more user-friendly names, and `customFieldName` when a property maps to a Polarion custom field rather than a built-in field.
## Relationships and Cardinality
Powersheet supports two relationship cardinality types in the data model, plus the implicit reverse of many-to-one:
| Cardinality | Direction | Navigation Property | UI Behavior |
| -------------- | ----------------------- | ------------------------------------------------------- | ----------------------------- |
| `many-to-one` | `direct` | Scalar (e.g., `chapter`) | Single-value reference picker |
| One-to-many | `back` (reverse of N:1) | Collection (e.g., `userNeeds`) | Child rows (new sheet level) |
| `many-to-many` | `back` | Collection via association (e.g., `systemRequirements`) | Multi-item reference picker |
Relationships are defined in the `relationships` array of the data model and map to Polarion link roles via the `linkRole` property. Each relationship specifies a `direct` and `back` navigation property name.
A many-to-one relationship links multiple entities to a single target. Use the `direct` navigation property name in your source expand and column binding:
```yaml theme={null}
relationships:
- from: UserNeed
to: Chapter
cardinality: many-to-one
storage: linkedWorkItems
linkRole: parent
direct:
name: chapter
back:
name: userNeeds
```
In the source, expand using the direct name. In columns, bind with `chapter` for a reference picker or `chapter.title` for a read-only display of the referenced entity's title.
Many-to-many relationships use an **association entity** between the two types. This requires a two-level expand in the source configuration and dot-notation in column bindings:
```yaml theme={null}
# Source: two-level expand
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: systemRequirement
# Columns: dot-notation binding
columns:
systemRequirements.systemRequirement:
title: System Requirement
list:
search:
- objectId
- title
systemRequirements.systemRequirement.title:
title: SysReq Title
hasFocus: true
```
The first level (`systemRequirements`) reaches the association entity; the second level (`systemRequirement`) reaches the actual target entity. See the [Data Model Guides](/powersheet/guides/data-model/index) for walkthrough examples.
## Configuration Tips
Always start with the simplest possible configuration and extend incrementally. Begin with a single entity type and one or two properties, verify it works in a sheet, then add relationships and additional entity types one at a time. Jumping directly to a complex multi-entity model leads to hard-to-diagnose configuration errors.
**Incremental approach**
Start with one entity type, add a source and a few columns, confirm the sheet loads. Then add a relationship and expand one level at a time. This makes it easy to identify which change introduced a problem.
The `linkRole` property in a relationship definition specifies the Polarion link role used to persist the connection. This must match a link role defined in your Polarion project's link role configuration. The `storage` property determines how the relationship is persisted — `linkedWorkItems` is the only supported storage mechanism, using Polarion's native linking to persist connections.
The `constraints` section on an entity type restricts which items appear in picker dialogs. You can filter by document location, type, or component:
```yaml theme={null}
domainModelTypes:
SystemRequirement:
polarionType: sys_req
constraints:
pick:
document:
moduleFolder: Requirements
type: requirements_specification
component: $context.source.document.component
```
The `$context.source.document.component` expression dynamically filters results based on the source entity's document component, enforcing component-scoped relationships. See the [Configuration FAQ](/powersheet/faq/configuration) for more on validation and constraints.
## Configuration Basics
A **sheet configuration** is a YAML file that defines how Nextedy Powersheet displays and interacts with data from the data model. It specifies columns, data sources, views, column groups, formatters, and sorting behavior. Each Powersheet document references a sheet configuration through the `nextedySheetConfig` custom field. Configurations are managed in **Administration > Nextedy Powersheet > Sheet Configurations**.
See [Creating Your First Sheet Configuration](/powersheet/getting-started/first-sheet-configuration) for a step-by-step tutorial.
The sheet configuration depends on the data model for entity type definitions, relationships, and property metadata. Column binding paths in the configuration reference properties and expansion paths defined in the data model. The `model` property in the `sources` section specifies which data model to use. If the model and configuration do not match, you will see errors when loading the sheet.
Start with the simplest possible configuration -- a single entity type, a few columns, and one data source. Verify that the basic setup loads correctly, then extend gradually by adding relationships, column groups, and formatters. Jumping to a complex multi-entity configuration leads to difficult-to-diagnose errors.
**Best practice**
See [Incremental Configuration Approach](/powersheet/getting-started/incremental-configuration) for a recommended step-by-step build strategy.
## Columns and Binding Paths
Column keys in the YAML use dot-separated **binding paths** that follow the expansion paths defined in the data model. A simple property like `title` maps directly to the base entity, while a multi-level path like `systemRequirements.systemRequirement.severity` navigates through a relationship to access a property on a related entity type. Each segment of the path corresponds to a navigation property in the data model.
```yaml theme={null}
columns:
title:
title: "Title"
width: 250
hasFocus: true
systemRequirements.systemRequirement.severity:
title: "Req Severity"
width: 100
formatter: severity-formatter
```
Each column supports several configuration properties:
| Property | Type | Description |
| ------------- | ------- | ------------------------------------------- |
| `title` | string | Display header text |
| `width` | number | Column width in pixels |
| `visible` | boolean | Show in default view (default: `true`) |
| `hasFocus` | boolean | Receives focus when editing a row |
| `formatter` | string | Name of a formatter for conditional styling |
| `columnGroup` | string | Associates column with a visual group |
Column visibility can be overridden in named views, allowing different analysis perspectives without changing the base configuration.
## Data Sources and Scoping
The `sources` section defines how Powersheet queries data from Polarion. Each data source specifies a `model` reference, a `from` entity type, optional `where` filters, `expand` paths for loading related entities, and `take` limits. Powersheet automatically applies document-scoping constraints to all queries, ensuring data is filtered to the current document context.
```yaml theme={null}
sources:
- model: my-rtm-model
from: UserNeed
where: "type:user_need"
take: 500
expand:
- systemRequirements
```
Yes. Sheet configurations support `$context` expressions that are resolved at runtime. For example, `$context.document.id` resolves the current document path, and `$context.source.project.id` resolves the source entity's project. Dynamic values are also used in constraint definitions to route entity creation based on the source entity type.
Yes. Sheet configurations are standalone YAML files stored in the repository. Multiple Powersheet documents can reference the same configuration file through the `nextedySheetConfig` custom field. This is the recommended approach for maintaining consistent views across related documents. Global configurations (stored at the repository level) can be shared across all projects in your Polarion instance.
## Document Management
Powersheet documents are created as Polarion LiveDoc modules with a specific document type (typically containing "powersheet"). You can create documents through the Powersheet administration interface by specifying a name, folder location, and the sheet configuration to use. Documents can also be created by duplicating an existing template, which copies the module structure and content from another project.
Powersheet Drive displays all documents matching the configured document query in the project. By default, it lists all documents of type `powersheet`. You can customize which documents appear by configuring the `com.powersheet.powersheetDocumentQuery` project property to include additional document types or apply custom filters.
See [Setting Up Navigation](/powersheet/getting-started/setup-navigation) for details on configuring Powersheet Drive.
## Upgrading Powersheet
Upgrading Powersheet follows the standard Polarion server extension upgrade process. Download the new version from Nextedy, replace the extension files on your Polarion server, and restart the server. After restart, verify the installation through **Administration > Nextedy Powersheet > Setup**. Your existing data models and sheet configurations stored in SVN are preserved during the upgrade.
See [Installing Powersheet](/powersheet/getting-started/installation) for the full installation procedure.
Data model and sheet configuration YAML files are stored in the Polarion SVN repository and are not modified during a Powersheet upgrade. The data model includes a `$version` field for schema compatibility checking, which allows Powersheet to handle older configuration formats. In most cases, existing configurations continue to work without changes.
**Breaking changes**
Always review the release notes for any breaking changes to YAML schema, property names, or deprecated features before upgrading in production.
License requirements may change between major versions. After upgrading, open **Administration > Nextedy Powersheet > License** and confirm that no warning or error banner appears on the license page. If a warning or error banner is displayed, contact Nextedy support for an updated license file. See [Licensing FAQ](/powersheet/faq/licensing) for details on license statuses.
## Configuration Migration
Yes. Since sheet configurations and data models are YAML files stored in the Polarion SVN repository, you can copy them between projects. **Global configurations** stored at the repository level are automatically available to all projects. For project-specific configurations, export the YAML file from the source project and import it into the target project through **Administration > Nextedy Powersheet > Sheet Configurations**.
Powersheet supports document duplication across projects through its template system. When creating a new document, you can select a template from any project. The duplication copies the module structure and content but excludes certain fields and link roles to ensure a clean copy in the target project.
**Template strategy**
Maintain a dedicated template project with your standard Powersheet documents and configurations for consistent deployments across new projects.
The migration path involves three steps: first, create a data model that maps your existing Polarion work item types and link roles to Powersheet entity types. Second, build a sheet configuration with columns matching your current LiveDoc view. Third, create a Powersheet document and assign the configuration. Your underlying Polarion data remains unchanged -- Powersheet provides an alternative view over the same work items.
See [Getting Started](/powersheet/getting-started/index) for the complete setup workflow.
## Loading and Display Issues
A blank sheet typically means the data source query returned no matching work items, the data model referenced in `sources` does not exist, or there is a YAML syntax error in the configuration. Start by verifying the data model exists in **Administration > Nextedy Powersheet > Data Models**, then confirm work items of the expected `polarionType` exist in the project. Check the browser developer console for error messages that pinpoint the failure.
**Start simple**
When setting up a new sheet, begin with a minimal single-entity configuration and extend incrementally. Jumping straight to a complex multi-level RTM often leads to hard-to-diagnose errors.
Read-only mode can be triggered by several conditions. Check the following causes in order:
| Cause | Resolution |
| ---------------------------------------- | ----------------------------------------------------------------------- |
| Invalid or expired license | Renew via **Administration > Nextedy Powersheet > License** |
| User lacks write permissions | Ask your Polarion administrator to assign the appropriate role |
| Document opened at a historical revision | Navigate to the current (HEAD) revision |
| Column-level `isReadOnly` set to `true` | Remove or set `isReadOnly: false` on the affected column |
| Formatter applies a read-only style | Check the `formatters` section for rules that force read-only rendering |
See [Licensing FAQ](/powersheet/faq/licensing) for details on license-related access restrictions.
Empty columns usually indicate a mismatch between the column binding path in the sheet configuration and the data model. Verify that the path (e.g., `systemRequirements.systemRequirement.severity`) follows a valid expansion path defined in your data model `relationships`, that the referenced properties exist on the target entity type in `domainModelTypes`, and that your data source `expand` array includes the navigation properties the column path depends on. If the expansion path is missing from `sources`, the related data simply will not be loaded.
## Configuration Issues
Configuration load failures are typically caused by YAML syntax errors, a reference to a non-existent data model, or invalid property paths. The configuration editor in **Administration > Nextedy Powersheet > Sheet Configurations** provides validation that catches many issues at edit time. If the YAML file cannot be parsed at all, Nextedy Powersheet falls back to its bundled default configuration, which usually appears as a generic empty sheet.
**Common YAML pitfalls**
Incorrect indentation, missing colons after keys, and unquoted special characters (such as `*` or `&`) are the most frequent causes of parse failures. Always use the built-in editor with schema validation to catch these errors before saving.
Powersheet loads its sheet configuration once when the widget initializes and does not hot-reload changes. After editing a YAML file through the administration interface, ensure the change was saved (committed to SVN) and then reload the Polarion document page in your browser. If you edited the data model rather than the sheet configuration, both the model and every sheet referencing it need a page reload. For global-scope configurations, verify the change was saved to the `_global` project scope if that is where your sheet reads from.
Picker dropdowns are filtered based on `pick` constraints defined in the data model for each entity type. If you see unexpected items, review the `constraints.pick` section on the relevant entity type -- these entries control filtering by `document.moduleFolder`, `document.moduleName`, `document.type`, or `document.component`. The `list.search` property on the column definition controls which fields are searchable when typing in the picker. Missing or overly broad constraints are the most common cause of unfiltered picker results.
For full constraint configuration details, see the [Data Model Reference](/powersheet/reference/data-model/index).
## Data Model Issues
This error occurs when the sheet configuration references an entity type name that does not exist in the data model `domainModelTypes` section. Entity type names are case-sensitive and must match exactly -- `SystemRequirement` is not the same as `systemRequirement` or `Systemrequirement`. Verify naming consistency between your data model, sheet configuration column paths, and `sources` definitions.
For a detailed walkthrough, see [Fix Type Name Errors](/powersheet/guides/troubleshooting/fix-type-name-errors).
Relationship navigation depends on three things being correctly aligned: the `from` and `to` entity types must exist in `domainModelTypes`, the `linkRole` must match a link role defined in the Polarion project, and the `direct` and `back` navigation property names must be referenced correctly in column binding paths and `expand` arrays. If any of these are mismatched, navigation paths will silently return no data. Review the [Fix Relationship Errors](/powersheet/guides/troubleshooting/fix-relationship-errors) guide for step-by-step diagnosis.
## Administration and Setup Issues
Powersheet administration is integrated into Polarion's standard administration area. Navigate to **Administration > Nextedy Powersheet** to find two sections: **Data Models** for managing entity type and relationship definitions, and **Sheet Configurations** for column layout, views, formatters, and sources. Both sections use an embedded file manager that supports editing YAML files with project-scope and global-scope configurations. Global configurations (stored under the `_global` project) provide system-wide defaults that individual projects can override.
See [Administration Guides](/powersheet/guides/administration/index) for detailed setup instructions.
Global configurations provide defaults that can be overridden at project level. If a project has its own copy of a data model or sheet configuration with the same name, the project-level file takes precedence over the global one. Check whether a project-level override exists in **Administration > Nextedy Powersheet** and either remove it to fall back to the global version, or update it to match your intended configuration.
## Data and Save Issues
Save failures typically occur when data violates constraints defined in the data model or when required fields are empty. Common causes include: attempting to create a relationship that violates cardinality rules (e.g., adding a second link where `cardinality` is set to `many-to-one`), picking entities from outside the allowed `moduleFolder` or `moduleName` scope, or submitting duplicate property values where uniqueness is enforced. The error message usually includes a numbered list of failing conditions.
For detailed resolution steps, see [Resolve Validation Errors](/powersheet/guides/troubleshooting/resolve-validation-errors).
Dynamic value expressions (using `$context` syntax like `$context.source.document.component`) resolve at runtime based on the current document context. If a dynamic expression returns an empty result, verify that the source document has the expected property set. For example, `$context.source.document.component` only works if the Polarion document has a component property assigned. Missing context values resolve to empty strings, which can cause picker constraints to match all items or no items depending on the filter logic.
See [Sheet Configuration Guides](/powersheet/guides/sheet-configuration/index) for more on dynamic values in source configurations.
**Can't find your answer?**
If your question is not covered in the FAQ, check the [How-To Guides](/powersheet/guides/index) for step-by-step instructions or the [Reference](/powersheet/reference/index) for detailed property documentation. For troubleshooting specific errors, see the [Troubleshooting Guides](/powersheet/guides/troubleshooting/index).
# Licensing FAQ
Source: https://learn.nextedy.com/powersheet/faq/licensing
Common questions about Nextedy POWERSHEET licensing, evaluation, and access control in Siemens Polarion ALM.
**Three layers of access**
Powersheet access is determined by three factors working together: **license state**, **Polarion user role**, and **Powersheet-level permissions**. All three must be satisfied for full read-write access.
## License Status and Behavior
Powersheet communicates its license state through four severity levels:
| Status | Icon | Meaning | Effect on Users |
| --------- | ---- | ---------------------- | ----------------------------------------- |
| `OK` | ✅ | Valid license | All features enabled |
| `INFO` | ℹ️ | Informational notice | Full functionality with a banner message |
| `WARNING` | ⚠️ | License issue detected | Limited functionality; action recommended |
| `INVALID` | ❌ | No valid license | Entire sheet forced into read-only mode |
When the status is anything other than `OK`, a message in the license panel explains the specific issue, such as an approaching expiration date or exceeded user count.
The license panel renders as a non-blocking banner at the bottom of the Powersheet viewport. It displays the current license state -- including trial, expired, or invalid conditions -- and provides a link to obtain or renew a license from Nextedy. The banner does not prevent you from viewing the sheet, but editing capabilities may be restricted depending on the severity level.
When the license status reaches `INVALID`, Powersheet enforces a global `readOnly` flag across the entire application. All data editing, configuration changes, and save operations are disabled for every user in the project. The effective read-only state is determined by combining the license status with user permissions -- if either the license is invalid or the user lacks write permissions, the sheet becomes read-only.
**Project-wide impact**
An invalid license affects **all users** in the project, not just administrators. Plan license renewals before expiration to avoid disrupting active workflows.
## License Management
Contact Nextedy support and provide your Polarion server details (hostname, environment type, and Polarion version). Nextedy will generate a time-limited evaluation license file that you can apply through the Polarion administration interface. Evaluation licenses typically provide full functionality for a fixed trial period.
Navigate to **Administration > Nextedy Powersheet > License** in the Polarion administration interface. The license management page is available at the project, project group, and repository (global) scope levels. From this page you can view the current license status, see expiration details, and apply new license files.
Contact Nextedy support with your server information and current license details before the expiration date. Once you receive the renewal file, apply it through **Administration > Nextedy Powersheet > License** in Polarion. The new license takes effect immediately without requiring a server restart.
**Verify in application**
The exact renewal workflow may vary depending on your organization's agreement with Nextedy. Contact your account representative for specific renewal procedures and pricing.
## Permissions and Access Control
Powersheet enforces a three-layer access model. Each layer must grant access for the user to have full capabilities:
1. **License layer** -- The license status sets the baseline. An `INVALID` license forces read-only mode for everyone, regardless of other permissions.
2. **Polarion role layer** -- The user's Polarion project role determines what actions are available in the platform (viewing, editing, administering).
3. **Powersheet permission layer** -- Powersheet checks specific capability flags fetched from the server at load time:
* **Document administration** -- `read` to view sheet configuration, `write` to modify it
* **Model administration** -- `read` to view the data model, `write` to modify it
The final effective permission is the intersection of all three layers. For example, a user with full Polarion write permissions will still be read-only if the license is `INVALID`.
Your effective permissions are determined by Powersheet at load time based on your Polarion user role combined with the current license status. If you cannot edit data or access configuration settings, verify two things with your Polarion administrator: (1) that you have the appropriate project role assigned, and (2) that the license status is `OK`. See the [Configuration FAQ](/powersheet/faq/configuration) for additional permission-related troubleshooting.
Powersheet fetches permissions from the server when the sheet loads. If your Polarion role is changed while you have a sheet open, the change will not take effect until you reload the page. Save any pending edits before asking your administrator to change your role, then refresh the browser to pick up the new permissions.
## Product Registration
Powersheet registers as a product within the Polarion server during initialization. The registration includes identity metadata (product name and version), a license status provider for real-time license checks, and an authorization checker that determines whether the current user can access Powersheet. This registration process is automatic and requires no manual configuration beyond applying a valid license file.
**Configuration file access**
Powersheet also registers a file supplier under the identifier `sheet_configuration`, which enables storage and retrieval of YAML sheet configurations from the project repository. This is why sheet configurations appear under **Administration > Nextedy Powersheet** in the Polarion UI.
# Migration FAQ
Source: https://learn.nextedy.com/powersheet/faq/migration
Common questions about migrating to or upgrading Nextedy POWERSHEET in Siemens Polarion ALM.
**Verify in application**
This page covers general migration guidance based on Powersheet's architecture. Specific version-to-version migration steps may vary. Always consult the release notes for your target version and contact Nextedy support for upgrade assistance.
How do I upgrade Powersheet to a new version?
Can I move configurations between projects?
# Sheet Configuration FAQ
Source: https://learn.nextedy.com/powersheet/faq/sheet-configuration
Common questions about Nextedy POWERSHEET sheet configurations -- column layout, data sources, views, and document management in Siemens Polarion ALM.
What is a sheet configuration?
How do column binding paths work?
How do data sources work in the sheet configuration?
How are Powersheet documents created?
# Troubleshooting FAQ
Source: https://learn.nextedy.com/powersheet/faq/troubleshooting
Common issues and solutions when working with Nextedy POWERSHEET in Siemens Polarion ALM.
**Quick symptom lookup**
Use the table below to jump directly to the most relevant troubleshooting guide for your issue.
| Symptom | Likely Cause | Guide |
| ----------------------------------------------- | ----------------------------------------------- | --------------------------------------------------------------------------------------------- |
| Sheet fails to load, connection status "Failed" | Data model path or syntax error | [Fix Model Connection Errors](/powersheet/guides/troubleshooting/fix-model-connection-errors) |
| Entity type not recognized | Case mismatch or missing `domainModelTypes` key | [Fix Type Name Errors](/powersheet/guides/troubleshooting/fix-type-name-errors) |
| Relationship errors or missing navigation | Invalid `direct`/`back` names or link role | [Fix Relationship Errors](/powersheet/guides/troubleshooting/fix-relationship-errors) |
| Multi-item column shows single value | Missing `multiItem: true` on column | [Fix Multi-Item Column Errors](/powersheet/guides/troubleshooting/fix-multi-item-errors) |
| Custom field not appearing in sheet | Property not declared in data model | [Debug Custom Field Issues](/powersheet/guides/troubleshooting/debug-custom-field-issues) |
| Save operation fails with validation errors | Constraint violation or data issue | [Resolve Validation Errors](/powersheet/guides/troubleshooting/resolve-validation-errors) |
Why does my Powersheet show a blank or empty sheet?
Why does my sheet configuration fail to load?
Why do I get errors about entity types not being found?
How do I access the Powersheet administration interface?
Why does saving data fail with validation errors?
If your issue is not covered above, try the full [Troubleshooting Guides](/powersheet/guides/troubleshooting/index) for step-by-step walkthroughs, or browse the other FAQ pages:
* [General FAQ](/powersheet/faq/general) -- product overview and capabilities
* [Configuration FAQ](/powersheet/faq/configuration) -- sheet configuration questions
* [Data Model FAQ](/powersheet/faq/data-model) -- data model and entity type questions
* [Licensing FAQ](/powersheet/faq/licensing) -- license and access questions
# How to Evaluate Powersheet
Source: https://learn.nextedy.com/powersheet/getting-started/evaluation
This guide walks you through the two ways to evaluate Nextedy POWERSHEET -- a hosted trial with zero setup, or a local installation in your own Siemens Polarion ALM instance.
## Evaluation options at a glance
| | Hosted Trial | Local Trial |
| ------------------ | ----------------- | -------------------------- |
| **Setup time** | Minutes | 30-60 minutes |
| **Infrastructure** | Nextedy-hosted | Your Polarion server |
| **License** | Automatic | 30-day trial file |
| **Best for** | Quick exploration | Testing with your own data |
## Option 1: Hosted trial (recommended)
1. Go to the trial signup page at [Try Nextedy Solutions Online](https://go.nextedy.com/online-trial-powersheet-rtm)
2. Fill in your details
3. Your evaluation account and dedicated demo project are created automatically
4. You will receive login credentials by email
5. Log into the demo server, open the demo project, and use the **Powersheet Drive** in the left-hand navigation to explore the available views
Nextedy can schedule an introductory call to guide you through Powersheet basics and discuss how it fits your workflow. Request this when signing up.
## Option 2: Local trial
1. [Request the trial package](https://go.nextedy.com/powersheet-download-page) and license from Nextedy. You will receive a download link and a trial license (unlimited users, valid for 30 days)
2. Install the package following the [installation guide](/powersheet/getting-started/installation)
3. Upload the license in **Administration > Nextedy Powersheet > License** and assign the named Powersheet users following the guidance on the administration page
4. Instantiate the **Powersheet RTM Demo Project** from the installed template via **Administration > Nextedy Powersheet > Setup**
5. Open the project and navigate to the **Powersheet Drive** to begin exploring
Make sure your Polarion version is still supported by Siemens. Check the [Polarion versions support policy](https://go.nextedy.com/supported-versions) before installing.
## What the demo project includes
The demo project provides everything needed to explore Powersheet capabilities out of the box:
* Example **User Needs Specifications** with pre-populated work items
* **RTM configuration**: `UserNeed` > `SystemRequirement` > `DesignRequirement` > Tests
* Pre-populated data for trying **guided authoring, linking, and traceability coverage**
When you move from the demo to your own project, start with the simplest possible configuration -- a single entity type with a few columns. Extend incrementally once the basics work. Jumping straight to complex multi-entity configurations leads to hard-to-diagnose errors. See [Incremental Configuration Approach](/powersheet/getting-started/incremental-configuration) for more details...
## Verification
After completing either evaluation option, you should see:
* The **Powersheet Drive** in the left sidebar listing available documents
* A demo document opening in sheet view with a hierarchical table
* Editable cells where you can add, link, and modify work items directly in the sheet
## See also
* [Installing Powersheet](/powersheet/getting-started/installation) -- full installation walkthrough for local setup
* [Setting Up Navigation](/powersheet/getting-started/setup-navigation) -- configure the Powersheet topic in your sidebar
* [Creating Your First Data Model](/powersheet/getting-started/first-data-model) -- begin configuring your own data model
* [Incremental Configuration Approach](/powersheet/getting-started/incremental-configuration) -- why starting simple prevents errors
# Creating Your First Data Model
Source: https://learn.nextedy.com/powersheet/getting-started/first-data-model
This tutorial guides you through creating a minimal data model for Nextedy POWERSHEET in Siemens Polarion ALM.
## What you will achieve
By the end of this tutorial you will have:
* A working data model with two entity types (`UserNeed` and `SystemRequirement`)
* A many-to-many relationship connecting the two entity types via a Polarion link role
* Navigation properties (`direct` and `back`) that you can reference in sheet configurations
* A foundation you can extend with additional entity types like `DesignRequirement`, `Hazard`, or `RiskControl`
This tutorial uses `UserNeed` and `SystemRequirement` throughout, drawn from the shipped RTM example model. In your own configuration, replace `UserNeed` and `SystemRequirement` with entity types that match your domain — any names meaningful to your workflow (a risk-analysis model, for instance, might use `Hazard` and `RiskControl` instead).
## Prerequisites
* Nextedy Powersheet installed and licensed (see [Installing Powersheet](/powersheet/getting-started/installation))
* Navigation topic enabled — this registers Powersheet as a routable page so your configured sheets are reachable from the project sidebar (see [Setting Up Navigation](/powersheet/getting-started/setup-navigation))
* At least two Polarion work item types configured in your project (e.g., `user_need` and `sys_req`)
* A Polarion link role defined for connecting the two types (e.g., `decomposes`)
Navigate to **Administration > Nextedy Powersheet > Data Models**.
The Data Models page lists existing models grouped by scope — **Global** models apply to all projects, while project-scoped sections (e.g., **RTM w/ Components**) hold models tied to a specific project.
Click **New** to create a new data model at the project level. Select **System Default** as the base and give your model a name (e.g., `rtm`).
**You should see:** A new row is added to the Data Models list for your project. Click **Open** on that row to launch the configuration editor — it opens in a **new browser tab**, preloaded with the default template content.
Saving a new model only adds a row to the Data Models list; it does not open the editor automatically. Click **Open** on the model row to launch the configuration editor in a separate browser tab, leaving the administration page open behind it. Save in the editor tab, then return to the administration tab to manage other models.
The **System Default** base preloads a rich template (around 270 lines defining many entity types such as `Document`, `Chapter`, and several requirement types). The minimal YAML shown in this tutorial is meant for learning the structure. For a real project, **extend** the template rather than wholesale-replacing it — and before you make sweeping changes, copy the original content aside (for example via **Menu > Download configuration**, see [Step 4](#step-4-review-the-complete-model)) so you can recover the entity definitions you would otherwise lose.
You can also reach the model editor directly from an open Powersheet document via **Menu > Configuration > Edit Data Model**.
Data model files use YAML syntax. Indentation must use spaces (not tabs), and each nesting level uses two spaces. Most errors in data model setup come from incorrect indentation. For a complete introduction to YAML syntax, see the [YAML Primer](/powersheet/concepts/yaml-primer).
For this tutorial, set the data model content to the following minimal YAML (for a real project, add these definitions to the existing template rather than replacing it — see the warning in [Step 1](#step-1-open-the-data-models-administration)):
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
description:
severity:
SystemRequirement:
polarionType: sys_req
properties:
description:
severity:
```
Each key under `domainModelTypes` defines an entity type name. The `polarionType` property maps the entity type to a Polarion work item type. The `properties` section lists which work item fields are exposed for use in sheet configurations.
**You should see:** The YAML is accepted without errors in the editor.
Entity type names under `domainModelTypes` must be single words with no spaces or special characters. PascalCase (e.g., `UserNeed`, `SystemRequirement`) is the recommended naming convention, but it is not enforced by the system. The important rule is that these names are used consistently throughout your configuration — in relationships, sources, and column bindings.
The `polarionType` value must be the **exact** ID of a Polarion work item type configured in your project — and the match is **case-sensitive**. Polarion type IDs are commonly **snake\_case** (for example `user_need`, `sys_req`), not the camelCase or PascalCase you might assume. Writing `userNeed` when the real type ID is `user_need` does **not** raise an error: the model saves cleanly, and the mismatch only surfaces later as a sheet that renders **empty** with no diagnostic.
Look up the real IDs before you fill in `polarionType`: go to **Administration > Work Items > Types** and copy each type's **ID** value verbatim (the ID, not the display name). Note that the entity type name (the key, e.g. `UserNeed`) is separate — it is what you reference everywhere else in Powersheet configuration, while `polarionType` is the bridge to Polarion.
Add the `relationships` section below the entity types. Relationships use `direct` and `back` properties to define forward and reverse navigation:
```yaml theme={null}
relationships:
- from: SystemRequirement
to: UserNeed
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds
back:
name: systemRequirements
```
This defines a many-to-many relationship from `SystemRequirement` to `UserNeed`, stored using the Polarion `decomposes` link role.
* **`direct`** creates a navigation property on the `from` entity (`SystemRequirement`). The name `userNeeds` lets you navigate from a system requirement to its linked user needs.
* **`back`** creates a reverse navigation property on the `to` entity (`UserNeed`). The name `systemRequirements` lets you navigate from a user need to its linked system requirements.
The `decomposes` link role and a `SystemRequirement` → `UserNeed` relationship are already present in the System Default template. If you kept that template instead of starting from the minimal YAML above, do **not** add a second definition — adjust the existing relationship's `direct`/`back` names if needed rather than duplicating it.
**You should see:** The complete model now has both `domainModelTypes` and `relationships` sections.
The `from` and `to` values must match the entity type names defined in `domainModelTypes` — not the Polarion work item type IDs. For example, use `UserNeed` (the entity type name), not `user_need` (the Polarion type ID). Mismatching these is a common cause of data model errors.
Your complete data model should look like this:
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
description:
severity:
SystemRequirement:
polarionType: sys_req
properties:
description:
severity:
relationships:
- from: SystemRequirement
to: UserNeed
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds
back:
name: systemRequirements
```
Save the model.
The configuration editor auto-indents on every Enter, and the indentation **accumulates** with each new line. If you type multi-line YAML by hand, the leading spaces compound and the structure quickly breaks (deeper-and-deeper indentation that no longer reflects the real nesting). Instead, **paste the whole block at once** — for example by copying the complete YAML above with the copy button on the code block — and verify the indentation matches what is shown here. If you do edit by hand, watch the leading spaces on each line rather than trusting the editor to indent for you.
**You should see:** The model saves without errors. The `direct.name` and `back.name` values become the navigation properties you reference in your sheet configuration — in source expand paths and column bindings.
The model editor also offers a **Menu > Download configuration** action that saves the current YAML as a file on your machine. This is useful for backing up models, sharing them between projects, or version-controlling them outside Polarion.
The navigation properties you defined (`userNeeds` and `systemRequirements`) are the bridge between your data model and your sheet configuration. Here is how they connect:
| Data model property | Used in sheet configuration | Purpose |
| ------------------------------- | ------------------------------------ | ----------------------------------------------------- |
| `direct.name: userNeeds` | `expand: - name: userNeeds` | Expands system requirements to show linked user needs |
| `back.name: systemRequirements` | `expand: - name: systemRequirements` | Expands user needs to show linked system requirements |
| `polarionType: user_need` | Resolved automatically | Maps entity to Polarion work item queries |
| `properties: description` | `columns: description:` | Exposes field for column display |
Begin with two entity types and one relationship. Once your sheet renders correctly, add more entity types (e.g., `DesignRequirement`, `Hazard`, `RiskControl`) and relationships incrementally. See [Incremental Configuration Approach](/powersheet/getting-started/incremental-configuration) for guidance.
By default, an entity loads every matching work item in the project. **Constraints** let you scope that behavior per relationship, using three actions that each take a Polarion query:
* **`load`** (`loadFromQueries`) — where the entity's items are **loaded from** (which items appear in the sheet).
* **`saveToQueries`** — where a **new item is created** when added through this relationship (for example, into a specific document or component). (This stage has no short `save` alias — the data-model editor rejects a bare `save`, unlike `load` and `pick`.)
* **`pick`** (`pickFromQueries`) — which items are offered **in the item picker** (the dropdown used to link existing items).
A constraint query can reference the current context — for example restricting items to the same component as the source document via `$context.source.document.component`. You typically add a `constraints` block to a relationship once the basic model works; it is not required to get a sheet rendering.
```yaml theme={null}
relationships:
- from: SystemRequirement
to: UserNeed
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
constraints:
load: # alias for loadFromQueries
document: # scope by document — NOT a work-item type
moduleFolder: Requirements
moduleName: UserNeedSpecification
direct:
name: userNeeds
back:
name: systemRequirements
```
For the full syntax and worked examples, see [Configure Constraints](/powersheet/guides/data-model/configure-constraints).
A single entity type can map to **more than one** Polarion work item type (a "multi-type entity") — useful when, say, several discipline-specific requirement types should behave as one entity in the sheet. See [Map Multiple Polarion Types to One Entity](/powersheet/guides/data-model/create-entity-type#map-multiple-polarion-types-to-one-entity).
## Next steps
* [Creating Your First Sheet Configuration](/powersheet/getting-started/first-sheet-configuration) — use the navigation properties from your data model in column bindings
* [Creating Your First Powersheet Document](/powersheet/getting-started/first-document) — embed your configured sheet in a Polarion LiveDoc
* [Data Model Reference](/powersheet/reference/data-model/index) — full reference for `domainModelTypes`, `relationships`, `cardinality`, and `storage` options
* [Data Model Guides](/powersheet/guides/data-model/index) — add custom properties, set permissions, and extend your model
# Creating Your First Powersheet Document
Source: https://learn.nextedy.com/powersheet/getting-started/first-document
This tutorial walks you through creating a LiveDoc in Siemens Polarion ALM that renders as a Nextedy POWERSHEET sheet, bringing together your data model and sheet configuration into an interactive, navigable document.
## What you will achieve
By the end of this tutorial you will have:
* A `nextedySheetConfig` custom field configured on documents
* A LiveDoc assigned to your sheet configuration
* A working powersheet document accessible from the Powersheet Drive
## Prerequisites
* Powersheet installed and licensed (see [Installing Powersheet](/powersheet/getting-started/installation))
* Navigation topic enabled (see [Setting Up Navigation](/powersheet/getting-started/setup-navigation))
* A data model created (see [Creating Your First Data Model](/powersheet/getting-started/first-data-model))
* A sheet configuration created (see [Creating Your First Sheet Configuration](/powersheet/getting-started/first-sheet-configuration))
If you set up your project from the **RTM Demo template** (the template the install flow configures), the **Sheet Config** document custom field is likely already present -- check **Administration > Documents & Pages > Custom Fields** before adding it. Step 1 is for projects that don't have the field yet.
A sheet configuration is assigned to a document through a dedicated **document-scope** custom field. In Polarion this is configured under **Administration > Documents & Pages > Custom Fields** (the document custom fields -- not the work-item custom fields, which live under a separate admin section).
This admin page does not present a point-and-click form. Instead, it shows an XML editor for the project's `custom-fields.xml` definition, where each field is declared as a `` element. Add (or upload) a field definition with the following attributes:
| Attribute | Value |
| --------- | ----------------------------- |
| **id** | `nextedySheetConfig` |
| **name** | Sheet Config |
| **type** | `enum:Nextedy - Sheet Config` |
In other words, the field **Type** is `Enum`, and the enum it points to is the `Nextedy - Sheet Config` enumeration -- a Powersheet-provided enum that dynamically discovers the available sheet configuration files in the repository. A minimal entry looks like:
```xml theme={null}
```
Save the `custom-fields.xml` content to apply the definition.
**You should see:** After saving, the new custom field is available on documents in the project, backed by the `Nextedy - Sheet Config` enum that dynamically discovers available sheet configuration files from the repository.
The field ID and name can be customized. If you use a different ID, you must declare it in **Administration > Nextedy Powersheet > Configuration Properties** with:
`com.nextedy.powersheet.sheetConfigFieldId=yourFieldId`
(only needed when you deviate from the default `nextedySheetConfig` id).
Create a new LiveDoc in your project. The creation wizard exposes several fields; the ones that matter here are:
| Field | Notes |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Name** | A descriptive document name (e.g., "User Needs Specification"). |
| **Type** | The document type. It defaults to **System Requirements Specification**, but can be any document type that exposes the **Sheet Config** field (Step 1). |
After the document is created, open its **Properties** and set the **Sheet Config** field to your sheet configuration name (e.g., `rtm-sheet`).
**You should see:** The **Sheet Config** field shows a dropdown with the available sheet configurations discovered from both project and global locations.
If no configurations appear in the dropdown, verify that your sheet configuration was saved correctly in **Administration > Nextedy Powersheet > Sheet Configurations**. The enum provider scans the repository for available YAML files.
To allow users to easily switch from the LiveDoc view to the Powersheet view, add the following Velocity snippet directly into the document body -- the LiveDoc's `homePageContent` (the rich-text content area you edit in the document itself), not a separate sidebar or panel:
```velocity theme={null}
$openPowersheetButton.renderOpenPowersheetButton($document)
```
**You should see:** An "Open with Nextedy Powersheet" button appears in the LiveDoc, allowing users to jump directly to the sheet view.
Navigate to the **Powersheet Drive** in the left sidebar. Your new document should appear in the list.
The Drive doesn't always list a freshly created document right away. If it doesn't appear, reload the Drive (or do a hard refresh of the browser) to force the list to update.
Click the document name to open it in the Powersheet view.
**You should see:** The sheet loads with the columns defined in your sheet configuration. If the project contains work items matching the `UserNeed` type, they appear as rows with their related `SystemRequirement` items expandable beneath them.
If the sheet appears empty, it means there are no work items matching your data model's entity types yet. You can add rows directly in the sheet using the add button in the toolbar. New entities are created with default values from the entity factory configuration -- the part of your sheet configuration that determines the initial field values applied to a work item (row) when it is first created from the sheet.
With the sheet open, try the following operations:
1. **Add a row** -- click the add button to create a new `UserNeed` work item. If the sheet has more than one hierarchy level, each level has its own `(+)` control; use the one at the level you want the row at. For a top-level entity like `UserNeed`, use the root-level add button.
2. **Edit a cell** -- click on the title cell and type a name
3. **Save** -- click the save button to persist your changes to Polarion
**You should see:** New work items are created in Polarion, editable directly in the sheet. The save button becomes enabled when you make changes and is disabled after a successful save.
## Next steps
* [Incremental Configuration Approach](/powersheet/getting-started/incremental-configuration) -- learn how to extend your configuration step by step
* [How-To Guides](/powersheet/guides/index) -- task-oriented guides for common operations
* [Reference](/powersheet/reference/index) -- complete YAML property reference
## Related guides
* [Creating Your First Sheet Configuration](/powersheet/getting-started/first-sheet-configuration) -- define the columns and views referenced by this document
* [Creating Your First Data Model](/powersheet/getting-started/first-data-model) -- define the entity types that appear as rows
* [Setting Up Navigation](/powersheet/getting-started/setup-navigation) -- enable the Powersheet Drive topic in the sidebar
# Creating Your First Sheet Configuration
Source: https://learn.nextedy.com/powersheet/getting-started/first-sheet-configuration
This tutorial walks you through creating a minimal sheet configuration for Nextedy POWERSHEET in Siemens Polarion ALM.
## What you will achieve
By the end of this tutorial you will have:
* A working sheet configuration with columns for `UserNeed` and related `SystemRequirement` entities
* A data source that queries and expands the entity hierarchy from your data model
* A complete configuration ready to be linked to a Nextedy Powersheet document
## Prerequisites
* Powersheet installed and licensed (see [Installing Powersheet](/powersheet/getting-started/installation))
* A data model created with at least `UserNeed` and `SystemRequirement` entity types (see [Creating Your First Data Model](/powersheet/getting-started/first-data-model))
* Navigation topic enabled (see [Setting Up Navigation](/powersheet/getting-started/setup-navigation))
Navigate to **Administration > Nextedy Powersheet > Sheet Configurations**.
Sheet Configurations are organized into a **Global** section (applied across all projects) and a **project-level** section (specific to the current project). You can create new configurations in either scope.
Click **New** at the project level. Select **System Default** as the base and give your configuration a name (e.g., `rtm-sheet`).
The screenshot above shows a different example name (`my new powersheet config`). This tutorial uses `rtm-sheet` throughout — including when linking the configuration to a document in [Step 5](#step-5-link-the-configuration-to-a-document) — so use `rtm-sheet` (or your own chosen name) **consistently** wherever the tutorial refers to it.
**You should see:** A new sheet configuration file opens in the editor with default template content. The configuration editor opens in a **separate browser tab**, so your Polarion Administration view stays open behind it.
The **System Default** base ships with a substantial starting template (roughly 270 lines of commented examples covering columns, views, formatters, and styles). In Step 2 this tutorial has you replace it to keep the example minimal and focused. For a **real project**, prefer to *extend* the supplied template — or copy it aside before editing — so you keep the worked examples and inline documentation as a reference instead of throwing them away.
Sheet configuration files use YAML syntax. Indentation must use spaces (not tabs), and each nesting level uses two spaces. Most configuration errors come from incorrect indentation. For a complete introduction to YAML syntax, see the [YAML Primer](/powersheet/concepts/yaml-primer).
Replace the editor content with the following YAML. This defines columns for the root `UserNeed` entity and nested columns for related `SystemRequirement` entities:
```yaml theme={null}
columns:
title:
title: User Need
width: 250
hasFocus: true
severity:
title: Severity
width: 120
systemRequirements.systemRequirement.title:
title: System Requirement
width: 200
systemRequirements.systemRequirement.severity:
title: SR Severity
width: 120
```
Each key under `columns` is a **binding path** that references properties from your data model. A simple key like `title` refers to a property on the root entity type. A dot-separated path navigates through relationships defined in the data model:
| Path segment | Meaning |
| -------------------- | ------------------------------------------------------------------ |
| `systemRequirements` | The `direct` navigation property from your data model relationship |
| `systemRequirement` | The target entity type name |
| `title` | The property to display from the target entity |
**You should see:** Four column definitions in the YAML editor.
The configuration editor auto-indents on every Enter, and the indentation **accumulates** with each new line. If you type multi-line YAML by hand, the leading spaces compound and the structure quickly breaks (deeper-and-deeper indentation that no longer reflects the real nesting). Instead, **paste the whole block at once** — for example by copying the YAML above with the copy button on the code block — and verify the indentation matches what is shown here. If you do edit by hand, watch the leading spaces on each line rather than trusting the editor to indent for you.
The `title` property sets the column header text. Without it, the header defaults to the binding path (e.g., `0.systemRequirements.systemRequirement.title`), which is not user-friendly. Always set an explicit `title` for clarity.
Add a `sources` section below the columns. This tells Powersheet which data model to use, which entity type to query, and which relationships to expand when loading data:
```yaml theme={null}
sources:
- id: requirements
model: rtm
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: systemRequirement
```
The source configuration has three required parts (plus optional expansion):
* **`id`** (required) -- a unique identifier you choose for this data source. You can name it anything meaningful
* **`model`** (required) -- the name of the data model to use, which must match the data model file name (without the `.yaml` extension). The `rtm` value here assumes you named your model `rtm`; use **whatever name you actually gave the model** when you created it in [Creating Your First Data Model](/powersheet/getting-started/first-data-model). For example, `model: rtm` references the `rtm.yaml` data model file, while a model named `traceability` would require `model: traceability`
* **`query.from`** (required) -- the root entity type name, matching a key in `domainModelTypes` from your data model
* **`expand`** (optional) -- which relationships to follow when loading data. Each `name` corresponds to a navigation property from your data model. Expansion can be nested to follow multi-level relationships
**You should see:** The complete configuration now has both `columns` and `sources` sections.
Built-in properties like `id` and `title` do not need to be explicitly defined in your sources or data model to be queried; they are implicitly available. However, you must explicitly list them in your `columns` section if you want them to appear in the sheet.
The `query.from` value must exactly match a `domainModelTypes` key from your data model. If you defined `UserNeed` in the data model, you must use `UserNeed` here -- not `userneed` or `user_need`. The match is case-sensitive.
Your complete sheet configuration should look like this:
```yaml theme={null}
columns:
title:
title: User Need
width: 250
hasFocus: true
severity:
title: Severity
width: 120
systemRequirements.systemRequirement.title:
title: System Requirement
width: 200
systemRequirements.systemRequirement.severity:
title: SR Severity
width: 120
sources:
- id: requirements
model: rtm
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: systemRequirement
```
Save the configuration file.
**You should see:** The editor accepts the YAML without errors. The configuration is now stored in your project repository.
To see your sheet in action, link this configuration to a Powersheet document. Open (or create) a Powersheet document in your project and open its **Properties** sidebar. There you will find the sheet configuration custom field -- field ID `nextedySheetConfig`, labelled **Sheet Config** in the UI. Use its dropdown to select the configuration you just created (`rtm-sheet`), as shown above.
The `nextedySheetConfig` field must be registered on the document type before it appears in Properties. If it is missing, see [Installing Powersheet](/powersheet/getting-started/installation) for adding the custom field. If your project uses a different field ID, it must be declared via the `com.nextedy.powersheet.sheetConfigFieldId` configuration property.
**You should see:** When you open the document with Powersheet, it renders as a hierarchical sheet with four columns -- `UserNeed` title and severity at the root level, and `SystemRequirement` title and severity as expandable child rows.
This configuration is intentionally minimal. Once it works, you can add more columns, define views, configure formatters, and introduce additional entity types one property at a time. See [Incremental Configuration Approach](/powersheet/getting-started/incremental-configuration) for the recommended workflow.
## Understanding root-level properties
The sheet configuration supports several root-level properties beyond `columns` and `sources`. You do not need all of these to start -- `columns` and `sources` are sufficient for a working sheet:
| Property | Purpose |
| --------------------- | ----------------------------------------------------------------------------- |
| `columns` | Column definitions with binding paths, titles, and display options |
| `sources` | Data source queries and expansion paths |
| `views` | Named column visibility presets for switching between analysis perspectives |
| `formatters` | Conditional formatting rules based on cell or row values |
| `styles` | Reusable style definitions (colors, text decoration) referenced by formatters |
| `columnGroups` | Visual grouping of related columns with collapsible headers |
| `sortBy` | Default client-side sort order by column and direction |
| `renderers` | Custom rendering functions for specialized cell display |
| `showGroupRowCounter` | Whether to display item counts on group rows (default: hidden) |
## Next steps
* [Incremental Configuration Approach](/powersheet/getting-started/incremental-configuration) -- learn how to extend your configuration step by step
* [Creating Your First Powersheet Document](/powersheet/getting-started/first-document) -- create a document and see your sheet in action
* [Sheet Configuration Reference](/powersheet/reference/sheet-config/index) -- full property reference for all sheet configuration options
* [Columns Reference](/powersheet/reference/sheet-config/columns) -- detailed reference for column settings like `isReadOnly`, `formatter`, and `groupBy`
* [Data Model Guides](/powersheet/guides/data-model/index) -- extend your data model with additional entity types and relationships
# Incremental Configuration Approach
Source: https://learn.nextedy.com/powersheet/getting-started/incremental-configuration
Nextedy POWERSHEET configurations are powerful. A single data model and sheet configuration can express complex multi-level traceability hierarchies with constraints, custom columns, and dynamic expressions -- so build them incrementally to keep configuration errors easy to isolate.
## Why incremental matters
Powersheet requires two YAML files working in concert: a **data model** that defines entity types and their relationships, and a **sheet configuration** that defines columns, sources, and views. These files are tightly coupled. The sheet configuration references navigation property names from the data model, uses entity types defined there, and constructs binding paths that traverse the relationship graph.
When both files are written from scratch with their full intended complexity, any mismatch between them produces errors that look similar regardless of the underlying cause. A misspelled navigation property name, a missing entity type, an incorrect relationship direction, or a malformed binding path can all surface as vague loading failures or empty sheets.
Support data shows that jumping straight to complex multi-entity configurations is the most common cause of setup errors. Users who start with a single entity type and extend incrementally experience far fewer issues and resolve problems faster.
The incremental approach works because each layer introduces a bounded set of new concepts. When something breaks, you know it was caused by the most recent change, not by an interaction between dozens of configuration elements.
## The layered configuration model
Think of Powersheet configuration as stacking blocks. Each layer adds one capability on top of a working, validated foundation. You never move to the next layer until the current one works correctly.
The layers below use RTM entity types (`UserNeed`, `SystemRequirement`, `DesignRequirement`, `Hazard`, `RiskControl`) as a running example. Apply the same incremental approach with whatever entity types your domain requires.
## Layer 1: Single entity type
Start with just one entity type in the data model and two or three columns in the sheet configuration. The goal is to prove that the fundamental wiring between Powersheet, the data model, and Siemens Polarion ALM works correctly.
At this stage, your data model defines a single entity type with its `polarionType` mapping, and your sheet configuration references that model and exposes basic properties like title and severity.
**What you are validating:**
* The data model YAML loads without parse errors
* The `polarionType` mapping correctly connects the entity type to a Polarion work item type
* The sheet configuration's `model` reference resolves to your data model file
* The sheet queries data and displays rows
* Basic column bindings (direct properties like `title`, `severity`) render values
**What to check if it fails:**
| Symptom | Likely cause |
| --------------------------------- | ----------------------------------------------------------------------------------- |
| Sheet shows "Configuration error" | YAML syntax error in data model or sheet configuration |
| Sheet loads but shows no rows | `polarionType` does not match any existing work item type in the project |
| Column shows blank cells | Column binding path does not match a property name on the entity type |
| "Model not found" error | The `model` value in the sheet configuration does not match the data model filename |
Use the Polarion administration interface at **Administration > Nextedy Powersheet > Data Models** to verify your data model file is recognized before troubleshooting the sheet configuration.
Once Layer 1 works, you have a known-good baseline. Every subsequent change is measured against this working state.
## Layer 2: One relationship
Add a second entity type and define a single relationship between the two. This is where configuration complexity increases significantly, because you are now dealing with navigation properties, expansion paths, and cross-entity binding paths.
For example, add `SystemRequirement` as a second entity type and create a relationship from `UserNeed` to `SystemRequirement`. In the sheet configuration, add an `expand` entry to the source and new columns that use binding paths traversing the relationship.
**What you are validating:**
* Relationship navigation property names (`direct.name`, `back.name`) are correctly defined in the data model
* The `expand` section in the source configuration references the correct navigation property
* Binding paths like `systemRequirements.systemRequirement.title` resolve correctly across the relationship
* Expanding a row in the sheet shows child items from the related entity type
**Common misconceptions at this layer:**
A frequent source of confusion is the direction of navigation properties. When you define a relationship between `UserNeed` and `SystemRequirement`, the `direct` property is the name used to navigate from the source entity to the target, and the `back` property navigates in reverse. These names must match exactly between the data model relationship definition and the sheet configuration's expansion and column binding paths.
A mismatch between the navigation property name in the data model and the binding path in the sheet configuration is the single most common error at Layer 2. Double-check that the property name used after the dot in your column binding path exactly matches the `direct.name` or `back.name` value from the relationship definition.
## Layer 3: Deeper hierarchy
With two entity types and one relationship working, add a third entity type and a second relationship to create a multi-level hierarchy. This is where you validate that Powersheet can handle nested expansion paths.
For example, add `DesignRequirement` with a relationship from `SystemRequirement`. This creates a three-level hierarchy: `UserNeed` > `SystemRequirement` > `DesignRequirement`. Your binding paths now span multiple levels, such as `systemRequirements.systemRequirement.designRequirements.designRequirement.title`.
**What you are validating at this layer:**
* Multi-level expansion paths resolve correctly through nested relationships
* Column groups can organize columns from different entity types visually
* Views (named column visibility presets) correctly show and hide columns per analysis perspective
* Constraints, if added, enforce the intended creation and linking rules
This is also the right stage to introduce **views**. With three entity types generating many columns, views let you define named presets that show only the columns relevant to a particular analysis perspective. For instance, a "Requirements Coverage" view might show `UserNeed` and `SystemRequirement` columns while hiding `DesignRequirement` details.
**What to check if multi-level expansion fails:**
| Symptom | Likely cause |
| --------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| Second-level children do not appear | The second relationship's navigation property is not referenced in the nested `expand` |
| Columns show data for wrong entity type | Binding path skips a level or uses incorrect navigation property name |
| Expansion works but columns are empty | The binding path after the last navigation property does not match a real property on the target entity |
## Layer 4: Full configuration
Once the three-level hierarchy is proven, add the remaining entity types, constraints, formatters, column groups, and any cross-entity features your domain requires. For a full RTM, this means adding entity types like `Hazard` and `RiskControl`, along with their relationships and dedicated columns.
At this point, each addition is isolated. If adding `Hazard` breaks something, you know the issue is in the `Hazard` entity type definition, its relationship, or its column bindings, not in the foundation you already validated.
**Features to add at Layer 4:**
* **Additional entity types** with their relationships and expansion paths
* **Formatters** for conditional cell styling based on values
* **Column groups** with color-coded headers for visual organization (`columnGroups` with `groupName`, `groupStyle`, `headerStyle`)
* **Sort and grouping defaults** (`sortBy` at the sheet level, `groupBy` and `sort` on individual columns)
* **Entity factories** for creating new work items directly from the sheet
* **Constraints** that control which items can be created or linked
## The validation loop
The incremental approach follows a consistent loop at every layer:
1. **Add one thing** -- a new entity type, a relationship, a column group, a constraint
2. **Reload the sheet** -- open the Powersheet document in the browser to test
3. **Verify it works** -- check that data loads, columns render, expansion functions
4. **Diagnose if it fails** -- the cause is isolated to your most recent change
5. **Commit when stable** -- save the working configuration before moving to the next addition
This loop is analogous to test-driven development in software engineering. You never write the entire program and then test it. Instead, you build and verify in small increments, ensuring each piece works before adding the next.
Keep a copy of your last known-good configuration at each layer. If an addition breaks things and you cannot quickly identify the cause, reverting to the previous working state and trying again is faster than debugging a complex, multi-change failure.
## How Powersheet architecture supports this
Several architectural features of Powersheet make the incremental approach practical:
**Configuration files are independent.** The data model and sheet configuration are separate YAML files managed through **Administration > Nextedy Powersheet**. You can update one without touching the other, and the sheet reloads configuration on each page load.
**Data models are additive.** Adding a new entity type or relationship to the data model does not affect existing types. The metadata system discovers entity types from the model and makes them available for binding. Existing columns continue to work as before.
**Sources and expansion are declarative.** The `expand` section in a source configuration explicitly lists which relationships to traverse. Adding a new entity type to the data model does not automatically add it to the sheet. You must explicitly configure expansion and columns, which keeps each addition deliberate and reviewable.
**Views provide isolation.** Named views let you create focused perspectives that show only the columns you are currently working with. When adding Layer 3 columns, you can create a temporary view that shows only those columns, making it easier to verify they work without visual clutter from existing columns.
**Configuration scoping supports gradual rollout.** Both data models and sheet configurations support project-level and global scoping. You can develop and test a configuration at the project level before promoting it to a global configuration shared across projects.
**The default configuration ships with Powersheet.** Every installation includes a bundled default configuration (`powersheet.yaml`) that serves as both a reference and a starting point. You can examine how it structures columns, sources, and expansion to understand the patterns before writing your own.
## When to deviate from the layers
The four-layer model is a guideline, not a rigid process. Some situations call for a different ordering:
* **If your domain has a flat structure** (no hierarchies), you may only need Layers 1 and 4. Define all entity types as independent sources without expansion paths.
* **If you are migrating from an existing configuration**, start by importing it and validating it works, then refactor incrementally rather than rebuilding from scratch.
* **If you need constraints early** (for instance, to prevent accidental data creation during testing), add them at Layer 2 rather than waiting for Layer 4.
The principle remains the same: change one thing, verify, then move on.
## Common validation pitfalls
Based on support patterns, these are the errors most frequently seen during initial configuration:
| Error pattern | Likely cause | Layer |
| ---------------------------------------------- | ------------------------------------------------------------------------------- | ----- |
| Data model fails to load | YAML syntax error or entity type name contains invalid characters | 1 |
| Sheet loads with no rows | `polarionType` does not match any work item type in the project | 1 |
| Columns show no data after adding relationship | Binding path uses wrong navigation property name | 2 |
| Expansion shows no children | `expand` references a navigation property that does not exist in the data model | 2 |
| Multi-level path resolves partially | Intermediate relationship navigation property is misspelled | 3 |
| Column group does not appear | `columnGroup` value on the column does not match any `columnGroups` key | 4 |
Each of these errors is immediately identifiable when only one change was made since the last working configuration. In a full configuration written from scratch, any combination of these could occur simultaneously, making root cause analysis far more difficult.
## Next steps
For hands-on tutorials that follow this incremental approach:
* [Creating Your First Data Model](/powersheet/getting-started/first-data-model) covers Layer 1 in detail
* [Creating Your First Sheet Configuration](/powersheet/getting-started/first-sheet-configuration) walks through source and column setup
* [Creating Your First Powersheet Document](/powersheet/getting-started/first-document) shows how to connect configuration to a LiveDoc
For reference material on data model and sheet configuration properties:
* [Data Model Reference](/powersheet/reference/data-model/index)
* [Sheet Configuration Reference](/powersheet/reference/sheet-config/index)
For task-oriented guidance on specific configuration topics:
* [Data Model Guides](/powersheet/guides/data-model/index)
* [Sheet Configuration Guides](/powersheet/guides/sheet-configuration/index)
# Getting Started
Source: https://learn.nextedy.com/powersheet/getting-started/index
Welcome to the Nextedy POWERSHEET getting started guide. This section walks you through every step from initial installation to creating your first fully functional powersheet document in Siemens Polarion ALM.
Understand what Powersheet does, how it fits into Polarion, and the core concepts behind data models and sheet configurations.
Deploy Powersheet, apply your license, and verify the installation in Polarion administration.
Try Powersheet through a hosted trial or local installation with the RTM demo project.
Enable the Powersheet Drive topic in Polarion's sidebar so users can access powersheet documents.
Define entity types, map them to Polarion work item types, and configure relationships between them.
Set up columns, sources, and expansion paths that reference your data model.
Create a LiveDoc, assign a sheet configuration, and open it in the Powersheet view.
Learn the recommended strategy of starting simple and extending your configuration gradually.
**Recommended learning path**
Follow these pages in order: start with **What is Powersheet?** for conceptual understanding, then proceed through **Installation**, **Navigation**, **Data Model**, **Sheet Configuration**, and finally **Your First Document**. Read **Incremental Configuration Approach** before attempting complex multi-entity setups.
# Installation
Source: https://learn.nextedy.com/powersheet/getting-started/installation
## What you will achieve
By the end of this tutorial you will have:
* Nextedy POWERSHEET deployed on your Polarion server
* A valid license applied through the administration interface
* Either a demo project with sample data or Powersheet enabled in an existing project
## Prerequisites
* A running Polarion server with a [version still supported by Nextedy](/overview/resources/polarion-version-support)
* Administrator access to the Polarion server filesystem and web interface
* A Powersheet distribution package (`nextedy_powersheet.zip`) downloaded from the [Powersheet Download](https://go.nextedy.com/powersheet-download-page) page
* A valid license file (trial or production) provided by Nextedy
Unpack the downloaded `nextedy_powersheet.zip`. Inside you will find a folder named `com.nextedy.powersheet`.
Copy this entire folder into your Polarion extensions directory:
```text theme={null}
[POLARION_INSTALL]/polarion/extensions/
```
After copying, delete the cached configuration folders to avoid plugin conflicts:
```text theme={null}
[POLARION_DATA]/workspace/.config
[POLARION_DATA]/workspace/.metadata
```
Deleting the `.config` and `.metadata` folders only removes cached data. This is safe and recommended by Polarion support to ensure Powersheet is recognized correctly. Clearing **both** caches is important: a stale `.metadata` cache can otherwise cause server-side rendering to fail even after the plugin is deployed.
Restart the Polarion server.
**You should see:** After the server restarts and you open **Administration**, a new section called **Nextedy Powersheet** appears in the sidebar. This confirms Powersheet is installed. Look for it near the **bottom** of the Administration sidebar, below **Configuration Properties**.
If the **Nextedy Powersheet** section does not appear immediately after the restart, perform a hard refresh of your browser (**Ctrl+F5** on Windows/Linux, **Cmd+Shift+R** on macOS) to clear cached UI assets, then reopen **Administration**.
Polarion ships its own native **License** and **Maintenance** Administration topics. After installing Powersheet you will see a *separate* **License** topic under the **Nextedy Powersheet** section. When applying or checking your Powersheet license, always use the one under **Administration > Nextedy Powersheet**, not the similarly named native Polarion topic.
You can apply the license either through the administration interface (Option A) or by placing the file on the server filesystem (Option B). Whichever method you use, the verification below applies.
Unlike some other Nextedy products, Powersheet licenses are managed directly in the Polarion administration interface -- not via a separate license server. Make sure you apply the license through **Administration > Nextedy Powersheet > License** or via the server filesystem.
### Option A: Upload through the administration interface
1. Navigate to **Administration > Nextedy Powersheet > License**
2. Drag and drop your license file onto the upload area, or select it from your filesystem
The license is persisted automatically as soon as it is uploaded -- there is no separate save action.
### Option B: Place the license file on the server filesystem
You can also upload the license by placing the file directly on the Polarion server filesystem. Copy the license file into the extension's license directory and restart Polarion. For the exact filesystem path and step-by-step instructions, see the [Nextedy license installation guide](/overview/resources/installing-the-license).
The filesystem method is useful in automated deployments, Docker containers, or environments where browser access to the administration interface is restricted.
**You should see (either method):** Open **Administration > Nextedy Powersheet > License**. The license page displays the license details (expiration date, user count) and no red or warning banner is shown. The absence of a banner means the license is valid.
Navigate to **Administration > Nextedy Powersheet > Setup**.
Install the demo template by selecting **Demo Project Template > Install Demo Template**. (Depending on your Powersheet version, the in-product button may read slightly differently, e.g. **Install Demo**. The label also varies by state: it reads **Install Demo Template** on first use, but **Update Demo Template** once a demo template is already installed -- both perform the same action.)
Once installed, create a new project:
1. Select **Create New Project**
2. Choose the template **Powersheet RTM Demo**. The template list shows all installed Polarion templates, so type `powersheet` into the template dropdown's filter to narrow it down and surface the **Powersheet RTM Demo** entry.
3. Complete the wizard (the standard Polarion new-project wizard: **Basics > Template > Summary**) and open the project home page
4. In the left navigator, select **Powersheet Drive**
Installing the demo template uploads it to the Polarion server filesystem at `.polarion/projects/templates/`, where it becomes available to the new-project wizard like any other Polarion project template.
**You should see:** The Powersheet Drive displays a list of preconfigured documents with sample data, including example User Needs Specifications and an RTM configuration covering User Needs, System Requirements, Design Requirements, and Tests.
The demo dataset is richer than this summary suggests. Alongside the requirements documents, your demo project also contains additional sample documents such as Backup, Communication, and Firmware SRS -- so don't be surprised to see more entries than the ones described here.
The demo project is the fastest way to explore Powersheet capabilities. It includes pre-populated data so you can immediately try editing, linking, and navigating the traceability hierarchy.
Open one of the demo documents from the Powersheet Drive. The sheet loads and displays a hierarchical table with editable cells, column headers, and expansion controls.
Opening a document from the Powersheet Drive launches it in a **new browser tab**, leaving the Drive open in the original tab. This is expected behavior.
It is also possible to open the sheet from the document in the standard Polarion view. To switch to the sheet view, click the **Open with Nextedy Powersheet** button (shown below).
Verify the following:
| Check | Expected result |
| ------------------------------------------------------- | ----------------------------------- |
| **Administration > Nextedy Powersheet** section visible | Plugin installed correctly |
| License page shows no red or warning banner | License applied and valid |
| Powersheet Drive lists documents | Navigation topic enabled |
| Demo document opens in sheet view | Configuration and data model loaded |
If the license page shows no warning or error banner, the license is valid -- the UI does not display a separate OK indicator.
## Troubleshooting
If Powersheet does not appear after installation:
1. Stop Polarion
2. Delete the cache folders: `[POLARION_DATA]/workspace/.config` and `[POLARION_DATA]/workspace/.metadata`
3. Restart Polarion
This forces Polarion to reinitialize the extension configuration and usually resolves recognition issues.
If the license page shows an **INVALID** or **WARNING** banner, check the following common causes:
* **Wrong product license:** Confirm you uploaded the license file for Powersheet specifically, not a license for a different Nextedy product (such as Risksheet or Checklist).
* **Expired license:** Check the expiration date displayed on the license page. Trial licenses have a fixed duration -- contact Nextedy to request a renewal if yours has expired.
* **Server hostname mismatch:** Some production licenses are bound to a specific server hostname. Verify that the hostname in the license matches your Polarion server's actual hostname.
* **Corrupted or truncated file:** If the license file was forwarded via email or downloaded multiple times, it may have been corrupted. Re-download the original file from the link provided by Nextedy.
* **Incomplete restart after filesystem upload:** When uploading a license via the server filesystem, a full Polarion restart is required. A partial restart or service reload may not pick up the new license file.
If none of these resolve the issue, contact [Nextedy support](https://support.nextedy.com/support/tickets/new) with a screenshot of the license status page and the exact error message shown.
## Next steps
* [Setting Up Navigation](/powersheet/getting-started/setup-navigation) -- configure the Powersheet topic in your project's sidebar
* [Creating Your First Data Model](/powersheet/getting-started/first-data-model) -- define entity types and relationships for your project
* [Creating Your First Sheet Configuration](/powersheet/getting-started/first-sheet-configuration) -- set up columns and views for your sheet
* [How to Evaluate Powersheet](/powersheet/getting-started/evaluation) -- explore hosted and local trial options
- [What is a Powersheet?](/powersheet/getting-started/what-is-powersheet)
- [Setting Up Navigation](/powersheet/getting-started/setup-navigation) -- enable Powersheet in an existing project
- [How to Evaluate Powersheet](/powersheet/getting-started/evaluation)
# Setting Up Navigation
Source: https://learn.nextedy.com/powersheet/getting-started/setup-navigation
This tutorial walks you through enabling the Nextedy POWERSHEET navigation topic in Siemens Polarion ALM, creating the required custom field for documents, and verifying that Powersheet Drive appears in the project sidebar.
## What you will achieve
By the end of this tutorial you will have:
* The `nextedySheetConfig` custom field created for documents in your project
* The Powersheet topic added to your project's navigation views
* Powersheet Drive visible in the left sidebar, listing all configured powersheet documents
## Prerequisites
* Powersheet installed and licensed (see [Installing Powersheet](/powersheet/getting-started/installation))
* Administrator access to the Polarion project
* At least one sheet configuration uploaded to **Administration > Nextedy Powersheet > Sheet Configurations**
Without completing these steps, Powersheet Drive will not appear in the sidebar and documents cannot be associated with sheet configurations. Both the custom field and the navigation topic are required.
Before Powersheet Drive can discover documents, each document needs a custom field that stores the reference to its sheet configuration file. You must create this field at the project level.
1. Navigate to **Administration > Documents & Pages > Document Custom Fields**
2. Add a new custom field with these settings:
| Setting | Value |
| -------- | -------------------- |
| **ID** | `nextedySheetConfig` |
| **Name** | Nextedy Sheet Config |
| **Type** | Enum (single value) |
3. Save the custom field definition
**You should see:** The `nextedySheetConfig` field listed among your document custom fields. Powersheet automatically populates the enum options through the `@NextedySheetConfigs` enum provider, which discovers all uploaded sheet configuration files.
The enum provider dynamically lists all sheet configuration YAML files that have been uploaded through **Administration > Nextedy Powersheet > Sheet Configurations**. You do not need to manually define the enum values.
Navigate to **Administration > Portal > Topics** in your Polarion project.
**You should see:** A list of views (such as `admin`, `team`, `docspec`) with their configured topics. Each view defines which sidebar topics are visible for users assigned to that view.
Add the following topic entry to each view where Powersheet should be available:
```xml theme={null}
```
Add this entry to the `admin`, `team`, and `docspec` views so that all relevant user roles can see the Powersheet Drive in the sidebar.
**You should see:** The topic entry appears in the view configuration alongside other topics like Documents, Work Items, and Plans.
Adding the topic to a view makes Powersheet Drive visible for all users assigned to that view. You can selectively enable it for specific roles by only adding it to certain views.
For Powersheet Drive to list a document, the document must have its `nextedySheetConfig` field set to a valid sheet configuration.
1. Open a LiveDoc in your project
2. Open the document properties panel
3. Set the **Nextedy Sheet Config** field to one of the available sheet configurations
4. Save the document
**You should see:** The selected sheet configuration name appears in the document properties. This document will now be discoverable by Powersheet Drive.
Save the topics configuration and navigate to your project home page. In the left sidebar, you should now see the **Powersheet Drive** entry.
**You should see:** Clicking **Powersheet Drive** displays a list of all documents in your project that have a valid `nextedySheetConfig` custom field value. Each document entry opens directly in the Powersheet sheet view.
If no documents appear in Powersheet Drive, verify that at least one document has a sheet configuration assigned in its `nextedySheetConfig` field. The drive discovers documents by querying for all documents where this field is populated.
Click any document listed in Powersheet Drive. Powersheet loads the associated sheet configuration and data model, then renders the hierarchical sheet with your configured columns and expansion paths.
**You should see:** The document opens in the Powersheet sheet view showing the configured columns, entity types, and hierarchical data. The toolbar provides access to editing, filtering, sorting, and export features.
You can also open any document with Powersheet using the **Open with Powersheet** button that appears in the Polarion document toolbar. This button is available on any document that has a sheet configuration assigned.
## Configuration scope
Data model and sheet configuration files can be managed at multiple levels through the Polarion administration interface:
* **Administration > Nextedy Powersheet > Data Models** -- for data model YAML files
* **Administration > Nextedy Powersheet > Sheet Configurations** -- for sheet configuration YAML files
| Configuration scope | Description |
| ------------------- | ----------------------------------------------------- |
| **Project** | Configuration files specific to one project |
| **Project Group** | Configuration files shared across projects in a group |
| **Global** | Configuration files shared across all projects |
## Troubleshooting
| Symptom | Cause | Solution |
| ---------------------------------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------- |
| Powersheet Drive not in sidebar | Topic not added to view | Add ` ` to the relevant view in **Administration > Portal > Topics** |
| Drive shows empty list | No documents configured | Assign a sheet configuration to at least one document via its `nextedySheetConfig` field |
| `nextedySheetConfig` field not available | Custom field not created | Create the custom field in **Administration > Documents & Pages > Document Custom Fields** |
| No enum options in config field | No configs uploaded | Upload at least one sheet configuration through **Administration > Nextedy Powersheet > Sheet Configurations** |
## Next steps
* [Creating Your First Data Model](/powersheet/getting-started/first-data-model) -- define entity types and relationships for your project
* [Creating Your First Sheet Configuration](/powersheet/getting-started/first-sheet-configuration) -- configure columns, formatters, and views
* [Creating Your First Powersheet Document](/powersheet/getting-started/first-document) -- build your first working powersheet document
* [Incremental Configuration Approach](/powersheet/getting-started/incremental-configuration) -- learn how to extend configurations step by step
# What is Powersheet?
Source: https://learn.nextedy.com/powersheet/getting-started/what-is-powersheet
Nextedy POWERSHEET is a hierarchical sheet app for Siemens Polarion ALM that brings Excel-like editing and model-driven data management directly into Polarion.
## The Problem Powersheet Solves
Polarion ALM stores data as individual work items connected through link roles, but viewing and editing those relationships at scale is cumbersome. Any team managing structured hierarchical data -- whether requirements traceability, risk registers, task boards, or custom data models -- faces the same challenge: they need to see the full chain at once, not click through dozens of separate pages. This is especially acute in regulated industries (automotive, aerospace, and medical devices) where traceability evidence must be complete and auditable.
Nextedy Powersheet solves this by projecting those multi-level relationships into a single, configurable sheet where every column, row hierarchy, and edit behavior is defined through YAML configuration.
## Core Architecture
Powersheet separates concerns into three distinct layers: a **data model** that defines the data structure, a **sheet configuration** that controls presentation and interaction, and a **document** that serves as the entry point within Polarion.
### 1. Data Model
The **data model** is a YAML file that defines what slice of the Polarion data model is visible and editable within Powersheet. It acts as a semantic layer that maps Polarion's native elements -- work item types, link roles, document types -- into structured entity types and relationships.
Key responsibilities of the data model:
* **Mapping and normalization** -- Enables centralized configuration even across projects with slightly different Polarion setups. You can reuse the same sheet configuration while only adjusting the data model mapping.
* **Process constraints** -- Defines custom rules not natively enforceable in Polarion, such as link cardinality (for example, a `SystemRequirement` may link to only one `UserNeed` in an RTM model) and document rules (an entity must exist in documents of a specific type).
* **Reusability** -- You can define both global models and project-specific models. Multiple models can exist and be reused across projects.
Data models are managed in Polarion at **Administration > Nextedy Powersheet > Data Models**. Powersheet ships with ready-to-use RTM traceability.
### 2. Sheet Configuration
The **sheet configuration** defines how data from the model is displayed and interacted with. Stored as a YAML file, it specifies:
* **Columns** -- Which attributes and relationships are visible, which are editable, and how they are formatted
* **Sources** -- Where to query data and how to expand related entities through expansion paths
* **Views** -- Named column visibility presets for different analysis perspectives (for example, one view for coverage analysis, another for risk assessment)
A single sheet configuration can be referenced from multiple documents. Each configuration is tied to a data model, so the column binding paths must match the entity types and relationships defined in the model.
### 3. Document Entry Point
Each powersheet is anchored to a Polarion LiveDoc. There are two patterns:
* **Self-contained** -- The document is associated with a sheet configuration and visualizes data defined by that configuration.
* **Template-based** -- The document references a shared sheet configuration that can be reused across many documents.
From the user's perspective, they open a Polarion document as usual. If a sheet configuration is assigned, they see the powersheet view and can begin editing, creating, and linking work items directly in the sheet.
## Powersheet Drive
Powersheet introduces **Powersheet Drive**, a dedicated topic in the Polarion sidebar that serves as a navigator for all configured powersheet documents. By default, it lists all documents with an assigned sheet configuration, providing a central entry point into structured traceability and planning views.
The Powersheet Drive topic must be enabled in Polarion's topic configuration before it appears in the sidebar. See [Setting Up Navigation](/powersheet/getting-started/setup-navigation) for instructions.
## How Configuration Layers Work Together
The separation between data model and sheet configuration is intentional. Consider a scenario where two projects use different Polarion work item type IDs for the same logical concept -- one uses `sys_req` and the other uses `system_requirement`. With Powersheet, you create two data models (each mapping to their project's type IDs) but share a single sheet configuration. The sheet configuration refers to the logical entity type (for example, `SystemRequirement` from the RTM model), and the data model handles the mapping to the actual Polarion type.
This architecture supports standards compliance for ISO 15288, Automotive SPICE, and ISO 26262 by keeping the process-level configuration (data model) separate from the presentation-level configuration (sheet configuration).
## What You Can Do in a Powersheet
Once configured, end users can:
* View hierarchical data with expandable rows showing related entities
* Edit work item properties inline with type-aware editors
* Create new work items and links directly in the sheet
* Filter and sort across all columns, including related entity properties
* Group rows by column values with collapsible group headers
* Switch between named views for different analysis perspectives
* Copy and paste cell ranges within the sheet
* Use keyboard shortcuts for common operations
Support experience shows that starting with a minimal single-entity configuration and extending incrementally is the most reliable approach. See [Incremental Configuration Approach](/powersheet/getting-started/incremental-configuration) for guidance.
## Next Steps
* [**Installing Powersheet**](/powersheet/getting-started/installation) -- Deploy Powersheet into your Polarion instance
* [**How to Evaluate Powersheet**](/powersheet/getting-started/evaluation) -- Try Powersheet through a hosted or local trial
* [**Concepts**](/powersheet/concepts/index) -- Deep dive into architecture, entity types, and relationships
# Configure Permissions
Source: https://learn.nextedy.com/powersheet/guides/administration/configure-permissions
Control who can view and edit data in Nextedy POWERSHEET by configuring property-level permissions in your data model, setting administration access, and applying sheet-level read-only mode.
## Prerequisites
* Access to the data model YAML file for your project
* **Administration > Nextedy Powersheet > Data Models** permissions to edit configurations
* Basic familiarity with the data model entity type structure
## Set Property-Level Permissions
Property-level permissions control whether individual fields on an entity type are visible or editable. Configure the `readable` and `updatable` flags on each property in your data model.
### Step 1: Open Your Data Model
Navigate to **Administration > Nextedy Powersheet > Data Models** and open the YAML file for your project.
### Step 2: Add Permission Flags to Properties
For each property where you want to restrict access, add `readable` and `updatable` flags:
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
title:
readable: true
updatable: true
description:
readable: true
updatable: true
severity:
readable: true
updatable: false
internalNotes:
readable: false
updatable: false
```
| Flag | Type | Default | Effect |
| ----------- | --------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `readable` | `boolean` | `true` | When `false`, the property is excluded from the data payload entirely -- it is not loaded or transmitted to the client |
| `updatable` | `boolean` | `false` | When `false` -- including when omitted, since this is the default -- the property appears in the sheet but cannot be modified by users |
**Hidden properties are not transmitted**
Setting `readable: false` does more than hide the column in the UI. The property is excluded from the data payload at the server level -- it is never loaded or sent to the client. This provides data-level security, not just visual hiding.
### Step 3: Save and Reload
Save the data model file. Users need to reload any open Powersheet pages to pick up the updated permission settings.
## Configure Administration Access
Powersheet separates administration permissions into two scopes: **document configuration** and **data model configuration**. Each scope has independent read and write flags.
| Permission | Controls |
| ---------------------- | ---------------------------------------- |
| `document.admin.read` | View the sheet configuration YAML |
| `document.admin.write` | Modify the sheet configuration YAML |
| `model.admin.read` | View the data model configuration YAML |
| `model.admin.write` | Modify the data model configuration YAML |
A user with `document.admin.read` but without `document.admin.write` can view the sheet configuration YAML but cannot save changes. The same applies independently to data model configuration.
**Separate read and write for safety**
Grant `model.admin.read` broadly so engineers can inspect the data model for reference, but restrict `model.admin.write` to administrators who understand the impact of model changes on existing data.
## Enable Sheet-Level Read-Only Mode
The entire sheet can be set to read-only using the `isReadOnly` property in the sheet configuration. This prevents all editing regardless of individual property permissions.
### Step 1: Open Your Sheet Configuration
Navigate to **Administration > Nextedy Powersheet > Sheet Configurations** and open the YAML file assigned to your document.
### Step 2: Set the Read-Only Flag
Add `isReadOnly: true` at the root level of your configuration:
```yaml theme={null}
isReadOnly: true
columns:
title:
title: Title
hasFocus: true
severity:
title: Severity
```
**Three conditions trigger read-only mode**
The sheet enters read-only mode if **any** of these conditions is true:
1. The sheet configuration has `isReadOnly: true`
2. The user has the `readOnly` permission flag set to `true`
3. The user is viewing a historical revision or baseline
You do not need to set all three -- any single condition is sufficient.
## Restrict Individual Columns
Beyond property-level permissions in the data model, you can also enforce read-only on specific columns in the sheet configuration using the `isReadOnly` column property:
```yaml theme={null}
columns:
title:
title: Title
hasFocus: true
severity:
title: Severity
isReadOnly: true
chapter.title:
title: Chapter Title
isReadOnly: true
```
This is useful when a property should be editable in one sheet configuration but read-only in another. The data model `updatable` flag applies globally across all sheets, while the column-level `isReadOnly` applies only to the specific sheet configuration.
| Approach | Scope | Defined In |
| ------------------------------ | -------------------------------- | -------------------------- |
| `updatable: false` on property | All sheets using this data model | Data model YAML |
| `isReadOnly: true` on column | Single sheet configuration | Sheet configuration YAML |
| `isReadOnly: true` at root | Entire sheet | Sheet configuration YAML |
| `readOnly` user flag | Per user | Server-managed permissions |
## Configure Navigation Property Permissions
Relationships in the data model define navigation properties using `direct` and `back` directions. Each direction can carry its own permission settings, independent of the target entity type:
```yaml theme={null}
relationships:
- from: UserNeed
to: SystemRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: systemRequirements
back:
name: userNeeds
```
The `direct` navigation property (from source to target) and `back` navigation property (from target to source) can each have permission settings that control whether users can traverse and modify the relationship from that direction.
**Verify in application**
Navigation property permissions are under active development. The exact flags and their behavior may change. Test permission settings in a non-production project before deploying.
## Combine Permission Layers
A practical configuration combines multiple permission layers. Here is a complete example that restricts a `SystemRequirement` entity so that `severity` is visible but not editable, and `internalNotes` is completely hidden:
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
title:
readable: true
updatable: true
description:
readable: true
updatable: true
severity:
readable: true
updatable: true
SystemRequirement:
polarionType: sys_req
properties:
title:
readable: true
updatable: true
description:
readable: true
updatable: true
severity:
readable: true
updatable: false
internalNotes:
readable: false
updatable: false
relationships:
- from: SystemRequirement
to: UserNeed
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds
back:
name: systemRequirements
```
In the sheet configuration for a review-oriented view, you might further lock down columns:
```yaml theme={null}
isReadOnly: false
columns:
title:
title: Title
hasFocus: true
description:
title: Description
severity:
title: Severity
isReadOnly: true
userNeeds.userNeed:
title: Linked User Needs
isReadOnly: true
```
In this setup:
* `title` and `description` are fully editable
* `severity` is visible but cannot be changed (enforced by both `updatable: false` in the model and `isReadOnly: true` in the sheet)
* `internalNotes` never appears because `readable: false` prevents it from being loaded
* The linked user needs column is displayed but cannot be modified in this particular sheet view
## Verify Your Configuration
After saving your data model and sheet configuration changes:
1. Open the Powersheet page as a regular user (not an administrator)
2. Verify that columns with `updatable: false` appear greyed out and reject edits
3. Verify that properties with `readable: false` do not appear in the sheet at all
4. If `isReadOnly: true` is set on the sheet, confirm that no cells are editable
5. Check that administration panels respect the `document.admin` and `model.admin` permission flags
You should now see restricted properties rendered as non-editable cells and hidden properties completely absent from the sheet view.
## See Also
* [Configure Read-Only Column](/powersheet/guides/sheet-configuration/configure-read-only-column) -- column-level `isReadOnly` usage
* [Set Entity Permissions](/powersheet/guides/data-model/set-permissions) -- data model property permission reference
* [Add a Custom Property](/powersheet/guides/data-model/add-custom-property) -- adding properties to entity types
* [Install and Manage License](/powersheet/guides/administration/install-manage-license) -- license status and its effect on access
* [Manage Global Configuration](/powersheet/guides/administration/manage-global-config) -- global vs project-level configuration scope
# Administration Guides
Source: https://learn.nextedy.com/powersheet/guides/administration/index
Nextedy POWERSHEET administration covers permissions and version maintenance that apply across all projects in your Siemens Polarion ALM instance.
For initial installation and license activation, see [Getting Started > Installation](/powersheet/getting-started/installation).
## Administration Topics
Control who can view, edit, and administer sheet configurations and data models by setting up role-based access at the project and global levels.
Upgrade Powersheet to a new version by replacing the extension files, clearing the cache, and verifying the installation.
Ask configuration questions inside the editor and get documentation-grounded answers from the in-product AI Assistant.
## Typical Administration Workflow
The following sequence represents the standard path for setting up Powersheet in a new Polarion environment:
```
┌──────────────────────┐ ┌────────────────────────┐ ┌──────────────────────┐
│ 1. Install & │ │ 2. Set Permissions │ │ 3. Maintain & │
│ Activate License │────▶│ for Projects & Roles │────▶│ Update Powersheet │
│ (Getting Started) │ │ │ │ │
└──────────────────────┘ └────────────────────────┘ └──────────────────────┘
```
1. **License first** — Powersheet features are unavailable until a valid license is installed and activated on the Polarion server. See [Getting Started > Installation](/powersheet/getting-started/installation) for license installation steps.
2. **Permissions** — Assign administrative and editing roles so that project teams can work with their sheet configurations while sensitive settings remain protected.
3. **Ongoing maintenance** — Apply updates as new Powersheet versions become available, ensuring users benefit from the latest features and fixes.
**Project-Level Configuration**
Most Powersheet configuration happens at the project level through data models and sheet configurations. Administrators control who can edit these artifacts via the permissions guide, while project teams own the configuration content itself.
## Related Resources
Once administration is complete, project teams can begin building their configurations:
* **[Data Model Guides](/powersheet/guides/data-model/index)** — Define entity types, relationships, and constraints for your domain
* **[Sheet Configuration Guides](/powersheet/guides/sheet-configuration/index)** — Set up columns, views, and formatting for project sheets
* **[Troubleshooting Guides](/powersheet/guides/troubleshooting/index)** — Resolve common configuration and connectivity issues
# Install and Manage License
Source: https://learn.nextedy.com/powersheet/guides/administration/install-manage-license
This guide walks you through installing Nextedy POWERSHEET on your Siemens Polarion ALM server and activating, renewing, or troubleshooting your license.
## Prerequisites
Before you begin, ensure the following:
* **Polarion ALM** is installed and running (version 2304 or later recommended)
* You have **administrator access** to the Polarion server file system
* You have received a Powersheet license file (`.lic`) or license key from Nextedy
* The Polarion service can be restarted during the installation window
1. Download the Powersheet distribution package (`.jar` file) from the Nextedy customer portal
2. Copy the `.jar` file into the Polarion extensions directory:
```
/polarion/extensions/
```
3. Restart the Polarion server service to load Powersheet
**Verify that Powersheet loaded**
After restart, check the Polarion server log for a line confirming Powersheet initialization. If Powersheet does not appear, verify that the `.jar` file has the correct read permissions.
Powersheet requires a valid license to operate. You can activate it through the Polarion administration interface.
1. Log in to Polarion as an administrator
2. Navigate to **Administration > Nextedy Powersheet > License**
3. Choose one of the activation methods below
### Option A: Upload License File
1. Click **Upload License**
2. Select the `.lic` file provided by Nextedy
3. Click **Activate**
4. The license details (type, expiration date, licensed user count) will appear on screen
### Option B: Enter License Key
1. Click **Enter License Key**
2. Paste the license key string into the text field
3. Click **Activate**
After activation, confirm the license is active:
1. Navigate to **Administration > Nextedy Powersheet > License**
2. Review the license information panel:
| Field | Description |
| ------------------- | --------------------------------- |
| **License Type** | Named-user or site license |
| **Status** | Active, Expired, or Trial |
| **Expiration Date** | Date the license expires |
| **Licensed Users** | Maximum concurrent users allowed |
| **Product Version** | Licensed Powersheet version range |
**Verify in application**
The exact fields displayed on the license panel may vary by Powersheet version. Check your administration panel for the current layout.
## Renew an Expiring License
When your license approaches its expiration date, Powersheet displays a notification banner to administrators.
1. Contact Nextedy support or your account manager to obtain a renewed license file
2. Navigate to **Administration > Nextedy Powersheet > License**
3. Click **Update License** and upload the new `.lic` file
4. The new expiration date should appear immediately — no server restart required
**Do not let the license expire**
Once expired, Powersheet sheets will display in **read-only mode**. Users will not be able to save changes or create new work items through the sheet. Upload the renewed license before the expiration date to avoid disruption.
## Manage License on Clustered Deployments
If your Polarion installation runs in a clustered (multi-node) configuration:
1. Install the Powersheet `.jar` on **every cluster node** in the same extensions directory path
2. Activate the license on the **primary node** only — the license state is stored centrally in the Polarion repository
3. Restart all cluster nodes after installation
4. Verify the license status from any node's administration panel
**Shared storage simplifies updates**
If your cluster nodes share a common file system for the extensions directory, you only need to copy the `.jar` file once. Each node will pick it up after its individual restart.
## Switch Between License Types
To upgrade from a trial or named-user license to a site license:
1. Navigate to **Administration > Nextedy Powersheet > License**
2. Click **Update License**
3. Upload the new license file — the new license type replaces the previous one
4. Confirm the updated **License Type** and **Licensed Users** values in the panel
No uninstallation or removal of the previous license is necessary. The new license file overwrites the old activation.
## Uninstall Powersheet
If you need to remove Powersheet from your Polarion server:
1. Stop the Polarion server service
2. Remove the Powersheet `.jar` file from:
```
/polarion/extensions/
```
3. Restart the Polarion server
**Configuration files are preserved**
Uninstalling Powersheet does not remove data model or sheet configuration YAML files from your project repositories. These files remain in SVN and are harmless without Powersheet installed. If you reinstall later, your configurations will still be available.
## Troubleshoot Common License Issues
| Symptom | Likely Cause | Resolution |
| --------------------------------- | ------------------------------------------------- | --------------------------------------------------------------------------------- |
| "License not found" after restart | `.lic` file not uploaded through Admin UI | Navigate to **Administration > Nextedy Powersheet > License** and upload the file |
| Sheet opens in read-only mode | License expired or user count exceeded | Check license status; renew or upgrade |
| License page not visible in Admin | Extension `.jar` not loaded | Verify the `.jar` is in the extensions directory and restart the server |
| "Invalid license" error on upload | License file corrupted or for a different product | Re-download the `.lic` file from the customer portal or contact support |
## Verification
You should now see:
* ✅ Powersheet loaded in **Administration > Extensions**
* ✅ An active license with a valid expiration date on the **Administration > Nextedy Powersheet > License** page
* ✅ Powersheet sheets rendering and allowing edits in your project documents
## See Also
* [Administration Guides](/powersheet/guides/administration/index) — overview of all administration tasks
* [Configure Permissions](/powersheet/guides/administration/configure-permissions) — set up user and role access controls
* [Getting Started](/powersheet/getting-started/index) — first steps after installation
# Manage Global Configuration
Source: https://learn.nextedy.com/powersheet/guides/administration/manage-global-config
This guide walks you through locating, editing, and maintaining the global Nextedy POWERSHEET configuration that applies across your Polarion instance.
## Prerequisites
* Administrator access to the Polarion server
* SVN access to the global repository (`.polarion` directory at repository root)
* Familiarity with YAML syntax and Powersheet [sheet configuration](/powersheet/reference/sheet-config/index) concepts
## Understand the Configuration Hierarchy
Powersheet resolves configuration at three levels. Global configuration provides defaults that project-level and document-level settings can override.
Global configuration is stored in the SVN repository root, not inside any individual project. Access it via the Polarion administration UI or directly through SVN.
**Via Polarion UI:**
1. Navigate to **Administration > Nextedy Powersheet**
2. Open the **Global Settings** section
3. Review the data models and sheet configurations listed
**Via SVN:**
The global configuration resides at the repository root level:
```
/
.polarion/
nextedy/
models/ # Global data models
default_model.yaml
sheet-configurations/ # Global sheet configurations
default_sheet.yaml
```
**Repository root vs. project root**
The global `.polarion/nextedy/` directory must be at the **SVN repository root**, not inside a project folder. Placing it inside a project makes it a project-level configuration, not a global one.
The global data model defines entity types and relationships available to all projects that do not declare their own model.
1. Check out the repository root via SVN:
```bash theme={null}
svn checkout https://your-polarion-server/svn/ --depth immediates
svn update .polarion/nextedy/models/ --set-depth infinity
```
2. Open the global data model YAML file and edit the entity types:
```yaml theme={null}
# .polarion/nextedy/models/default_model.yaml
domainModelTypes:
- name: UserNeed
polarionType: requirement
prefix: UN
icon: requirement
- name: SystemRequirement
polarionType: requirement
prefix: SR
icon: requirement
- name: DesignRequirement
polarionType: requirement
prefix: DR
icon: requirement
- name: Hazard
polarionType: hazard
prefix: HZ
icon: risk
- name: RiskControl
polarionType: riskControl
prefix: RC
icon: shield
relationships:
- name: systemRequirements
from: UserNeed
to: SystemRequirement
linkRole: relates_to
cardinality: oneToMany
direct: systemRequirements
back: userNeeds
```
3. Save and commit:
```bash theme={null}
svn commit -m "Update global data model"
```
**Use consistent entity naming**
Define entity type names in PascalCase (e.g., `UserNeed`, `SystemRequirement`). This convention keeps binding paths readable across sheet configurations and expansion paths.
Global sheet configurations define default column layouts available across all projects.
1. Open the global sheet configuration file:
```yaml theme={null}
# .polarion/nextedy/sheet-configurations/default_sheet.yaml
columns:
- key: id
header: ID
width: 80
isReadOnly: true
- key: title
header: Title
width: 300
- key: status
header: Status
width: 120
isReadOnly: true
- key: severity
header: Severity
width: 100
views:
- name: Default
visibleColumns:
- id
- title
- status
- name: Full Detail
visibleColumns:
- id
- title
- status
- severity
```
2. Adjust columns, widths, and views as needed for your organization's defaults.
3. Commit via SVN.
**Verify in application**
The exact set of global sheet configuration properties may vary by Powersheet version. Test your changes in a non-production environment first.
When a project needs different behavior, create a project-level configuration that overrides the global one.
1. Navigate to the project's SVN directory:
```
<svn-root>/<ProjectGroup>/<ProjectId>/.polarion/nextedy/
```
2. Create or edit the model and sheet configuration files inside the project's `.polarion/nextedy/` directory.
3. Any entity types, relationships, or columns defined at the project level **replace** the corresponding global definitions for that project.
| Scope | Location | Applies to |
| -------- | ------------------------------- | ------------------------------------- |
| Global | `/.polarion/nextedy/` | All projects without their own config |
| Project | `/.polarion/nextedy/` | Single project only |
| Document | Widget parameters in LiveDoc | Single document only |
After committing global configuration changes:
1. **Trigger a reload** --- In Polarion, navigate to **Administration > Nextedy Powersheet** and click **Reload Configuration** (or restart the Polarion service if no reload button is available).
2. **Verify in a project** --- Open a project that relies on global configuration. Open a sheet and confirm:
* Entity types from the global data model appear in expansion paths
* Global columns display with the expected headers and widths
* Views defined globally are selectable in the sheet toolbar
3. **Check for conflicts** --- If a project has its own configuration, verify that the project-level settings take precedence as expected.
**Cache after SVN commit**
Polarion may cache configuration from SVN. If changes do not appear after committing, perform a server-side cache refresh or restart the Polarion service.
## Common Pitfalls
**Mixing global and project models**
If a project defines its own data model, the global model is **not merged** --- it is replaced entirely. Ensure project-level models include all entity types the project needs, even those that were inherited from the global model.
**Incorrect SVN path depth**
When checking out the repository root, use `--depth immediates` to avoid downloading all project data. Then selectively deepen only the `.polarion/nextedy/` directory.
**Version control your configurations**
Since all configuration lives in SVN, you get full version history automatically. Use meaningful commit messages to track why changes were made, making it easy to roll back if a configuration change causes issues.
## Verification
You should now see:
* Global data model entity types available in any project that does not define its own model
* Global sheet configuration columns and views appearing as defaults in sheets across your Polarion instance
* Project-level overrides correctly replacing global settings where defined
## See Also
* [Sheet Configuration Reference](/powersheet/reference/sheet-config/index) --- Full property reference for sheet YAML files
* [Data Model Reference](/powersheet/reference/data-model/index) --- Entity types, relationships, and cardinality
* [Configure Permissions](/powersheet/guides/administration/configure-permissions) --- Control who can modify configurations
* [Install and Manage License](/powersheet/guides/administration/install-manage-license) --- License setup for Powersheet
* [Create an Entity Type](/powersheet/guides/data-model/create-entity-type) --- Step-by-step entity type creation
* [Add a Column](/powersheet/guides/sheet-configuration/add-column) --- How to add columns to a sheet configuration
# Update Powersheet
Source: https://learn.nextedy.com/powersheet/guides/administration/update-powersheet
This guide walks you through upgrading Nextedy POWERSHEET to a new version on your Siemens Polarion ALM server.
## Prerequisites
* Administrator access to the Polarion server filesystem and web interface
* The new Powersheet distribution package (`nextedy_powersheet.zip`) downloaded from the [Powersheet Download](https://go.nextedy.com/powersheet-download-page) page
* Release notes for the target version reviewed for breaking changes
Before upgrading, create a backup of the existing extension directory:
```
[POLARION_INSTALL]/polarion/extensions/com.nextedy.powersheet
```
Copy this entire folder to a safe location so you can restore the previous version if the upgrade causes unexpected issues. If your organization has multiple Polarion instances (e.g., staging and production), perform the upgrade on the staging instance first to verify compatibility before deploying to production.
**Configuration files are safe**
Data models and sheet configurations stored in the Polarion SVN repository are independent of the extension files. They are not affected by the upgrade process and do not need separate backup.
Unpack the new `nextedy_powersheet.zip`. The archive contains a folder named `com.nextedy.powersheet` with the updated extension.
Remove the existing extension folder and copy the new one into the Polarion extensions directory:
```
[POLARION_INSTALL]/polarion/extensions/com.nextedy.powersheet
```
After replacing, delete the cached configuration folders to ensure the server picks up the new version cleanly:
```
[POLARION_DATA]/workspace/.config
```
Deleting the `.config` cache folder only removes cached plugin data. This is safe and recommended by Siemens Polarion support to ensure extensions are recognized correctly after an update.
Restart the Polarion server to load the updated version. The server will detect the new version during its initialization sequence.
Monitor the server log file during startup for any errors related to Powersheet. Look for entries containing `com.nextedy.powersheet` to confirm it loaded successfully. If errors appear, check that:
* The extension folder structure is intact (not nested inside an extra directory)
* All JAR files from the distribution package are present
* The Polarion server version meets the minimum requirements listed in the release notes
After the server restarts, navigate to **Administration > Nextedy Powersheet > Setup** and confirm that the displayed version matches the new release.
Check the license status at **Administration > Nextedy Powersheet > License**. If the status shows `WARNING` or `INVALID`, contact Nextedy support for an updated license file. See [Install and Manage License](/powersheet/guides/administration/install-manage-license) for license troubleshooting.
**Configuration compatibility**
Data model and sheet configuration YAML files stored in the Polarion SVN repository are not modified during an upgrade. The data model `$version` field enables schema compatibility checking, so existing configurations continue to work in most cases. Review the release notes for any deprecated properties or schema changes.
## Rollback
If the new version causes problems, stop the Polarion server, remove the updated `com.nextedy.powersheet` folder, restore the backup from Step 1, delete the `.config` cache again, and restart. Your configurations remain unchanged because they are stored in SVN independently of the extension.
## See Also
* [Installing Powersheet](/powersheet/getting-started/installation) -- full initial installation procedure
* [Migration FAQ](/powersheet/faq/migration) -- common upgrade and migration questions
* [Install and Manage License](/powersheet/guides/administration/install-manage-license) -- license activation and renewal
# Use the Admin AI Assistant
Source: https://learn.nextedy.com/powersheet/guides/administration/use-admin-ai-assistant
Ask configuration questions directly inside the Nextedy POWERSHEET configuration editor. The Admin AI Assistant answers from the Powersheet documentation so you can solve setup problems without leaving your workflow.
The **Admin AI Assistant** is a documentation-grounded chat in the Powersheet configuration editor, added by the separately installed **Nextedy AI** package — opened from the sparkle button in the editor toolbar, its window titled **✦ Powersheet AI**. While you are editing a sheet configuration or data model, you can ask natural-language questions about Powersheet configuration -- "How do I make this column read-only?", "What property controls this behavior?", "Why is this column not updating?" -- and get answers drawn from the Powersheet documentation, with the relevant pages linked. The answer is one click away from where the question arises, so you do not have to switch to a separate documentation site or support channel.
**The assistant guides, it does not configure**
The Admin AI Assistant answers questions and points you to the right configuration. It does **not** change, save, or apply configuration on your behalf -- you stay in control of your YAML. Use its guidance to make the edit yourself in the editor.
## Before you begin
* The assistant is available to administrators working in the **configuration editor** (the browser-based YAML editor you reach via **Menu > Configuration > Edit Sheet Configuration** or **Edit Data Model**, or by opening a data model or sheet configuration from the administration page).
* **No Nextedy AI license is required.** The assistant is free with the **Nextedy AI plugin**, which must be installed on your Polarion server, and you must be signed in to Polarion.
* The assistant connects to the Nextedy AI service. If the Nextedy AI package or that service is unavailable, the rest of Powersheet continues to work normally -- only the assistant is affected: the button is disabled with the tooltip *"AI Assistant is currently unavailable"*.
* If the button is disabled with the tooltip *"AI Assistant requires a valid Nextedy AI license"*, this is not actually a licensing problem -- Polarion could not identify your signed-in user. Sign in again.
## Open the assistant
Open a sheet configuration or data model in the configuration editor. From an open Powersheet document, use **Menu > Configuration > Edit Sheet Configuration** (or **Edit Data Model**); from the administration page, open the model or configuration entry. The editor opens in its own browser tab.
In the editor toolbar, select the **AI Assistant** button (the sparkle chat icon). The **✦ Powersheet AI** window opens. You can dock it to the side of the editor as a sidebar -- the editor reflows to make room -- or float it freely; its mode, position, and size are remembered between sessions.
Type your question in the input box, or pick one of the suggested **starter questions** shown when the panel is empty. The answer streams in as it is generated, and links to the relevant documentation pages appear alongside it so you can read further.
## What you can ask
The assistant is meant for the questions that come up while you configure Powersheet. For example:
| You want to... | Ask something like |
| ----------------------------- | --------------------------------------------------------------------- |
| Configure a specific behavior | "How do I make this column read-only?" / "How do I hide this field?" |
| Find the right property | "What property controls this behavior?" / "Where is this configured?" |
| See example YAML | "Show me YAML for this setup" / "How would this configuration look?" |
| Understand existing config | "What does this do?" / "Why is this behaving like this?" |
| Troubleshoot | "Why is this not working?" / "Why is this column not updating?" |
| Compare concepts | "What is the difference between a field and a column?" |
| Combine multiple aspects | "How do I configure this scenario end-to-end?" |
**Follow-up questions keep their context**
The assistant keeps the context of your conversation. After a broad question such as "How do I configure read-only columns?", you can refine it with a short follow-up like "only for computed fields" -- references to "it" or "that" are understood from the earlier turns. The conversation survives closing and reopening the panel. It is not kept indefinitely, though: once the service has dropped it, the panel starts fresh and your follow-up needs its context again.
## Give the assistant context (optional)
By default the assistant answers from the documentation alone. When a question is about the configuration you are editing, you can attach the open file so the answer takes it into account:
* **Add sheet configuration** -- attaches the YAML currently open in the editor. The button is labelled after what you are editing, so it reads **Add model** when you have a data model open.
* **Add data model** -- when you are editing a sheet configuration, attaches the data model it references, so the assistant can reason about the entity types and relationships behind your columns. This option is specific to Powersheet.
Attachments are added explicitly by you and apply to the questions you ask after attaching them. Remove an attachment with the dismiss control on its chip when you no longer want it considered.
## Verify
* The **AI Assistant** button appears in the configuration editor toolbar.
* Selecting it opens the **✦ Powersheet AI** window with starter questions in the empty state.
* Asking a question returns a streamed answer with links to documentation pages.
* Closing and reopening the panel brings your conversation back.
**AI can make mistakes**
The assistant shows a reminder that "AI can make mistakes. Verify important information." Treat its answers as guidance: confirm property names and behavior against the linked documentation before relying on them in a production configuration.
## See Also
* [Admin AI Assistant](/powersheet/concepts/admin-ai-assistant) -- how the assistant works: documentation grounding, availability, and the authentication architecture behind it
* [Install and Manage License](/powersheet/guides/administration/install-manage-license) -- activate a Nextedy AI license, required for in-product assistants but not for this one
* [Add a Column](/powersheet/guides/sheet-configuration/add-column) -- a typical task you can ask the assistant about
* [Configure Read-Only Column](/powersheet/guides/sheet-configuration/configure-read-only-column) -- make a column non-editable
* [Sheet Configuration Reference](/powersheet/reference/sheet-config/index) -- the full property reference the assistant draws on
# Configure Picker Filters
Source: https://learn.nextedy.com/powersheet/guides/customization/configure-picker-filters
Restrict which work items appear in picker dropdowns by configuring `constraints.pick` in your Nextedy POWERSHEET data model, ensuring users only see relevant items when creating or editing relationships.
## Prerequisites
* A working data model with entity types and relationships defined
* Access to **Administration > Nextedy Powersheet > Data Models**
* Knowledge of your Polarion document structure (module folders, document types, components)
Open your data model YAML and locate the entity type whose picker you want to filter. Pick constraints are defined on the **target** entity type -- the type that appears in the dropdown when a user selects a related item.
For example, to control which `SystemRequirement` items appear when linking from a `UserNeed`, you add constraints to `SystemRequirement`:
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: requirement
properties:
description:
SystemRequirement:
polarionType: systemRequirement
properties:
description:
```
Add a `constraints` section with a `pick` sub-section to the target entity type. The `document` property within `pick` controls filtering by document location:
```yaml theme={null}
domainModelTypes:
SystemRequirement:
polarionType: systemRequirement
properties:
description:
constraints:
pick:
document:
moduleFolder: "Requirements"
type: "systemRequirementsSpec"
```
This restricts the picker to show only system requirements located in documents within the `Requirements` folder that have the document type `systemRequirementsSpec`.
**Pick vs. other constraint types**
The `constraints` section supports three sub-sections: `pick` (picker dropdown filtering), `load` (data loading filters), and `create` (new item defaults). This guide focuses on `pick`. For a broader overview of all constraint types, see [Configure Constraints](/powersheet/guides/data-model/configure-constraints).
Use the following properties inside `constraints.pick.document` to narrow picker results:
| Property | Description | Example Value |
| -------------- | ---------------------------------------------------------------------------------------- | -------------------------- |
| `moduleFolder` | Restricts to work items within a specific module folder (space) in the project hierarchy | `"Requirements"` |
| `moduleName` | Restricts to work items within a specific document by exact name | `"System Requirements"` |
| `type` | Restricts to documents of a specific document type | `"systemRequirementsSpec"` |
| `component` | Restricts by document component property | `"Braking"` |
**Use document type IDs, not display names**
The `type` property must use the Polarion document type **ID** (e.g., `systemRequirementsSpec`), not the human-readable display name (e.g., "System Requirements Specification"). Using the display name silently returns no results. Find type IDs in **Administration > Documents & Pages > Document Types**.
For component-scoped filtering, use `$context.source.document.component` to dynamically match the source entity's component at runtime. This is especially useful in multi-component projects where each component maintains its own set of documents:
```yaml theme={null}
domainModelTypes:
DesignRequirement:
polarionType: designRequirement
properties:
description:
constraints:
pick:
document:
moduleFolder: "Design"
type: "designSpec"
component: $context.source.document.component
```
When a user picks a `DesignRequirement` from within a document whose component is "Braking", the picker shows only design requirements from "Braking" documents. Switching to an "Engine" document automatically filters to "Engine" design requirements.
You can specify multiple filter properties together. All conditions are applied as a logical AND -- every condition must match for an item to appear in the picker:
```yaml theme={null}
domainModelTypes:
Hazard:
polarionType: hazard
properties:
severity:
likelihood:
constraints:
pick:
document:
moduleFolder: "Risks"
type: "hazardAnalysis"
component: $context.source.document.component
```
In this example, the `Hazard` picker only shows items that satisfy **all three** conditions:
1. Located in the `Risks` module folder
2. In a document of type `hazardAnalysis`
3. Belonging to the same component as the source document
**Start with one filter and add more**
Begin with a single constraint (e.g., `moduleFolder`) and verify it works before combining additional filters. This makes it easier to identify which constraint causes unexpected filtering.
When a relationship column uses a picker, you can configure which fields are searchable in the dropdown. Add a `list` property to the column definition in your sheet configuration:
```yaml theme={null}
columns:
riskControls.riskControl:
title: "Risk Control"
multiItem: true
display: title
list:
searchableFields:
- title
- id
```
The `searchableFields` array controls which entity properties the user can type to search and filter the picker dropdown. Common choices include `title`, `id`, and custom property names.
Here is a complete data model excerpt demonstrating pick constraints across a requirements traceability hierarchy:
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: requirement
properties:
description:
SystemRequirement:
polarionType: systemRequirement
properties:
description:
constraints:
pick:
document:
moduleFolder: "Requirements"
type: "systemRequirementsSpec"
DesignRequirement:
polarionType: designRequirement
properties:
description:
constraints:
pick:
document:
moduleFolder: "Design"
type: "designSpec"
component: $context.source.document.component
Hazard:
polarionType: hazard
properties:
severity:
constraints:
pick:
document:
moduleFolder: "Risks"
type: "hazardAnalysis"
RiskControl:
polarionType: riskControl
properties:
controlType:
constraints:
pick:
document:
moduleFolder: "Risks"
type: "riskControlSpec"
component: $context.source.document.component
```
**Constraints are on the target entity type**
A common mistake is placing `constraints.pick` on the **source** entity type (e.g., `UserNeed`) instead of the **target** (e.g., `SystemRequirement`). The constraint must be on the entity type that **appears in the picker dropdown**, not the one initiating the link.
**Sheet subqueries also filter the picker**
`constraints.pick` (this guide) is a data-model filter that applies to every sheet. Separately, a [subquery `where` on an expand level](/powersheet/reference/query-api/expand-clause#expand-subquery-filtering) in a sheet configuration also constrains that column's picker: the candidates are re-rooted onto the picked entity along the binding path and only those satisfying the subquery are offered, so a picked item will not disappear when the sheet reloads. The two mechanisms combine with AND.
## Verify Your Configuration
After saving your data model changes:
1. Reload the sheet in Polarion (refresh the page or re-open the document)
2. Click a cell in a relationship column that references the constrained entity type
3. The picker dropdown should now show only items matching your filter criteria
4. If using `$context.source.document.component`, verify that switching to a document with a different component changes the picker results accordingly
You should now see a filtered picker dropdown showing only work items that match your `moduleFolder`, `type`, `moduleName`, or `component` constraints.
**Debugging empty picker results**
If the picker shows no results after adding constraints, verify: (1) the `moduleFolder` value matches the exact Polarion space name, (2) the `type` uses the document type ID (not the display name), and (3) work items actually exist in the constrained location. Remove constraints one at a time to isolate which filter is too restrictive.
## See Also
* [Configure Constraints](/powersheet/guides/data-model/configure-constraints) -- full overview of pick, load, and create constraint types
* [Configure a Relationship](/powersheet/guides/data-model/configure-relationship) -- set up relationships between entity types
* [Configure a Formatter](/powersheet/guides/sheet-configuration/configure-formatter) -- apply conditional styling to picker columns
* [Add a Column](/powersheet/guides/sheet-configuration/add-column) -- column configuration basics including `display` and `list` properties
* [Data Model Reference](/powersheet/reference/data-model/index) -- complete data model YAML reference
***
# Customization Guides
Source: https://learn.nextedy.com/powersheet/guides/customization/index
Nextedy POWERSHEET offers extensive customization options for fields, enum dropdowns, header styling, and navigation widgets in Siemens Polarion ALM.
Add custom Polarion fields to your data model and expose them as editable columns in the sheet.
Visualize your data model structure and expansion paths using the Model Helper LiveReport page.
Control which entities appear in dropdown pickers by configuring load and pick constraints.
**Incremental approach**
Start with predefined styles and built-in fields, then progressively add custom fields and styling as your project requirements become clearer. See [Incremental Configuration Approach](/powersheet/getting-started/incremental-configuration) for guidance.
# Use Model Helper Widget
Source: https://learn.nextedy.com/powersheet/guides/customization/use-model-helper
Visualize your data model structure, entity relationships, and available binding paths using the Model Helper widget in Nextedy POWERSHEET to simplify sheet configuration in Siemens Polarion ALM.
## Prerequisites
* A data model already configured in **Administration > Nextedy Powersheet > Data Models**
* Permissions to create a LiveReport page in your Polarion project
* At least one entity type with relationships defined in your data model
Model Helper runs as a LiveReport page inside Polarion. To set it up:
1. Navigate to your project in Polarion
2. Go to **Wiki > LiveReport Pages**
3. Create a new **LiveReport** page
4. Import the Model Helper page archive provided by Nextedy
**Verify in application**
The Model Helper page archive is supplied with the Powersheet installation package. Contact your administrator if you do not have access to the archive file.
When you open the Model Helper LiveReport, fill in four parameter values at the top of the page:
| Parameter | Description | Example |
| ------------- | ------------------------------------------------------------- | ---------- |
| `model` | Name of the data model to visualize | `rtm` |
| `projectId` | Project ID where the model is defined | `RTM_Demo` |
| `startEntity` | Root entity type for expansion visualization | `UserNeed` |
| `depth` | Number of relationship levels to expand from the start entity | `3` |
Enter these values and submit to generate the visualization.
**Start with a low depth**
Begin with `depth: 2` or `3`. Higher values produce very large visualizations that can be difficult to read, especially for data models with many cross-entity relationships.
The Model Helper displays three key pieces of information:
* **Entity types** shown as nodes, each displaying the entity name and its `polarionType` mapping (for example, `UserNeed` mapped to `user_need`)
* **Relationships** shown as labeled connections between entity nodes, annotated with the navigation property name (the `direct` or `back` name from your data model)
* **Expansion depth** indicating how many relationship levels each entity sits from the start entity
This visualization directly maps to the three configuration layers you work with in Powersheet:
| Layer | What it defines | What Model Helper shows |
| ----------------- | ------------------------------------- | ------------------------------------- |
| **Data model** | Entity types and relationships | Nodes and connections |
| **Sheet sources** | How to query and expand relationships | Expansion paths from start entity |
| **Sheet columns** | How to display the resulting data | Available binding paths at each level |
The expansion paths shown in Model Helper translate directly to the `expand` section of your sheet sources. The cardinality of each relationship determines the expand pattern.
### Many-to-One (N:1) Relationships
For scalar navigation properties (one parent per child), use a single-level expand with the `direct` name:
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: chapter
```
The `direct` name in your data model (`chapter`) becomes the expand `name`. In your columns, bind to this property for a reference picker:
```yaml theme={null}
columns:
chapter:
title: Chapter
display: title
list:
search:
- title
chapter.title:
title: Chapter Title
isReadOnly: true
```
* `chapter` renders a single-value reference picker (scalar navigation property)
* `chapter.title` renders a read-only display of the referenced Chapter's title using dot-notation
### One-to-Many (1:N) Relationships
For collection navigation properties (one parent, many children), the expand opens a new hierarchy level using the `back` name:
```yaml theme={null}
sources:
- id: chapters
query:
from: Chapter
expand:
- name: userNeeds
```
The `back` name in your data model (`userNeeds`) becomes the expand `name`. In columns, reference the child level directly:
```yaml theme={null}
columns:
title:
title: Chapter
hasFocus: true
userNeeds:
title: Title
hasFocus: true
```
The expand creates child rows in the sheet -- no dot-notation needed because the expand directly opens the child level.
### Many-to-Many (M:N) Relationships
Many-to-many relationships use an **association entity** between the two types. The source expand requires two levels:
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: systemRequirement
```
The first level (`systemRequirements`) is the association collection; the second level (`systemRequirement`) is the target entity. Column bindings use dot-notation through the association:
```yaml theme={null}
columns:
systemRequirements.systemRequirement:
title: System Requirement
list:
search:
- objectId
- title
createNew: true
systemRequirements.systemRequirement.title:
title: SysReq Title
hasFocus: true
```
**Association entity pattern**
For M:N relationships, always use two-level expansion: the collection name (`systemRequirements`) followed by the singular entity name (`systemRequirement`). Using only the first level will expose the association entity itself, not the target entity you want to display.
After building your source and column configuration, use Model Helper to verify that every binding path in your columns corresponds to a valid expansion path.
Cross-check each column key against the visualization:
1. **Simple property** (e.g., `title`, `description`) -- the property must exist on the source entity type
2. **Single-level navigation** (e.g., `chapter`) -- must match a `direct` or `back` name in a relationship from the source entity
3. **Dot-notation path** (e.g., `systemRequirements.systemRequirement.title`) -- each segment must follow a valid relationship defined in the data model
### Cardinality Quick Reference
| Cardinality | Data Model | Source Expand | Column Binding | UI Behavior |
| ----------- | -------------------------------------------------------------- | ------------------------------------------------------------- | -------------------------------------- | -------------------------------- |
| **N:1** | `cardinality: many-to-one`, `direct` name: `chapter` | `- name: chapter` | `chapter`, `chapter.title` | Single-value reference picker |
| **1:N** | Reverse of N:1, `back` name: `userNeeds` | `- name: userNeeds` | `userNeeds` | Child rows (new hierarchy level) |
| **M:N** | `cardinality: many-to-many`, `back` name: `systemRequirements` | `- name: systemRequirements` then `- name: systemRequirement` | `systemRequirements.systemRequirement` | Multi-item reference picker |
**Use Model Helper when adding new relationships**
After modifying your data model (adding entity types or relationships), re-run Model Helper with an updated depth to verify that the new paths appear correctly before updating your sheet configuration.
After configuring your sheet based on Model Helper output:
1. Open the Powersheet document that uses your sheet configuration
2. Verify that all entity types listed in Model Helper appear as expandable levels in the sheet
3. Confirm that column headers match the expected entity properties at each level
4. Expand rows at each hierarchy level to confirm that relationships load correctly
5. Test reference pickers to ensure they display the correct linked entities
You should now see your data model relationships reflected in the sheet, with each expansion level matching the depth and navigation property names shown in Model Helper.
**Keep Model Helper open while editing**
Open Model Helper in a separate browser tab while editing your sheet configuration YAML. This lets you quickly verify navigation property names and expansion paths without switching back and forth between configuration files.
## See Also
* [Configure a Relationship](/powersheet/guides/data-model/configure-relationship) -- define relationships between entity types in the data model
* [Create Bidirectional Links](/powersheet/guides/data-model/create-bidirectional-links) -- set up `direct` and `back` navigation properties
* [Configure Many-to-Many Relationships](/powersheet/guides/data-model/configure-many-to-many) -- association entity pattern for M:N links
* [Configure Sources](/powersheet/guides/sheet-configuration/configure-sources) -- full reference for the `sources` section
* [Add a Column](/powersheet/guides/sheet-configuration/add-column) -- column binding syntax and display options
* [Data Model Reference](/powersheet/reference/data-model/index) -- complete data model specification
***
# Add a Custom Property
Source: https://learn.nextedy.com/powersheet/guides/data-model/add-custom-property
Expose a Polarion custom field as a property on an entity type in your Nextedy POWERSHEET data model so it can be displayed and edited in the sheet.
## Prerequisites
* The custom field must already be defined in Polarion (**Administration > Work Items > Custom Fields**)
* The entity type must exist in your `domainModelTypes` section
* Access to the data model YAML via **Menu > Configuration > Edit Data Model**
Locate the custom field ID in Polarion. Custom field IDs typically use the `c_` prefix.
| Polarion Setting | Example |
| -------------------------- | ----------------------- |
| Custom field ID | `c_probability` |
| Display name | Probability |
| Field type | Enum / String / Integer |
| Applicable work item types | `hazard` |
For most cases, add the property name directly under the entity type's `properties` section. The property name must match the Polarion field name.
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: userNeed
properties:
description:
severity:
component:
c_customRating:
```
Setting the value to `null` (empty after the colon) uses default configuration: the property is readable, updatable, and uses the property name as the Polarion field name.
For custom fields that need additional configuration, use the extended property format.
```yaml theme={null}
domainModelTypes:
Hazard:
polarionType: hazard
properties:
description:
severity:
c_probability:
customFieldName: c_probability
readable: true
updatable: true
```
### Property Configuration Options
| Property | Type | Default | Description |
| ----------------- | ------- | ---------- | ------------------------------------------------------------------------------------ |
| `name` | string | (key name) | Property name used in queries and binding paths. |
| `customFieldName` | string | None | Polarion custom field ID. Required when the property name differs from the field ID. |
| `readable` | boolean | `true` | Controls whether the property is visible in the sheet. |
| `updatable` | boolean | `true` | Controls whether the property can be edited in the sheet. |
| `scalar` | boolean | `true` | `true` for single values, `false` for collections. |
After adding the property to the data model, reference it in your sheet configuration:
```yaml theme={null}
columns:
c_customRating:
title: Custom Rating
width: 120
```
For properties on related entity types, use the full binding path:
```yaml theme={null}
columns:
systemRequirements.systemRequirement.c_customRating:
title: SR Rating
width: 120
```
If the custom field is an enumeration, you can optionally constrain the allowed values:
```yaml theme={null}
domainModelTypes:
Hazard:
polarionType: hazard
properties:
c_probability:
```
**Verify in application**
Enum values must match the exact option IDs defined in Polarion's enumeration configuration. Check **Administration > Work Items > Enumerations** for the correct IDs.
To make a property visible but not editable:
```yaml theme={null}
properties:
c_calculatedScore:
readable: true
updatable: false
```
1. Save the data model
2. Reload the powersheet document
3. You should now see the custom property displayed in the sheet column
If the column shows empty values, verify:
* The `customFieldName` matches the Polarion field ID exactly
* The custom field is defined for the correct work item type in Polarion
* The property `readable` is not set to `false`
**Built-in vs Custom Fields**
Built-in Polarion fields (like `description`, `severity`, `title`) do not need a `customFieldName`. Custom fields (prefixed with `c_`) require the exact Polarion custom field ID. Using the wrong field ID results in empty columns without error messages.
## See Also
* [Create an Entity Type](/powersheet/guides/data-model/create-entity-type) -- define the entity type that holds the property
* [Configure a Relationship](/powersheet/guides/data-model/configure-relationship) -- add navigation properties for related entities
* [Set Entity Permissions](/powersheet/guides/data-model/set-permissions) -- control read/write access at the property level
* [Properties](/powersheet/reference/data-model/properties) -- full property configuration reference
* [Debug Custom Field Issues](/powersheet/guides/troubleshooting/debug-custom-field-issues) -- troubleshoot custom field problems
# Configure Constraints
Source: https://learn.nextedy.com/powersheet/guides/data-model/configure-constraints
Define load, pick, and create constraints in your Nextedy POWERSHEET data model to control which entities are visible in the sheet, what appears in picker dialogs, and where new items can be created.
1. Navigate to **Administration > Nextedy Powersheet > Data Models**
2. Select the data model you want to edit
3. Locate the entity type under `domainModelTypes` where you want to add constraints
Powersheet supports three constraint stages, each controlling a different operation:
| Stage | Purpose | Effect |
| -------- | ----------------------------------------------- | -------------------------------------------------------- |
| `load` | Filters which entities are visible in the sheet | Only matching entities appear when data loads |
| `pick` | Filters picker dialog options | Only matching items appear in relationship pickers |
| `create` | Sets defaults for new entities | New items are created in the specified document location |
**Stage cascading**
Stages cascade upward: **pick** inherits `load` constraints, and **create** inherits both `load` and `pick`. If no `create` constraints are defined, the system falls back to `pick` constraints for the create stage.
Load constraints filter which entities are visible when data loads into the sheet. Add a `constraints` block with `load` to the entity type:
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
description:
constraints:
load:
document:
type: stakeholderRequirement
```
With this constraint, only `UserNeed` work items that exist in documents of type `stakeholderRequirement` will appear in the sheet.
Pick constraints filter what appears in relationship picker dialogs. This is useful when users link entities and you want to restrict which items they can select:
```yaml theme={null}
domainModelTypes:
SystemRequirement:
polarionType: system_requirement
properties:
description:
severity:
constraints:
pick:
document:
moduleFolder: Requirements
type: systemSpecification
```
This ensures that when a user picks a `SystemRequirement` through a relationship picker, only items from the `Requirements` space in documents of type `systemSpecification` are shown.
Create constraints specify the default document location when new items of this type are created through the sheet:
```yaml theme={null}
domainModelTypes:
DesignRequirement:
polarionType: design_requirement
properties:
description:
constraints:
create:
document:
moduleFolder: Design
moduleName: Design Specification
type: designSpecification
```
When a user creates a new `DesignRequirement` from the sheet, it will be placed in the `Design Specification` document within the `Design` space.
You can define multiple constraint stages on the same entity type. Each stage applies to its respective operation, and cascading applies automatically:
```yaml theme={null}
domainModelTypes:
SystemRequirement:
polarionType: system_requirement
properties:
description:
severity:
constraints:
load:
document:
type: systemSpecification
pick:
document:
moduleFolder: Requirements
create:
document:
moduleFolder: Requirements
moduleName: System Requirements Spec
type: systemSpecification
```
In this example:
* **Load** stage: only system requirements from `systemSpecification` documents are visible
* **Pick** stage: inherits the load filter, plus restricts to the `Requirements` space
* **Create** stage: inherits both, plus targets a specific document name
Constraint values support five comparison operators beyond exact matching:
| Operator | Behavior | Example |
| ------------ | --------------------------- | ----------------------------------------- |
| *(default)* | Exact equality | `type: systemSpecification` |
| `contains` | Substring match | `moduleName: { contains: Spec }` |
| `in` | Matches any value in a list | `type: { in: [systemSpec, designSpec] }` |
| `startsWith` | Prefix match | `moduleFolder: { startsWith: Req }` |
| `endsWith` | Suffix match | `moduleName: { endsWith: Specification }` |
When you use a plain string value (e.g., `type: systemSpecification`), the `equals` operator is applied by default. To use another operator, wrap the value in an operator object:
```yaml theme={null}
constraints:
load:
document:
type:
in: [systemRequirementsSpecification, designRequirementsSpecification]
moduleName:
contains: Specification
```
Multiple properties within the same `document` block are combined with **AND** logic -- all conditions must match simultaneously.
For **OR** logic, use the `or` keyword inside the `document` block to match entities from multiple locations:
```yaml theme={null}
constraints:
pick:
document:
or:
- moduleName: Alpha Requirements
- moduleName: Beta Requirements
```
This matches work items from either the "Alpha Requirements" or "Beta Requirements" document.
**Conflicting constraints produce empty results**
If you define constraints that conflict with each other (for example, specifying a `moduleFolder` that does not contain any documents of the specified `type`), the result set will be empty. No error is raised -- the picker simply shows no items. Always verify your constraint combinations against your actual Polarion project structure.
For component-scoped relationships, use `$context.source.document.component` to dynamically filter based on the source entity's document component:
```yaml theme={null}
domainModelTypes:
SystemRequirement:
polarionType: system_requirement
constraints:
pick:
document:
component: $context.source.document.component
```
This ensures picker results are scoped to the same component as the source entity's document. For example, if a user is editing a `UserNeed` in a document with component "Braking System", the picker will only show system requirements from documents that also belong to the "Braking System" component.
**When to use dynamic context**
Dynamic context references are particularly useful in multi-component projects where each subsystem has its own set of documents. They prevent users from accidentally linking to entities outside their component scope.
## Constrainable Document Properties
The `document` block in constraints supports the following properties:
| Property | Description |
| -------------- | ---------------------------------------------------------------------- |
| `moduleFolder` | The space (folder) where the document resides in the project hierarchy |
| `moduleName` | The exact name of the target document |
| `type` | The document type ID (as defined in Polarion configuration) |
| `id` | The document ID in `folder/name` format |
| `title` | The document display title |
| `component` | The component property of the document, often used with `$context` |
**Use document type ID, not display name**
The `type` property must use the document type **ID** (e.g., `systemSpecification`), not the human-readable display name (e.g., "System Specification"). Using the display name will silently produce no matches. Check your Polarion project configuration under **Administration > Document Types** for the correct type IDs.
**Start simple and add constraints incrementally**
Begin with a working data model that has no constraints, then add `pick` constraints first (easiest to test via the picker dialog), followed by `create` and `load` constraints. This makes it straightforward to identify which constraint is causing unexpected behavior.
## Verification
After saving the data model with constraints:
1. Open a sheet that uses this data model
2. For **load** constraints: verify that only matching entities appear in the sheet rows
3. For **pick** constraints: click a relationship picker cell and verify the dropdown shows only items matching your filter criteria
4. For **create** constraints: create a new item through the sheet and verify it appears in the expected document location
You should now see constraints actively filtering entities according to your configuration. If pickers show no results or the sheet loads with no data, review the constraint properties against your actual Polarion project structure -- particularly the `type` ID and `moduleFolder` values.
## See Also
* [Configure Context Constraints](/powersheet/guides/data-model/configure-context-constraints) -- advanced context-based constraint patterns
* [Configure a Relationship](/powersheet/guides/data-model/configure-relationship) -- setting up relationships that constraints apply to
* [Create an Entity Type](/powersheet/guides/data-model/create-entity-type) -- defining the entity types that hold constraints
* [Create an Entity Type](/powersheet/guides/data-model/create-entity-type) -- ensuring `polarionType` values are correct
* [Data Model Reference](/powersheet/reference/data-model/index) -- complete constraints property reference
# Configure Context Constraints
Source: https://learn.nextedy.com/powersheet/guides/data-model/configure-context-constraints
Use `$context` expressions in your Nextedy POWERSHEET data model constraints to dynamically filter entities based on the source work item's document properties at runtime, enabling component-scoped relationships.
## Prerequisites
* A working data model with entity types and relationships already defined
* At least one relationship with `direct` and `back` navigation properties configured
* Familiarity with the three constraint stages (`load`, `pick`, `create`) covered in [Configure Constraints](/powersheet/guides/data-model/configure-constraints)
## How Context Expressions Work
A context expression uses the `$context` prefix followed by a dot-notation property path. Powersheet resolves this path at runtime by reading the current row's source entity properties. Unlike static constraint values, context expressions produce **different filter results per row** depending on each source entity's document.
**Context expressions vs. dynamic values**
Context expressions (`$context.property.path`) are used **only in data model YAML** -- specifically inside `constraints` blocks. They support dot-notation property access but not JavaScript logic. For dynamic expressions in **sheet configuration** YAML (sources, columns, formatters), use the `() => expression` syntax instead. See [Configure Dynamic Expressions](/powersheet/guides/sheet-configuration/configure-dynamic-expressions) for that approach.
## Available Context Paths
The `$context` object provides access to the source entity's document properties. These are the paths you can use:
| Path | Description | Example Value |
| --------------------------------------- | ------------------------------------ | ----------------------------------- |
| `$context.source.type` | Source entity's work item type | `"sys_req"` |
| `$context.source.document.id` | Source entity's document ID | `"Requirements/SRS"` |
| `$context.source.document.moduleName` | Source entity's document module name | `"UserNeedSpecification"` |
| `$context.source.document.moduleFolder` | Source entity's document folder | `"Requirements"` |
| `$context.source.document.component` | Source entity's document component | `"Braking"` |
| `$context.source.document.type` | Source entity's document type | `"systemRequirementsSpecification"` |
| `$context.source.document.title` | Source entity's document title | `"System Requirements"` |
The most common use case is scoping relationship pickers by the source entity's document component. This prevents users from accidentally linking to entities outside their subsystem.
Add a `$context` reference inside the constraint `document` block on the appropriate relationship direction:
```yaml theme={null}
relationships:
- from: DesignRequirement
to: SystemRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: satisfies
direct:
name: systemRequirements
back:
name: designRequirements
constraints:
load:
document:
component: $context.source.document.component
```
With this constraint, when viewing a `SystemRequirement` in a document with component "Braking", only `DesignRequirement` items from "Braking" documents will be loaded as children.
To restrict linked items to the exact same document as the source entity, combine `moduleName` and `moduleFolder`:
```yaml theme={null}
constraints:
load:
document:
moduleName: $context.source.document.moduleName
moduleFolder: $context.source.document.moduleFolder
```
This pattern is useful in projects where each document represents a self-contained specification, and traceability should stay within document boundaries.
Context expressions work across all three constraint stages. Apply them to `pick` to scope the relationship picker dialog, or to `create` to control where new items are created:
```yaml theme={null}
relationships:
- from: Hazard
to: UserNeed
cardinality: many-to-many
storage: linkedWorkItems
linkRole: mitigates
direct:
name: userNeeds
back:
name: hazards
constraints:
load:
document:
component: $context.source.document.component
pick:
document:
type: $context.source.document.type
create:
document:
moduleFolder: $context.source.document.moduleFolder
```
In this configuration:
* **load**: only hazards from the same component appear in the sheet
* **pick**: the picker shows items from documents of the same type as the source
* **create**: new hazards are created in the same folder as the source document
**Stage cascading with context expressions**
The same cascading rules apply to context constraints as to static constraints. The `pick` stage inherits `load` constraints, and `create` inherits both `load` and `pick`. You only need to define the additional filter at each stage.
Context expressions can also be placed on `domainModelTypes` entries (not just relationships). This applies the constraint globally whenever that entity type is loaded, picked, or created:
```yaml theme={null}
domainModelTypes:
SystemRequirement:
polarionType: sys_req
properties:
description:
severity:
constraints:
pick:
document:
component: $context.source.document.component
```
**Entity-level vs. relationship-level constraints**
When both the entity type and a relationship define constraints, both are applied. If they conflict (for example, the entity constraint specifies one component and the relationship constraint specifies a different filter), the intersection may produce an empty result set. Place context constraints at either the entity type **or** the relationship level, not both, unless you intentionally need combined filtering.
You can mix `$context` expressions with static values in the same constraint block. Static values act as fixed filters while context values adapt per row:
```yaml theme={null}
constraints:
pick:
document:
type: systemRequirementsSpecification
component: $context.source.document.component
```
This restricts the picker to items that are both in `systemRequirementsSpecification` documents **and** in the same component as the source entity's document.
## Common Patterns
| Scenario | Context Path | Constraint Example |
| --------------------- | --------------------------------------- | ----------------------------------------------------- |
| Same component | `$context.source.document.component` | `component: $context.source.document.component` |
| Same document | `$context.source.document.moduleName` | `moduleName: $context.source.document.moduleName` |
| Same folder | `$context.source.document.moduleFolder` | `moduleFolder: $context.source.document.moduleFolder` |
| Same document type | `$context.source.document.type` | `type: $context.source.document.type` |
| Same document (exact) | `$context.source.document.id` | `id: $context.source.document.id` |
## Complete YAML Example
Below is a full data model snippet demonstrating context constraints across entity types and relationships in a standard RTM hierarchy:
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
description:
severity:
SystemRequirement:
polarionType: sys_req
properties:
description:
severity:
DesignRequirement:
polarionType: des_req
properties:
description:
RiskControl:
polarionType: risk_control
properties:
description:
relationships:
- from: SystemRequirement
to: UserNeed
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds
back:
name: systemRequirements
constraints:
load:
document:
component: $context.source.document.component
pick:
document:
component: $context.source.document.component
type: systemRequirementsSpecification
- from: DesignRequirement
to: SystemRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: satisfies
direct:
name: systemRequirements
back:
name: designRequirements
constraints:
load:
document:
component: $context.source.document.component
- from: RiskControl
to: DesignRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: mitigates
direct:
name: designRequirements
constraints:
pick:
document:
moduleFolder: $context.source.document.moduleFolder
back:
name: riskControls
```
## Verification
After saving the data model with context constraints:
1. Open a sheet that uses this data model
2. Navigate to a row whose source entity belongs to a specific document component (e.g., "Braking")
3. For **load** constraints: verify that child rows show only entities from the same component
4. For **pick** constraints: click a relationship picker cell and confirm the dropdown shows only items matching the source entity's document properties
5. Compare two rows from different components -- each should show different filtered results based on its own source entity context
You should now see context-sensitive filtering where each row's constraints resolve independently based on its source entity's document properties. If all rows show the same results regardless of component, verify that:
* The `$context` path is spelled correctly (case-sensitive)
* Source entities actually have different document component/folder values in Polarion
* The constraint is placed on the correct relationship direction (`direct` or `back`)
**Empty picker results**
If a source entity's document has no `component` value set in Polarion, a constraint using `$context.source.document.component` will resolve to an empty string, which typically matches no items. Ensure your Polarion documents have the relevant properties populated before relying on context constraints.
## See Also
* [Configure Constraints](/powersheet/guides/data-model/configure-constraints) -- static constraint stages, operators, and logical composition
* [Configure a Relationship](/powersheet/guides/data-model/configure-relationship) -- setting up the relationships that context constraints filter
* [Configure Dynamic Expressions](/powersheet/guides/sheet-configuration/configure-dynamic-expressions) -- `() => expression` syntax for sheet configuration YAML
* [Data Model Reference](/powersheet/reference/data-model/index) -- complete property reference for data model YAML
* [Create Bidirectional Links](/powersheet/guides/data-model/create-bidirectional-links) -- establishing the `direct` and `back` navigation properties used in constraints
# Configure Many-to-Many Relationships
Source: https://learn.nextedy.com/powersheet/guides/data-model/configure-many-to-many
Set up many-to-many (M:N) relationships in your Nextedy POWERSHEET data model so that multiple entities on each side can link to each other -- for example, system requirements linked to multiple use cases and vice versa.
## Prerequisites
Before you begin, make sure you have:
* An existing data model with at least two entity types defined in `domainModelTypes`
* A Polarion link role created for the relationship (e.g., `decomposes`, `verifies`)
* Access to **Administration > Nextedy Powersheet > Data Models**
## How M:N Relationships Work
Many-to-many relationships in Powersheet use an **association entity** pattern. Unlike simpler cardinalities (N:1 or 1:N), the M:N relationship introduces an intermediate association layer between the two entity types. This affects how you configure sources and columns:
The source expand traverses two levels -- first the association collection, then the target entity -- and columns use **two-level dot-notation** to bind through the association to the target.
Ensure both sides of the relationship are defined in your data model under `domainModelTypes`. Each entity type must have a `polarionType` mapping to the corresponding Polarion work item type:
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
description:
severity:
SystemRequirement:
polarionType: sys_req
properties:
description:
severity:
```
In the `relationships` section of your data model, add a relationship with `cardinality: many-to-many`. Define both the `direct` and `back` navigation property names:
```yaml theme={null}
relationships:
- from: SystemRequirement
to: UserNeed
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds
back:
name: systemRequirements
```
Key properties:
| Property | Purpose | Example |
| ------------- | -------------------------------------------------------- | -------------------- |
| `from` | Source entity type (must match a `domainModelTypes` key) | `SystemRequirement` |
| `to` | Target entity type (must match a `domainModelTypes` key) | `UserNeed` |
| `cardinality` | Relationship multiplicity | `many-to-many` |
| `storage` | How links are persisted in Polarion | `linkedWorkItems` |
| `linkRole` | Polarion link role ID (must exist in project config) | `decomposes` |
| `direct.name` | Forward navigation property (from source to target) | `userNeeds` |
| `back.name` | Reverse navigation property (from target to source) | `systemRequirements` |
**Navigation property naming convention**
Use **plural camelCase** names for M:N navigation properties (e.g., `userNeeds`, `systemRequirements`). The association entity Powersheet creates automatically derives its singular form from this name. If you use a singular name, the two-level dot-notation in columns will not resolve correctly.
In your sheet configuration, set up a two-level expand in the `sources` section. The first level expands to the association collection, and the second level expands to the actual target entity:
```yaml theme={null}
sources:
- id: user_needs
model: rtm
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: systemRequirement
```
This two-level expand is what distinguishes M:N from other cardinalities:
* **Level 1** (`systemRequirements`) -- navigates to the association entity collection
* **Level 2** (`systemRequirement`) -- navigates from each association to the actual target entity
**The singular form is automatic**
The second-level expand name (`systemRequirement`, singular) is derived automatically from the navigation property name (`systemRequirements`, plural). You do not define this singular name in the data model -- Powersheet generates it from the association entity pattern.
In the `columns` section of your sheet configuration, use the two-level dot-notation to bind through the association entity to the target:
```yaml theme={null}
columns:
title:
title: Title
hasFocus: true
systemRequirements.systemRequirement:
title: System Requirement
list:
search:
- objectId
- title
createNew: true
systemRequirements.systemRequirement.title:
title: SysReq Title
hasFocus: true
```
The column bindings follow this pattern:
* **`systemRequirements.systemRequirement`** -- a multi-item reference picker that lets users link and unlink target entities through the association
* **`systemRequirements.systemRequirement.title`** -- a read-only display of the linked entity's `title` property (extend the dot-notation with any target property)
The `list` block on the reference picker column configures the search dialog:
* `search` -- which fields to search when filtering candidates
* `createNew: true` -- allows creating new target entities directly from the picker
**Second linked entity column requires `multiItem: true`**
When a sheet has two different entity types linked to the same parent (e.g., design outputs and design verifications both linked to system requirements), the second linked column must declare `multiItem: true` in the sheet configuration. Without this flag, only the first linked column renders correctly. This is a common first-time setup issue.
After saving your data model and sheet configuration:
1. Open a Polarion LiveDoc or Wiki page that uses this sheet configuration
2. Expand a row in the sheet -- you should see the linked entities appear as child items through the association
3. Click the reference picker cell to open the search dialog and verify you can link and unlink target entities
4. Confirm that read-only columns (e.g., `systemRequirements.systemRequirement.title`) display the correct values from linked entities
You should now see M:N relationships rendered in your sheet with a multi-item reference picker. Each source entity can link to multiple targets, and each target can be linked from multiple sources.
## Cardinality Comparison
For reference, here is how M:N compares to other cardinality types across the three configuration layers:
| Cardinality | Model | Source expand | Column binding | UI behavior |
| ----------- | ------------------------------------------------------------ | ------------------------------------------------------------- | -------------------------------------- | ----------------------------- |
| **N:1** | `cardinality: many-to-one`, `direct.name: chapter` | `- name: chapter` | `chapter`, `chapter.title` | Single-value reference picker |
| **1:N** | Reverse of N:1, `back.name: userNeeds` | `- name: userNeeds` | `userNeeds` | Child rows (new sheet level) |
| **M:N** | `cardinality: many-to-many`, `back.name: systemRequirements` | `- name: systemRequirements` then `- name: systemRequirement` | `systemRequirements.systemRequirement` | Multi-item reference picker |
**Association entities are managed automatically**
Powersheet creates and manages the intermediate association entities for M:N relationships. When you unlink two entities, Powersheet removes the association but preserves both linked entities. Deleting an entity removes all its association links as well.
## See Also
* [Configure a Relationship](/powersheet/guides/data-model/configure-relationship) -- general relationship configuration for all cardinality types
* [Create Bidirectional Links](/powersheet/guides/data-model/create-bidirectional-links) -- setting up `direct` and `back` navigation properties
* [Configure Sources](/powersheet/guides/sheet-configuration/configure-sources) -- source and expand configuration reference
* [Configure Multi-Item Column](/powersheet/guides/sheet-configuration/configure-multi-item-column) -- detailed multi-item column setup
* [Data Model Reference](/powersheet/reference/data-model/index) -- complete data model property reference
***
# Configure a Relationship
Source: https://learn.nextedy.com/powersheet/guides/data-model/configure-relationship
Define a relationship between two entity types in your Nextedy POWERSHEET data model to enable hierarchical navigation and traceability in Siemens Polarion ALM.
## Prerequisites
* Both entity types must already exist in your `domainModelTypes` section
* A Polarion link role must be configured in your project for the relationship
* Access to the data model YAML file in your project's SVN repository
Determine the source and target entity types, the cardinality, and which Polarion link role to use.
| Decision | Question | Example |
| --------------- | ---------------------------------------- | ------------------- |
| Source (`from`) | Which entity initiates the relationship? | `UserNeed` |
| Target (`to`) | Which entity is being referenced? | `SystemRequirement` |
| Cardinality | How many targets per source? | `many-to-many` |
| Link role | Which Polarion link role stores this? | `decomposes` |
Add an entry to the `relationships` array in your data model YAML. Each relationship uses `direct` and `back` objects to define the forward and reverse navigation property names.
```yaml theme={null}
relationships:
- from: UserNeed
to: SystemRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: systemRequirements
back:
name: userNeeds
```
### Relationship Properties
| Property | Type | Required | Description |
| ------------- | ------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `from` | string | Yes | Source entity type name. Must match a `domainModelTypes` key exactly. |
| `to` | string | Yes | Target entity type name. Must match a `domainModelTypes` key exactly. |
| `cardinality` | string | Yes | Multiplicity: `many-to-one`, `one-to-many`, or `many-to-many`. See the [Cardinality reference](/powersheet/reference/data-model/cardinality) for supported values. |
| `storage` | string | Yes | Persistence mechanism. Use `linkedWorkItems` for Polarion link-based relationships. |
| `linkRole` | string | Yes | Polarion link role ID. Must exist in your project's link role configuration. |
| `direct` | object | Yes | Forward navigation property. Contains a `name` field used to traverse from source to target. |
| `back` | object | Yes | Reverse navigation property. Contains a `name` field used to traverse from target back to source. |
**`from` and `to` Must Reference Entity Type Names**
The `from` and `to` values must be data model entity type names (e.g., `UserNeed`), **not** Polarion work item type IDs (e.g., `user_need`). Using the Polarion type ID instead of the entity type name causes connection errors that are difficult to diagnose.
The `direct.name` and `back.name` values define how you traverse the relationship in sheet configurations, expansion paths, and column bindings. Follow these naming conventions:
* **Forward** (`direct.name`): Use the plural camelCase form of the **target** entity -- e.g., `systemRequirements` when the target is `SystemRequirement`
* **Reverse** (`back.name`): Use the plural camelCase form of the **source** entity -- e.g., `userNeeds` when the source is `UserNeed`
For `many-to-one` relationships, the forward navigation property should be **singular** (scalar), since it references exactly one target:
```yaml theme={null}
# many-to-one: each UserNeed belongs to one Chapter
- from: UserNeed
to: Chapter
cardinality: many-to-one
storage: linkedWorkItems
linkRole: parent
direct:
name: chapter # singular -- scalar reference
back:
name: userNeeds # plural -- collection of children
```
**Naming Convention Drives UI Behavior**
The cardinality and navigation property name together determine what the sheet renders. A singular `direct.name` like `chapter` produces a single-value reference picker. A plural `back.name` like `userNeeds` produces expandable child rows or a multi-item picker, depending on how you bind columns.
The cardinality you choose affects how sources expand and how columns bind. Use the following patterns.
### Many-to-One (N:1)
Each source entity references exactly one target. The `direct.name` is singular.
```yaml theme={null}
# Data model
- from: UserNeed
to: Chapter
cardinality: many-to-one
storage: linkedWorkItems
linkRole: parent
direct:
name: chapter
back:
name: userNeeds
# Sheet source -- expand the scalar reference
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: chapter
# Sheet columns -- dot-notation for target properties
columns:
chapter:
title: Chapter
display: title
list:
search:
- title
chapter.title:
title: Chapter Title
isReadOnly: true
```
### One-to-Many (1:N)
Each source entity has multiple children. This is the reverse side of a many-to-one relationship, using the `back.name` collection property.
```yaml theme={null}
# Sheet source -- expand the collection
sources:
- id: chapters
query:
from: Chapter
expand:
- name: userNeeds
# Sheet columns -- collection expands into child rows
columns:
title:
title: Chapter
hasFocus: true
userNeeds:
title: User Need
hasFocus: true
```
### Many-to-Many (M:N)
Both sides can reference multiple entities. The expand uses an **association entity** pattern with two levels of expansion.
```yaml theme={null}
# Data model
- from: SystemRequirement
to: UserNeed
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds
back:
name: systemRequirements
# Sheet source -- two-level expand through association
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: systemRequirement
# Sheet columns -- dot-notation through association
columns:
systemRequirements.systemRequirement:
title: System Requirement
list:
search:
- objectId
- title
createNew: true
systemRequirements.systemRequirement.title:
title: SysReq Title
hasFocus: true
```
**Second Linked Entity Requires `multiItem: true`**
When a sheet has two entity types linked to the same parent (e.g., design outputs and design verifications both linked to system requirements), the second linked column must be declared with `multiItem: true` in the sheet configuration. Omitting this property causes the second column to silently fail during initial setup.
After saving the data model YAML:
1. Open a Powersheet that uses this data model
2. Expand the source entity to confirm child rows or linked items appear
3. Check that column bindings resolve correctly -- the referenced entity properties should display their values
If the sheet does not load or shows errors, verify:
* The `from` and `to` values match entity type names in `domainModelTypes` exactly (case-sensitive)
* The `linkRole` value exists in your Polarion project's link role configuration
* The `sources.model` property in your sheet configuration matches your custom data model name
You should now see the related entities navigable through expansion paths in your sheet, with columns displaying the linked entity properties.
**Model Name Must Match**
The `sources.model` property in your sheet configuration must match the data model name -- not the default `rtm`. This is a common first-time setup mistake that causes model connection errors.
## Quick Reference
| Cardinality | `direct.name` | `back.name` | Source Expand | Column Binding | UI Behavior |
| ----------- | -------------------- | ----------------------------- | -------------------------------------------------------- | -------------------------------------- | ----------------------------- |
| **N:1** | `chapter` (singular) | `userNeeds` (plural) | `- name: chapter` | `chapter`, `chapter.title` | Single-value reference picker |
| **1:N** | reverse of N:1 | `userNeeds` (plural) | `- name: userNeeds` | `userNeeds` | Expandable child rows |
| **M:N** | `userNeeds` (plural) | `systemRequirements` (plural) | Two-level: `systemRequirements` then `systemRequirement` | `systemRequirements.systemRequirement` | Multi-item reference picker |
## See Also
* [Create an Entity Type](/powersheet/guides/data-model/create-entity-type) -- define the entity types before adding relationships
* [Create Bidirectional Links](/powersheet/guides/data-model/create-bidirectional-links) -- advanced bidirectional linking patterns
* [Configure Many-to-Many Relationships](/powersheet/guides/data-model/configure-many-to-many) -- detailed M:N configuration
* [Data Model Reference](/powersheet/reference/data-model/index) -- complete property reference for data models
* [Cardinality Reference](/powersheet/reference/data-model/cardinality) -- supported cardinality values and their behavior
* [Configure Sources](/powersheet/guides/sheet-configuration/configure-sources) -- connect relationships to sheet expansion paths
* [Add a Column](/powersheet/guides/sheet-configuration/add-column) -- bind columns to relationship navigation properties
# Create Bidirectional Links
Source: https://learn.nextedy.com/powersheet/guides/data-model/create-bidirectional-links
Define bidirectional relationships in your Nextedy POWERSHEET data model so that entity types can be navigated in both directions -- from source to target and from target back to source.
## Prerequisites
* Both entity types must already exist in your `domainModelTypes` section (see [Create an Entity Type](/powersheet/guides/data-model/create-entity-type))
* A Polarion link role must be configured in your project for the relationship
* Basic familiarity with the data model `relationships` array (see [Configure a Relationship](/powersheet/guides/data-model/configure-relationship))
Every relationship in the data model supports two navigation directions through the `direct` and `back` properties. The `direct` direction navigates from the `from` entity to the `to` entity. The `back` direction navigates in reverse -- from `to` back to `from`.
Add a relationship entry with both `direct` and `back` names defined:
```yaml theme={null}
relationships:
- from: UserNeed
to: SystemRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: systemRequirements
back:
name: userNeeds
```
This single relationship definition creates two navigation properties:
| Direction | Property Name | Added To | Navigates To |
| --------- | -------------------- | ------------------- | ---------------------------- |
| `direct` | `systemRequirements` | `UserNeed` | `SystemRequirement` entities |
| `back` | `userNeeds` | `SystemRequirement` | `UserNeed` entities |
The cardinality determines how navigation properties behave in sources and columns. Pick the pattern that matches your traceability structure:
| Cardinality | When to Use | Direct Property | Back Property |
| -------------- | ---------------------------------------- | ------------------- | ------------------- |
| `many-to-one` | Each child belongs to exactly one parent | Singular (scalar) | Plural (collection) |
| `one-to-many` | One parent has many children | Plural (collection) | Singular (scalar) |
| `many-to-many` | Items linked freely in both directions | Plural (collection) | Plural (collection) |
### Many-to-One Example
Each `UserNeed` belongs to exactly one `Chapter`:
```yaml theme={null}
relationships:
- from: UserNeed
to: Chapter
cardinality: many-to-one
storage: linkedWorkItems
linkRole: parent
direct:
name: chapter
back:
name: userNeeds
```
* The `direct` property `chapter` is **singular** -- it returns one `Chapter` entity
* The `back` property `userNeeds` is **plural** -- it returns a collection of `UserNeed` entities
### Many-to-Many Example
`UserNeed` links to multiple `SystemRequirement` items and vice versa:
```yaml theme={null}
relationships:
- from: UserNeed
to: SystemRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: systemRequirements
back:
name: userNeeds
```
Both navigation properties return collections in this cardinality.
**Navigation property names must be unique within an entity type**
Each entity type can only have one navigation property with a given name. If `SystemRequirement` already has a `userNeeds` property from another relationship, you will get a conflict error. Use distinct, descriptive names for each navigation property.
Once the data model defines both directions, configure your sheet sources to expand the navigation properties. The direction you expand determines which entities appear as child rows.
**Expanding the direct direction** (from `UserNeed` to `SystemRequirement`):
```yaml theme={null}
sources:
- id: user_needs
model: rtm
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: systemRequirement
```
**Expanding the back direction** (from `SystemRequirement` to `UserNeed`):
```yaml theme={null}
sources:
- id: sys_reqs
model: rtm
query:
from: SystemRequirement
expand:
- name: userNeeds
expand:
- name: userNeed
```
The same relationship serves both views -- no need to define a separate relationship for each direction.
**Many-to-many relationships use an association entity**
For `many-to-many` cardinality, the source expand is two levels deep: first the collection (e.g., `systemRequirements`), then the target entity (e.g., `systemRequirement`). This intermediate association entity is what enables the many-to-many link.
Reference the navigation properties in your column configuration to display data from both sides of the relationship.
**Columns for a UserNeed-centric sheet** (expanding toward `SystemRequirement`):
```yaml theme={null}
columns:
title:
title: User Need
hasFocus: true
systemRequirements.systemRequirement:
title: System Requirement
list:
search:
- objectId
- title
createNew: true
systemRequirements.systemRequirement.title:
title: SysReq Title
isReadOnly: true
```
**Columns for a SystemRequirement-centric sheet** (expanding back toward `UserNeed`):
```yaml theme={null}
columns:
title:
title: System Requirement
hasFocus: true
userNeeds.userNeed:
title: User Need
list:
search:
- objectId
- title
userNeeds.userNeed.description:
title: UN Description
isReadOnly: true
```
The binding path follows the pattern: `navigationProperty.targetEntity.field`. For many-to-one relationships, the binding is simpler since the property is scalar:
```yaml theme={null}
columns:
chapter:
title: Chapter
display: title
list:
search:
- title
chapter.title:
title: Chapter Title
isReadOnly: true
```
Chain multiple bidirectional relationships to create a full requirements traceability matrix:
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
description:
severity:
SystemRequirement:
polarionType: sys_req
properties:
description:
severity:
DesignRequirement:
polarionType: des_req
properties:
description:
relationships:
- from: UserNeed
to: SystemRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: systemRequirements
back:
name: userNeeds
- from: SystemRequirement
to: DesignRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: designRequirements
back:
name: systemRequirements
```
With this model, you can build a sheet that navigates the full chain: `UserNeed` → `SystemRequirement` → `DesignRequirement` -- or traverse it in reverse from any level using the `back` navigation properties.
**Avoid duplicate navigation property names in chained relationships**
In the example above, `SystemRequirement` has a `back` property named `systemRequirements` from the second relationship. Make sure this does not conflict with any other navigation property on the same entity type. If the name is already taken, use a more specific name such as `parentSystemRequirements` or `relatedUserNeeds`.
1. Open the [Model Helper widget](/powersheet/guides/customization/use-model-helper) in your Polarion project
2. Set the **depth** parameter to at least 2 to see multi-level relationships
3. Confirm that each entity type shows both its `direct` and `back` navigation properties
4. Open a sheet that uses the data model and expand a row -- you should see child items loaded through the navigation property
5. Switch to a sheet using the reverse direction and verify the `back` property loads the expected parent items
You should now see navigation working in both directions: expanding a `UserNeed` shows its linked `SystemRequirement` items, and expanding a `SystemRequirement` shows the `UserNeed` items that reference it.
**Use the Model Helper to debug missing links**
If one direction works but the reverse does not, open the Model Helper and verify that both `direct.name` and `back.name` appear on their respective entity types. A missing `back` property usually means the relationship was defined without the `back` section.
## Common Pitfalls
**Second linked entity column requires `multiItem: true`**
When a sheet has two work item types linked to the same parent entity (for example, both design outputs and design verifications linked to system requirements), the second linked column must be declared with `multiItem: true` in the sheet configuration. This is a non-obvious requirement that frequently blocks first-time setups.
Ensure the `sources.model` property in your sheet configuration matches the custom model name defined in your YAML file, not the default `rtm`. A mismatch causes model connection errors.
## See Also
* [Configure a Relationship](/powersheet/guides/data-model/configure-relationship) -- core relationship setup
* [Configure Many-to-Many Relationships](/powersheet/guides/data-model/configure-many-to-many) -- association entity patterns and advanced M:N configuration
* [Add a Column](/powersheet/guides/sheet-configuration/add-column) -- column binding path syntax
* [Expand Navigation Properties](/powersheet/guides/queries/expand-navigation-properties) -- query-level navigation property expansion
* [Use Model Helper Widget](/powersheet/guides/customization/use-model-helper) -- visual model verification tool
* [Data Model Reference](/powersheet/reference/data-model/index) -- full property reference for relationships
***
# Create an Entity Type
Source: https://learn.nextedy.com/powersheet/guides/data-model/create-entity-type
Add a new entity type to your Nextedy POWERSHEET data model and map it to a Siemens Polarion ALM work item type so it can be queried, displayed, and linked in your sheets.
## Prerequisites
* Access to your project's data model YAML file via **Administration > Nextedy Powersheet > Data Models** or through **Menu > Configuration > Edit Data Model** within a powersheet document
* The Polarion work item type you want to map to must already exist in your project configuration
1. Open your powersheet document
2. Go to **Menu > Configuration > Edit Data Model**
3. Locate the `domainModelTypes` section in the YAML editor
If this is a new data model, the `domainModelTypes` section may be empty or contain only a placeholder. You will add your entity types as keys under this section.
Add a new key under `domainModelTypes`. The key becomes the entity type name used throughout Powersheet for relationships, source queries, and column bindings.
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
description:
severity:
```
**Naming Convention**
PascalCase (e.g., `UserNeed`, `SystemRequirement`) is the recommended naming convention for entity type names but is not enforced by the system. Type names must be single words without spaces or special characters. `SystemRequirement` is valid; `System Requirement` is not. Invalid names cause silent errors during model loading.
### Entity Type Fields
| Field | Required | Description |
| -------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `polarionType` | Recommended | Maps to one or more Polarion work item type IDs. If omitted, the entity type name is used as-is. Accepts a single string or a list of strings. |
| `properties` | Yes | Map of property names to expose. Use `null` values (empty after the colon) for default configuration. |
| `constraints` | No | Optional filtering constraints that scope which Polarion items this entity type includes. |
**Entity Name vs Polarion Type ID**
The entity type name (e.g., `UserNeed`) is the Powersheet-internal identifier used in relationships, queries, and column binding paths. The `polarionType` value (e.g., `user_need`) is the Polarion work item type ID used for server queries. These can and often do differ. A common mistake is using the Polarion display name instead of the type ID.
List the Polarion work item fields you want to expose on this entity type. Each key in `properties` must match a built-in field name or custom field name in Polarion.
```yaml theme={null}
SystemRequirement:
polarionType: sys_req
properties:
description:
severity:
component:
type:
status:
```
Common built-in properties:
| Property Name | Description |
| ------------- | ----------------------------------------------------------- |
| `title` | Work item title (automatically included even if not listed) |
| `description` | Work item description (rich text) |
| `severity` | Severity enum field |
| `status` | Workflow status |
| `component` | Component assignment |
| `type` | Work item sub-type |
Properties with a `null` value (empty after the colon) use default configuration. For advanced property configuration including custom field mappings and enum values, see [Add a Custom Property](/powersheet/guides/data-model/add-custom-property).
**Start Minimal**
Begin with only the properties you need to display in your sheet. You can add more properties later without breaking existing configurations. Starting with a simple single-entity setup makes it easier to diagnose errors during initial setup.
The data model supports the `Document` built-in entity type that does not require a `polarionType` mapping:
```yaml theme={null}
domainModelTypes:
Document:
UserNeed:
polarionType: user_need
properties:
description:
```
* **`Document`** -- represents Polarion LiveDoc modules. Automatically includes module-level properties.
**Verify in application**
Other structural types such as headings may need explicit `polarionType` mapping (e.g., `Chapter` with `polarionType: heading`). Check your project's work item type configuration to confirm which types are available.
An entity type can map to more than one Polarion work item type by providing a list:
```yaml theme={null}
DesignOutput:
polarionType:
- design_output
- design_verification
properties:
description:
severity:
```
This is useful when a single domain concept spans multiple Polarion types and you want to query them together in one sheet source.
1. Save the data model YAML
2. Reload the powersheet document
3. You should now see the new entity type available in source queries and relationship configurations
To verify the entity type is loaded correctly, use the **Model Helper** widget:
* Set **model** to your model name
* Set **startEntity** to your new entity type name
* Set **depth** to `1`
The Model Helper displays the entity type with its properties and any configured relationships.
**Model Name Must Match**
The `sources.model` property in your sheet configuration must match the name of your custom data model, not the default `rtm`. If the model name does not match, Powersheet silently falls back to the default model and your entity types will not appear.
## Complete Example: RTM Entity Types
A typical requirements traceability matrix uses several entity types connected through relationships:
```yaml theme={null}
domainModelTypes:
Chapter:
polarionType: heading
UserNeed:
polarionType: user_need
properties:
description:
severity:
component:
SystemRequirement:
polarionType: sys_req
properties:
description:
severity:
component:
DesignRequirement:
polarionType: des_req
properties:
description:
relationships:
- from: UserNeed
to: Chapter
cardinality: many-to-one
storage: linkedWorkItems
linkRole: parent
direct:
name: chapter
back:
name: userNeeds
- from: SystemRequirement
to: UserNeed
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds
back:
name: systemRequirements
```
After defining entity types, the `relationships` section connects them using `from`/`to` references, `direct`/`back` navigation property names, and a Polarion `linkRole`. See [Configure a Relationship](/powersheet/guides/data-model/configure-relationship) for the full walkthrough.
**Relationship References Are Case-Sensitive**
Any `relationships` entry that references an entity type by name in `from` or `to` fields must use the exact type name including capitalization. A mismatch causes a "left error" (invalid `from` entity) or "right error" (invalid `to` entity) during model loading.
## Verification Checklist
After saving your data model, confirm the following:
| Check | Expected Result |
| ------------------------------ | ------------------------------------------------------------------------- |
| Model Helper shows entity type | Type appears with listed properties |
| Sheet source query works | `query: { from: YourType }` returns Polarion work items |
| Columns display data | Properties defined in the entity type can be used as column binding paths |
| No console errors | Browser console shows no metadata loading errors |
You should now see your new entity type available in the Model Helper, ready for use in source queries and sheet column configurations.
## Map Multiple Polarion Types to One Entity
When several Polarion work item types share the same structure, map them all to a single data model entity type using an array:
```yaml theme={null}
domainModelTypes:
Requirement:
polarionType:
- systemRequirement
- softwareRequirement
- hardwareRequirement
properties:
description:
severity:
```
Powersheet queries for the `Requirement` entity type return work items of all three Polarion types. This is useful for consolidated views where you want to display different requirement subtypes in a single sheet level.
**When to use multi-type mapping**
Use array-style `polarionType` when the Polarion types share the same custom fields and you want to view them together. If they have different properties, create separate entity types instead so you can define distinct property sets for each.
## Map Relationship Link Roles
Relationships between entity types use the `linkRole` property to reference a Polarion link role. The link role must already exist in your Polarion project configuration under **Administration > Work Items > Link Roles**.
```yaml theme={null}
relationships:
- from: UserNeed
to: Chapter
cardinality: many-to-one
storage: linkedWorkItems
linkRole: parent
direct:
name: chapter
back:
name: userNeeds
- from: SystemRequirement
to: UserNeed
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds
back:
name: systemRequirements
```
Key properties in each relationship definition:
| Property | Purpose |
| ------------- | --------------------------------------------------------------------------------- |
| `from` / `to` | Source and target entity type names (must match keys in `domainModelTypes`) |
| `cardinality` | `many-to-one`, `one-to-many`, or `many-to-many` |
| `storage` | `linkedWorkItems` -- the only supported storage mechanism (Polarion native links) |
| `linkRole` | Polarion link role ID used to persist the relationship |
| `direct.name` | Forward navigation property name (source to target) |
| `back.name` | Reverse navigation property name (target back to source) |
**Link role must exist in Polarion**
If the `linkRole` value does not match a link role defined in your Polarion project, Powersheet fails to load related items. Verify available link roles under **Administration > Work Items > Link Roles** before configuring relationships.
## Connect Mappings to Sheet Sources and Columns
After mapping entity types and relationships, wire them into a sheet configuration. The three configuration layers -- data model, sheet sources, and sheet columns -- connect through navigation property names.
**Source configuration** uses the navigation property names from `direct.name` and `back.name` to expand related entities:
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: chapter
```
**Column configuration** uses the same navigation property names for binding paths:
```yaml theme={null}
columns:
title:
title: Title
hasFocus: true
chapter:
title: Chapter
display: title
list:
search:
- title
chapter.title:
title: Chapter Title
isReadOnly: true
```
The cardinality of the relationship determines how columns behave:
| Cardinality | Source expand | Column binding | UI behavior |
| ---------------------- | ------------------------------------------------------------- | -------------------------------------- | ----------------------------- |
| **N:1** (many-to-one) | `- name: chapter` | `chapter`, `chapter.title` | Single-value reference picker |
| **1:N** (one-to-many) | `- name: userNeeds` | `userNeeds` | Child rows (new sheet level) |
| **M:N** (many-to-many) | `- name: systemRequirements` then `- name: systemRequirement` | `systemRequirements.systemRequirement` | Multi-item reference picker |
**Multi-item columns for second linked type**
When a parent entity links to two different work item types (e.g., design outputs and design verifications both linked to system requirements), declare the second linked column with `multiItem: true` in the sheet configuration. Without this flag, only the first linked type displays correctly.
## See Also
* [Configure a Relationship](/powersheet/guides/data-model/configure-relationship) -- connect entity types with navigation properties
* [Add a Custom Property](/powersheet/guides/data-model/add-custom-property) -- expose custom fields on entity types
* [Configure Constraints](/powersheet/guides/data-model/configure-constraints) -- add filtering constraints to entity types
* [Set Entity Permissions](/powersheet/guides/data-model/set-permissions) -- control CRUD access on entity types
* [Validate Your Data Model](/powersheet/guides/data-model/validate-model) -- check your model for errors
* [Data Model Reference](/powersheet/reference/data-model/index) -- full data model property reference
# Data Model Guides
Source: https://learn.nextedy.com/powersheet/guides/data-model/index
These guides cover common data model configuration tasks in Nextedy POWERSHEET.
Add a new entity type to your data model and map it to a Polarion work item type.
Define relationships between entity types with link roles and navigation properties.
Scope entity loading, creation, and picker filters using constraint rules.
Control read and write access at the entity and property level.
## Advanced Guides
* **[Create Bidirectional Links](/powersheet/guides/data-model/create-bidirectional-links)** -- Set up forward and reverse navigation properties for full two-way traversal
* **[Configure Many-to-Many Relationships](/powersheet/guides/data-model/configure-many-to-many)** -- Handle complex multi-item relationships between entity types
* **[Validate Your Data Model](/powersheet/guides/data-model/validate-model)** -- Check your data model for naming errors, missing references, and configuration issues
**Recommended Order**
For a new data model, follow these guides in sequence: **Create an Entity Type** first (which includes Polarion type mapping and property definitions), and then **Configure a Relationship**. Add constraints and permissions after the basic structure is working.
## Related Resources
* [Data Model Reference](/powersheet/reference/data-model/index) -- full property-level reference for data model YAML
* [Example Models Reference](/powersheet/reference/example-models/index) -- complete model examples to study
* [Creating Your First Data Model](/powersheet/getting-started/first-data-model) -- introductory tutorial
# Set Entity Permissions
Source: https://learn.nextedy.com/powersheet/guides/data-model/set-permissions
Control read and write access to entity properties and navigation properties in your Nextedy POWERSHEET data model using the `readable` and `updatable` flags.
**Verify in application**
This page is based on code-level analysis. Verify permission behavior in your Polarion environment, as server-side enforcement may vary by version.
1. Navigate to **Administration > Nextedy Powersheet > Data Models**
2. Select the data model to edit
3. Locate the entity type under `domainModelTypes` where you want to configure permissions
Each property in an entity type can have `readable` and `updatable` flags to control visibility and editability:
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: userNeed
properties:
id:
readable: true
updatable: false
title:
readable: true
updatable: true
description:
readable: true
updatable: true
severity:
readable: true
updatable: false
outlineNumber:
readable: true
updatable: false
```
## Permission Flag Reference
| Flag | Default | Effect when `false` |
| ----------- | ------- | ------------------------------------ |
| `readable` | `true` | Property is hidden from the sheet UI |
| `updatable` | `false` | Property is displayed as read-only |
Some properties are enforced as read-only regardless of your data model settings:
* `id` -- the work item identifier. This is a built-in property and is always read-only.
Other properties become read-only only when explicitly declared in the entity type:
* `outlineNumber` -- the document hierarchy position. Unlike `id`, `outlineNumber` is **not** a built-in property. It must be declared under `properties` for the entity type before it appears on the sheet, and it is treated as read-only when declared (the server controls outline numbers automatically).
For `Document` entity types, properties like `moduleFolder`, `moduleName`, `title`, and `type` are also read-only after creation.
**System fields override data model settings**
Setting `updatable: true` on `id` has no effect -- it is always enforced as read-only by the server. The same applies to `outlineNumber` once you declare it: the server ignores `updatable: true` and keeps the value under its control.
Nextedy Powersheet also enforces user-level permissions for document and model administration. These are determined by the user's Polarion roles:
* **document.admin.read** -- can view sheet configuration
* **document.admin.write** -- can modify sheet configuration
* **model.admin.read** -- can view data model configuration
* **model.admin.write** -- can modify data model configuration
A top-level `readOnly` flag is also evaluated, which makes the entire powersheet read-only when the user lacks write permissions or the license is invalid.
**Use permissions with formatters for layered control**
Combine data model permissions with [column-level read-only settings](/powersheet/guides/sheet-configuration/configure-read-only-column) for fine-grained control. Data model permissions apply globally, while formatters can be conditional.
Permissions can also be set on relationship navigation properties via the `direct` and `back` definitions:
```yaml theme={null}
relationships:
- from: UserNeed
to: SystemRequirement
cardinality: one-to-many
storage: linkedWorkItems
linkRole: refines
direct:
name: systemRequirements
back:
name: userNeeds
```
Navigation property permissions are inherited from the target entity type's permission settings. If the target entity has `updatable: false`, the relationship column will also be read-only.
## Verify
After saving your data model changes, open a powersheet document. You should now see:
* Properties with `readable: false` are **not displayed** as columns
* Properties with `updatable: false` are displayed but **cannot be edited** (cells appear greyed out)
* `id` remains read-only regardless of settings; `outlineNumber`, when declared, is also enforced as read-only by the server
## See Also
* [Configure Read-Only Column](/powersheet/guides/sheet-configuration/configure-read-only-column) -- make individual columns read-only in sheet configuration
* [Add a Custom Property](/powersheet/guides/data-model/add-custom-property) -- define properties on entity types
* [Create an Entity Type](/powersheet/guides/data-model/create-entity-type) -- define new entity types with properties
* [Apply Column Styles](/powersheet/guides/sheet-configuration/apply-style) -- visual styling for read-only columns
# Validate Your Data Model
Source: https://learn.nextedy.com/powersheet/guides/data-model/validate-model
Verify your Nextedy POWERSHEET data model configuration against common errors before deploying it to a live sheet, catching mismatches between entity types, relationships, and Polarion settings early.
Open your data model YAML file and confirm each entity type under `domainModelTypes` has a valid structure. Entity type names should follow PascalCase convention (e.g., `UserNeed`, `SystemRequirement`) for consistency across the configuration:
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
description:
severity:
SystemRequirement:
polarionType: sys_req
properties:
description:
severity:
DesignRequirement:
polarionType: des_req
properties:
description:
```
Each entry must have:
* A **unique name** as the map key (the `name` field is automatically set from the key)
* A `polarionType` value that maps to a Polarion work item type ID
* An optional `properties` map defining available fields
**Entity type names must not contain spaces or special characters**
Names like `User Need` (with a space) or `System-Requirement` (with a hyphen) cause parsing errors. PascalCase without separators is the recommended convention: `UserNeed`, `SystemRequirement`, `DesignRequirement`.
Each `polarionType` value must match an actual Polarion work item type **ID** -- not the display name. Navigate to **Administration > Work Item Types** in Polarion to find the correct IDs.
| Data Model Entity | `polarionType` | Where to Verify |
| ------------------- | -------------- | ------------------------------------ |
| `UserNeed` | `user_need` | **Administration > Work Item Types** |
| `SystemRequirement` | `sys_req` | **Administration > Work Item Types** |
| `DesignRequirement` | `des_req` | **Administration > Work Item Types** |
| `Hazard` | `hazard` | **Administration > Work Item Types** |
| `RiskControl` | `riskControl` | **Administration > Work Item Types** |
**Use type ID, not display name**
A frequent first-time setup mistake: writing `polarionType: System Requirement` (the display name) instead of `polarionType: sys_req` (the type ID). The data model requires the **ID** value. Check Polarion administration to find the correct ID for each work item type.
In the `relationships` section, both `from` and `to` values must reference entity type names defined in `domainModelTypes` -- never Polarion work item type IDs:
```yaml theme={null}
relationships:
- from: UserNeed
to: Chapter
cardinality: many-to-one
storage: linkedWorkItems
linkRole: parent
direct:
name: chapter
back:
name: userNeeds
- from: SystemRequirement
to: UserNeed
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds
back:
name: systemRequirements
```
Check each relationship for:
1. **`from`** and **`to`** -- must exactly match a `domainModelTypes` key (case-sensitive)
2. **`cardinality`** -- one of: `one-to-one`, `many-to-one`, `one-to-many`, `many-to-many`
3. **`storage`** -- set to `linkedWorkItems` for Polarion link-based relationships
4. **`linkRole`** -- must match a link role ID defined in Polarion
5. **`direct.name`** and **`back.name`** -- navigation property names used in sources and column bindings
**Use entity type names, not Polarion type IDs**
Writing `from: user_need` (Polarion type ID) instead of `from: UserNeed` (data model entity name) is a common error. The `from` and `to` fields must match `domainModelTypes` keys exactly, including case.
Navigation property names defined in `direct.name` and `back.name` must be unique within each entity type. These names are how sources and columns reference the relationship.
The `direct` direction navigates from the `from` entity to the `to` entity. The `back` direction navigates in reverse. Verify that:
* **Scalar nav properties** (N:1 direct side) use singular names: `chapter`, `userNeed`
* **Collection nav properties** (1:N back side, or M:N) use plural names: `userNeeds`, `systemRequirements`
* No two relationships define the same nav property name on the same entity type
The `direct.name` and `back.name` values appear directly in your sheet source `expand` entries and column binding paths. Getting these right in the data model prevents cascading errors in sheet configuration. See [Configure Many-to-Many Relationships](/powersheet/guides/data-model/configure-many-to-many) for expand patterns per cardinality type.
Each `linkRole` in a relationship must correspond to a link role configured in your Polarion project:
1. Go to **Administration > Work Item Link Roles** in Polarion
2. Confirm the link role ID exists (e.g., `parent`, `decomposes`, `verifies`, `relatesTo`)
3. Verify the link role allows connections between the work item types specified by `polarionType` on both sides of the relationship
**Link role ID vs. display name**
Like work item types, link roles have an internal ID and a display name. The `linkRole` field requires the **ID**, not the display name. For example, use `relatesTo` not `Relates To`.
Properties listed under entity type definitions should correspond to valid Polarion fields -- either built-in fields or custom fields defined in the project:
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
description: # built-in Polarion field
severity: # built-in Polarion field
```
Key rules for properties:
* **Property names** map to Polarion field identifiers
* **Custom fields** require matching `customFieldName` if the property name differs from the Polarion field name
* The `storage` property on a relationship definition determines how the link is persisted — `linkedWorkItems` is the only supported storage mechanism
* **Reserved names**: `project` and `document` have special handling and should not be defined as custom properties
**Adding custom Polarion fields as sheet columns**
To expose a custom Polarion field in the sheet, you need two configuration steps: (1) add the property to the entity type definition in the data model, and (2) add a corresponding column in the sheet configuration. See [Add a Custom Property](/powersheet/guides/data-model/add-custom-property) for the full walkthrough.
The Model Helper widget provides a visual tree of your data model structure, letting you verify that entity types and relationships are correctly connected before opening a full sheet:
1. Open a LiveReport page in Polarion
2. Add the Model Helper widget and configure its parameters:
* **model**: your model name (must match the `sources.model` value in your sheet configuration)
* **projectId**: your Polarion project ID
* **startEntity**: the root entity type to visualize (e.g., `UserNeed`)
* **depth**: number of relationship levels to display
3. Review the displayed tree structure and confirm:
* All expected entity types appear at the correct levels
* Navigation property names match what you defined in `direct.name` and `back.name`
* No missing branches that indicate broken relationship references
The `sources.model` property in your sheet configuration must match the name of your data model file (without the `_model.yaml` suffix). For example, if your file is `rtm_model.yaml`, set `sources.model: rtm`. Using the wrong name (such as leaving the default when you have a custom model name) is one of the most common first-time configuration errors.
After validating the data model itself, verify that your sheet configuration `sources` section correctly references the navigation properties you defined. The expand path must match the cardinality:
| Cardinality | Model Config | Source Expand | Column Binding |
| ----------- | ------------------------------- | ------------------------------------------------------------- | -------------------------------------- |
| **N:1** | `direct.name: chapter` | `- name: chapter` | `chapter`, `chapter.title` |
| **1:N** | `back.name: userNeeds` | `- name: userNeeds` | `userNeeds` (child rows) |
| **M:N** | `back.name: systemRequirements` | `- name: systemRequirements` then `- name: systemRequirement` | `systemRequirements.systemRequirement` |
**M:N relationships use two-level expand**
Many-to-many relationships use an association entity between the two types. The source expand must be two levels deep: first the association collection, then the target entity. Column bindings use dot-notation through both levels: `systemRequirements.systemRequirement`.
**Second linked entity column needs `multiItem: true`**
When a sheet has two work item types linked to the same parent entity (for example, design outputs and design verifications both linked to system requirements), the second linked column must be declared with `multiItem: true` in the sheet configuration. This is a non-obvious requirement that commonly blocks new users during initial setup.
## Validation Checklist
Use this checklist before deploying your data model to a sheet:
* [ ] Entity type names use PascalCase without spaces or special characters
* [ ] Each `polarionType` matches a Polarion work item type **ID** (not display name)
* [ ] All `from` and `to` values in relationships match `domainModelTypes` keys exactly
* [ ] All `linkRole` values match link role IDs in Polarion configuration
* [ ] Navigation property names (`direct.name`, `back.name`) are unique per entity type
* [ ] Scalar nav properties use singular names; collection nav properties use plural names
* [ ] Property names reference valid Polarion field names (built-in or custom)
* [ ] `cardinality` is one of: `one-to-one`, `many-to-one`, `one-to-many`, `many-to-many`
* [ ] `storage` is set to `linkedWorkItems` for Polarion link-based relationships
* [ ] `sources.model` in the sheet configuration matches the data model file name
* [ ] Source expand paths match the navigation property names and follow cardinality patterns
## Verify
After correcting any issues found during validation, save the data model and open a Powersheet document. You should now see:
* The sheet loads without model connection errors
* All entity types display the correct Polarion work items
* Relationships expand correctly in the hierarchy, with child rows appearing at the expected levels
* Picker dialogs show items of the correct types when editing reference columns
* Navigation property names in column bindings resolve without errors
## See Also
* [Fix Model Connection Errors](/powersheet/guides/troubleshooting/fix-model-connection-errors) -- resolve model loading failures
* [Fix Type Name Errors](/powersheet/guides/troubleshooting/fix-type-name-errors) -- troubleshoot entity type mapping issues
* [Fix Relationship Errors](/powersheet/guides/troubleshooting/fix-relationship-errors) -- diagnose broken relationship definitions
* [Create an Entity Type](/powersheet/guides/data-model/create-entity-type) -- add a new entity type to the data model
* [Configure a Relationship](/powersheet/guides/data-model/configure-relationship) -- set up relationships between entity types
* [Create an Entity Type](/powersheet/guides/data-model/create-entity-type) -- map entity types to Polarion work item types
* [Use Model Helper Widget](/powersheet/guides/customization/use-model-helper) -- detailed Model Helper reference
# Export to Excel
Source: https://learn.nextedy.com/powersheet/guides/export/export-to-excel
Export your Nextedy POWERSHEET data to an Excel (.xlsx) file that preserves column headers, cell styling, group structure, and complex cell content for offline analysis and reporting.
## Prerequisites
* A Powersheet document open in Polarion with populated data
* The sheet must be fully loaded (all rows visible) before starting the export
Before exporting, configure which columns appear in the output. The export includes **only visible columns** — hidden columns are excluded automatically.
1. Open your powersheet document in Polarion
2. Use the **Views** selector to switch to the view that contains the columns you want to export
3. Verify that all desired columns are visible in the sheet
**Use Views to control export scope**
Create a dedicated view with only the columns relevant for your export. Switch to that view before exporting to get a focused, clean Excel file without manual cleanup afterward. See [Create a View](/powersheet/guides/sheet-configuration/create-view) for instructions.
1. Open the sheet toolbar menu
2. Select **Export to Excel**
3. A loading indicator appears while the export is being generated
4. When the export completes, your browser automatically downloads an `.xlsx` file named after the current document
## What the Excel File Contains
The exported `.xlsx` file mirrors the visible state of your sheet:
| Component | Description |
| ------------------------ | ------------------------------------------------------------------------------------------- |
| **Column headers** | Bold, centered text matching the column titles in the sheet |
| **Column group headers** | If your sheet uses `columnGroup` settings, grouped columns are merged under a shared header |
| **Row numbers** | Sequential row numbers (1-based) appear in the row header column |
| **Cell styling** | Bold and underline formatting from sheet cells is preserved |
| **Merged cells** | Cell merging from the sheet is reproduced in Excel |
| **Group rows** | Group row headers appear bold and centered, with optional item counts |
## How Column Types Are Exported
Powersheet converts each column type to an Excel-compatible format:
| Sheet Column Type | Excel Output |
| ------------------------ | -------------------------------------- |
| Plain text | Text value as-is |
| Multi-item | Each value on a new line |
| Workflow state | State name as text |
| Reference (many-to-one) | Referenced item label as text |
| Reference (many-to-many) | Each linked item on a new line |
| Collection | Items on separate lines, icons removed |
| External link | URL text (not a clickable hyperlink) |
| Security-denied cell | Denied indicator preserved |
**External links export as plain text**
Columns with the `hasUrl` property export URL values as plain text strings, not as clickable Excel hyperlinks. If you need clickable links in your Excel file, you will need to convert them manually after export.
## Group Row Behavior
Group rows in the Excel output appear as bold, centered text. The `showGroupRowCounter` configuration property controls whether the item count (e.g., "Requirements (5 items)") appears in group headers:
```yaml theme={null}
# In your sheet configuration
showGroupRowCounter: true # Shows "(N items)" in group headers
```
When `showGroupRowCounter` is set to `false`, the counter text is removed from group rows in the export.
## Character Limit Handling
Excel cells have a maximum capacity of 32,767 characters. If any cell in your sheet exceeds this limit, Powersheet automatically truncates the content and displays a warning notification:
> ⚠️ "Text trimmed in: row X, column Y. Excel cells are limited to 32,767 characters."
**Large text fields may be truncated**
Cells with extensive content — such as rich text descriptions or large collections — may exceed the Excel character limit. Check the warning notifications after export to identify any truncated cells. Consider splitting large content across multiple fields if truncation is a recurring issue.
## Export Notifications
Powersheet provides clear feedback during the export process:
| Event | Notification |
| ----------------- | ------------------------------------------------------------------------- |
| Export starts | Loading indicator appears on the sheet |
| Export succeeds | ✅ "Export downloaded: `.xlsx`" (auto-dismisses after 5 seconds) |
| Export fails | "Export failed: ``" (auto-dismisses after 5 seconds) |
| Content truncated | ⚠️ Character limit warning (persists until dismissed) |
## Troubleshooting Common Issues
### Empty or Missing Columns
If columns are missing from the export, verify they are visible in the current view. Switch to a view that includes all required columns, or check that no columns are hidden via the column visibility settings.
### Slow Export on Large Sheets
Cell merging is the primary performance factor for Excel exports. Sheets with deep hierarchies and extensive merged cells take longer to process.
**Reduce export time**
For large sheets with many merged cells, consider temporarily switching to a flat view (without hierarchical merging) before exporting. This can significantly reduce processing time.
### Export Fails with Error
If the export fails, the error notification includes a reason. Common causes include:
* Browser memory limits on very large sheets (thousands of rows with complex columns)
* Network interruption during the export process
* Corrupted cell data that cannot be serialized
Try refreshing the page and exporting again. If the issue persists, reduce the number of visible columns or rows before retrying.
## Verification
You should now see a downloaded `.xlsx` file in your browser's download folder. Open it in Excel or a compatible spreadsheet application and confirm that:
* All visible columns appear with correct bold headers
* Column groups display merged header cells spanning the grouped columns
* Row numbers start at 1 and increment sequentially
* Multi-item and reference cells show values on separate lines
* Bold and underline formatting from the sheet is preserved
* Group rows appear bold with the correct item counts (if `showGroupRowCounter` is enabled)
## See Also
* [Export to PDF](/powersheet/guides/export/export-to-pdf) — why Powersheet has no PDF export, and the Excel-only alternative
* [Export Guides](/powersheet/guides/export/index) — overview of all export options
* [Create a View](/powersheet/guides/sheet-configuration/create-view) — set up column visibility presets for targeted exports
* [Configure a Column Group](/powersheet/guides/sheet-configuration/configure-column-group) — organize columns under shared headers
* [Configure Read-Only Column](/powersheet/guides/sheet-configuration/configure-read-only-column) — control which columns are editable vs. display-only
# Export to PDF
Source: https://learn.nextedy.com/powersheet/guides/export/export-to-pdf
Nextedy POWERSHEET has no built-in PDF export. Sheet data exports to Microsoft Excel (.xlsx) only; use your browser's Print to PDF if a PDF is required.
**Powersheet has no built-in PDF export**
Powersheet does **not** provide a PDF export. The sheet's **Menu > Export** offers a single format — **Microsoft Excel (.xlsx)**. There is no "Export to PDF" action in the product.
## Export your sheet (Excel)
The only built-in Powersheet export is Excel. Open the sheet's **Menu > Export > Microsoft Excel (.xlsx)** — see [Export to Excel](/powersheet/guides/export/export-to-excel). The exported workbook preserves the active view's visible columns, hierarchy, grouping, and cell formatting.
## If you need a PDF
Because Powersheet has no PDF export, produce the PDF outside Powersheet — for example, use your browser's **Print > Save as PDF** on the document page. This is a standard browser capability, not a Powersheet feature, so layout fidelity depends on the browser rather than on Powersheet.
## See Also
* [Export to Excel](/powersheet/guides/export/export-to-excel) — the supported Powersheet export
* [Export Guides](/powersheet/guides/export/index) — export overview
# Export Guides
Source: https://learn.nextedy.com/powersheet/guides/export/index
Nextedy POWERSHEET provides built-in export capabilities that let you take your sheet data out of Siemens Polarion ALM for offline analysis, reporting, and stakeholder distribution.
## Export Options
Export your sheet data to an Excel spreadsheet, preserving column structure, formatting, and hierarchy for offline analysis and editing.
Powersheet has no built-in PDF export — sheet data exports to Excel only. See the details and PDF alternatives.
## Export format
Powersheet provides a single built-in export format — **Microsoft Excel (`.xlsx`)**. There is no PDF export (see [Export to PDF](/powersheet/guides/export/export-to-pdf)). The Excel export is a fully editable spreadsheet that preserves column structure, hierarchy (via indentation and grouping), and cell formatting, and can be re-imported.
**Export Scope**
The Excel export respects the currently active **view** in your sheet configuration. If you have configured views with specific column visibility presets, only the visible columns will appear in the exported file. Adjust your view before exporting to control what data is included.
## Typical Export Workflow
1. **Configure your view** — Select or create a view that shows only the columns you need in the export.
2. **Apply filters** — Use entity queries or document filters to narrow the data set.
3. **Export to Excel** — generate and download the Excel file (the only built-in export format).
4. **Download the file** — The exported file is generated and downloaded to your browser.
## Related Resources
* [Sheet Configuration Guides](/powersheet/guides/sheet-configuration/index) — Learn how to configure views and columns that affect export output
* [Create a View](/powersheet/guides/sheet-configuration/create-view) — Set up column visibility presets before exporting
# How-To Guides
Source: https://learn.nextedy.com/powersheet/guides/index
Nextedy POWERSHEET how-to guides provide step-by-step instructions for common configuration and administration tasks.
## Data Model
**[Data Model Guides](/powersheet/guides/data-model/index)** -- Define entity types, relationships, and properties in your data model.
* **[Create an Entity Type](/powersheet/guides/data-model/create-entity-type)** -- Add a new entity type to your data model YAML
* **[Configure a Relationship](/powersheet/guides/data-model/configure-relationship)** -- Define relationships between entity types with link roles
* **[Configure Constraints](/powersheet/guides/data-model/configure-constraints)** -- Scope entity loading, creation, and picker filters
* **[Set Entity Permissions](/powersheet/guides/data-model/set-permissions)** -- Control read and write access at the property level
* **[Create Bidirectional Links](/powersheet/guides/data-model/create-bidirectional-links)** -- Set up forward and reverse navigation properties
* **[Configure Many-to-Many Relationships](/powersheet/guides/data-model/configure-many-to-many)** -- Handle complex multi-item relationships
* **[Validate Your Data Model](/powersheet/guides/data-model/validate-model)** -- Check your data model for common errors
## Sheet Configuration
**[Sheet Configuration Guides](/powersheet/guides/sheet-configuration/index)** -- Configure columns, views, formatters, and sources.
* **[Add a Column](/powersheet/guides/sheet-configuration/add-column)** -- Add a column bound to an entity property
* **[Add a Computed Column](/powersheet/guides/sheet-configuration/add-computed-column)** -- Derive a column from an expression, stored or display-only
* **[Configure a Column Group](/powersheet/guides/sheet-configuration/configure-column-group)** -- Group related columns with shared styling
* **[Create a View](/powersheet/guides/sheet-configuration/create-view)** -- Define named column visibility presets
* **[Apply Column Styles](/powersheet/guides/sheet-configuration/apply-style)** -- Apply CSS styling to columns
* **[Configure a Formatter](/powersheet/guides/sheet-configuration/configure-formatter)** -- Add conditional formatting rules
* **[Configure Sources](/powersheet/guides/sheet-configuration/configure-sources)** -- Define data sources and expansion paths
* **[Add External Reference Column](/powersheet/guides/sheet-configuration/add-external-reference-column)** -- Display linked external references
* **[Configure Multi-Item Column](/powersheet/guides/sheet-configuration/configure-multi-item-column)** -- Handle one-to-many column display
* **[Configure Read-Only Column](/powersheet/guides/sheet-configuration/configure-read-only-column)** -- Prevent editing on specific columns
* **[Use JavaScript Display Functions](/powersheet/guides/sheet-configuration/use-javascript-display)** -- Custom display rendering
* **[Configure Collapsible Groups](/powersheet/guides/sheet-configuration/configure-collapsible-groups)** -- Set up collapsible column groups
* **[Assign Configuration to Document](/powersheet/guides/sheet-configuration/assign-config-to-document)** -- Link a sheet configuration to a document
* **[Download Configuration as YAML](/powersheet/guides/sheet-configuration/download-config-as-yaml)** -- Export configuration files
## Queries
**[Query Guides](/powersheet/guides/queries/index)** -- Write and optimize entity queries.
* **[Write an Entity Query](/powersheet/guides/queries/write-entity-query)** -- Construct queries for loading data
* **[Use Predicates](/powersheet/guides/queries/use-predicates)** -- Filter results with predicate expressions
* **[Expand Navigation Properties](/powersheet/guides/queries/expand-navigation-properties)** -- Load related entities via expansion paths
* **[Filter by Document](/powersheet/guides/queries/filter-by-document)** -- Scope queries to specific documents
* **[Query Baseline or Revision](/powersheet/guides/queries/query-baseline-revision)** -- Access historical data
* **[Optimize Queries](/powersheet/guides/queries/optimize-queries)** -- Improve query performance
## Server Rendering
**[Server Rendering Guides](/powersheet/guides/server-rendering/index)** -- Computed properties and Velocity templates.
* **[Use Velocity Templates](/powersheet/guides/server-rendering/use-velocity-template)** -- Write server-side rendering templates
* **[Access Polarion Services](/powersheet/guides/server-rendering/access-polarion-services)** -- Use Polarion APIs in templates
* **[Debug Template Errors](/powersheet/guides/server-rendering/debug-template-errors)** -- Troubleshoot rendering issues
## Save Operations
**[Save Operations Guides](/powersheet/guides/save-operations/index)** -- Create and update work items through Powersheet.
* **[Create a Work Item](/powersheet/guides/save-operations/create-work-item)** -- Add new work items from the sheet
* **[Update a Work Item](/powersheet/guides/save-operations/update-work-item)** -- Modify existing work item properties
* **[Create a Link](/powersheet/guides/save-operations/create-link)** -- Establish relationships between work items
* **[Handle Validation Errors](/powersheet/guides/save-operations/handle-validation-errors)** -- Resolve save errors
## Customization
**[Customization Guides](/powersheet/guides/customization/index)** -- Extend Powersheet with custom fields and behaviors.
* **[Use Model Helper Widget](/powersheet/guides/customization/use-model-helper)** -- Visualize data model structure
* **[Configure Picker Filters](/powersheet/guides/customization/configure-picker-filters)** -- Filter entity selection dropdowns
## Migration
**[Migration Guides](/powersheet/guides/migration/index)** -- Migrate from legacy configurations.
* **[Migrate from Risksheet to Powersheet](/powersheet/guides/migration/migrate-from-risksheet)** -- Transition from Risksheet
## Troubleshooting
**[Troubleshooting Guides](/powersheet/guides/troubleshooting/index)** -- Diagnose and fix common issues.
* **[Fix Model Connection Errors](/powersheet/guides/troubleshooting/fix-model-connection-errors)** -- Resolve model loading failures
* **[Fix Type Name Errors](/powersheet/guides/troubleshooting/fix-type-name-errors)** -- Correct entity type naming issues
* **[Fix Relationship Errors](/powersheet/guides/troubleshooting/fix-relationship-errors)** -- Debug relationship configuration
* **[Fix Multi-Item Column Errors](/powersheet/guides/troubleshooting/fix-multi-item-errors)** -- Resolve multi-item display issues
* **[Debug Custom Field Issues](/powersheet/guides/troubleshooting/debug-custom-field-issues)** -- Troubleshoot custom field problems
* **[Resolve Validation Errors](/powersheet/guides/troubleshooting/resolve-validation-errors)** -- Fix save validation failures
**Where to Start**
If you are new to Powersheet configuration, begin with [Creating Your First Data Model](/powersheet/getting-started/first-data-model) and [Creating Your First Sheet Configuration](/powersheet/getting-started/first-sheet-configuration) before diving into these guides.
# Migration Guides
Source: https://learn.nextedy.com/powersheet/guides/migration/index
This section collects guides for moving existing data and configurations into Nextedy POWERSHEET.
Currently, the available guide covers migrating from Nextedy Risksheet. See [Migrate from Risksheet](/powersheet/guides/migration/migrate-from-risksheet) for the step-by-step process.
**Back up before migrating**
Always create a backup of your `.polarion/` directory and any attached configuration files before starting a migration. Use SVN to preserve a known-good revision you can revert to if needed.
## See Also
* [Getting Started](/powersheet/getting-started/index) -- set up Powersheet from scratch
* [Sheet Configuration Guides](/powersheet/guides/sheet-configuration/index) -- configure sheets after migration
* [Data Model Guides](/powersheet/guides/data-model/index) -- adjust your data model post-migration
# Migrate from Risksheet to Powersheet
Source: https://learn.nextedy.com/powersheet/guides/migration/migrate-from-risksheet
Transition an existing Risksheet project to Nextedy POWERSHEET, converting your data model, sheet configurations, and document bindings to the Powersheet platform.
## Before You Start
Risksheet and Powersheet share the same underlying architecture and data model concepts. The migration primarily involves moving configuration files to new locations and updating document references. Your existing Polarion work items, link roles, and custom fields remain unchanged.
**Start with a test project**
Create a copy of your project (or use a sandbox project) and perform the migration there first. Validate everything works before migrating your production project.
Ensure Powersheet is installed and licensed on your Siemens Polarion ALM server. See [Installing Powersheet](/powersheet/getting-started/installation) for details.
After installation, verify that the **Administration > Nextedy Powersheet** menu section is available.
Risksheet data models define entity types with `workItems` arrays and `relationships`. Powersheet uses the same YAML structure with an updated format.
1. Locate your existing Risksheet model YAML (typically in `.polarion/nextedy/models/` or `.polarion/models/`)
2. If the model is in `.polarion/models/`, move it to `.polarion/nextedy/models/` via SVN
3. Open **Administration > Nextedy Powersheet > Models** and verify the model loads
The key data model properties map directly:
| Risksheet Property | Powersheet Equivalent | Notes |
| ----------------------------- | ------------------------ | ------------------------------- |
| `workItems[].name` | `domainModelTypes` keys | Entity type identifiers |
| `workItems[].type` | `polarionType` | Polarion work item type mapping |
| `workItems[].properties` | `properties` | Entity properties |
| `relationships[].from` / `to` | Relationship definitions | Same syntax |
| `relationships[].role` | Link role | Same link role references |
| `relationships[].cardinality` | Cardinality | Same cardinality values |
If your model uses the legacy array-based entity format, convert it to the key-based format:
**Before (array-based):**
```yaml theme={null}
workItems:
- name: Hazard
type: hazard
properties:
- name: severity
type: enum
```
**After (key-based):**
```yaml theme={null}
domainModelTypes:
Hazard:
polarionType: hazard
properties:
severity:
type: enum
```
**Verify in application**
The exact conversion syntax depends on your Risksheet version. Some versions may already use the key-based format. Open the model in **Administration > Nextedy Powersheet > Models** to verify it parses correctly.
If you do not already have the `nextedySheetConfig` custom field:
1. Navigate to **Administration > Documents & Pages > Document Custom Fields**
2. Create a new field:
* **Id:** `nextedySheetConfig`
* **Name:** Sheet Config
* **Type:** Enum: Nextedy - Sheet Config
1. Open **Administration > Nextedy Powersheet > Configurations**
2. Create new configuration entries for each Risksheet view you want to preserve
3. Copy the YAML content from your Risksheet configurations
4. Adapt the column binding paths to use the Powersheet data model entity names
A typical RTM sheet configuration in Powersheet:
```yaml theme={null}
columnGroups:
Risks:
groupName: Risk Analysis
groupStyle: orange
columns:
title:
title: Hazard
width: 250
hasFocus: true
severity:
title: Severity
width: 100
riskControls.riskControl.title:
title: Risk Control
width: 200
columnGroup: Risks
multiItem: true
sources:
- id: hazards
title: Hazards
model: risk-model
query:
from: Hazard
expand:
- name: riskControls
title: Risk Controls
```
For each document that previously used a Risksheet view:
1. Open the document properties
2. Set the **Sheet Config** field to the appropriate Powersheet configuration
3. Save the document
**Data model must match configuration**
Ensure the data model referenced by your sheet configuration defines all entity types and relationships used in column binding paths. Mismatched models cause columns to fail silently.
Powersheet uses Powersheet Drive for sidebar navigation. Update the document query property if needed:
```
com.powersheet.powersheetDocumentQuery=type:powersheet OR HAS_VALUE:templateDoc.KEY
```
This determines which documents appear in the Powersheet Drive sidebar topic.
1. Open **Administration > Nextedy Powersheet > Models** -- confirm the data model loads
2. Open **Administration > Nextedy Powersheet > Configurations** -- confirm sheet configurations are visible
3. Open a migrated document -- confirm the Powersheet table view displays correctly
4. Create a test work item to verify save operations work
5. Check that link roles and relationships resolve correctly in the sheet
You should now see the Powersheet table view rendering with your migrated data, columns, and relationships from the former Risksheet configuration.
## See Also
* [Creating Your First Data Model](/powersheet/getting-started/first-data-model) -- data model setup tutorial
* [Configure a Relationship](/powersheet/guides/data-model/configure-relationship) -- adjust relationships post-migration
* [Assign Configuration to Document](/powersheet/guides/sheet-configuration/assign-config-to-document) -- document binding details
* [Incremental Configuration Approach](/powersheet/getting-started/incremental-configuration) -- extend configurations gradually after migration
# Expand Navigation Properties
Source: https://learn.nextedy.com/powersheet/guides/queries/expand-navigation-properties
Load related entities through expansion paths in your Nextedy POWERSHEET source configuration to display hierarchical data across multiple entity types in a single sheet.
## Prerequisites
Before configuring expansion paths, ensure you have:
* A [data model](/powersheet/guides/data-model/index) with entity types and relationships defined
* A [sheet configuration](/powersheet/guides/sheet-configuration/index) with at least one source
* Familiarity with [writing entity queries](/powersheet/guides/queries/write-entity-query)
## How Expansion Connects Model, Source, and Columns
The three configuration layers -- **data model**, **sheet sources**, and **sheet columns** -- connect through navigation property names. The data model defines entity types and relationships. Sources define how to query and expand those relationships. Columns define how to display the resulting data.
The **cardinality** of a relationship determines the expand pattern and the column binding syntax.
## Shared Data Model for Examples
All examples below use this data model:
```yaml theme={null}
domainModelTypes:
Chapter:
polarionType: heading
UserNeed:
polarionType: user_need
properties:
description:
severity:
SystemRequirement:
polarionType: sys_req
properties:
description:
severity:
DesignRequirement:
polarionType: des_req
properties:
description:
relationships:
- from: UserNeed
to: Chapter
cardinality: many-to-one
storage: linkedWorkItems
linkRole: parent
direct:
name: chapter
back:
name: userNeeds
- from: SystemRequirement
to: UserNeed
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds
back:
name: systemRequirements
```
Each relationship defines a `direct` and `back` navigation direction. The `direct` side navigates from the `from` entity toward the `to` entity. The `back` side navigates in reverse.
**Scenario:** Each `UserNeed` belongs to exactly one `Chapter`. Use the `direct` direction -- the navigation property `chapter` (singular, scalar).
Add the expand to your source configuration:
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: chapter
```
Then bind columns to the expanded entity:
```yaml theme={null}
columns:
title:
title: Title
hasFocus: true
chapter:
title: Chapter
display: title
list:
search:
- title
chapter.title:
title: Chapter Title
isReadOnly: true
```
* `chapter` -- renders a single-value reference picker (scalar navigation property)
* `chapter.title` -- displays the referenced Chapter's title as a read-only column
**Scenario:** Each `Chapter` has multiple child `UserNeed` items. Use the `back` direction -- the navigation property `userNeeds` (plural, collection).
```yaml theme={null}
sources:
- id: chapters
query:
from: Chapter
expand:
- name: userNeeds
```
```yaml theme={null}
columns:
title:
title: Chapter
hasFocus: true
userNeeds:
title: Title
hasFocus: true
```
* `userNeeds` -- expands into child rows in the sheet, creating a new grid level
* No dot-notation is needed; the expand directly opens the child level beneath each parent row
**Scenario:** `UserNeed` items are linked to multiple `SystemRequirement` items and vice versa. Many-to-many relationships use an **association entity** between the two types.
The source expand requires **two levels** -- first to the association entity, then through to the target entity:
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: systemRequirement
```
Column bindings use dot-notation to traverse both levels:
```yaml theme={null}
columns:
title:
title: Title
hasFocus: true
systemRequirements.systemRequirement:
title: System Requirement
list:
search:
- objectId
- title
createNew: true
systemRequirements.systemRequirement.title:
title: SysReq Title
hasFocus: true
```
* `systemRequirements` -- navigates to the association entity
* `systemRequirements.systemRequirement` -- navigates through to the target `SystemRequirement` entity, acting as a multi-item reference picker
* `systemRequirements.systemRequirement.title` -- displays the target entity's title
**Two-level expand is required for M:N**
A many-to-many relationship always uses an intermediate association entity. If you only expand one level (`- name: systemRequirements` without the nested `- name: systemRequirement`), you will see the association entities rather than the target items.
You can nest expansion paths to any depth. For a full requirements traceability matrix (RTM), chain expansions across multiple entity types:
```yaml theme={null}
sources:
- id: rtm
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: systemRequirement
expand:
- name: designRequirements
expand:
- name: designRequirement
```
Each nested level adds another tier of child rows in the sheet. Columns at each level bind to their respective entity type properties.
**Keep expansion depth manageable**
Each expansion level triggers additional queries to fetch related entities. For large datasets, limit expansion to 2-3 levels and consider using [query optimization techniques](/powersheet/guides/queries/optimize-queries) to maintain performance.
Constrain expanded entities to the current document by adding `constraints` to the source:
```yaml theme={null}
sources:
- id: main
query:
from: UserNeed
constraints:
applyCurrentDocumentTo: SystemRequirement
expand:
- name: systemRequirements
expand:
- name: systemRequirement
```
The `applyCurrentDocumentTo` constraint filters expanded `SystemRequirement` entities to only include those from the same Polarion document context. This is useful when your document contains a scoped subset of work items and you want expansions to respect that boundary.
To filter an expanded level by its **own attributes** -- independently of the current document -- add a `query.where` to the expand node. The condition applies only to that level; parent rows are unaffected.
```yaml theme={null}
sources:
- id: chapters
query:
from: Chapter
expand:
- name: requirements
expand:
- name: requirement
query:
where:
targetSystem: iOS
```
This shows, under each chapter, only the expanded requirements whose `targetSystem` is `iOS`. A `where` can be attached to any expand node -- scalar (N:1) or collection (1:N, M:N) -- and multiple keys in the same `where` are combined with AND.
**Drive the subquery from a URL parameter**
The subquery value can be a [dynamic expression](/powersheet/guides/sheet-configuration/configure-dynamic-expressions), for example `"() => context.parameters.system"`, so one configuration serves many scoped views from the URL. When the parameter has no value, the condition is dropped and the level expands unfiltered. See [Open a Scoped Sheet with URL Parameters](/powersheet/guides/sheet-configuration/parametrize-sheet-url).
**The picker respects the subquery**
When a filtered expand level is also editable through a reference picker, the picker offers only candidates that satisfy the subquery `where`, so a chosen item will not disappear on the next load. See [Configure Picker Filters](/powersheet/guides/customization/configure-picker-filters).
## Cardinality Quick Reference
| Cardinality | Model definition | Source expand | Column binding | UI behavior |
| ----------- | ------------------------------------------------------------ | ------------------------------------------------------------- | -------------------------------------- | ----------------------------- |
| **N:1** | `cardinality: many-to-one`, `direct.name: chapter` | `- name: chapter` | `chapter`, `chapter.title` | Single-value reference picker |
| **1:N** | Reverse of N:1, `back.name: userNeeds` | `- name: userNeeds` | `userNeeds` | Child rows (new grid level) |
| **M:N** | `cardinality: many-to-many`, `back.name: systemRequirements` | `- name: systemRequirements` then `- name: systemRequirement` | `systemRequirements.systemRequirement` | Multi-item reference picker |
## Common Pitfalls
**Navigation property names are case-sensitive**
Property names must exactly match the `direct.name` or `back.name` values in your data model. A misspelled property name causes the expansion to silently return no related entities. Verify names in **Administration > Nextedy Powersheet > Models**.
**Don't confuse direct and back directions**
The `direct` direction follows the relationship as declared (from the `from` type to the `to` type), while `back` reverses it. Using the wrong direction returns an empty result set. Check the relationship definition to confirm which navigation property name belongs to which direction.
**Use read-only columns for expanded scalar properties**
When displaying properties from an expanded entity (e.g., `chapter.title`), set `isReadOnly: true` on the column. This prevents users from attempting to edit values that belong to a different entity type.
**Match column bindings to expand paths**
For a column binding like `systemRequirements.systemRequirement.title` to display data, the source must include a matching expand entry with `name: systemRequirements` and nested `name: systemRequirement`. Missing or mismatched expansions result in empty columns.
## Verify Your Configuration
After saving your sheet configuration:
1. Open the Polarion document that uses this sheet configuration
2. You should now see nested rows under each parent entity corresponding to the expanded navigation properties
3. For N:1 expansions, verify the reference picker column shows the correct related entity
4. For 1:N expansions, verify child rows appear beneath each parent
5. For M:N expansions, verify the dot-notation columns display target entity properties through both expand levels
If no expanded rows appear, check the navigation property names against your data model and confirm that linked work items exist in Polarion for the relationship.
## See Also
* [Write an Entity Query](/powersheet/guides/queries/write-entity-query) -- basics of the `from` clause and query structure
* [Configure a Relationship](/powersheet/guides/data-model/configure-relationship) -- how to define relationships with `direct` and `back` names
* [Configure Many-to-Many Relationships](/powersheet/guides/data-model/configure-many-to-many) -- association entity setup for M:N links
* [Create Bidirectional Links](/powersheet/guides/data-model/create-bidirectional-links) -- linking entities in both directions
* [Configure Multi-Item Column](/powersheet/guides/sheet-configuration/configure-multi-item-column) -- column settings for collection bindings
* [Configure Sources](/powersheet/guides/sheet-configuration/configure-sources) -- full source configuration reference
* [Optimize Queries](/powersheet/guides/queries/optimize-queries) -- performance tips for deep expansion paths
* [Filter by Document](/powersheet/guides/queries/filter-by-document) -- apply document constraints to queries
* [Open a Scoped Sheet with URL Parameters](/powersheet/guides/sheet-configuration/parametrize-sheet-url) -- drive expand subqueries from the URL
# Filter by Document
Source: https://learn.nextedy.com/powersheet/guides/queries/filter-by-document
Restrict Nextedy POWERSHEET query results to work items that belong to or are linked within a specific Siemens Polarion ALM document.
## Prerequisites
* A data model with entity types and `constraints` configured
* A sheet configuration with at least one data source
* A Polarion LiveDoc containing the work items you want to filter
Powersheet can automatically scope queries to the current document. This happens through the `constraints` section of your data model, which defines how entity types relate to documents.
In your data model YAML, add a `constraints` block with a `load` section that defines document filtering criteria:
```yaml theme={null}
domainModelTypes:
SystemRequirement:
polarionType: systemRequirement
constraints:
load:
document:
moduleFolder: Requirements
moduleName: System-Requirements
properties:
title:
type: string
```
This restricts the `SystemRequirement` entity to only load items from the document at `Requirements/System-Requirements`.
For more flexible filtering, use `$context.source.document` to dynamically reference the current document:
```yaml theme={null}
domainModelTypes:
SystemRequirement:
polarionType: systemRequirement
constraints:
load:
document:
moduleFolder: $context.source.document.moduleFolder
moduleName: $context.source.document.moduleName
properties:
title:
type: string
```
**Dynamic context resolution**
Using `$context.source.document` allows a single data model to work across multiple documents without hardcoding paths. The current document path is resolved at runtime.
You can also constrain entity loading by document `type`:
```yaml theme={null}
domainModelTypes:
Hazard:
polarionType: hazard
constraints:
load:
document:
type: riskAnalysis
```
This loads only `Hazard` work items from documents whose Polarion type is `riskAnalysis`.
When creating links between entities, you may want the picker dropdown to show only items from specific documents. Use `pick` constraints:
```yaml theme={null}
domainModelTypes:
DesignRequirement:
polarionType: designRequirement
constraints:
pick:
document:
moduleName: Categorized
```
**Pick vs. load constraints**
`load` constraints filter what appears in the sheet. `pick` constraints filter what appears in the dropdown picker when selecting linked items. Mixing them up can cause items to appear in the picker but not in the sheet, or vice versa.
For precise scoping, combine document constraints with the `allowedWITypes` property:
```yaml theme={null}
domainModelTypes:
Requirement:
polarionType:
- sys_req
- des_req
constraints:
load:
document:
allowedWITypes: $context.source.type
create:
document:
moduleFolder: $context.source.document.moduleFolder
moduleName: $context.source.document.moduleName
```
**Verify in application**
The `allowedWITypes` property enables document-based routing of entities when multiple work item types map to a single entity type. Verify the exact behavior for your configuration.
## Verify
After applying document constraints:
1. Open the powersheet document in Polarion
2. You should now see only work items that match the document filter criteria
3. If using picker constraints, click a relationship cell and confirm the dropdown only shows items from the constrained documents
4. Items from other documents should not appear in the sheet
## See Also
* [Configure Constraints](/powersheet/guides/data-model/configure-constraints) -- full constraint configuration guide
* [Write an Entity Query](/powersheet/guides/queries/write-entity-query) -- general query writing
* [Use Predicates](/powersheet/guides/queries/use-predicates) -- query predicate syntax
# Query Guides
Source: https://learn.nextedy.com/powersheet/guides/queries/index
These guides cover the Nextedy POWERSHEET query system -- the mechanism that controls how data is fetched from Siemens Polarion ALM and presented in your sheet.
## Topics
Define a source query that fetches entities from your data model into the sheet. Covers `from`, `where`, and basic query structure in the `sources` section.
Filter query results using equality, comparison, and logical operators in your source `where` clause to narrow down returned work items.
Load related entities through expansion paths for hierarchical sheet display. Traverse data model relationships like `UserNeed` to `SystemRequirement`.
Restrict query results to work items within a specific Polarion LiveDoc. Use document constraints and the `applyCurrentDocumentTo` setting.
Fetch historical data from specific project baselines or revisions instead of current data, enabling point-in-time traceability views.
Improve query performance for large datasets and complex expansion paths. Learn about query structure best practices and efficient predicate usage.
All query settings are defined inside the `sources` section of your sheet configuration YAML. Each source specifies a `query` with `from` (entity type), `where` (filter predicates), and `expand` (navigation properties to load). See [Configure Sources](/powersheet/guides/sheet-configuration/configure-sources) for the full configuration reference.
## Recommended Reading Order
If you are new to Powersheet queries, follow this sequence:
| Step | Guide | What You Learn |
| ---- | --------------------------------------------------------------------------------------- | --------------------------------------------------------- |
| 1 | [Write an Entity Query](/powersheet/guides/queries/write-entity-query) | Basic query structure and the `from` / `where` pattern |
| 2 | [Use Predicates](/powersheet/guides/queries/use-predicates) | Filtering with operators and compound conditions |
| 3 | [Expand Navigation Properties](/powersheet/guides/queries/expand-navigation-properties) | Loading related entities through data model relationships |
| 4 | [Filter by Document](/powersheet/guides/queries/filter-by-document) | Scoping results to a LiveDoc context |
| 5 | [Query Baseline or Revision](/powersheet/guides/queries/query-baseline-revision) | Accessing historical snapshots |
| 6 | [Optimize Queries](/powersheet/guides/queries/optimize-queries) | Performance tuning for production sheets |
## See Also
* [Configure Sources](/powersheet/guides/sheet-configuration/configure-sources) -- define data sources in sheet configuration YAML
* [Data Model Guides](/powersheet/guides/data-model/index) -- set up entity types and relationships that queries target
* [Query API Reference](/powersheet/reference/query-api/index) -- technical reference for query parameters and operators
* [Troubleshooting Guides](/powersheet/guides/troubleshooting/index) -- resolve query-related errors
# Optimize Queries
Source: https://learn.nextedy.com/powersheet/guides/queries/optimize-queries
Improve Nextedy POWERSHEET query performance by structuring predicates, constraints, and expansion paths to minimize server load and response times on Siemens Polarion ALM.
## Prerequisites
* A working powersheet document with configured data sources
* Familiarity with [entity queries](/powersheet/guides/queries/write-entity-query) and [predicates](/powersheet/guides/queries/use-predicates)
* Access to Polarion server logs for debug output
When Powersheet loads data, each query goes through a processing pipeline that translates your configuration into Polarion Lucene queries. Understanding this pipeline helps you write efficient queries.
The query engine splits predicates into two categories:
* **Lucene-compatible predicates** execute as database queries (fast)
* **Complex predicates** execute as in-memory post-filters after fetching (slow for large datasets)
Your goal is to keep as many predicates as possible in the Lucene-compatible category so the database does the heavy lifting.
Simple equality and comparison operators translate directly to Lucene and execute efficiently. Structure your `where` clause to use these operators:
```yaml theme={null}
sources:
- id: requirements
model: rtm
query:
from: SystemRequirement
where:
status:
eq: approved
priority:
gt: "2"
```
**Lucene-friendly operators**
These operators translate directly to Lucene: `eq`, `ne`, `gt`, `lt`, `ge`, `le`. Use these whenever possible instead of complex expressions. Alias operators (`==`, `!=`, `>`, `<=`) also work and are converted internally.
Avoid mixing complex logical groupings when simple predicates will do. The query engine handles `and` at the top level automatically, so flat predicate structures perform best:
```yaml theme={null}
# Efficient -- flat predicates, all Lucene-compatible
query:
where:
status:
eq: approved
severity:
eq: high
priority:
gt: "3"
```
**Complex predicates fall back to in-memory filtering**
Predicates that use `contains` on non-indexed fields or deeply nested `or` groups may not translate to Lucene. These execute as in-memory post-filters, meaning the server first fetches a broader result set, then filters in memory. On large datasets (1000+ items), this causes noticeable delays.
Always define project and document constraints in your data model. The query engine resolves these early in the pipeline, dramatically reducing the result set before other filters apply:
```yaml theme={null}
domainModelTypes:
SystemRequirement:
polarionType: systemRequirement
constraints:
load:
project:
id: myProject
document:
moduleFolder: Requirements
moduleName: System-Requirements
```
Project and document constraints work together as pre-filters. The query engine converts them to Lucene clauses that narrow the search scope before your `where` clause predicates are evaluated.
**Missing constraints hurt performance**
Without project or document constraints, queries scan all work items of a type across the entire Polarion instance. For large installations with thousands of work items, this causes significant delays. Always specify at least a project constraint.
For dynamic document scoping, use `applyCurrentDocumentTo` in your constraints so the sheet automatically filters to the current LiveDoc without hardcoding document paths:
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: requirement
constraints:
load:
applyCurrentDocumentTo: UserNeed
```
This injects the current document ID as a query parameter, scoping results to the active document context.
Deeply nested `expand` clauses cause cascading queries. Each expansion level triggers additional database lookups for related entities:
```yaml theme={null}
# Shallow expansion (fast) -- one level of related entities
sources:
- id: requirements
from: SystemRequirement
expand:
- designRequirements
# Deep expansion (slow) -- use with caution
sources:
- id: requirements
from: SystemRequirement
expand:
- designRequirements:
- hazards:
- riskControls
```
The expand clause is converted internally to dot-notation strings for the query protocol. Each level adds another round of relationship resolution on the server.
**Use views to manage expansion cost**
Create separate [views](/powersheet/guides/sheet-configuration/create-view) for different analysis needs. A lightweight view showing only direct properties loads faster than a full traceability view with three levels of expansion. Users switch views as needed rather than loading everything at once.
Sorting interacts with query performance. Inside a `query:` block, use `orderBy` to determine the order of returned results. (Note that `sortBy` is a separate sheet-level option that belongs at the YAML root, not inside `query:`.)
```yaml theme={null}
sources:
- id: requirements
model: rtm
query:
from: SystemRequirement
orderBy:
- outlineNumber asc
```
Keep sort properties simple and aligned with indexed Polarion fields. Sorting by navigation property paths (e.g., `designRequirement.title`) requires the server to resolve relationships before sorting, which adds overhead.
**Default sorting**
When no `orderBy` is specified, results come back in Polarion's default order (typically by work item ID). Specify `outlineNumber asc` for document-ordered display.
Powersheet auto-discovers enum properties from metadata and dynamically creates data sources for dropdown pickers. Each enum source generates a query to fetch `EnumOption` entities. To avoid unnecessary queries:
* Only include enum columns in views where they are needed
* Use constraints on enum queries to limit results to the relevant project and work item type
* The auto-discovery uses `polarionType`, `projectId`, and `enumId` metadata to build targeted queries
To identify slow queries, use the `explain` query parameter. The server logs each executed query with details:
* The entity type being queried
* The full Lucene query string generated from your predicates and constraints
* The result count
* A preview of the first returned items
**Verify in application**
Check your Polarion server's logging configuration for the exact log level and category needed to enable query debug output. The `explain` parameter in query configuration enables additional diagnostic information.
## Performance Decision Matrix
| Scenario | Recommendation | Impact |
| ---------------------------- | --------------------------------------------- | ------ |
| Loading all items of a type | Add project + document constraints | High |
| Filtering by string value | Use `eq` instead of `contains` where possible | High |
| Deep hierarchy display | Limit `expand` depth to 2--3 levels | High |
| Large result sets (1000+) | Add narrowing predicates to `where` clause | High |
| Cross-project queries | Specify explicit project ID constraints | Medium |
| Multiple enum columns | Use views to load only visible enum sources | Medium |
| Sort by related entity field | Sort by direct properties instead | Low |
## Verify
After applying optimization changes:
1. Open the powersheet document and note the initial load time
2. You should now see faster data loading compared to before your changes
3. Check Polarion server logs for query execution output to confirm Lucene queries are being generated (not in-memory post-filters)
4. Compare the predicate split -- fewer post-filter operations means better performance
5. Test with views that hide deep expansion columns to confirm they load faster
## See Also
* [Write an Entity Query](/powersheet/guides/queries/write-entity-query) -- query structure fundamentals
* [Use Predicates](/powersheet/guides/queries/use-predicates) -- predicate operator reference
* [Filter by Document](/powersheet/guides/queries/filter-by-document) -- document scoping techniques
* [Expand Navigation Properties](/powersheet/guides/queries/expand-navigation-properties) -- controlling expansion depth
* [Query Baseline or Revision](/powersheet/guides/queries/query-baseline-revision) -- historical query considerations
* [Configure Sources](/powersheet/guides/sheet-configuration/configure-sources) -- data source setup
# Query Baseline or Revision
Source: https://learn.nextedy.com/powersheet/guides/queries/query-baseline-revision
View Nextedy POWERSHEET data at a specific historical baseline or revision in Siemens Polarion ALM, enabling point-in-time analysis of requirements and traceability matrices.
## Prerequisites
* A Polarion project with at least one baseline created
* A working powersheet document with configured data sources
* Understanding of Polarion baselines (project-level snapshots)
## Step 1: Open a Document in Revision Mode via the UI
The simplest way to view historical data is through the Powersheet **History** menu:
1. Open the powersheet document in Polarion
2. Navigate to the **History** menu group in the toolbar
3. Select the desired baseline or revision number
4. The document reloads with historical data
When viewing a document in revision mode, the sheet is automatically set to read-only. You cannot edit work items while viewing historical data.
## Step 2: Open a Revision via URL Parameter
You can link directly to a specific revision by appending the `revision` parameter to the Powersheet URL:
```text theme={null}
/polarion/#/project/myProject/powersheet?document=Folder/DocName&revision=42
```
| Parameter | Value | Description |
| ---------- | ------------ | -------------------------------- |
| `revision` | Integer >= 0 | Specific revision number to view |
| (omitted) | -- | Shows latest (HEAD) data |
The revision URL parameter enables bookmarking and sharing specific historical snapshots. Share the full URL with team members for audit reviews or milestone comparisons.
## Step 3: Return to Current Data
To exit revision mode and return to the live document:
1. Open the **History** menu
2. Select **Close Revision** (or the equivalent option to return to HEAD)
3. The document reloads with current data and editing is re-enabled
Alternatively, remove the `revision` parameter from the URL and reload.
## Step 4: Create a Baseline in Polarion
Baselines are created in Polarion, not in Powersheet. Each baseline captures a project-wide snapshot that Powersheet can reference by revision number:
1. In Polarion, navigate to your project
2. Go to **Administration > Baselines** (or the equivalent baseline management page)
3. Create a new baseline
4. Note the revision number assigned to the baseline
The exact steps for creating baselines may vary depending on your Polarion version and project configuration. Consult your Polarion administrator for project-specific baseline procedures.
### How Revision Queries Work
When you open a document with a revision parameter, the query engine executes all queries against the historical data snapshot rather than the current state. The revision can come from:
* The `revision` URL query parameter (explicit user request)
* A context baseline set by the Polarion project
All entity queries, navigation property expansions, and constraint evaluations operate on the historical snapshot. Enum options and picker values also reflect the state at that revision.
The revision parameter must be a non-negative integer. Invalid values may cause the document to fail to load. If you encounter issues, verify the baseline exists in your Polarion project.
## Step 5: Inspect Revision in Document Title
When viewing a historical revision, the document title updates to include the revision number in parentheses. For example:
* **Current:** "RTM Requirements Traceability"
* **Revision 42:** "RTM Requirements Traceability (Revision 42)"
This visual indicator confirms you are viewing historical data.
## Verify
After opening a document with a revision parameter:
1. You should now see the document title with the revision number appended
2. The sheet should display data as it existed at that point in time
3. All editing controls should be disabled (read-only mode)
4. Closing the revision should return you to the current live data with editing re-enabled
## See Also
* [Filter by Document](/powersheet/guides/queries/filter-by-document) -- scope queries to specific documents
* [Write an Entity Query](/powersheet/guides/queries/write-entity-query) -- query fundamentals
* [Optimize Queries](/powersheet/guides/queries/optimize-queries) -- performance tips for large datasets
# Use Predicates
Source: https://learn.nextedy.com/powersheet/guides/queries/use-predicates
Filter entity query results in your Nextedy POWERSHEET sheet configuration using predicate operators for equality, comparison, null checks, and logical composition.
## Predicate Basics
Predicates are conditions placed in the `where` clause of a source query. The query engine evaluates predicates to determine which entities from Siemens Polarion ALM are included in the sheet. Simple predicates compare a property value to a target; composite predicates combine multiple conditions with AND/OR logic.
The simplest predicate matches a property to an exact value:
```yaml theme={null}
sources:
- id: main
model: rtm-model
query:
from: UserNeed
where:
severity: critical
```
This returns only `UserNeed` entities where `severity` equals `critical`.
For explicit equality syntax:
```yaml theme={null}
where:
severity:
eq: critical
```
The following comparison operators are available for filtering:
| Operator | Meaning | Example |
| ---------- | --------------------- | ----------------------------- |
| `eq` | Equals | `severity: { eq: critical }` |
| `ne` | Not equals | `status: { ne: deleted }` |
| `gt` | Greater than | `priority: { gt: 3 }` |
| `ge` | Greater than or equal | `priority: { ge: 2 }` |
| `contains` | Substring match | `title: { contains: safety }` |
```yaml theme={null}
where:
priority:
gt: 3
```
**Numeric comparisons**
The `gt` and `ge` operators work with numeric properties (integer, float). They are not applicable to string or boolean properties.
**Known limitation**
Null value predicates (`eq: null` and `ne: null`) are **not working in the current version**. The syntax shown below is the intended usage once the limitation is resolved, but these predicates will not currently filter entities by null status. Use alternative filtering approaches until this is fixed.
To filter entities based on whether a property has a value:
```yaml theme={null}
# Entities where title IS NOT null (has a value)
where:
title:
ne: null
# Entities where title IS null (missing value)
where:
title:
eq: null
```
Once functional, null checks will be useful for finding incomplete work items or ensuring required fields are populated.
Use the `and` operator to require all conditions to match:
```yaml theme={null}
where:
and:
- severity: critical
- status: approved
```
This returns entities that are both `critical` severity AND `approved` status. AND arrays support any number of sub-predicates:
```yaml theme={null}
where:
and:
- severity: critical
- status: approved
- priority:
ge: 2
```
Use the `or` operator when any condition should match:
```yaml theme={null}
where:
or:
- severity: critical
- severity: major
```
This returns entities where severity is either `critical` OR `major`.
AND and OR predicates can be nested for complex filtering logic:
```yaml theme={null}
where:
and:
- status: approved
- or:
- severity: critical
- severity: major
```
This returns approved entities with either critical or major severity.
## Verification
After updating the `where` clause in your sheet configuration and reloading the document:
1. You should now see only entities that match your predicate conditions
2. The row count in the sheet should reflect the filtered result set
3. Verify that excluded entities are not displayed in the sheet
## See Also
* [Write an Entity Query](/powersheet/guides/queries/write-entity-query) -- complete source query setup
* [Filter by Document](/powersheet/guides/queries/filter-by-document) -- scope predicates to a specific document
* [Optimize Queries](/powersheet/guides/queries/optimize-queries) -- performance tips for predicate-heavy queries
* [Configure Sources](/powersheet/guides/sheet-configuration/configure-sources) -- full source configuration reference
# Write an Entity Query
Source: https://learn.nextedy.com/powersheet/guides/queries/write-entity-query
Define a source query in your Nextedy POWERSHEET sheet configuration that fetches entities from the data model and populates the sheet with data.
Open your sheet configuration YAML and add an entry to the `sources` array. Each source requires an `id`, `title`, `model`, and `query`:
```yaml theme={null}
sources:
- id: userNeeds
title: User Needs
model: rtm-model
query:
from: UserNeed
```
| Property | Purpose |
| ------------ | -------------------------------------------------------------------------------------------- |
| `id` | Unique identifier for this data source |
| `title` | Display label shown in the sheet UI |
| `model` | Reference to the data model ID (defined in **Administration > Nextedy Powersheet > Models**) |
| `query.from` | Entity type name from the data model to query |
The `from` value must match an entity type defined in your data model (e.g., `UserNeed`, `SystemRequirement`, `Hazard`).
To restrict which entities are loaded, add a `where` clause to the query. The `where` clause uses filter predicates:
```yaml theme={null}
sources:
- id: userNeeds
title: User Needs
model: rtm-model
query:
from: UserNeed
where:
status:
ne: deleted
```
This loads only `UserNeed` entities whose `status` is not `deleted`.
Common filter patterns:
```yaml theme={null}
# Equality
where:
severity: critical
# Not equal
where:
status:
ne: deleted
# Null check (has value)
where:
title:
ne: null
# Combined conditions (AND)
where:
and:
- severity: critical
- status: approved
```
**Verify in application**
The exact predicate syntax supported in `where` clauses depends on the query engine. Simple equality and comparison operators are widely supported. For complex predicate patterns, see [Use Predicates](/powersheet/guides/queries/use-predicates).
Control the default order in which the query returns entities by specifying property paths and directions:
```yaml theme={null}
sources:
- id: userNeeds
title: User Needs
model: rtm-model
query:
from: UserNeed
orderBy:
- id asc
```
Append `desc` after the property path for descending order. The `orderBy` clause governs the order of results produced by the query itself, which also determines the default order in which pickers and other query consumers present entities.
To load related entities (for multi-level hierarchical display), add an `expand` section to the source:
```yaml theme={null}
sources:
- id: userNeeds
title: User Needs
model: rtm-model
query:
from: UserNeed
expand:
- name: systemRequirements
title: System Requirements
```
Expansion paths follow the navigation properties defined in your data model. For deeper hierarchies, nest expansions:
```yaml theme={null}
expand:
- name: systemRequirements
title: System Requirements
expand:
- name: designRequirements
title: Design Requirements
```
See [Expand Navigation Properties](/powersheet/guides/queries/expand-navigation-properties) for detailed guidance on multi-level expansion.
For performance, limit the number of entities returned:
```yaml theme={null}
sources:
- id: userNeeds
title: User Needs
model: rtm-model
query:
from: UserNeed
take: 100
```
**Large queries affect performance**
Queries without a `take` limit or a `where` filter may load thousands of work items, causing slow sheet loading. Always apply appropriate filters for production configurations. See [Optimize Queries](/powersheet/guides/queries/optimize-queries) for performance guidance.
## Complete Example
```yaml theme={null}
sources:
- id: rtm-source
title: Requirements Traceability
model: rtm-model
query:
from: UserNeed
where:
status:
ne: deleted
orderBy:
- id asc
expand:
- name: systemRequirements
title: System Requirements
expand:
- name: designRequirements
title: Design Requirements
```
## Verification
After saving the sheet configuration and opening the associated document:
1. You should now see the sheet populated with entities matching your query
2. Expanded relationships should display as nested rows beneath parent items
3. The row count should reflect the filter criteria in your `where` clause
## See Also
* [Use Predicates](/powersheet/guides/queries/use-predicates) -- advanced filtering with comparison and logical operators
* [Expand Navigation Properties](/powersheet/guides/queries/expand-navigation-properties) -- multi-level relationship expansion
* [Filter by Document](/powersheet/guides/queries/filter-by-document) -- scope queries to the current document
* [Configure Sources](/powersheet/guides/sheet-configuration/configure-sources) -- full source configuration reference
* [Add a Column](/powersheet/guides/sheet-configuration/add-column) -- configure sorting and column properties at the sheet level
# Create a Link
Source: https://learn.nextedy.com/powersheet/guides/save-operations/create-link
This guide walks you through creating relationships between work items in Nextedy POWERSHEET using the linking workflow in Siemens Polarion ALM, covering both toolbar-driven linking and picker-based approaches.
## Prerequisites
* A powersheet document containing at least two entity types connected by a relationship in the data model
* The relationship must define a valid `linkRole` with `storage: linkedWorkItems`
* Your Polarion account must have permissions to create links between the relevant work item types
Before you can link entities, the data model must define the relationship between them. Open your data model YAML and verify the relationship exists:
```yaml theme={null}
relationships:
- from: UserNeed
to: SystemRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: requires
direct:
name: systemRequirements
back:
name: userNeeds
```
| Property | Purpose |
| ------------- | ------------------------------------------------------------------ |
| `from` / `to` | The two entity types being connected |
| `cardinality` | Relationship type (`many-to-many`, `one-to-many`, or `one-to-one`) |
| `storage` | Must be `linkedWorkItems` to use Polarion link roles |
| `linkRole` | The Polarion link role that stores the association |
| `direct` | Navigation property name on the `from` entity |
| `back` | Navigation property name on the `to` entity |
The `direct` and `back` properties create bidirectional navigation. In this example, a `UserNeed` entity exposes a `systemRequirements` navigation property, while each `SystemRequirement` exposes a `userNeeds` navigation property pointing back.
**Check existing link roles in Polarion**
Navigate to **Administration > Work Items > Link Roles** in Polarion to see all available link role names. The `linkRole` value in your data model must match an existing Polarion link role exactly.
To link entities visually, your sheet configuration needs a column that displays the navigation property. This is typically a multi-item column bound to the relationship:
```yaml theme={null}
columns:
- key: systemRequirements.systemRequirement
label: System Requirements
width: 250
```
The binding path uses dot notation: the navigation property name (`systemRequirements`) followed by the target entity type in camelCase (`systemRequirement`). This column displays linked entities and provides the picker interface for creating new associations.
Powersheet offers two methods to create links between entities:
### Method A: Toolbar Link Command
1. Select a cell in the **source** row (the entity you want to link from)
2. Click the **Link** button in the toolbar
3. The sheet enters linking mode -- the source row becomes highlighted and the sheet switches to row-selection mode
4. A visual indicator on the sheet confirms that linking mode is active
### Method B: Entity Picker in a Multi-Item Column
For many-to-many relationships, use the inline picker:
1. Double-click the multi-item cell in the source row
2. The picker dropdown appears showing available target entities
3. Use the search field to filter entities by title or ID
4. Click an entity from the list to create the association immediately
When using the toolbar link command (Method A), click the target row to establish the link. Powersheet validates the operation before creating the association:
* The target entity type must match the relationship definition in the data model
* Duplicate links between the same two entities are prevented
* Self-referencing links (linking an entity to itself) are blocked
**Duplicate and self-referencing links**
Powersheet silently rejects duplicate links and self-referencing links. If you click a target and nothing happens, check whether the link already exists or whether you selected the source row itself.
After selecting a valid target, the cell in the multi-item column updates to show the newly linked entity. The row is marked as modified (indicated by a visual change indicator on the row header) but the link is not yet persisted to Polarion.
Before persisting the link, review your changes using Powersheet's review mode:
1. Click the **Review** button in the toolbar to filter the sheet to only rows with pending changes
2. Modified rows display a change indicator on the row header
3. The review mode filter shows a count of changed rows (format: `N/M rows`)
4. Use the dropdown menu to filter specifically by **Changed rows** or **Added** items
**Review mode for bulk linking**
When creating multiple links across several rows, review mode helps you verify all associations before committing. You can toggle it on and off without losing your other active filters.
To remove an existing link without deleting either work item:
1. Locate the linked entity in the multi-item column
2. Click the **Unlink** action ( ) next to the entity name
3. The association is marked for removal -- both work items remain intact in Polarion
The unlink operation follows the same save workflow: changes remain pending until you explicitly save.
**Undo link and unlink operations**
Both linking and unlinking support undo/redo. Press **Ctrl+Z** (or **Cmd+Z** on macOS) to reverse a link creation or removal before saving. The undo stack tracks all link operations alongside other edits.
Click 💾 **Save** to persist the new links to Polarion. During the save operation:
1. The sheet temporarily enters a read-only state to prevent concurrent edits
2. Entities are saved in topologically sorted order -- parent entities and dependencies are persisted first to ensure referential integrity
3. The save operation creates the appropriate link role associations in Polarion's work item linking system
4. On success, the undo stack is cleared and the sheet returns to its normal editable state
**Save errors block further saves**
If an error occurs during save, Powersheet displays an error state. You must resolve the error (or reload the page) before attempting another save. The review mode remains active after a failed save so you can identify and fix problem rows.
You should now see the linked entity displayed in the corresponding multi-item column. To confirm the link was created correctly:
1. **In Powersheet**: Expand the source entity's expansion path to see the linked target entity in the hierarchy
2. **In Polarion**: Open the source work item and check the **Linked Work Items** section -- the target should appear under the configured link role (e.g., `requires`)
3. **Bidirectional check**: Open the target work item in Polarion and verify the back-link appears under the reverse link role
## Constrained Linking
When your data model includes constraints (such as `applyCurrentDocumentTo`), Powersheet automatically scopes new links to the current document context. This means:
* The entity picker only shows entities from matching document types
* New entities created during the linking workflow inherit the document scope
* Multi-level constraints filter through the entire expansion path
For example, in an RTM configuration where `SystemRequirement` entities are constrained to a specific document type, the picker when linking from a `UserNeed` only shows system requirements from the correct requirements document.
**Verify in application**
Constraint behavior depends on your specific data model and project configuration. Test linking with constraints in a sandbox project before deploying to production.
## See Also
* [Configure a Relationship](/powersheet/guides/data-model/configure-relationship) -- set up the data model relationship that enables linking
* [Create Bidirectional Links](/powersheet/guides/data-model/create-bidirectional-links) -- configure `direct` and `back` navigation properties
* [Configure Many-to-Many Relationships](/powersheet/guides/data-model/configure-many-to-many) -- advanced many-to-many relationship setup
* [Configure Multi-Item Column](/powersheet/guides/sheet-configuration/configure-multi-item-column) -- set up the column that displays linked entities
* [Handle Validation Errors](/powersheet/guides/save-operations/handle-validation-errors) -- troubleshoot errors during save operations
* [Configure Constraints](/powersheet/guides/data-model/configure-constraints) -- document-scoping and picker filtering rules
# Create a Work Item
Source: https://learn.nextedy.com/powersheet/guides/save-operations/create-work-item
Add new work items directly from the Nextedy POWERSHEET sheet view, with automatic document routing and constraint-driven placement.
## Prerequisites
* A Powersheet document open in Siemens Polarion ALM with a valid sheet configuration and data model
* The entity type you want to create must be defined in the data model with a valid `polarionType` mapping
* Your user account must have create permissions (`isCreatable` enabled) for the target work item type
Click the **Add** button ( ) in the sheet toolbar. A new empty row appears in the sheet with default values from the entity factory configuration.
**Row placement in hierarchical sheets**
The new row is created at the current hierarchy level. If you have a multi-level sheet (for example, `UserNeed` > `SystemRequirement` > `DesignRequirement`), the row is added at the level corresponding to the selected cell's entity type.
Click into the new row and type directly into cells to populate field values. The cell that receives initial focus is determined by the `hasFocus` property in your sheet configuration:
```yaml theme={null}
columns:
title:
title: Title
width: 200
hasFocus: true
severity:
title: Severity
width: 100
```
Press **Enter** to commit the cell edit. Fields configured as `isReadOnly: true` or with `updatable: false` in the data model cannot be edited.
**Custom field types**
Powersheet supports saving several custom field types including integer fields (`c_intField`), floating-point fields (`c_floatField`), and currency fields (`c_currencyField`). Each field type tracks both the current value and the original value for change detection.
When your data model defines constraints on the entity type, new work items are automatically routed to the correct Polarion document. The constraint system scopes new entities to the current document context automatically.
For example, a data model that routes `SystemRequirement` items to a specific document:
```yaml theme={null}
domainModelTypes:
SystemRequirement:
polarionType: sys_req
constraints:
create:
document:
moduleFolder: /System Requirements
moduleName: SRS
type: sys_req_spec
```
When a user creates a `SystemRequirement`, it is automatically placed in the document matching the specified folder, name, and type.
**Context-aware routing**
The constraint system can route new items based on the source entity's document context. This is useful when the same entity type should go to different documents depending on where it was created from within the expansion path.
### Constrained Picker Values
In a multi-level sheet, constraints can also filter the available values in picker columns. For example, when creating a `UserNeed` and selecting a linked `SystemRequirement`, the picker shows only system requirements from the matching document type.
| Constraint Type | Behavior |
| ---------------- | ----------------------------------------------------------------- |
| Document routing | New items are placed in the specified Polarion document |
| Picker filtering | Dropdown values are filtered based on document type and component |
| Multi-property | Combines document type and component constraints |
Before saving, use **review mode** to inspect your pending changes:
1. The **Review** toggle appears automatically in the toolbar when any changes exist
2. Click it to filter the sheet to show only rows with pending changes
3. New rows are indicated with the **Added** state marker on the row header
4. Use the review mode dropdown menu to filter by change type
| Review Filter | What It Shows |
| ------------- | ------------------------------------------------ |
| **Added** | Newly created rows not yet persisted to Polarion |
| **Modified** | Existing rows with changed cell values |
| **Problems** | Rows with validation errors that block saving |
The row count display shows the format **N/M rows** where N is the number of visible filtered rows and M is the total row count.
**Empty rows do not count as changes**
Adding a row without entering any data does not enable the **Save** button. Only actual data changes (typing values into cells) mark the row as dirty. If you add a row and then undo, the sheet returns to its original clean state.
Click the **Save** button (💾) in the toolbar. During the save operation:
1. The sheet checks for any active error state -- if errors exist, you see an alert message and the save is blocked
2. The sheet temporarily enters read-only mode to prevent concurrent edits
3. All pending entity changes (with `Added` state) are validated and sent to the server
4. Server-generated identifiers (such as `objectId`) are assigned to new items via key mapping
5. The undo stack is cleared on successful save
6. Original read-only state and permissions (`isCreatable`, `isDeletable`, `isUpdatable`) are restored
**Error state blocks save**
If the sheet is in an error state, the save operation is blocked with the message: "There is an error in the app and save should not happen. Please, reload the browser." Resolve any errors or reload the page before attempting to save again.
If you make a mistake before saving, use the **Undo** () and **Redo** () buttons in the toolbar:
* **Undo** reverses the last operation (add, remove, or edit) and restores the previous sheet state including row position and content
* **Redo** re-applies a previously undone operation
* Both operations preserve selection state, including multi-row selections
* Undoing all operations disables both the **Undo** and **Save** buttons
**Multi-row operations**
Select multiple rows using **Shift+Click** (click the first row, hold Shift, click the last row). You can then remove all selected rows at once with the **Remove** button. This operation is fully undoable.
You should now see the new work item in the sheet with a server-assigned ID. The row header no longer shows the **Added** state indicator, and the **Save** button is disabled (indicating no pending changes remain).
**Verify in application**
Open the corresponding Polarion LiveDoc to confirm the work item appears in the expected document location with the correct work item type. If document routing constraints are configured, verify the item was placed in the correct module folder.
## Troubleshooting
| Symptom | Cause | Resolution |
| ------------------------------- | ---------------------------------------- | ------------------------------------------------------ |
| **Save** button stays disabled | No actual data entered in the new row | Type values into at least one cell |
| Save blocked with error alert | Sheet is in an error state | Reload the browser and retry |
| Row appears but picker is empty | Constraint filtering too restrictive | Check `constraints` configuration in data model |
| Wrong document placement | Missing or incorrect `create` constraint | Verify `moduleFolder`, `moduleName`, and `type` values |
## See Also
* [Update a Work Item](/powersheet/guides/save-operations/update-work-item) -- modify existing work item fields
* [Create a Link](/powersheet/guides/save-operations/create-link) -- link the new work item to other entities
* [Handle Validation Errors](/powersheet/guides/save-operations/handle-validation-errors) -- resolve errors during save
* [Configure Constraints](/powersheet/guides/data-model/configure-constraints) -- set up document routing constraints
* [Create an Entity Type](/powersheet/guides/data-model/create-entity-type) -- configure `polarionType` mappings
* [Set Entity Permissions](/powersheet/guides/data-model/set-permissions) -- control `readable` and `updatable` properties
# Handle Validation Errors
Source: https://learn.nextedy.com/powersheet/guides/save-operations/handle-validation-errors
This guide shows you how to identify, review, and resolve validation errors that occur during save operations in Nextedy POWERSHEET for Siemens Polarion ALM.
## Prerequisites
* A powersheet document with pending changes that you are attempting to save
* Familiarity with the review mode toolbar controls
When a save operation encounters validation errors, Powersheet collects all errors across all entities and presents them as a single aggregated error message. The sheet does not lose your changes -- all pending modifications remain in place for correction.
Errors fall into two categories:
| Error Type | Behavior | Recovery |
| ----------------------- | ------------------------------------------------------- | --------------------------- |
| Entity validation error | Collected per entity, reported after all saves complete | Fix the data and retry save |
| Application error | Save is interrupted immediately | Reload the browser |
**Application-level errors halt the save**
If an application-level error occurs (such as a server timeout or connectivity issue), the save process stops immediately. Entity validation errors, by contrast, are collected for all entities and reported together after the save cycle completes.
After a failed save, the review mode remains active. Use it to locate problematic rows:
1. Click the **Review** toggle if it is not already active
2. Open the review filter menu and select **Problems** to filter to rows with validation errors
3. The row count display shows how many rows have issues (e.g., "2/45 rows")
Rows with validation errors display both the modified and error visual indicators on the row header. The review filter menu shows the count of problem rows (e.g., "Problem rows: 2").
Individual cells contributing to errors may also show a modified state indicator. Check the following common causes:
* **Missing required fields** -- a required Polarion field has no value
* **Invalid enum value** -- the selected value is not in the allowed options for the work item type
* **Constraint violations** -- the entity does not match the document routing constraints
* **Workflow state conflicts** -- attempting a workflow transition on an unsaved entity
**Save unsaved entities before workflow transitions**
Workflow transitions require the entity to be persisted first. If you attempt a transition on a newly created (unsaved) work item, you will receive a validation error. Save the entity first, then apply the workflow transition.
Edit the problematic cells directly in the sheet:
1. Click into the cell with the error
2. Enter a valid value
3. The error indicator should clear when you commit the edit
**Use undo to revert problematic changes**
If you cannot determine the correct value, use `Ctrl+Z` to undo the change and restore the original value. You can then re-attempt the edit with the correct data.
After correcting all validation errors, click **Save** again. Entities are saved in topologically sorted order (parents before dependents) to prevent foreign key violations.
**Error state save guard**
If the sheet entered an error state during the previous save attempt, you may see a blocking message: "There is an error in the app and save should not happen. Please, reload the browser." In this case, reload the page. Your unsaved changes may need to be re-entered.
You should now see all rows saved successfully. The review mode toggle disappears when no pending changes remain. The **Save** button is disabled, and row headers show no modification or error indicators.
## See Also
* [Create a Work Item](/powersheet/guides/save-operations/create-work-item) -- understand the creation flow and constraints
* [Update a Work Item](/powersheet/guides/save-operations/update-work-item) -- edit existing fields with change tracking
* [Resolve Validation Errors](/powersheet/guides/troubleshooting/resolve-validation-errors) -- troubleshoot persistent validation problems
* [Configure Constraints](/powersheet/guides/data-model/configure-constraints) -- adjust constraints that may cause routing errors
# Save Operations Guides
Source: https://learn.nextedy.com/powersheet/guides/save-operations/index
Nextedy POWERSHEET provides inline editing with full save operation support, allowing users to create, update, and link work items directly from the sheet view in Siemens Polarion ALM.
Add new work items directly from the sheet with automatic document routing and constraint enforcement.
Edit existing work item fields inline with change tracking, undo/redo, and review mode.
Establish relationships between work items using linking mode with visual target selection.
Identify, review, and resolve validation errors before and after save operations.
**Save workflow**
Powersheet tracks all pending changes locally until you explicitly save. Use the **review mode** to inspect added, modified, and deleted rows before committing changes to the server. The save operation is atomic -- either all changes succeed or none are persisted.
## Related Guides
* [Configure Constraints](/powersheet/guides/data-model/configure-constraints) -- control where new work items can be created
* [Configure a Relationship](/powersheet/guides/data-model/configure-relationship) -- define link roles for entity linking
* [Resolve Validation Errors](/powersheet/guides/troubleshooting/resolve-validation-errors) -- troubleshoot persistent save failures
# Update a Work Item
Source: https://learn.nextedy.com/powersheet/guides/save-operations/update-work-item
This guide shows you how to edit existing work item fields inline in the Nextedy POWERSHEET sheet view, track your changes, and save them back to Siemens Polarion ALM.
## Prerequisites
* A powersheet document with loaded data
* Your user account must have update permissions for the target fields
* The fields you want to edit must have `updatable: true` in the data model (this is **not** the default -- it must be set explicitly)
Click on a cell to select it. Double-click or start typing to enter edit mode. Depending on the field type, you will see one of these editors:
To inspect a row in Polarion's native work item form, use the **Open in form** action ( ) on the work items tree. The Polarion form opens in a new tab, leaving your unsaved changes in the sheet intact.
| Field Type | Editor Behavior |
| ------------------------------- | ----------------------------------- |
| Text / String | Inline text input |
| Enum | Dropdown with available options |
| Integer / Float / Currency | Numeric input |
| Reference (navigation property) | Picker with search |
| Read-only / Calculated | No editing allowed (cursor changes) |
**Read-only fields**
Fields marked with `updatable: false` in the data model, system fields like `id` and `outlineNumber`, and server-rendered properties cannot be edited. The cell will not enter edit mode when clicked.
Type the new value and press `Enter` to commit the edit. The cell is marked as modified, and the row header shows a visual change indicator.
For **enum fields**, the dropdown automatically filters available options based on the entity context (project, work item type, and enumeration scope). Select the desired option from the list.
For **reference fields** (navigation properties), a picker opens where you can search for related entities by title or ID.
```yaml theme={null}
# Example: Making severity editable in the data model
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
severity:
updatable: true
readable: true
```
If you make a mistake, use undo and redo to navigate your edit history:
* **Undo**: `Ctrl+Z` -- reverts the last change
* **Redo**: `Ctrl+Y` -- re-applies the last undone change
The undo stack tracks all operations including cell edits, row additions, and row deletions. Undoing all changes disables the **Save** button.
Enable **review mode** by clicking the review toggle in the toolbar. The sheet filters to display only modified rows. The toolbar shows the count of changed rows (e.g., "Changed rows: 3").
Individual cells that have been modified show a visual indicator, and the row header displays the modification state.
Click **Save** to persist all pending changes. The save operation:
1. Validates all modified entities
2. Saves entities one by one in dependency order
3. Clears the undo stack on success
4. Restores the sheet to its normal editing state
**Save blocked on error state**
If the sheet has an active error state, the save is blocked with a message: "There is an error in the app and save should not happen. Please, reload the browser." Reload the page and try again.
You should now see the updated values reflected in the sheet. The row headers no longer show the modified indicator, and the **Save** button is disabled.
**Copy and paste**
You can copy and paste cell values using `Ctrl+C` and `Ctrl+V`. Pasting across different hierarchy levels is not supported -- the sheet will display a warning if you attempt it.
## See Also
* [Create a Work Item](/powersheet/guides/save-operations/create-work-item) -- add new work items to the sheet
* [Handle Validation Errors](/powersheet/guides/save-operations/handle-validation-errors) -- resolve errors that occur during save
* [Set Entity Permissions](/powersheet/guides/data-model/set-permissions) -- control field-level `readable` and `updatable` settings
* [Configure Read-Only Column](/powersheet/guides/sheet-configuration/configure-read-only-column) -- make specific columns non-editable
# Access Polarion Services
Source: https://learn.nextedy.com/powersheet/guides/server-rendering/access-polarion-services
Use Siemens Polarion ALM platform services within Nextedy POWERSHEET server-rendered expressions to query work items, check permissions, and access repository metadata.
## Prerequisites
* A data model with at least one server-rendered property (see [Create a Computed Property](/powersheet/guides/server-rendering/create-computed-property))
* Familiarity with [Velocity template syntax](/powersheet/guides/server-rendering/use-velocity-template)
## Available Platform Services
Powersheet automatically injects the following Polarion services into every server-rendered template evaluation context:
| Variable | Service | Purpose |
| -------------------- | ------------------- | --------------------------------------------------------- |
| `$trackerService` | ITrackerService | Query work items, access project tracker metadata |
| `$txService` | ITransactionService | Transaction management and context |
| `$repositoryService` | IRepositoryService | Project metadata, users, roles, configuration |
| `$securityService` | ISecurityService | Permission checks, user authentication, role-based access |
The `$trackerService` provides access to Polarion's tracker for querying work items and project data:
```yaml theme={null}
properties:
parentProject:
serverRender: "$trackerService.getProjectById($item.projectId).getName()"
readable: true
updatable: false
```
**Performance consideration**
Each call to `$trackerService` methods executes against the Polarion database. Avoid expensive queries like `getDataService().searchInstances()` in templates that render for every row in a large sheet.
The `$repositoryService` provides access to project-level metadata, users, and roles:
```yaml theme={null}
properties:
authorName:
serverRender: "#if($item.author)$repositoryService.getUser($item.author).getName()#else Unknown#end"
readable: true
updatable: false
```
**Cache-friendly patterns**
The service context is cached across all template evaluations within a single query. Methods that return static data (project names, user names) are efficient to call repeatedly.
The `$securityService` enables role-based visibility and permission-aware computed values:
```yaml theme={null}
properties:
accessLevel:
serverRender: "#if($securityService.canReadInstance($wi))Full Access#else Restricted#end"
readable: true
updatable: false
```
Use cases for `$securityService`:
* Show or hide sensitive data based on user role
* Display different labels depending on write permissions
* Create audit-friendly computed fields showing access status
The `$tx` variable provides access to the current transaction, useful for read-only operations that need transactional consistency:
```yaml theme={null}
properties:
txInfo:
serverRender: "#if($tx)In transaction#else No transaction#end"
readable: true
updatable: false
```
**Verify in application**
The exact methods available on each service depend on your Polarion version and API. Consult your Polarion SDK documentation for the complete method reference of ITrackerService, IRepositoryService, ISecurityService, and ITransactionService.
For complex computed properties, combine several services in a single template:
```yaml theme={null}
properties:
auditField:
serverRender: "#set($user = $repositoryService.getUser($item.author))#set($project = $trackerService.getProjectById($item.projectId))$user.getName() @ $project.getName()"
readable: true
updatable: false
```
If a service call fails, the template engine returns `#SERVER_RENDER_ERROR`. Protect against common failures:
```yaml theme={null}
properties:
safeProject:
serverRender: "#set($proj = $trackerService.getProjectById($item.projectId))#if($proj)$proj.getName()#else Unknown Project#end"
readable: true
updatable: false
```
**Error marker in cells**
If you see `#SERVER_RENDER_ERROR` in the sheet, the Velocity template failed. Check the Polarion server logs for the specific exception -- common causes include null pointer access, invalid method calls, or missing resources.
## Verify
After adding service-based computed properties:
1. Open the powersheet document in Polarion
2. You should now see computed values populated from platform services
3. Test with different user accounts to verify permission-aware fields display correctly
4. If any cells show `#SERVER_RENDER_ERROR`, consult the [Debug Template Errors](/powersheet/guides/server-rendering/debug-template-errors) guide
## See Also
* [Create a Computed Property](/powersheet/guides/server-rendering/create-computed-property) -- defining server-rendered properties
* [Use Velocity Templates](/powersheet/guides/server-rendering/use-velocity-template) -- template syntax and patterns
* [Debug Template Errors](/powersheet/guides/server-rendering/debug-template-errors) -- troubleshooting rendering failures
* [Set Entity Permissions](/powersheet/guides/data-model/set-permissions) -- entity-level access control
# Create a Computed Property
Source: https://learn.nextedy.com/powersheet/guides/server-rendering/create-computed-property
Define a property in your Nextedy POWERSHEET data model or sheet configuration that computes its value dynamically at runtime, using either server-side Velocity templates or client-side JavaScript expressions.
## Prerequisites
* A working data model with at least one entity type
* A sheet configuration displaying entity properties
* Access to the project SVN repository to edit YAML configuration files
## Choose Your Approach
Powersheet supports two mechanisms for computed properties, each suited to different use cases:
| Approach | Syntax | Runs On | Defined In | Best For |
| ---------------------------- | ----------------------------------------------------------- | ------------------- | ------------------------ | ---------------------------------------------------------------------- |
| **Server-rendered property** | `serverRender: "$item.id"` | Server (Velocity) | Data-model YAML | Accessing Polarion services, secure calculations, cross-entity queries |
| **Dynamic value expression** | `value: "() => context.entity.count * context.entity.rate"` | Client (JavaScript) | Sheet-configuration YAML | UI-driven calculations, formatting, parameter-based filtering |
**Rule of thumb**
The two mechanisms live in different files. `serverRender` must be defined in the **data model** YAML (it needs Polarion platform access); `value` / `() =>` expressions must be defined in the **sheet configuration** YAML (they run client-side and need UI reactivity). Putting either in the wrong file has no effect.
***
## Option A: Server-Rendered Property (Velocity)
Use this approach when you need to compute a value on the server using Polarion platform services and work item data.
### Step 1: Add the Property to Your Data Model
Open your data model YAML file and add a property with a `serverRender` pattern to the target entity type. The value is a Velocity template expression that the server evaluates for each work item:
```yaml theme={null}
domainModelTypes:
SystemRequirement:
polarionType: systemRequirement
properties:
title:
type: string
computedLabel:
serverRender: "$item.id - $item.title"
```
The `serverRender` value is a standard Velocity template string. The server evaluates it in a context that includes the current work item and Polarion platform services.
### Step 2: Use Context Variables in Your Template
Server-rendered properties have access to these context variables during evaluation:
| Variable | Type | Description | Availability |
| ---------- | ----------------- | -------------------------------------------------------------------------------------- | ------------------------ |
| `$item` | ModelObject | Work item model object (`.id`, `.title`, `.status`, `.author`, `.created`, `.updated`) | All work items |
| `$wi` | IWorkItem | Low-level Polarion work item API for operations not available on `$item` | Work item entities only |
| `$module` | IModule | Current LiveDoc (`.moduleFolder`, `.moduleName`, `.space`) | Document-scoped entities |
| `$context` | PowersheetContext | Powersheet context (project, document scope, query helpers) | Always |
| `$tx` | Transaction | Current transaction for read-only operations | Always |
In addition, the Polarion platform services (`$trackerService`, `$txService`, `$repositoryService`, `$securityService`) are automatically injected and cached for performance. For the full list and what each service is for, see [Platform Services in the Velocity Templates reference](/powersheet/reference/server-rendering/velocity-templates#platform-services).
**Example** -- concatenate ID and title with a status badge:
```yaml theme={null}
properties:
statusLabel:
serverRender: "$item.id [$item.status.id] $item.title"
```
**Example** -- conditional label using Velocity directives:
```yaml theme={null}
properties:
riskLabel:
serverRender: "#if($item.riskScore > 5)High Risk#{else}Low Risk#end"
readable: true
updatable: false
```
**Use Velocity directives for logic**
Velocity templates support `#if`, `#else`, `#foreach`, `#set`, and other directives. Use them to create dynamic labels, computed statuses, or aggregated displays.
**Example** -- count directly linked work items using `$wi` (the low-level work item API, for methods not available on `$item`):
```yaml theme={null}
properties:
linkedCount:
serverRender: "#set($links = $wi.getLinkedWorkItemsStructsDirect())$links.size()"
```
### Step 3: Mark the Property as Read-Only
Server-rendered properties are automatically treated as non-editable by the rendering mechanism. You should explicitly set `readable: true` and `updatable: false` in your property definition to make the intent clear:
```yaml theme={null}
domainModelTypes:
SystemRequirement:
polarionType: systemRequirement
properties:
computedLabel:
serverRender: "$item.id - $item.title"
readable: true
updatable: false
```
**Server-rendered properties are always read-only**
A property with `serverRender` is always read-only -- even if you set `updatable: true`, the rendering mechanism overrides it and prevents client-side edits, since the value is always recomputed from the template. Setting `updatable: false` explicitly just avoids confusing the column display. See [Configure Read-Only Column](/powersheet/guides/sheet-configuration/configure-read-only-column#how-read-only-resolution-works) for how this interacts with the other read-only resolution rules.
### Step 4: Display the Property in Your Sheet
Add a column in your sheet configuration that binds to the computed property:
```yaml theme={null}
columns:
computedLabel:
title: "Requirement Label"
width: 250
```
The column displays the server-computed value. Since the property is server-rendered, the value is recalculated on each data load and reflects the latest work item state.
### Step 5: Use Custom Field Data in Templates
`customFieldName` maps a data-model property to a Polarion **custom field** by its field ID, so the property reads and writes that custom field's value. Once mapped, you can reference the property within a Velocity template:
```yaml theme={null}
domainModelTypes:
SystemRequirement:
polarionType: systemRequirement
properties:
riskScore:
customFieldName: risk_score
riskSummary:
serverRender: "#if($item.riskScore > 5)HIGH: Score $item.riskScore#{else}OK#end"
readable: true
updatable: false
```
### Step 6: Alias Field Names with serverName
`serverName` aliases a property to a different underlying Polarion field ID: the property keeps its client-facing name in the sheet while reading and writing the field named by `serverName` on the server. Use it when the Polarion field name differs from the name you want to expose:
```yaml theme={null}
properties:
friendlyName:
serverName: internalPolarionFieldId
type: string
```
This lets you expose a user-friendly name in the sheet while mapping to the actual Polarion field behind the scenes.
***
## Option B: Dynamic Value Expression (JavaScript)
Use this approach for client-side calculations in your sheet configuration. Dynamic value expressions use JavaScript arrow function syntax and are evaluated in the browser.
### Step 1: Add a Computed Column
To compute a value from other properties on the current entity, use the `value` property in your column definition:
```yaml theme={null}
columns:
total:
title: "Total"
value: "() => context.entity.count * context.entity.rate"
```
On a column bound to a real property, `value` computes a result and **saves it back** to that property. If you only need to change how an existing value is displayed, use `render` instead. If you want a computed value that is never stored at all, prefix the binding key with `$` -- the column is then unbound and leaves the work item untouched. See [Add a Computed Column](/powersheet/guides/sheet-configuration/add-computed-column).
### Step 2: Understand Context Availability
Not all context properties are available in every location. The available properties depend on where the expression is used. In the table below, **✅** means the property is available at that location and **`--`** means it is not available:
| Usage Location | `.user` | `.sources` | `.document` | `.entity` | `.value` | `.source` | `.row` |
| ---------------------------- | ------- | ---------- | ----------- | --------- | -------- | --------- | ------ |
| `where` | ✅ | ✅ | ✅ | -- | -- | -- | -- |
| `entityFactory` | ✅ | ✅ | -- | -- | -- | -- | -- |
| `value` (bound column) | ✅ | ✅ | -- | ✅ | -- | -- | -- |
| `value` (unbound `$` column) | ✅ | ✅ | -- | ✅ | -- | ✅ | ✅ |
| `render` / `renderers` | -- | -- | -- | ✅ | ✅ | -- | -- |
| `formatter` | -- | -- | ✅ | ✅ | ✅ | -- | -- |
| `display` | -- | -- | -- | ✅ | ✅ | ✅ | -- |
`context.value` is the value already in the cell, so it is `undefined` inside a `value` expression -- read what you need from `context.entity`.
`context.item` is deprecated because it's ambiguous -- in some cell expressions it's the entity, in others the whole row. Use `context.entity` or `context.row` instead; each always means exactly one thing.
### Step 3: Use Dynamic Expressions in Different Locations
**Filter a query by current document:**
```yaml theme={null}
sources:
- id: opportunities
query:
from: Opportunity
where:
Module:
"==": "() => context.document.moduleName"
```
**Render custom HTML in a cell:**
```yaml theme={null}
renderers:
linkedItems: "() => context.value.map((item) => `${item.name} `).join(', ')"
```
**Display a property from a linked entity:**
```yaml theme={null}
columns:
systemRequirement.document:
display: "() => context.document.title"
```
**Set initial values for new items from a URL parameter:**
```yaml theme={null}
entityFactory:
Client: "() => context.parameters.client"
```
**Dates require ISO format**
When using dates in dynamic expressions, always convert to ISO string format: `"() => new Date().toISOString()"`. The resulting value must match the expected data type format.
### Step 4: Add Conditional Formatting
Formatter expressions use a simplified syntax without the `() =>` prefix. The expression is evaluated as a boolean condition directly:
```yaml theme={null}
formatters:
criticalHighlight:
expression: "context.entity.Probability <= 99"
style: warningStyle
```
**Formatter syntax difference**
Unlike other dynamic expressions, formatter `expression` values do **not** use the `() =>` prefix. They are evaluated as direct boolean conditions.
***
## Debugging Computed Properties
### Server-Rendered Properties
If a server-rendered property returns `#SERVER_RENDER_ERROR`, the Velocity template failed to evaluate. Common causes:
| Error Type | Cause | Fix |
| --------------------------- | -------------------------------- | ------------------------------------------------------------------------- |
| `ParseErrorException` | Invalid Velocity syntax | Check template for unclosed directives or typos |
| `MethodInvocationException` | Called method threw an exception | Verify the method exists on the target object |
| `ResourceNotFoundException` | Referenced resource not found | Check that `$item`, `$module`, or `$wi` is available for your entity type |
**Check server logs for details**
The `#SERVER_RENDER_ERROR` marker in the cell means the template failed. Check the Polarion server logs for the full stack trace, which includes the specific exception type and the failing template expression.
#### Column renders the literal template text, or does not appear at all
A computed column that shows the raw template (e.g. `$item.id - $item.title`) verbatim instead of the evaluated value -- or that does not appear in the sheet at all -- usually points to one of the following. Work through them in order:
1. **Install-time cache not cleared.** This is the most common cause. The `serverRender` annotation is only picked up after the install-time caches are cleared and the server is restarted. Confirm that **both** `[POLARION_DATA]/workspace/.config` **and** `[POLARION_DATA]/workspace/.metadata` were deleted and Polarion was fully restarted -- a stale `.metadata` cache in particular lets the plugin load while server-side rendering silently fails to engage. See [Installing Powersheet, Step 1](/powersheet/getting-started/installation) for the exact procedure.
2. **`polarionType` mismatch.** Confirm the entity's `polarionType` matches the real Polarion work-item type ID **exactly** -- the match is case-sensitive. If it does not match a real type, the property is never bound to live work items and nothing is rendered.
3. **Document caches its column layout.** An existing Powersheet document caches the columns it was opened with, so a newly added column may not appear until you fully close and re-open (or reload) the document -- the in-sheet refresh action alone is not always enough.
**Diagnostics, not a guarantee**
These are diagnostic steps for the most frequent causes. If a column still renders its literal template after working through all three, capture the server logs and the exact property and column YAML, then contact [Nextedy support](https://support.nextedy.com/support/tickets/new).
### Dynamic Value Expressions
Client-side expressions fail silently if the context property is not available. Verify:
1. You are using the `() =>` prefix (not `$context`, which is for model constraints only)
2. The context property is available at the location where you are using it (see the availability table above)
3. Property names match your data model exactly (case-sensitive)
***
## Verification
After saving your YAML configuration and reloading the sheet:
1. **Server-rendered property**: You should now see the computed value in the column. Edit the underlying work item fields and reload -- the computed value updates to reflect the changes
2. **Computed column**: You should now see the calculated value appear. For a column bound to a real property, verify the value is persisted by checking the work item in Polarion; for a `$`-prefixed column, verify the work item is left untouched
3. **Render/display**: You should now see formatted output in the cell without any data modification
If you see `#SERVER_RENDER_ERROR` in a column, refer to [Debug Template Errors](/powersheet/guides/server-rendering/debug-template-errors) for troubleshooting steps.
## See Also
* [Use Velocity Templates](/powersheet/guides/server-rendering/use-velocity-template) -- write and test Velocity template expressions for server rendering
* [Access Polarion Services](/powersheet/guides/server-rendering/access-polarion-services) -- use platform services like `$trackerService` in your templates
* [Debug Template Errors](/powersheet/guides/server-rendering/debug-template-errors) -- diagnose and fix server rendering failures
* [Configure Dynamic Expressions](/powersheet/guides/sheet-configuration/configure-dynamic-expressions) -- full guide to `() =>` expressions in sheet configuration
* [Add a Computed Column](/powersheet/guides/sheet-configuration/add-computed-column) -- client-side computed columns in depth, stored and display-only
* [Add a Custom Property](/powersheet/guides/data-model/add-custom-property) -- add standard (non-computed) properties to entity types
* [Configure a Formatter](/powersheet/guides/sheet-configuration/configure-formatter) -- apply conditional styling with formatter expressions
# Debug Template Errors
Source: https://learn.nextedy.com/powersheet/guides/server-rendering/debug-template-errors
Identify and fix Nextedy POWERSHEET server-rendered template failures by recognizing error markers, checking server logs, and applying systematic debugging techniques on Siemens Polarion ALM.
## Prerequisites
* A powersheet document with server-rendered properties configured
* Access to Polarion server logs
* Familiarity with [Velocity template syntax](/powersheet/guides/server-rendering/use-velocity-template)
When a Velocity template evaluation fails, Powersheet displays `#SERVER_RENDER_ERROR` in the affected cell instead of the computed value. This is a constant error marker that indicates a template configuration problem.
The three most common exception types appear in the Polarion server logs when a template fails:
| Exception Type | Cause | Example |
| ------------------------- | --------------------------------- | --------------------------------------- |
| ParseErrorException | Invalid Velocity syntax | Missing `#end`, unbalanced quotes |
| MethodInvocationException | Method call on null or wrong type | `$item.getTitle()` when `$item` is null |
| ResourceNotFoundException | Referenced resource not found | Missing include or macro |
Open the Polarion server log file and search for these exception names to find the exact error message and line number.
Common Velocity syntax errors that cause ParseErrorException:
```yaml theme={null}
# WRONG: Missing #end
serverRender: "#if($item.title)$item.title"
# CORRECT: Properly closed block
serverRender: "#if($item.title)$item.title#end"
```
```yaml theme={null}
# WRONG: Unescaped special characters
serverRender: "$item.title & $item.status"
# CORRECT: Escaped or avoided
serverRender: "$item.title and $item.status"
```
**Single-line templates**
Server-rendered expressions are typically single-line strings in YAML. Multi-line Velocity logic must be compressed into one line or use Velocity's inline syntax.
MethodInvocationException commonly occurs when accessing properties on null objects. Always guard against nulls:
```yaml theme={null}
# WRONG: Assumes $module is always available
serverRender: "$module.moduleName"
# CORRECT: Null check first
serverRender: "#if($module)$module.moduleName#else N/A#end"
```
Key variables that can be null:
* `$module` -- null when entity is not document-scoped
* `$wi` -- null when entity is not a work item
* Custom field values -- null when not set on the work item
**Defensive template pattern**
Always wrap service calls and property access in `#if` checks: `#if($var && $var.method())$var.method()#else default#end`
When debugging a complex template, simplify to isolate the problem:
1. Replace your template with a constant: `serverRender: "test"` -- verify rendering works at all
2. Add one variable: `serverRender: "$item.id"` -- verify context is available
3. Add the failing expression piece by piece until the error reappears
Ensure the property hosting the server-rendered expression is correctly configured:
```yaml theme={null}
properties:
computedField:
serverRender: "$item.title"
readable: true # Must be true to display
updatable: false # Always false for server-rendered
```
**Verify in application**
Some Polarion service methods may behave differently across versions. If a method call in your template causes errors, verify the method signature against your Polarion installation's API documentation.
## Common Error Patterns
| Symptom | Likely Cause | Fix |
| ------------------------------- | ---------------------------- | ----------------------------------------- |
| All rows show error | Template syntax error | Check for missing `#end` or bad directive |
| Some rows show error | Null data on specific items | Add null checks for optional fields |
| Error after Polarion upgrade | API change in service method | Update method calls to new API |
| Error on document entities only | `$wi` used on non-work-item | Use `$item` instead or add type check |
## Verify
After fixing template errors:
1. Open the powersheet document in Polarion
2. You should now see computed values in all cells that previously showed `#SERVER_RENDER_ERROR`
3. Test with work items that have empty or null fields to confirm null checks work
4. Verify that the Polarion server logs no longer show template-related exceptions
## See Also
* [Create a Computed Property](/powersheet/guides/server-rendering/create-computed-property) -- setting up server-rendered properties
* [Use Velocity Templates](/powersheet/guides/server-rendering/use-velocity-template) -- template syntax reference
* [Access Polarion Services](/powersheet/guides/server-rendering/access-polarion-services) -- platform service usage
* [Troubleshooting Guides](/powersheet/guides/troubleshooting/index) -- general troubleshooting resources
# Server Rendering Guides
Source: https://learn.nextedy.com/powersheet/guides/server-rendering/index
Nextedy POWERSHEET provides a server-side rendering engine that evaluates Velocity templates to produce computed property values at query time.
Add a server-rendered property to your data model that computes its value dynamically from work item data, related entities, or platform services.
Write Velocity template expressions that access work item fields, document context, and the full set of context variables available during rendering.
Call Polarion platform services such as `$trackerService`, `$repositoryService`, and `$securityService` from within your Velocity templates for advanced queries and permission checks.
Diagnose and resolve common rendering failures including parse errors, missing variables, method invocation exceptions, and the `#SERVER_RENDER_ERROR` marker.
## How Server Rendering Works
The following diagram shows how a server-rendered property flows from configuration to display.
```
Data Model YAML Server API Sheet
+-----------------------+ +---------------------+ +------------------+
| entity: Hazard | | 1. Parse YAML | | |
| properties: | ---> | 2. Detect | --> | Rendered value |
| riskLevel: | | serverRender | | shown in cell |
| serverRender: ... | | 3. Build Velocity | | |
+-----------------------+ | context ($item, | +------------------+
| $wi, $module, |
| $context, $tx) |
| 4. Evaluate template |
| 5. Return result |
+---------------------+
```
When a property includes a `serverRender` definition, the server API evaluates the Velocity template for each entity row. The template receives a pre-populated context containing the current work item, document, transaction, and injected Polarion services. The evaluated result is returned as the property value and displayed in the sheet column.
**When to use server rendering**
Server-rendered properties are best suited for values that cannot be expressed as a simple field binding:
* **Cross-entity lookups** -- aggregate or reference data from linked work items
* **Conditional formatting** -- compute display strings based on multiple field values
* **Platform queries** -- run Lucene queries via `$trackerService` to count or filter related items
* **Permission-aware values** -- use `$securityService` to vary output by user role
For straightforward field display or client-side calculations, use standard column bindings or the `value` expression in your [sheet configuration](/powersheet/guides/sheet-configuration/index) instead.
| Context Variable | Type | Description |
| -------------------- | ------------------ | ----------------------------------------------------------------- |
| `$item` | ModelObject | Current work item with access to all properties |
| `$wi` | IWorkItem | Low-level Polarion work item API (work items only) |
| `$module` | IModule | Current LiveDoc document context (null for non-document entities) |
| `$context` | IDatabridgeContext | Server API context with project and query capabilities |
| `$tx` | Transaction | Current transaction for scoped read operations |
| `$trackerService` | ITrackerService | Query work items, run Lucene searches, access tracker metadata |
| `$repositoryService` | IRepositoryService | Access project metadata, users, and repository configuration |
| `$securityService` | ISecurityService | Check permissions and enforce role-based visibility |
## Related Resources
* **[Server Rendering Reference](/powersheet/reference/server-rendering/index)** -- complete property and context variable reference
* **[Use Velocity Templates](/powersheet/guides/server-rendering/use-velocity-template)** -- step-by-step guide to writing your first template
* **[Configure Dynamic Expressions](/powersheet/guides/sheet-configuration/configure-dynamic-expressions)** -- client-side `() =>` expressions as an alternative to server rendering
# Use Velocity Templates
Source: https://learn.nextedy.com/powersheet/guides/server-rendering/use-velocity-template
Write Velocity template expressions for Nextedy POWERSHEET server-rendered properties to compute dynamic values from work item data and Siemens Polarion ALM platform services.
## Prerequisites
* A data model with a server-rendered property (see [Create a Computed Property](/powersheet/guides/server-rendering/create-computed-property))
* Basic understanding of Apache Velocity template syntax
The `$item` variable provides access to the work item model object. Use it to read standard and custom field values:
```velocity theme={null}
$item.title
$item.status
$item.author
$item.created
$item.updated
```
Example `serverRender` expression that combines fields:
```yaml theme={null}
properties:
summary:
serverRender: "$item.id: $item.title ($item.status)"
readable: true
updatable: false
```
Velocity supports `#if`, `#elseif`, `#else`, and `#end` directives for conditional rendering:
```yaml theme={null}
properties:
priorityLabel:
serverRender: "#if($item.priority == 'critical')CRITICAL#elseif($item.priority == 'high')High#else Normal#end"
readable: true
updatable: false
```
| Directive | Purpose |
| ----------------------- | ------------------------ |
| `#if(condition)` | Start conditional block |
| `#elseif(condition)` | Alternative condition |
| `#else` | Default fallback |
| `#end` | Close block |
| `#foreach($x in $list)` | Iterate over collections |
| `#set($var = value)` | Assign a variable |
When a work item belongs to a LiveDoc, the `$module` variable provides document-level properties:
```yaml theme={null}
properties:
docContext:
serverRender: "$module.moduleFolder/$module.moduleName"
readable: true
updatable: false
```
**\$module is null for non-document entities**
If the entity is not associated with a document, `$module` will be null. Always add a null check: `#if($module)$module.moduleName#else N/A#end`
The `$wi` variable exposes the Polarion work item API for operations not available on `$item`:
```yaml theme={null}
properties:
linkedCount:
serverRender: "$wi.getLinkedWorkItemsStructsDirect().size()"
readable: true
updatable: false
```
**\$wi availability**
The `$wi` variable is only available for work item entities. For other entity types (documents, chapters), use `$item` or `$module` instead.
Server-rendered templates have access to several Polarion platform services:
```yaml theme={null}
properties:
projectName:
serverRender: "$trackerService.getProjectById($item.projectId).getName()"
readable: true
updatable: false
```
Available service variables:
| Variable | Service | Common Uses |
| -------------------- | ----------------- | --------------------------------- |
| `$trackerService` | Work item tracker | Query work items, access projects |
| `$txService` | Transaction | Transaction context |
| `$repositoryService` | Repository | Project metadata, users, roles |
| `$securityService` | Security | Permission checks, user auth |
See [Access Polarion Services](/powersheet/guides/server-rendering/access-polarion-services) for detailed examples of each service.
When a Velocity template fails, Powersheet returns the error marker `#SERVER_RENDER_ERROR` in the cell. Protect against common failures with defensive coding:
```yaml theme={null}
properties:
safeTitle:
serverRender: "#if($item && $item.title)$item.title#else (untitled)#end"
readable: true
updatable: false
```
**Template error marker**
If you see `#SERVER_RENDER_ERROR` in a column cell, the template failed due to a parse error, method invocation error, or missing resource. Check the Polarion server logs for the specific exception type.
## Template Patterns Reference
**String concatenation:**
```velocity theme={null}
$item.id - $item.title
```
**Null-safe access:**
```velocity theme={null}
#if($item.severity)$item.severity#else Unset#end
```
**Collection iteration:**
```velocity theme={null}
#foreach($link in $wi.getLinkedWorkItemsStructsDirect())$link.getLinkedItem().getId() #end
```
**Variable assignment:**
```velocity theme={null}
#set($count = $wi.getLinkedWorkItemsStructsDirect().size())$count linked items
```
**Verify in application**
The available methods on `$item`, `$wi`, and platform services depend on your Polarion version. Test templates with simple expressions before building complex logic.
## Verify
After configuring a Velocity template expression:
1. Open the powersheet document in Polarion
2. You should now see computed values in the server-rendered column
3. Verify that null-safe checks work by testing with work items that have empty fields
4. If values show `#SERVER_RENDER_ERROR`, consult the [Debug Template Errors](/powersheet/guides/server-rendering/debug-template-errors) guide
## See Also
* [Create a Computed Property](/powersheet/guides/server-rendering/create-computed-property) -- setting up server-rendered properties
* [Access Polarion Services](/powersheet/guides/server-rendering/access-polarion-services) -- using platform services in templates
* [Debug Template Errors](/powersheet/guides/server-rendering/debug-template-errors) -- troubleshooting template failures
* [Configure a Formatter](/powersheet/guides/sheet-configuration/configure-formatter) -- styling computed values
# Add a Column
Source: https://learn.nextedy.com/powersheet/guides/sheet-configuration/add-column
Define a new column in your Nextedy POWERSHEET sheet configuration to display entity properties, linked entity fields, or multi-level expansion paths in the sheet view.
1. Open your powersheet document in Polarion
2. Navigate to **Menu > Configuration > Edit Sheet Configuration**. This opens the sheet's YAML configuration in the configuration editor.
3. Locate the `columns` section in the YAML configuration
The `columns` section is an object where each key is a **binding path** that maps to an entity property or expansion path defined in your data model.
After making changes in the configuration editor, click **Save** to persist them. The editor validates the YAML as you type and shows a status indicator (for example, **No issues found**).
Add a new entry under `columns` with a key matching a property name from your data model entity type:
```yaml theme={null}
columns:
title:
title: Title
width: 200
hasFocus: true
description:
title: Description
width: 300
wordWrap: true
severity:
title: Severity
width: 100
isReadOnly: true
```
The binding path key (e.g., `title`, `description`, `severity`) must match a property name defined in the entity type of your source configuration.
**Set `hasFocus` on the primary editing column**
The `hasFocus` property determines which column receives focus when a new row is created. Set it on the column users will most frequently edit first -- typically `title`. If no column has `hasFocus`, the first column with `hasUrl` is used instead. If neither is set, the first editable column receives focus.
To display properties from related entities, use dot-separated binding paths that follow the expansion path defined in the data model sources configuration:
```yaml theme={null}
columns:
systemRequirements.systemRequirement:
title: System Requirement
multiItem: true
display: title
list:
search:
- title
- id
systemRequirements.systemRequirement.designRequirements.designRequirement:
title: Design Requirement
multiItem: true
display: title
```
The path `systemRequirements.systemRequirement` navigates from the root entity through the `systemRequirements` relationship (the direct navigation property) to the `SystemRequirement` entity type.
The binding path in a column must follow an expansion path defined in your `sources` section. If you reference `systemRequirements.systemRequirement` in a column but have not defined this expansion in `sources[].expand`, the column will not display any data. See [Configure Sources](/powersheet/guides/sheet-configuration/configure-sources) for setting up expansion paths.
When a column binds to a navigation property (a related entity), use `display` to specify which field of the related entity to show in the cell:
```yaml theme={null}
columns:
hazards.hazard:
title: Hazard
display: title
list:
search:
- title
- id
```
Common `display` values:
| Value | Shows |
| ------------- | ---------------------------------- |
| `title` | The entity title field |
| `titleOrName` | Title if available, otherwise name |
| `id` | The entity identifier (default) |
For custom rendering that combines multiple fields, use the `render` property referencing a named renderer:
```yaml theme={null}
renderers:
hazardLabel: "() => `${context.value.id}: ${context.value.title}`"
columns:
hazards.hazard:
title: Hazard
render: hazardLabel
display: title
```
When a relationship is one-to-many or many-to-many, set `multiItem: true` to display all linked entities in a single cell and enable the multi-item picker:
```yaml theme={null}
columns:
riskControls.riskControl:
title: Risk Controls
multiItem: true
display: title
list:
search:
- title
- id
```
The `multiItem: true` flag tells the sheet to render every linked entity in the cell and activates the multi-item picker for adding or removing items. See [Configure Multi-Item Column](/powersheet/guides/sheet-configuration/configure-multi-item-column) for advanced multi-item scenarios.
Control column dimensions using `width` and `minWidth`:
```yaml theme={null}
columns:
title:
title: Title
width: 250
minWidth: 150
status:
title: Status
width: "*"
```
| Format | Behavior |
| ------ | ------------------------------------------------------ |
| `200` | Fixed width of 200 pixels |
| `"*"` | Proportional -- fills remaining space equally |
| `"2*"` | Proportional -- takes twice the space of `"*"` columns |
The default width is `"*"` (proportional) and the default `minWidth` is `150` pixels.
Apply a predefined style to the column header and assign it to a column group for visual organization:
```yaml theme={null}
styles:
reqStyle:
color: white
backgroundColor: indigo500
columnGroups:
reqs:
groupName: Requirements
groupStyle: reqStyle
headerStyle: reqStyle
collapseTo: title
columns:
title:
title: Title
width: 200
columnGroup: reqs
header:
style: reqStyle
description:
title: Description
width: 300
columnGroup: reqs
```
**Use YAML anchors for reusable header styles**
Define a style anchor once and reuse it across columns to keep your configuration DRY:
```yaml theme={null}
columns:
title:
title: Title
header: &blueHeader
style: blue
description:
title: Description
header: *blueHeader
```
See [Configure a Column Group](/powersheet/guides/sheet-configuration/configure-column-group) and [Apply Column Styles](/powersheet/guides/sheet-configuration/apply-style) for the full list of style options.
## Column Properties Quick Reference
| Property | Type | Default | Description |
| ------------- | ----------------- | ------------ | ----------------------------------------------------------------------------------------------------------------------------------- |
| `title` | string | binding path | Display label in the column header |
| `width` | number or string | `"*"` | Width in pixels or proportional (`"*"`, `"2*"`) |
| `minWidth` | number | `150` | Minimum width in pixels |
| `visible` | boolean | `true` | Whether the column is shown by default |
| `display` | string | `id` | Which property of a referenced entity to show |
| `multiItem` | boolean | `false` | Enable multi-item picker for collection relationships |
| `isReadOnly` | boolean | `false` | Prevent editing (may be overridden by permissions) |
| `isRequired` | boolean | `false` | Require a value before save |
| `hasFocus` | boolean | `false` | Column receives initial focus on new row |
| `hasUrl` | boolean | `false` | Show a link to the entity in the target platform |
| `frozen` | boolean | `false` | Keep column visible when scrolling horizontally |
| `formatter` | string | -- | Name of a formatter for conditional styling |
| `columnGroup` | string | -- | Assign column to a visual column group |
| `header` | object | -- | Custom header styling (`header.style` references a style name) |
| `groupBy` | boolean or object | `false` | Enable row grouping by column values |
| `sort` | string | -- | Default sort direction (`asc` or `desc`) |
| `aggregate` | string | `sum` | Aggregate calculation: `sum`, `avg`, `min`, `max`, `count` (defaults to `sum` if omitted or invalid) |
| `filter` | object | -- | Initial client-side filter (`filter.values: [...]`) |
| `wordWrap` | boolean | `true` | Wrap long text in the cell |
| `multiLine` | boolean | `true` | Allow multi-line text editing |
| `format` | string | -- | Display format string (e.g., `c0$` for currency) |
| `render` | string | -- | Reference to a named renderer or JavaScript expression |
| `value` | string | -- | Computed column using `() => expression` syntax. Stored in the bound property, or displayed only if the binding key is `$`-prefixed |
| `valueType` | string | `string` | Result type of a `$`-prefixed column's `value`: `string`, `number`, or `date`. Not valid on a bound column |
| `list` | object | -- | Picker configuration: `search` fields, `createNew` toggle |
## Verify
After saving the sheet configuration, do a full browser reload or re-open the powersheet document -- the in-sheet refresh button only reloads data, not the configuration. You should now see:
* ✅ The new column appears in the sheet with the specified title
* ✅ Data from the bound property or expansion path is displayed correctly
* ✅ For `multiItem` columns, all linked entities appear in the cell
* ✅ Picker dialogs allow searching by the configured `list.search` fields
* ✅ Column header shows the applied style if `header.style` was set
**Verify in application**
If the column appears but shows no data, verify that the binding path matches an expansion path defined in your `sources` configuration and that the entity type has the property defined in the data model.
If the column does not appear at all, the binding-path key likely doesn't match a real property or expansion in the model -- an unresolvable key is silently dropped (no column, no error). Re-check the spelling of each path segment against the property and expansion names in your data model.
## Column Sizing
Control column dimensions using fixed pixel widths, proportional star-sizing, and minimum width constraints.
### Fixed Pixel Width
Assign a number to set the column width in pixels:
```yaml theme={null}
columns:
id:
width: 80
description:
title: "Foreseeable Sequence of Events"
width: 140
```
### Proportional Width
Use a string with `*` to define proportional width relative to other star-sized columns. The available space (after fixed-width columns are allocated) is distributed proportionally:
```yaml theme={null}
columns:
id:
width: 80
title:
width: "*"
description:
width: "2*"
```
In this example, after the `id` column takes 80 pixels, the remaining space is split -- `title` gets one share and `description` gets two shares.
**Default width**
If `width` is not specified, the default value is `"*"` -- the column takes one proportional share of the available space.
### Minimum Width
Use `minWidth` to prevent a column from shrinking below a certain pixel threshold when the sheet is resized:
```yaml theme={null}
columns:
validationTestCases.validationTestCase:
title: Validation Test Cases
minWidth: 200
```
The default `minWidth` is `150` pixels.
### Width Strategy Decision Guide
**Combine strategies for best results**
Use fixed pixel widths for narrow identifier columns (`id`, `outlineNumber`), proportional `"*"` for content-heavy columns (`title`, `description`), and `minWidth` for collection columns that need guaranteed minimum space.
## Default Sorting
Configure the initial sort order for rows using the `sortBy` property at the top level of your sheet configuration.
### sortBy Array Configuration
Add a `sortBy` array with entries specifying a `columnId` and optional `direction`:
```yaml theme={null}
sortBy:
- columnId: outlineNumber
direction: asc
```
| Property | Required | Description | Default |
| ----------- | -------- | -------------------------------------------------------- | ------- |
| `columnId` | Yes | Dot-separated binding path to the column to sort by | -- |
| `direction` | No | Sort order: `"asc"` (ascending) or `"desc"` (descending) | `"asc"` |
The `columnId` value must match a binding path defined in your `columns` section.
### Multi-Column Sort
Multiple entries in the `sortBy` array create a multi-column sort. Rows are sorted by the first column, then ties are broken by the second, and so on:
```yaml theme={null}
sortBy:
- columnId: outlineNumber
direction: asc
- columnId: title
direction: desc
```
### Per-Column Sort Property
Individual columns also support a `sort` property that defines a default sort direction for that specific column:
```yaml theme={null}
columns:
outlineNumber:
title: "#"
width: 80
sort: asc
```
**Prefer sortBy over per-column sort**
The global `sortBy` array gives you explicit control over sort priority. The per-column `sort` property is applied in addition to the global `sortBy` configuration, which can lead to unexpected ordering if both are used.
### Interactive Sorting
Users can interactively sort by clicking column headers. Powersheet supports these sort interactions:
* **Click** a column header to sort by that column (toggles ascending/descending)
* **Ctrl+Click** a column header to add it to the multi-column sort chain
* Column headers display a visual sort direction indicator when active
**Client-side sorting**
Sorting is applied on the client side after data loads. The sort order specified in `sortBy` defines the initial view -- users can change it interactively from the toolbar.
## See Also
* [Add a Computed Column](/powersheet/guides/sheet-configuration/add-computed-column) -- derive a column's content from an expression, stored or display-only
* [Configure a Column Group](/powersheet/guides/sheet-configuration/configure-column-group) -- group related columns visually
* [Configure a Formatter](/powersheet/guides/sheet-configuration/configure-formatter) -- add conditional styling to columns
* [Apply Column Styles](/powersheet/guides/sheet-configuration/apply-style) -- style column headers
* [Configure Sources](/powersheet/guides/sheet-configuration/configure-sources) -- define expansion paths for navigation columns
* [Create a View](/powersheet/guides/sheet-configuration/create-view) -- create named column visibility presets
* [Configure Read-Only Column](/powersheet/guides/sheet-configuration/configure-read-only-column) -- control column editability
* [Configure Multi-Item Column](/powersheet/guides/sheet-configuration/configure-multi-item-column) -- advanced multi-item picker setup
* [Sheet Configuration Reference](/powersheet/reference/sheet-config/index) -- complete YAML property reference
# Add a Computed Column
Source: https://learn.nextedy.com/powersheet/guides/sheet-configuration/add-computed-column
Derive a column's content from an expression in Nextedy POWERSHEET — either stored back to an entity property, or displayed only, with no property behind it.
A **computed column** derives its content from a `value` expression instead of reading a stored
property directly. Powersheet computes it in the browser every time the sheet renders.
There are two kinds, and one character in the binding decides which you get:
* a **stored** computed column writes its result back to the property it binds to, and
* a **display-only** computed column stores nothing — it exists in the sheet and nowhere else.
## Prerequisites
* A working sheet configuration YAML file
* A data model whose properties you want to compute from
* Familiarity with [dynamic value expressions](/powersheet/reference/sheet-config/dynamic-expressions) (`() =>` syntax)
## Decide Whether the Value Should Be Stored
The binding key decides. A key prefixed with `$` is **unbound**: it names a column, not a property.
| Binding | `value` | Result |
| -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `total` | not set | Ordinary stored column — the user edits it |
| `total` | set | Computed **and stored** — the result is written to `total`, marks the row modified, and persists on save. Read-only to the user |
| `$total` | set | Computed and **displayed only** — nothing is stored, nothing is saved. Read-only to the user |
| `$total` | not set | Configuration error — an unbound column has nothing to derive its content from |
**`value` is about data; `render` and `display` are about appearance.**
Do not reach for `render` to avoid writing data — `render` styles whatever the cell already holds.
If the value should never be stored, make the column unbound with `$`. If it should be stored,
bind it to a real property.
Bind the column to a real property and give it a `value` expression. The result is written to that
property, so it saves with the rest of the row:
```yaml theme={null}
columns:
total:
title: Total
value: "() => context.entity.count * context.entity.rate"
format: "c0$"
```
The user cannot type into the column — a computed column is read-only, because its content comes
from the expression rather than from input. Editing `count` or `rate` recomputes it, marks
the row modified, and the new total persists on the next save.
Prefix the binding key with `$` to name a column that has no property behind it:
```yaml theme={null}
columns:
$riskScore:
title: Risk Score
value: "() => context.entity.Probability * context.entity.Severity"
valueType: number
```
Nothing is written anywhere. The column appears in the sheet, is read-only, and leaves the work
item untouched — saving the row does not create or update a `riskScore` field.
The `$` marker belongs on the **last** segment only. Everything before it is an ordinary path that
must resolve in the data model, and it decides which entity the column reads from:
```yaml theme={null}
columns:
# derives from the root entity
$riskScore:
value: "() => context.entity.Probability * context.entity.Severity"
# derives from the expanded system requirement
systemRequirements.systemRequirement.$coverage:
value: "() => context.entity.verifiedCount + ' / ' + context.entity.totalCount"
```
**`$total` and `total` can coexist.**
The marker stays part of the column's internal identity, so a display-only `$total` does not
collide with a real `total` property in the same sheet. Give them different `title` values so
readers can tell them apart.
If you leave `title` out, the header shows the name without the marker — `$riskScore` displays as
`riskScore`.
A display-only column has no metadata to take its type from, so declare it with `valueType`:
| `valueType` | Use for | Notes |
| ----------- | ---------------------------- | -------------------------------------------------------- |
| `string` | Text, labels, concatenations | The default when `valueType` is omitted |
| `number` | Scores, counts, sums, prices | Enables `format` and `aggregate` |
| `date` | Dates and date-times | Formats as `MMM dd, yyyy` unless `format` says otherwise |
```yaml theme={null}
columns:
$riskScore:
title: Risk Score
value: "() => context.entity.Probability * context.entity.Severity"
valueType: number
format: "n0"
$reviewDue:
title: Review Due
value: "() => context.entity.approvedOn"
valueType: date
format: "yyyy-MM-dd"
```
**`valueType` is for unbound columns only.**
A bound column takes its type from the data model, so declaring `valueType` on one is rejected.
And because there is no metadata to consult, `valueType: date` cannot distinguish a date from a
date-time — set `format` if you need the time part shown or hidden.
A numeric display-only column can be aggregated into group rows like any other numeric column:
```yaml theme={null}
columns:
$riskScore:
title: Risk Score
value: "() => context.entity.Probability * context.entity.Severity"
valueType: number
aggregate: sum
groupBy: true
```
`aggregate` requires `valueType: number` — declaring it on a text or date column is rejected.
Inside an unbound column's `value` expression you can reach past the current entity:
| Expression | Gives you |
| ---------------- | --------------------------------------------------------------------------- |
| `context.entity` | The entity at the column's own level — the one the binding path resolves to |
| `context.source` | The entity one level up, the one this level was navigated from |
| `context.row` | The whole row, as `context.row.entities[]` across every level |
```yaml theme={null}
columns:
systemRequirements.systemRequirement.$origin:
title: Origin
value: "() => `${context.source.id} → ${context.entity.id}`"
```
**`context.value` is empty in a `value` expression.**
A computed column has no stored cell value to start from, so `context.value` is `undefined`.
Read the properties you need from `context.entity` instead.
## What a Display-Only Column Cannot Do
A display-only column stores nothing and resolves no metadata, so several column properties do not
apply to it. Each one is rejected outright rather than ignored:
| Property | Why it is rejected |
| --------------------------------------- | -------------------------------------------------------------------- |
| `isRequired` | The column is read-only and holds no stored data |
| `multiItem` | It binds no navigation property |
| `list` | The stages that resolve enumerations and references never run for it |
| `valueType` on a **bound** column | A bound column takes its type from the data model |
| `aggregate` without `valueType: number` | Only numeric derived values aggregate meaningfully |
`render`, `renderers`, `format`, `groupBy`, `sort`, `filter`, `columnGroup`, and the styling
properties all work normally.
## Verify
After saving the configuration, do a full browser reload or re-open the document — the in-sheet
refresh button reloads data, not the configuration. You should now see:
* The computed column shows its derived value on every row
* Clicking a cell does not enter edit mode, and pasting into the column changes nothing
* Editing a property the expression reads updates the derived cell immediately
* For a **stored** computed column, the row is marked modified and the value persists after save
* For a **display-only** column, saving leaves the work item untouched
* Grouping, sorting, filtering, sheet search, and Excel export all use the derived value
**Grouping and sorting keep the keys they were built with.**
A derived cell repaints as soon as a property it reads changes, but an active grouping or sort
is not rebuilt from the new values. Reload the sheet to regroup or resort on the updated keys.
## Troubleshooting
| Message | Cause |
| ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- |
| `The '$' marker is only allowed on the last segment.` | The marker is on a path segment other than the leaf |
| `The '$' marker needs a name (eg. '$riskScore').` | The binding is a bare `$` with nothing after it |
| `The path before '$' does not resolve.` | The segments preceding the marker are not a valid path in the data model |
| `has no 'value' expression to derive its content from` | A `$`-prefixed column without a `value` expression |
| Column is blank on some rows | The row has no entity at that level. The expression still runs, but `context.entity` is `undefined` — guard with `?.` |
## See Also
* [Add a Column](/powersheet/guides/sheet-configuration/add-column) -- basic column setup and property binding
* [Configure Dynamic Expressions](/powersheet/guides/sheet-configuration/configure-dynamic-expressions) -- `() =>` expressions across the whole sheet configuration
* [Configure Read-Only Column](/powersheet/guides/sheet-configuration/configure-read-only-column) -- how read-only is resolved
* [Use JavaScript in Display and Render](/powersheet/guides/sheet-configuration/use-javascript-display) -- change appearance without changing data
* [Create a Computed Property](/powersheet/guides/server-rendering/create-computed-property) -- compute on the server with Velocity instead
* [Columns](/powersheet/reference/sheet-config/columns) -- complete column property reference
* [Binding Syntax](/powersheet/reference/sheet-config/binding-syntax) -- binding path patterns, including the `$` marker
* [Dynamic Value Expressions Reference](/powersheet/reference/sheet-config/dynamic-expressions) -- the context object and where each expression runs
# Add External Reference Column
Source: https://learn.nextedy.com/powersheet/guides/sheet-configuration/add-external-reference-column
Display external reference work items linked to entities in your Nextedy POWERSHEET sheet by configuring the data model, sources, and column definition.
## Verify the ExternalReference Entity Type
Open the data model for your sheet (**Menu > Configuration > Edit Data Model**). In the `domainModelTypes` section, confirm that `ExternalReference` is defined:
```yaml theme={null}
domainModelTypes:
ExternalReference:
```
**Shared entity type**
The `ExternalReference` entity type may already exist if it is used elsewhere in your model (for example, linked to verification or validation test cases).
## Add the Relationship
In the `relationships` section of your data model, add a relationship from `ExternalReference` to the target entity. For example, to link external references to `DesignRequirement`:
```yaml theme={null}
relationships:
- from: ExternalReference
to: DesignRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: relatesTo
direct:
name: designRequirement
back:
name: externalReferences
```
Because this relationship is backed by a Polarion work item link, set `storage: linkedWorkItems` and `linkRole` to the link role configured in the next step (for example, `relatesTo`). Without `storage` and `linkRole`, the relationship cannot traverse the underlying Polarion links and the column stays empty.
The `back.name` value (`externalReferences`) becomes the expansion path used in the sources and column binding.
## Configure the Link Role in Polarion
Go to **Administration > Work Items > Enumerations** in Polarion and open the **`workitem-link-role-enum.xml`** configuration (this is where work item link roles are defined). Verify that the link role (for example, `relatesTo`):
* Can be created from `externalReference` to the target work item type (for example, `designRequirement`)
* Is bidirectional (recommended)
This link role must match the `linkRole` value set on the relationship in the previous step.
## Update the Sources Section
Open the sheet configuration (**Menu > Configuration > Edit Sheet Configuration**), locate the `sources` section, and add the `externalReferences` expansion under the appropriate entity:
```yaml theme={null}
sources:
- model: rtm
query:
from: UserNeed
where: "type = 'UserNeed'"
take: 50
expand:
- name: systemRequirements
expand:
- name: systemRequirement
expand:
- name: designRequirements
expand:
- name: designRequirement
expand:
- name: verificationTestCases
expand:
- name: verificationTestCase
- name: externalReferences
expand:
- name: externalReference
```
Each relationship navigation (the plural `back.name`, such as `externalReferences`) must be followed by a nested `expand` that names the related entity (the singular `direct.name`, such as `externalReference`). The `externalReferences` entry sits at the same level as other relationships on `designRequirement`.
## Add the Column
In the same sheet configuration, define the column in the `columns` section using the full binding path through the entity hierarchy. Set `multiItem: true` to enable multi-reference picker behavior:
```yaml theme={null}
header: &blue
style: blue
columns:
systemRequirements.systemRequirement.designRequirements.designRequirement.externalReferences.externalReference:
title: External References
multiItem: true
header: *blue
minWidth: 200
```
The binding path specifies the full hierarchy from the root entity down to the `externalReference` entity. The YAML anchor `&blue` reuses a previously defined header style.
**Binding path must match expansion**
The column binding path must exactly mirror the expansion path defined in the `sources` section. A mismatch between expansion and column binding results in an empty column with no data.
## Complete Example
```yaml theme={null}
sources:
- model: rtm
query:
from: UserNeed
where: "type = 'UserNeed'"
take: 50
expand:
- name: systemRequirements
expand:
- name: systemRequirement
expand:
- name: designRequirements
expand:
- name: designRequirement
expand:
- name: externalReferences
expand:
- name: externalReference
header: &blue
style: blue
columns:
outlineNumber:
title: "#"
width: 80
isReadOnly: true
title:
title: Title
width: "*"
hasFocus: true
systemRequirements.systemRequirement.designRequirements.designRequirement.externalReferences.externalReference:
title: External References
multiItem: true
header: *blue
minWidth: 200
```
## Verify
After saving the sheet configuration, reload the powersheet document. You should now see a new column displaying external references linked to each design requirement. Users can select or add external references using the multi-reference picker in each cell.
## See also
* [Add a Column](/powersheet/guides/sheet-configuration/add-column)
* [Configure Multi-Item Column](/powersheet/guides/sheet-configuration/configure-multi-item-column)
* [Configure Sources](/powersheet/guides/sheet-configuration/configure-sources)
* [Expand Navigation Properties](/powersheet/guides/queries/expand-navigation-properties)
* [Configure a Relationship](/powersheet/guides/data-model/configure-relationship)
# Apply Column Styles
Source: https://learn.nextedy.com/powersheet/guides/sheet-configuration/apply-style
Apply predefined or custom visual styles to column headers and column groups in Nextedy POWERSHEET to color-code related data by domain.
## Apply a Predefined Header Style
Powersheet includes 20 built-in styles you can apply directly to any column header. Add the `header` property with a `style` reference inside your column definition:
```yaml theme={null}
columns:
description:
title: "Foreseeable Sequence of Events"
width: 140
header:
style: lightpurple
```
This sets the header text color and background according to the predefined `lightpurple` style.
## Predefined Styles Reference
| Style Name | Text Color | Background Color | Other |
| ------------- | ---------- | ---------------- | ---------------------------- |
| `none` | -- | -- | -- |
| `boldTitle` | -- | -- | fontWeight: 600 |
| `unsupported` | grey800 | grey200 | textDecoration: line-through |
| `readOnly` | -- | -- | Read-only visual indicator |
| `darkgrey` | grey700 | grey200 | -- |
| `grey` | grey700 | grey100 | -- |
| `darkred` | red700 | red200 | -- |
| `red` | red700 | red100 | -- |
| `darkorange` | orange700 | orange200 | -- |
| `orange` | orange700 | orange100 | -- |
| `darkgreen` | green700 | green200 | -- |
| `green` | green700 | green100 | -- |
| `lightgreen` | green700 | primaryalt100 | -- |
| `darkblue` | blue700 | blue200 | -- |
| `blue` | blue700 | blue100 | -- |
| `lightblue` | blue700 | teal100 | -- |
| `darkteal` | teal700 | teal200 | -- |
| `teal` | teal700 | teal100 | -- |
| `darkpurple` | purple700 | purple200 | -- |
| `purple` | purple700 | purple100 | -- |
| `lightpurple` | purple700 | primary100 | -- |
**Color-code by domain**
Use color families to visually group related columns: risks in `red`, controls in `blue`, requirements in `purple`, verification in `green`.
## Define a Custom Style
To create your own style, add a definition in the `styles` section and reference it by name:
```yaml theme={null}
styles:
warningHeader:
backgroundColor: 'orange200'
color: 'orange700'
columns:
outlineNumber:
title: "#"
width: 80
header:
style: warningHeader
```
Custom styles are merged on top of the built-in defaults, so you can override any predefined style name with your own definition.
## Apply Styles to Column Groups
Use `columnGroups` to apply consistent styling across a set of related columns. Each group supports three style properties:
```yaml theme={null}
columnGroups:
epic:
groupName: Epics
groupStyle: darkgreen
headerStyle: green
collapseTo: title
columns:
title:
title: Title
width: 200
columnGroup: epic
```
| Property | Description |
| ------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `groupName` | Display name shown in the group header row (required) |
| `groupStyle` | Style applied to the group header band (optional). Predefined name or custom style. Defaults to white. |
| `headerStyle` | Style applied to all sub-column headers in the group (optional) -- can be overridden per column via `header.style`. Defaults to white. |
| `collapseTo` | Binding path of the column shown when the group is collapsed (optional) |
**Style resolution order**
A column-level `header.style` takes priority over the group-level `headerStyle`. Use group styles for defaults and column styles for exceptions.
## Color Tokens
Powersheet color tokens use a naming pattern of `{color}{level}` where levels range from `100` (lightest) to `700` (darkest). Available color families:
Use these tokens in custom style definitions:
```yaml theme={null}
styles:
customHighlight:
backgroundColor: 'red100'
color: 'red700'
```
For the full list of color tokens and their levels, see the [Styles reference](/powersheet/reference/sheet-config/styles).
## Use YAML Anchors for Reuse
Define a header style once as a YAML anchor and reuse it across columns:
```yaml theme={null}
columns:
systemRequirements.systemRequirement.title:
title: System Requirement
header: &blueHeader
style: blue
systemRequirements.systemRequirement.severity:
title: Severity
header: *blueHeader
```
## Use Custom Styles in Formatters
Custom styles defined in the `styles` section can also be referenced by conditional formatters for cell-level styling:
```yaml theme={null}
styles:
readOnlyStyle:
backgroundColor: 'grey100'
criticalHeader:
color: 'red700'
backgroundColor: 'red200'
fontWeight: 600
formatters:
readonly:
- expression: 'true'
style: readOnlyStyle
```
**Color-code by domain**
Use consistent colors across your sheet to group related columns visually: for example, red for risks, blue for requirements, green for controls, and purple for references.
## Verify
After saving the sheet configuration, reload the powersheet document. You should now see styled column headers with the colors you specified, and any column group headers displaying their configured `groupStyle`. Verify that:
* Individual column headers show the correct style
* Group headers span the correct columns with the specified `groupStyle`
* The `collapseTo` toggle works if configured (click the collapse button in the group header)
## See also
* [Configure a Column Group](/powersheet/guides/sheet-configuration/configure-column-group)
* [Configure a Formatter](/powersheet/guides/sheet-configuration/configure-formatter)
* [Add a Column](/powersheet/guides/sheet-configuration/add-column)
# Assign Configuration to Document
Source: https://learn.nextedy.com/powersheet/guides/sheet-configuration/assign-config-to-document
Link a Nextedy POWERSHEET sheet configuration to a Polarion LiveDoc so that opening the document displays the configured sheet view.
## Prerequisites
* At least one sheet configuration created in **Administration > Nextedy Powersheet > Sheet Configurations**
* A data model configured in **Administration > Nextedy Powersheet > Data Models**
* The `nextedySheetConfig` custom field defined for your document type
If the `nextedySheetConfig` custom field does not yet exist, create it in Siemens Polarion ALM:
1. Navigate to **Administration > Documents & Pages > Document Custom Fields**
2. Decide whether the field applies to all documents or only a specific document type (e.g., `powersheet`, `userNeedsSpec`)
3. Create a new field with these settings:
| Property | Value |
| -------- | ---------------------------- |
| **Id** | `nextedySheetConfig` |
| **Name** | Sheet Config |
| **Type** | Enum: Nextedy - Sheet Config |
The enum provider automatically discovers configuration files from both global and project-specific repository locations. Global configurations appear with a `(Global)` suffix in the dropdown. There is no default configuration -- users must explicitly select one.
1. Open the Polarion LiveDoc you want to connect to Powersheet
2. Open the document properties panel
3. In the **Sheet Config** field, select the desired sheet configuration from the dropdown
The dropdown lists all available configurations:
* **Project-specific configurations** -- shown by filename without path
* **Global configurations** -- shown with `(Global)` suffix, ID starts with `/`
Powersheet discovers configurations at two levels:
| Scope | Repository Location | ID Format | Use Case |
| ------- | ----------------------------------------------------------------------------------------------------------- | --------------- | ------------------------------- |
| Project | `.polarion/nextedy/sheet-configurations/` | Filename only | Project-specific layouts |
| Global | Global repository location (see [Configuration Hierarchy](/powersheet/concepts/global-vs-project-specific)) | Starts with `/` | Shared across multiple projects |
A single sheet configuration can be reused across multiple documents. Each document references the configuration independently through its `nextedySheetConfig` field.
**Configuration must match the data model**
The sheet configuration references column binding paths that must exist in the associated data model. If you assign a configuration designed for one data model to a document using a different model, columns with unresolvable bindings will fail to display correctly.
**Start with simple configurations**
New users should begin with a minimal single-entity configuration and extend incrementally. Jumping directly to complex multi-entity configurations leads to hard-to-diagnose errors. See [Incremental Configuration Approach](/powersheet/getting-started/incremental-configuration) for guidance.
Once a configuration is linked to a document, authors can open it directly from the Powersheet toolbar without returning to the administration page. Inside the document, open **Menu > Configuration > Edit Sheet Configuration** to jump straight into the YAML editor for the currently assigned configuration. The same submenu also exposes **Edit Data Model** to reach the associated data model.
This shortcut is the fastest way to iterate on a configuration while testing it against real data in the document.
For standardized deployments, you can create **template documents** that already have the sheet configuration pre-assigned. New documents duplicated from the template inherit the configuration assignment, saving administrators from manually assigning configurations for each new document.
Templates can be duplicated across projects. The configuration and data model are resolved in the target project context.
## Verification
After assigning the configuration and saving the document:
1. Open the LiveDoc in Polarion
2. You should now see the Powersheet table view embedded in the document, displaying columns and data according to your configuration
3. The sheet should load data from the sources defined in the configuration
4. The Powersheet Drive sidebar topic should list your document
## See Also
* [Creating Your First Sheet Configuration](/powersheet/getting-started/first-sheet-configuration) -- build a configuration from scratch
* [Creating Your First Powersheet Document](/powersheet/getting-started/first-document) -- end-to-end document setup tutorial
* [Download Configuration as YAML](/powersheet/guides/sheet-configuration/download-config-as-yaml) -- export an existing configuration for editing
* [Configure Sources](/powersheet/guides/sheet-configuration/configure-sources) -- define data sources within a sheet configuration
* [Incremental Configuration Approach](/powersheet/getting-started/incremental-configuration) -- best practices for building configurations gradually
# Configure Collapsible Groups
Source: https://learn.nextedy.com/powersheet/guides/sheet-configuration/configure-collapsible-groups
Organize related columns into collapsible groups in your Nextedy POWERSHEET sheet configuration so users can expand or collapse entire sections of columns to focus on what matters.
## Prerequisites
* A working sheet configuration with multiple columns defined
* Familiarity with [column groups](/powersheet/guides/sheet-configuration/configure-column-group)
In your sheet configuration YAML, add a `columnGroups` section. For each group that should be collapsible, specify the `collapseTo` property pointing to the column that remains visible when the group is collapsed.
```yaml theme={null}
columnGroups:
Requirements:
groupName: Requirements
groupStyle: blue
headerStyle: blue
collapseTo: systemRequirements.systemRequirement.title
Risks:
groupName: Risks
groupStyle: orange
headerStyle: orange
collapseTo: hazards.hazard.title
```
The `collapseTo` value must be a valid binding path of a column that belongs to the same group.
Each column that should participate in a collapsible group needs a `columnGroup` property matching the group key:
```yaml theme={null}
columns:
systemRequirements.systemRequirement.title:
title: Sys Req Title
width: 200
columnGroup: Requirements
hasFocus: true
systemRequirements.systemRequirement.severity:
title: Severity
width: 100
columnGroup: Requirements
systemRequirements.systemRequirement.status:
title: Status
width: 100
columnGroup: Requirements
```
When the **Requirements** group is collapsed, only the `systemRequirements.systemRequirement.title` column remains visible because it matches the `collapseTo` path.
The group header row displays a toggle button when `collapseTo` is configured. Clicking the button hides all columns in the group except the designated collapse target column. Clicking the toggle again expands the group back to its full column set.
**Groups without collapseTo**
If a column group does not define `collapseTo`, no collapse toggle button appears in the group header. The group still provides visual organization but cannot be collapsed.
Columns that are not assigned to any `columnGroup` still display correctly. They appear with a blank group header cell, maintaining the consistent two-row header structure across the entire sheet.
**Collapse target must belong to the group**
The column referenced by `collapseTo` must have its `columnGroup` set to the same group. If the column path does not match any column in the group, the collapse button may not appear or may behave unexpectedly.
**Use collapseTo for summary columns**
Choose a column that provides the best summary when the group is collapsed -- typically the primary identifier such as `title` or `id`. This lets users scan the sheet efficiently without expanding every group.
Collapsible column groups work independently from row grouping. You can combine both features:
* **Column groups** collapse columns horizontally (hiding detail columns)
* **Row grouping** collapses rows vertically (using `groupBy` on a column or keyboard shortcuts `Ctrl+G` / `Ctrl+Shift+G`)
## Verification
After saving the configuration and reloading the powersheet document:
1. You should now see group headers spanning multiple columns with the group name displayed
2. Groups with `collapseTo` defined should show a toggle button in the group header
3. Clicking the toggle should hide all columns except the collapse target
4. Clicking again should restore all columns in the group
## See Also
* [Configure a Column Group](/powersheet/guides/sheet-configuration/configure-column-group) -- set up basic column grouping with styling
* [Add a Column](/powersheet/guides/sheet-configuration/add-column) -- add individual columns to your sheet configuration
* [Add a Column](/powersheet/guides/sheet-configuration/add-column) -- column sizing and configuration
* [Create a View](/powersheet/guides/sheet-configuration/create-view) -- create named views with different column visibility presets
# Configure a Column Group
Source: https://learn.nextedy.com/powersheet/guides/sheet-configuration/configure-column-group
Organize related columns under visual group headers in your Nextedy POWERSHEET sheet configuration, with optional collapse behavior and shared styling.
Add a `columnGroups` section to your sheet configuration YAML. Each group has a unique ID and configuration properties:
```yaml theme={null}
columnGroups:
requirements:
groupName: Requirements
groupStyle: blue
headerStyle: lightblue
collapseTo: title
```
| Property | Required | Description |
| ------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `groupName` | Yes | Display name shown in the group header row |
| `groupStyle` | No | Color style applied to grouped column backgrounds. Uses a predefined style name or a custom style. Defaults to white. |
| `headerStyle` | No | Color style applied to all sub-column headers within the group. Can be overridden per column with `header.style`. Defaults to white. |
| `collapseTo` | No | Binding path of the column to show when the group is collapsed. If omitted, the group cannot be collapsed. |
Add a `columnGroup` property to each column that should belong to the group:
```yaml theme={null}
columnGroups:
requirements:
groupName: Requirements
groupStyle: blue
headerStyle: lightblue
collapseTo: title
columns:
title:
title: Title
width: 200
columnGroup: requirements
description:
title: Description
width: 300
columnGroup: requirements
severity:
title: Severity
width: 100
columnGroup: requirements
```
All three columns will appear under a shared "Requirements" group header in the sheet.
Define multiple groups with different color schemes to visually separate entity domains:
```yaml theme={null}
columnGroups:
requirements:
groupName: Requirements
groupStyle: blue
headerStyle: lightblue
risks:
groupName: Risk Analysis
groupStyle: red
headerStyle: darkorange
collapseTo: hazard
controls:
groupName: Risk Controls
groupStyle: green
headerStyle: lightgreen
collapseTo: riskControls.riskControl
columns:
title:
title: User Need
columnGroup: requirements
systemRequirements.systemRequirement:
title: System Req
columnGroup: requirements
hazard:
title: Hazard
columnGroup: risks
riskControls.riskControl:
title: Risk Control
columnGroup: controls
```
When `collapseTo` is set, a collapse toggle button appears in the group header. Clicking it hides all columns in the group except the specified one:
```yaml theme={null}
columnGroups:
risks:
groupName: Risk Analysis
groupStyle: red
headerStyle: darkorange
collapseTo: hazard
```
When collapsed, only the `hazard` column is visible. Click the toggle again to expand all columns back.
**Collapse target must be a column in the group**
The `collapseTo` value is specified by column binding path. If the target column is hidden (`visible: false`), the last visible column in the group is used instead.
**Use color coding to distinguish entity domains**
Apply semantic colors: `red`/`darkorange` for risks, `blue`/`lightblue` for requirements, `green`/`lightgreen` for controls, `purple`/`lightpurple` for references. This helps users quickly identify column context in wide sheets.
## Predefined Style Names
You can use any of these built-in style names for `groupStyle` and `headerStyle`:
`none`, `grey`, `darkgrey`, `red`, `darkred`, `orange`, `darkorange`, `green`, `darkgreen`, `lightgreen`, `blue`, `darkblue`, `lightblue`, `teal`, `darkteal`, `purple`, `darkpurple`, `lightpurple`
For custom colors, define styles in the `styles` section and reference them by name. See [Apply Column Styles](/powersheet/guides/sheet-configuration/apply-style).
## Verify
After saving the sheet configuration, reload the powersheet document. You should now see:
* A group header row appears above the column headers
* Columns assigned to the same group share a merged group header cell
* Columns without a `columnGroup` show a blank group header
* Groups with `collapseTo` display a collapse toggle button
## See Also
* [Apply Column Styles](/powersheet/guides/sheet-configuration/apply-style) -- define custom styles for headers and groups
* [Styles Reference](/powersheet/reference/sheet-config/styles) -- advanced header styling
* [Configure Collapsible Groups](/powersheet/guides/sheet-configuration/configure-collapsible-groups) -- detailed collapse configuration
* [Add a Column](/powersheet/guides/sheet-configuration/add-column) -- column basics and binding paths
# Configure Dynamic Expressions
Source: https://learn.nextedy.com/powersheet/guides/sheet-configuration/configure-dynamic-expressions
Use dynamic expressions in Nextedy POWERSHEET sheet configurations and data models to resolve values at runtime based on the current document, user, URL parameters, or entity properties.
## Prerequisites
* A working sheet configuration YAML file
* Familiarity with the [sheet configuration reference](/powersheet/reference/sheet-config/index) and [data model reference](/powersheet/reference/data-model/index)
## Understand the Two Expression Notations
Powersheet supports two distinct expression syntaxes, each used in a different configuration context:
| Notation | Syntax | Used In |
| ---------------------- | ------------------------ | ------------------------------------------------ |
| **Context expression** | `$context.property.path` | Data model configuration (constraints) |
| **Dynamic value** | `() => expression` | Sheet configuration (where, value, render, etc.) |
**Rule of Thumb**
If you are editing a **data model** YAML file (entity types, relationships), use `$context`. If you are editing a **sheet configuration** YAML file (sources, columns, formatters), use `() =>`.
Dynamic where clauses let you filter source data using runtime values such as the current document or the current date.
**Filter by the current document:**
```yaml theme={null}
sources:
- id: opportunities
query:
from: Opportunity
where:
Module:
"==": "() => context.document.moduleName"
```
When the sheet loads inside a LiveDoc, only records whose `Module` equals the current `moduleName` are returned.
**Filter by today's date (show only future items):**
```yaml theme={null}
sources:
- id: tasks
query:
from: Task
where:
DueDate:
">": "() => new Date().toISOString()"
```
**Date Format Requirement**
Dynamic date values must return ISO 8601 format. Always call `.toISOString()` on Date objects. Returning a raw Date object will cause the query to fail silently.
**Combine multiple document properties using template literals:**
```yaml theme={null}
sources:
- id: filtered
query:
from: EntityType
where:
Scope:
"==": "() => `${context.document.moduleFolder}/${context.document.moduleName}`"
```
Use `entityFactory` to pre-populate fields on newly created items with values resolved at runtime:
```yaml theme={null}
sources:
- id: userNeeds
query:
from: UserNeed
entityFactory:
type: "() => context.source.type + '_VerificationTestCase'"
Status: Planned
```
In this example, `type` is derived from the source entity's type at runtime (for instance, a `SystemRequirement` source yields `SystemRequirement_VerificationTestCase`), while `Status` receives the static value `Planned`.
The `value` property computes a column's content from other properties on the current entity. On a column bound to a real property, the computed result is **persisted** back to the data source on save.
```yaml theme={null}
columns:
total:
value: "() => context.entity.count * context.entity.rate"
title: Total
format: "c0$"
```
The expression reads entity properties through `context.entity`. In this case it multiplies `count` by `rate` each time the sheet refreshes. A computed column is read-only by definition, so there is no need to declare `isReadOnly`.
To compute a value that is shown but **never** stored, prefix the binding key with `$`. Such a column is unbound -- it has no property behind it -- so declare its result type with `valueType`:
```yaml theme={null}
columns:
$riskScore:
title: Risk Score
value: "() => context.entity.Probability * context.entity.Severity"
valueType: number
```
**`value` is about data; `render` is about appearance.**
On a bound column, `value` modifies the **underlying data** -- the computed result is saved. `render` only changes how an existing value is displayed and cannot supply content of its own. If the result should never be stored, make the column unbound with `$` rather than reaching for `render`.
For the full walkthrough -- result types, aggregation, and what an unbound column cannot do -- see [Add a Computed Column](/powersheet/guides/sheet-configuration/add-computed-column).
Renderers produce custom HTML output for cell display. They do not affect persisted data.
**Inline render expression on a column:**
```yaml theme={null}
columns:
Priority:
render: "() => '' + context.value + ' '"
title: Priority
```
**Named renderer definition (reusable across columns):**
```yaml theme={null}
renderers:
linkedItems: "() => context.value.map((item) => `${item.name} `).join(', ')"
columns:
relatedItems:
render: linkedItems
title: Related Items
```
Named renderers are defined in the top-level `renderers` section and referenced by name in the column `render` property.
Formatters apply styles to cells based on a boolean expression. Unlike `value` and `render`, formatter expressions use **simplified syntax** -- they do not start with `() =>`.
```yaml theme={null}
formatters:
criticalHighlight:
expression: "context.entity.Probability <= 99"
style: warningStyle
styles:
warningStyle:
color: red700
backgroundColor: red100
textDecoration: line-through
```
Apply the formatter to a column:
```yaml theme={null}
columns:
Probability:
title: Probability
formatter: criticalHighlight
```
The formatter context provides access to `context.document`, `context.entity`, and `context.value`.
In data model YAML files, use the `$context` notation to create dynamic constraints that filter relationship data based on the source entity's properties.
**Filter linked items to the same document component:**
```yaml theme={null}
relationships:
- from: DesignRequirement
to: SystemRequirement
back:
name: designRequirements
constraints:
load:
document:
component: $context.source.document.component
```
When viewing a `SystemRequirement` from the "Braking" component, only `DesignRequirement` items from "Braking" documents are loaded.
**Filter by document name and folder:**
```yaml theme={null}
constraints:
load:
document:
moduleName: $context.source.document.moduleName
moduleFolder: $context.source.document.moduleFolder
```
**Constrain picker to same document type:**
```yaml theme={null}
constraints:
pick:
document:
type: $context.source.document.type
```
**Per-Row Evaluation**
`$context` constraints are evaluated **per row**. Different rows can produce different constraint values depending on their source entity's properties. This enables context-sensitive filtering without separate configurations.
## Context Object Reference
The `context` object provides different properties depending on where the expression is evaluated:
| Usage Location | `.user` | `.sources` | `.document` | `.entity` | `.value` | `.source` | `.row` |
| ------------------------ | ------- | ---------- | ----------- | --------- | -------- | --------- | ------ |
| `where` | ✅ | ✅ | ✅ | -- | -- | -- | -- |
| `entityFactory` | ✅ | ✅ | -- | -- | -- | ✅ | -- |
| `value` (bound column) | ✅ | ✅ | -- | ✅ | -- | -- | -- |
| `value` (unbound column) | ✅ | ✅ | -- | ✅ | -- | ✅ | ✅ |
| `render` / `renderers` | -- | -- | -- | ✅ | ✅ | -- | -- |
| `formatter` | -- | -- | ✅ | ✅ | ✅ | -- | -- |
| `display` | -- | -- | -- | ✅ | ✅ | ✅ | -- |
Key context properties:
* **`context.user`** -- Current logged-in user (`id`, `name`)
* **`context.document`** -- Current document information (`title`, `type`, `id`, `moduleName`, `moduleFolder`, `component`)
* **`context.entity`** -- Current entity with all its properties, e.g., `context.entity.severity`
* **`context.source`** -- Parent/source entity -- the level the current one was navigated from
* **`context.row`** -- The whole row, as `context.row.entities[]` across every navigation level
* **`context.value`** -- Current cell's display value. It is `undefined` inside a `value` expression, because that expression is what produces the value
## Verification
After saving your configuration changes:
1. Reload the sheet in Polarion
2. For **where clauses**: verify that only matching records appear (try opening the sheet inside different documents)
3. For **computed columns**: confirm the column shows correct values and updates when the properties it reads change. A bound `value` column persists its result on save; an unbound (`$`) column leaves the work item untouched
4. For **renderers**: inspect cells for the expected HTML rendering
5. For **formatters**: verify that styling applies when the condition is met and disappears when it is not
6. For **\$context constraints**: expand a relationship and confirm that only items matching the source entity's document properties are loaded
You should now see dynamic values resolving correctly at runtime across all configured expression locations.
## See Also
* [Add a Computed Column](/powersheet/guides/sheet-configuration/add-computed-column) -- `value`, the `$` unbound marker, and `valueType` in depth
* [Configure Sources](/powersheet/guides/sheet-configuration/configure-sources) -- set up data source queries including where clauses
* [Configure a Formatter](/powersheet/guides/sheet-configuration/configure-formatter) -- conditional styling reference
* [Apply Column Styles](/powersheet/guides/sheet-configuration/apply-style) -- define reusable style objects
* [Configure Constraints](/powersheet/guides/data-model/configure-constraints) -- full constraint configuration including `$context` patterns
* [Sheet Configuration Reference](/powersheet/reference/sheet-config/index) -- complete property reference for sheet YAML
* [Data Model Reference](/powersheet/reference/data-model/index) -- entity types, relationships, and constraint configuration
# Configure a Formatter
Source: https://learn.nextedy.com/powersheet/guides/sheet-configuration/configure-formatter
Define named formatters in Nextedy POWERSHEET to apply conditional styling to column cells based on expression evaluation against entity data.
## Prerequisites
Before configuring a formatter, ensure you have:
* A working sheet configuration with at least one column defined
* Access to edit the YAML configuration (see [Download Configuration as YAML](/powersheet/guides/sheet-configuration/download-config-as-yaml))
* Familiarity with the properties available on your entity types
## Define a Formatter
Formatters live in the `formatters` section at the root level of your sheet configuration. Each formatter is a named key containing an array of rules. Each rule pairs an `expression` (a condition) with a `style` (the visual treatment to apply when the condition is true).
**Step 1.** Open your sheet configuration YAML and add a `formatters` section:
```yaml theme={null}
formatters:
boldTitle:
- expression: 'true'
style: boldTitleStyle
```
**Step 2.** Define the referenced style in the `styles` section:
```yaml theme={null}
styles:
boldTitleStyle:
fontWeight: "bold"
```
This example defines a custom `boldTitleStyle` to illustrate the full define-and-reference flow. Powersheet also ships a built-in `boldTitle` style (see [Predefined Styles](#predefined-styles)); you can reference it directly without a `styles` entry when its default appearance suits you.
The `expression` property accepts a JavaScript expression string. When it evaluates to `true`, the referenced `style` is applied to the cell. Using the literal `'true'` means the style applies unconditionally to every cell in that column.
**Styles apply to the whole cell**
A formatter style is applied to the entire cell container -- both its background (`backgroundColor`) and its text (`color`, `fontWeight`, `textDecoration`) -- not only to the text content.
**Formatter syntax difference**
Unlike other dynamic expressions, a formatter `expression` is a bare boolean expression (e.g., `value > 100`). It does **not** use the `() =>` prefix; it is evaluated as a direct boolean condition.
## Apply a Formatter to a Column
Reference the formatter by name in the column's `formatter` property:
```yaml theme={null}
columns:
title:
title: Title
width: 200
formatter: boldTitle
```
The `formatter` value must match a key defined in the `formatters` section exactly. If the name does not match any defined formatter, no styling is applied and no error is raised.
**Mismatched formatter names fail silently**
If you reference a formatter name that does not exist in the `formatters` section, Powersheet will not display an error. The column simply renders without conditional styling. Double-check that the `formatter` value on your column exactly matches a key under `formatters`.
## Formatter Evaluation Flow
When a cell renders, Powersheet checks whether the column has a `formatter` assigned. If so, it evaluates each rule's expression in the order they appear. The first matching rule determines the style applied.
## Use the Expression Context
Inside a formatter expression, you have access to a `context` object that provides data about the current cell:
| Context Property | Description |
| ------------------ | ------------------------------------------ |
| `context.entity` | The current entity (work item) for the row |
| `context.value` | The value of the current cell |
| `context.document` | The document data object |
Use dot notation to access entity properties. For example, `context.entity.Probability` reads the `Probability` field of the current row's entity.
```yaml theme={null}
formatters:
highProbability:
- expression: "context.entity.Probability > 80"
style: criticalStyle
```
## Use Multiple Rules
A formatter can contain multiple expression-style pairs. Rules are evaluated top-to-bottom, and the **first matching rule** determines the applied style. Place the most specific conditions first and use a catch-all `'true'` rule last for a default style:
```yaml theme={null}
formatters:
severityHighlight:
- expression: "context.value === 'Critical'"
style: criticalStyle
- expression: "context.value === 'Major'"
style: majorStyle
- expression: 'true'
style: defaultStyle
styles:
criticalStyle:
backgroundColor: 'red100'
color: 'red700'
majorStyle:
backgroundColor: 'orange100'
color: 'orange700'
defaultStyle:
backgroundColor: 'grey100'
```
**Use a catch-all rule for consistent appearance**
End your formatter with `expression: 'true'` to ensure every cell receives a baseline style, even when no specific condition matches. This prevents visual inconsistency between styled and unstyled cells.
## Create a Read-Only Formatter
A common pattern combines a formatter with the `isReadOnly` column property to both visually indicate and enforce that a column cannot be edited:
```yaml theme={null}
formatters:
readonly:
- expression: 'true'
style: readOnlyStyle
styles:
readOnlyStyle:
backgroundColor: 'grey100'
columns:
outlineNumber:
title: "#"
width: 80
formatter: readonly
isReadOnly: true
```
The `isReadOnly: true` property prevents editing at the column level, while the formatter applies a grey background to visually communicate the read-only state. Note that `isReadOnly` can also be overridden by document-level permissions or user access control settings.
**Start simple, extend incrementally**
Begin with a single formatter rule and verify it works before adding conditional expressions. Jumping straight to complex multi-rule formatters leads to hard-to-diagnose styling issues.
## Define Custom Styles
Styles use CSS-like property names in camelCase. Common properties include:
| Property | Example Value | Effect |
| ----------------- | ----------------------- | --------------------- |
| `backgroundColor` | `'red100'`, `'#ffcdd2'` | Cell background color |
| `color` | `'red700'`, `'#d32f2f'` | Text color |
| `fontWeight` | `"bold"` | Bold text |
| `textDecoration` | `"line-through"` | Strikethrough text |
Powersheet provides a set of predefined color tokens (such as `red100`, `red700`, `grey100`, `orange100`, `blue100`, `green100`, `purple100`, `teal100`, and their dark/light variants) that you can use alongside standard CSS color values.
**Nonexistent style references fail silently**
Every `style` value in a formatter rule must match either a key you defined in the `styles` section or one of the built-in style names (`none`, `boldTitle`, `readOnly`, `grey`, `red`, `green`, `blue`, `purple`, `teal`, `orange`, and their dark/light variants). A typo in the style name causes the rule to silently produce no visual effect.
## Complete YAML Example
This example shows a full configuration with two formatters applied to columns in a requirements traceability sheet:
```yaml theme={null}
formatters:
readonly:
- expression: 'true'
style: readOnlyStyle
priorityFormat:
- expression: "context.value === 'Critical'"
style: criticalStyle
- expression: "context.value === 'High'"
style: highStyle
- expression: 'true'
style: normalStyle
styles:
readOnlyStyle:
backgroundColor: 'grey100'
criticalStyle:
backgroundColor: 'red100'
color: 'red700'
fontWeight: "bold"
highStyle:
backgroundColor: 'orange100'
color: 'orange700'
normalStyle:
backgroundColor: 'green100'
columns:
outlineNumber:
title: "#"
width: 80
formatter: readonly
isReadOnly: true
title:
title: Title
width: 300
hasFocus: true
severity:
title: Severity
width: 120
formatter: priorityFormat
systemRequirements.systemRequirement.title:
title: System Requirement
width: 250
columnGroup: reqs
```
## Advanced: Conditional Formatting
### Use Expression Variables
The `expression` string is evaluated as JavaScript. The variable `value` represents the current cell value, enabling numeric comparisons and pattern matching:
```yaml theme={null}
formatters:
numberRange:
- expression: "value > 100"
style: red
- expression: "value > 50"
style: orange
- expression: 'true'
style: green
```
**Always include a fallback rule**
End your formatter rules with `expression: 'true'` as a catch-all. Without a fallback, cells that match no rule receive no formatting.
### Predefined Styles
Powersheet includes 20 built-in styles you can reference directly without defining them in the `styles` section:
| Style Name | Description |
| --------------------------------------- | --------------------------------------- |
| `none` | No styling |
| `boldTitle` | Bold font weight |
| `readOnly` | Read-only visual indicator |
| `unsupported` | Strikethrough text on a grey background |
| `grey` / `darkgrey` | Grey background variants |
| `red` / `darkred` | Red background variants |
| `orange` / `darkorange` | Orange background variants |
| `green` / `darkgreen` / `lightgreen` | Green background variants |
| `blue` / `darkblue` / `lightblue` | Blue background variants |
| `teal` / `darkteal` | Teal background variants |
| `purple` / `darkpurple` / `lightpurple` | Purple background variants |
You can use predefined style names directly in formatter rules:
```yaml theme={null}
formatters:
statusColor:
- expression: "value === 'Approved'"
style: green
- expression: "value === 'Rejected'"
style: red
- expression: 'true'
style: grey
```
**Custom styles override predefined names**
If you define a style in the `styles` section with the same name as a predefined style, your custom definition takes priority. The 20 predefined styles serve as defaults that are merged with your custom styles.
## Verification
After saving your configuration changes:
1. Reload the sheet in Polarion with a full browser reload (press `F5`, or `Ctrl+R` / `Cmd+R`)
2. You should now see cells in the formatted columns displaying the conditional styles you defined
3. Verify that cells matching your expression conditions show the correct background color and text styling
4. For read-only formatters, confirm that clicking the cell does not enter edit mode and the grey background is visible
If no styling appears, check that the `formatter` value on the column matches a key in the `formatters` section, and that each `style` value within the formatter matches a key in the `styles` section.
## See Also
* [Apply Column Styles](/powersheet/guides/sheet-configuration/apply-style) -- apply cell, header, and column-group styles, including styling the headers of columns within a group
* [Configure a Column Group](/powersheet/guides/sheet-configuration/configure-column-group) -- visually organize related columns with shared styling
* [Configure Read-Only Column](/powersheet/guides/sheet-configuration/configure-read-only-column) -- enforce read-only behavior at the column level
* [Add a Column](/powersheet/guides/sheet-configuration/add-column) -- basic column configuration properties
* [Create a View](/powersheet/guides/sheet-configuration/create-view) -- define named view presets with different column visibility
* [Keyboard Shortcuts](/powersheet/reference/keyboard-shortcuts) -- row grouping, column freezing, and other in-sheet shortcuts
* [Sheet Configuration Reference](/powersheet/reference/sheet-config/index) -- complete property reference for sheet configuration YAML
# Configure Multi-Item Column
Source: https://learn.nextedy.com/powersheet/guides/sheet-configuration/configure-multi-item-column
Set up a column in Nextedy POWERSHEET that displays and edits multiple related entities within a single cell using the `multiItem` property in your sheet configuration.
## When to Use multiItem
Use `multiItem: true` when a column binding path points to a **many-to-many relationship** in the data model. In these cases, a single parent entity can link to multiple child entities, and those child entities can also link back to multiple parents. Common scenarios include:
* Verification test cases linked to requirements
* Validation test cases linked to requirements
* Risk controls linked to hazards
Without `multiItem: true`, the column treats the binding as a single-value reference and only displays one item.
**multiItem is for many-to-many relationships**
The `multiItem` property works with **many-to-many relationships** that use association entities in the data model. It does not support one-to-many relationships. If your relationship is one-to-many (a parent expanding to child rows), use a standard expansion path with nested columns instead.
Before configuring the column, confirm that the relationship in your data model is defined as many-to-many. The relationship must use an association entity type to connect the two sides. For example, a `SystemRequirement` linked to multiple `VerificationTestCase` entities:
```yaml theme={null}
# Data model excerpt
relationships:
- name: verificationTestCases
from: SystemRequirement
to: VerificationTestCase
type: many-to-many
```
The binding path in your column configuration must follow the navigation property names defined in the data model.
In the `columns` section of your sheet configuration, add a column whose key is the full binding path to the collection navigation property. Set `multiItem: true`:
```yaml theme={null}
columns:
verificationTestCases.verificationTestCase:
title: Verification Test Cases
multiItem: true
display: title
width: 250
```
| Property | Type | Default | Purpose |
| ----------- | ------- | ------- | --------------------------------------------------------------------------------------------------- |
| `multiItem` | boolean | `false` | Enables multi-value display and editing for collection columns |
| `display` | string | `id` | Which property of the referenced entity to show (`title`, `titleOrName`, or a custom property path) |
When `multiItem` is `true`, the cell renders all linked entities as a list and provides a multi-reference picker for adding or removing items.
The `sources` section **must** include an `expand` entry for the collection relationship. Without this expansion, the column has no data to display:
```yaml theme={null}
sources:
- id: systemRequirements
model: rtm
query:
from: SystemRequirement
expand:
- name: verificationTestCases
```
Each `expand` entry corresponds to a navigation property in the data model. The names must match exactly.
**Missing expansion is the most common multi-item error**
If you add `multiItem: true` to a column but forget the corresponding `expand` entry in `sources`, the column appears empty with no error message. Always verify that every multi-item column has a matching expansion path.
For multi-item columns, add a `list` property to control the reference picker dropdown. The `list.search` array defines which entity properties users can search when selecting items:
```yaml theme={null}
columns:
verificationTestCases.verificationTestCase:
title: Verification Test Cases
multiItem: true
display: title
list:
search:
- title
- id
createNew: true
```
* **`list.search`** -- array of property names the picker searches against as the user types
* **`list.createNew`** -- set to `true` to allow creating a new entity directly from the picker dropdown without leaving the sheet
In a full traceability matrix, you may need multi-item columns at multiple levels of the hierarchy. Each level requires its own expansion path in `sources`:
```yaml theme={null}
sources:
- id: userNeeds
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: verificationTestCases
- name: designRequirements
expand:
- name: verificationTestCases
columns:
systemRequirements.systemRequirement:
title: System Requirements
multiItem: true
display: title
list:
search:
- title
- id
systemRequirements.systemRequirement.verificationTestCases.verificationTestCase:
title: Verification Tests (SysReq)
multiItem: true
display: title
list:
search:
- title
systemRequirements.systemRequirement.designRequirements.designRequirement:
title: Design Requirements
multiItem: true
display: title
systemRequirements.systemRequirement.designRequirements.designRequirement.verificationTestCases.verificationTestCase:
title: Verification Tests (DesReq)
multiItem: true
display: title
```
Notice how each column's binding path mirrors the nesting in the `expand` section. Every dot-separated segment must have a corresponding expansion entry.
**Second linked entity type requires multiItem**
When a parent entity links to two different entity types (for example, a `SystemRequirement` linked to both `DesignRequirement` and `VerificationTestCase`), the second linked column **must** use `multiItem: true`. This is a non-obvious requirement that consistently blocks new users during initial setup.
You can combine `multiItem` with other column properties for additional control:
```yaml theme={null}
columns:
verificationTestCases.verificationTestCase:
title: Verification Test Cases
multiItem: true
display: title
isReadOnly: true
columnGroup: testCases
visible: true
minWidth: 200
formatter: statusFormatter
```
* **`isReadOnly`** -- prevents editing while still displaying linked items
* **`columnGroup`** -- assigns the column to a visual group (see [Configure a Column Group](/powersheet/guides/sheet-configuration/configure-column-group))
* **`formatter`** -- applies conditional styling (see [Configure a Formatter](/powersheet/guides/sheet-configuration/configure-formatter))
* **`visible`** -- set to `false` to hide the column in the default view while keeping it available in named views (see [Create a View](/powersheet/guides/sheet-configuration/create-view))
**Start simple, extend incrementally**
Begin with a minimal single-item configuration and verify it works before adding multi-item columns. Jumping straight to complex multi-item setups leads to hard-to-diagnose errors. Add one multi-item column at a time and confirm each one displays data correctly before proceeding.
## Verify Your Configuration
After saving the sheet configuration:
1. Reload the powersheet document
2. You should now see the multi-item column displaying linked entities as a comma-separated list in each cell
3. Click a cell in the multi-item column -- a reference picker should appear, allowing you to search, add, or remove linked entities
4. If the column appears empty, check that the `expand` path in `sources` matches the column binding path exactly
**Verify in application**
The multi-reference picker behavior (including search results and the "Add New" option) depends on the server-side query configuration. If the picker returns unexpected results, verify that the data model relationship and expansion paths are correctly defined.
## See Also
* [Add a Column](/powersheet/guides/sheet-configuration/add-column) -- basics of column configuration and binding paths
* [Configure Sources](/powersheet/guides/sheet-configuration/configure-sources) -- defining data sources and expansion paths
* [Configure a Column Group](/powersheet/guides/sheet-configuration/configure-column-group) -- organizing multi-item columns into visual groups
* [Add External Reference Column](/powersheet/guides/sheet-configuration/add-external-reference-column) -- linking to entities outside the current document
* [Fix Multi-Item Column Errors](/powersheet/guides/troubleshooting/fix-multi-item-errors) -- troubleshooting common multi-item issues
* [Create Bidirectional Links](/powersheet/guides/data-model/create-bidirectional-links) -- setting up the data model relationships that multi-item columns depend on
# Configure Read-Only Column
Source: https://learn.nextedy.com/powersheet/guides/sheet-configuration/configure-read-only-column
Prevent users from editing specific columns in Nextedy POWERSHEET by setting the `isReadOnly` property or applying a read-only formatter in your sheet configuration.
## Prerequisites
Before configuring read-only columns, ensure you have:
* A working sheet configuration YAML file
* Access to the project's sheet configuration in **Administration > Nextedy Powersheet**
* Familiarity with the [column properties](/powersheet/reference/sheet-config/index) available in Powersheet
**Formatters style only -- they do not enforce**
A read-only **formatter** applies visual styling only (for example, a grey background). It does **not** prevent editing on its own. To actually enforce that a column cannot be changed, set `isReadOnly: true` on the column (UI-level) and/or `updatable: false` on the property in the data model (server-level). Use the formatter alongside these to signal read-only status to users -- not in place of them.
Add `isReadOnly: true` to any column definition in your sheet configuration to disable editing for that column:
```yaml theme={null}
columns:
outlineNumber:
title: "#"
width: 80
isReadOnly: true
systemRequirements.systemRequirement.id:
title: "Req ID"
width: 120
isReadOnly: true
```
The `isReadOnly` property accepts a boolean value and defaults to `false`. When set to `true`, cells in that column cannot be modified regardless of user permissions or formatter rules.
| Property | Type | Default | Description |
| ------------ | ------- | ------- | ------------------------------------ |
| `isReadOnly` | boolean | `false` | Prevents user editing of this column |
**Document-level override**
The `isReadOnly` value on a column can be overwritten by the user's permission level or the global configuration of the document. If a user has read-only access to the entire document, all columns become read-only regardless of individual column settings.
Setting `isReadOnly: true` prevents editing but does not change the column's appearance. To add a visual cue so users can immediately see which columns are non-editable, combine the property with a formatter:
```yaml theme={null}
formatters:
readOnlyFormat:
- expression: "true"
style: readOnlyStyle
styles:
readOnlyStyle:
backgroundColor: grey100
columns:
outlineNumber:
title: "#"
width: 80
isReadOnly: true
formatter: readOnlyFormat
```
This approach provides both functional protection (the cell cannot be edited) and a visual indicator (the grey background signals read-only status to users).
`grey100` is one of Powersheet's built-in **color tokens**. For the full palette of valid token names (each color family runs from `100` lightest to `700` darkest) and the predefined style names, see the [Styles reference](/powersheet/reference/sheet-config/styles#color-token-reference).
**Use a shared formatter for consistency**
Define a single `readOnlyFormat` formatter and reference it across all read-only columns. This keeps your configuration DRY and ensures a uniform appearance throughout the sheet.
For columns that should be read-only only under certain conditions, use a formatter with a conditional expression instead of a static `isReadOnly` flag:
```yaml theme={null}
formatters:
lockedWhenApproved:
- expression: "context.entity.Status === 'Approved'"
style: readOnlyStyle
styles:
readOnlyStyle:
backgroundColor: grey100
columns:
title:
title: "Title"
width: 300
formatter: lockedWhenApproved
```
In this example, the `title` column becomes visually styled as read-only when the work item's `Status` is `Approved`. The formatter expression has access to the `context` object, which provides:
* `context.entity` -- the current entity (row data)
* `context.value` -- the current cell value
* `context.document` -- the document data
**Property names are case-sensitive**
In client-side expressions, `context.entity.` must match the property name as defined in your data model **exactly**, including case. The examples here use `Status` because that is the property name in the demo model; substitute your own model's casing. This client-side accessor is distinct from the server-side Velocity form `$item.status.id` used in [server-rendered templates](/powersheet/reference/server-rendering/velocity-templates) -- do not mix the two notations.
**Verify in application**
Conditional formatter expressions apply visual styling. To fully enforce editing restrictions based on status, combine formatters with data model constraints or document-level permissions.
## How Read-Only Resolution Works
Powersheet evaluates multiple conditions to determine whether a column is editable. A column becomes read-only if **any** of these conditions are true:
1. **Configuration flag** -- `isReadOnly: true` is set on the column in the sheet configuration YAML
2. **Historical revision** -- The user is viewing a past revision of the document (all columns automatically become read-only)
3. **User permission** -- The document access control grants the user only viewer (not editor) access
4. **Computed column** -- The column declares a `value` expression, so its content comes from the expression rather than from input
**Troubleshooting: a column is read-only when you did not expect it**
Because the conditions above are combined with OR, any single one makes the column read-only. Work backwards from the symptom:
* **Every column in the document is read-only** -- check conditions 2 and 3: you are most likely viewing a past revision, or your access to the document is viewer-only.
* **One specific column is always read-only** -- check condition 1 (`isReadOnly: true` on that column), condition 4 (a `value` expression on that column), and the data model (`updatable: false`, or a `serverRender` annotation, on the underlying property).
* **A formatter-styled column looks locked but still edits** -- that is expected: a formatter only styles, it does not enforce (see the warning at the top of this page).
**Computed columns are read-only by definition**
A column with a `value` expression takes its content from that expression, so declaring `isReadOnly: true` on it is redundant. A column whose binding key is `$`-prefixed goes further: it is **unbound**, stores nothing, and is forced read-only -- not only in the editing UI but on every write path, so paste and fill cannot change it either. See [Add a Computed Column](/powersheet/guides/sheet-configuration/add-computed-column).
**System-managed and server-rendered columns are always read-only**
Certain columns such as `outlineNumber` are inherently managed by Polarion and should always have `isReadOnly: true`. In addition -- **this is the canonical rule referenced from the server-rendering pages** -- any property that defines a `serverRender` annotation, or that has `updatable: false` in the data model, is automatically read-only regardless of the sheet configuration. For server-rendered properties this override cannot be disabled: even `updatable: true` is ignored, because the value is always recomputed from the template.
## Complete Configuration Example
Here is a full sheet configuration excerpt showing multiple read-only patterns in a requirements traceability context:
```yaml theme={null}
formatters:
readOnlyFormat:
- expression: "true"
style: readOnlyStyle
lockedOnApproval:
- expression: "context.entity.Status === 'Approved'"
style: readOnlyStyle
styles:
readOnlyStyle:
backgroundColor: grey100
columns:
outlineNumber:
title: "#"
width: 80
isReadOnly: true
formatter: readOnlyFormat
id:
title: "ID"
width: 100
isReadOnly: true
formatter: readOnlyFormat
hasUrl: true
title:
title: "Title"
width: 300
hasFocus: true
formatter: lockedOnApproval
systemRequirements.systemRequirement.id:
title: "Sys Req ID"
width: 120
isReadOnly: true
formatter: readOnlyFormat
systemRequirements.systemRequirement.title:
title: "Sys Req Title"
width: 250
```
In this example:
* `outlineNumber` and `id` are always read-only with grey background styling
* `title` becomes visually styled when the item status is `Approved`
* The expanded `systemRequirement.id` column is read-only since IDs should not be user-editable
* `systemRequirement.title` remains editable (no `isReadOnly` flag)
## Property-Level Permissions in the Data Model
You can also control editability at the data model level using the `readable` and `updatable` properties on entity type definitions:
```yaml theme={null}
domainModelTypes:
UserNeed:
properties:
id:
readable: true
updatable: false
title:
readable: true
updatable: true
```
| Property | Default | Description |
| ----------- | ------- | ------------------------------------------------------ |
| `readable` | `true` | Controls whether the property is visible to users |
| `updatable` | `false` | Controls whether the property can be modified by users |
When `updatable` is `false`, the column becomes read-only for that property regardless of the sheet configuration `isReadOnly` setting.
`updatable` defaults to `false` for every property, ordinary ones included -- a property is read-only unless you explicitly set `updatable: true`. A property with a `serverRender` annotation is read-only too, but for a different reason: Powersheet forces its effective value to `false` and ignores any `updatable: true` you set (see the [Velocity Templates reference](/powersheet/reference/server-rendering/velocity-templates#server-rendered-property-configuration)) -- unlike an ordinary property, an explicit override can never make it editable.
**Combine approaches for defense in depth**
Use `isReadOnly` in the sheet configuration for UI-level protection and `updatable: false` in the data model for server-level enforcement. This ensures data integrity even if a configuration is accidentally changed.
## Verification
After saving your sheet configuration changes, reload the Powersheet document in Polarion:
1. Open the sheet and click on a cell in the read-only column -- you should see that the cell does not enter edit mode and the selection marquee shows a read-only indicator
2. If you applied a formatter, verify the grey background (or your custom style) appears on the read-only cells
3. Try pasting into a read-only column -- the paste operation should be blocked
4. Confirm that editable columns next to the read-only ones still accept input normally
You should now see that the configured columns are protected from editing, with visual styling distinguishing them from editable columns.
## See Also
* [Add a Column](/powersheet/guides/sheet-configuration/add-column) -- basic column setup and property binding
* [Add a Computed Column](/powersheet/guides/sheet-configuration/add-computed-column) -- columns whose content comes from an expression, and are therefore read-only
* [Configure a Formatter](/powersheet/guides/sheet-configuration/configure-formatter) -- conditional formatting and style rules
* [Apply Column Styles](/powersheet/guides/sheet-configuration/apply-style) -- custom visual styling for columns
* [Configure Permissions](/powersheet/guides/administration/configure-permissions) -- document-level access control
* [Sheet Configuration Reference](/powersheet/reference/sheet-config/index) -- complete property reference
# Configure Sources
Source: https://learn.nextedy.com/powersheet/guides/sheet-configuration/configure-sources
Define data sources in your Nextedy POWERSHEET sheet configuration to control which entities are loaded, how they are filtered, and which relationships are expanded for display in the sheet.
## Define a Basic Source
The `sources` section is an array at the root level of your sheet configuration YAML. Each source specifies a unique identifier, the data model it queries against, a query targeting an entity type, and optional expansion paths:
```yaml theme={null}
sources:
- id: user_needs
model: rtm
query:
from: UserNeed
expand:
- name: systemRequirements
```
| Property | Required | Description |
| --------------- | -------- | ------------------------------------------------------------------------------ |
| `id` | Yes | Unique identifier for the source, referenced from tool settings |
| `model` | Yes | Data model name the source queries (must match a configured model, e.g. `rtm`) |
| `query.from` | Yes | Root entity type to query (must exist in the data model) |
| `query.where` | No | Filter predicate to restrict which entities are loaded |
| `query.orderBy` | No | Server-side sort order for the query results |
| `query.take` | No | Maximum number of root entities to load |
| `expand` | No | Array of expansion paths for loading related entities |
| `entityFactory` | No | Default property values applied when creating new entities |
**Use the Model Helper to verify bindings**
The Model Helper widget visualizes the data model structure and correct expansion paths. See [Use Model Helper Widget](/powersheet/guides/customization/use-model-helper) for details.
## Expand Relationships
The `expand` array defines which related entities are loaded alongside the root entity. Each entry uses the `name` property corresponding to a navigation property from your data model relationships:
```yaml theme={null}
sources:
- id: user_needs
model: rtm
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: systemRequirement
expand:
- name: designRequirements
expand:
- name: designRequirement
```
Nested `expand` entries create multi-level hierarchies. The expansion path structure must match the `direct` and `back` navigation property names defined in your data model relationships.
**Start simple, extend incrementally**
Begin with a single-level expansion and verify it loads correctly before adding deeper levels. Jumping straight to complex multi-level expansions leads to hard-to-diagnose errors that are difficult to trace.
### Expansion by Cardinality
The cardinality of a relationship determines the expand pattern and how columns bind to expanded data:
| Cardinality | Model Direction | Source Expand | Column Binding | UI Behavior |
| ---------------------- | ------------------------ | ------------------------------------------------------------- | -------------------------------------- | ----------------------------- |
| **N:1** (many-to-one) | `direct` name (singular) | `- name: chapter` | `chapter`, `chapter.title` | Single-value reference picker |
| **1:N** (one-to-many) | `back` name (plural) | `- name: userNeeds` | `userNeeds` | Child rows (new sheet level) |
| **M:N** (many-to-many) | `back` name (plural) | `- name: systemRequirements` then `- name: systemRequirement` | `systemRequirements.systemRequirement` | Multi-item reference picker |
For many-to-many relationships, the expand must go through the association entity first, then to the target entity. This two-level expand pattern is required:
```yaml theme={null}
expand:
- name: systemRequirements # association collection
expand:
- name: systemRequirement # target entity
```
For a complete walkthrough of expansion patterns, see [Expand Navigation Properties](/powersheet/guides/queries/expand-navigation-properties).
## Filter with a WHERE Clause
Use the `query.where` property to restrict which entities are loaded. The where clause uses predicate syntax:
```yaml theme={null}
sources:
- id: active_needs
model: rtm
query:
from: UserNeed
where:
severity:
"!=": "low"
expand:
- name: systemRequirements
```
You can also use dynamic value expressions with the `() =>` arrow function syntax to build runtime-evaluated filters. For example, to filter by a date or a document parameter:
```yaml theme={null}
sources:
- id: recent_items
model: rtm
query:
from: UserNeed
where:
dueDate:
">": "() => new Date().toISOString()"
```
```yaml theme={null}
sources:
- id: filtered_by_param
model: rtm
query:
from: UserNeed
where:
Client:
"==": "() => `${context.parameters.client}`"
```
**Dynamic expression format**
The `() =>` notation evaluates at runtime. For date predicates, ensure the expression returns an ISO string using `.toISOString()`. For parameters, use `context.parameters.` to inject values from the document configuration.
## Set Default Values with Entity Factory
The `entityFactory` property defines default property values applied when a user creates a new entity from the sheet. This works at any expand level:
```yaml theme={null}
sources:
- id: user_needs
model: rtm
query:
from: UserNeed
entityFactory:
Status: "Planned"
Priority: "Medium"
expand:
- name: systemRequirements
entityFactory:
Status: "Draft"
expand:
- name: systemRequirement
```
Entity factory values can also use dynamic expressions:
```yaml theme={null}
entityFactory:
Client: "() => context.parameters.client"
```
## Configure Multiple Sources
A sheet configuration can define multiple sources. Each source must have a unique `id` and reference a `model`:
```yaml theme={null}
sources:
- id: user_needs
model: rtm
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: systemRequirement
- id: hazards
model: rtm
query:
from: Hazard
expand:
- name: riskControls
expand:
- name: riskControl
```
Multiple sources allow a single sheet to display data from different parts of the data model, each with its own query filters and expansion hierarchy.
## Limit Results with Take
Use `query.take` to cap the number of root entities returned by a source. This is useful for large datasets where loading all entities would impact performance:
```yaml theme={null}
sources:
- id: top_items
model: rtm
query:
from: UserNeed
take: 100
orderBy: severity desc
expand:
- name: systemRequirements
```
**Combine take with orderBy**
When using `take` to limit results, pair it with `orderBy` so you control which entities are included. Without ordering, the subset returned is unpredictable.
## Complete Configuration Example
Here is a full sources section for a requirements traceability matrix that queries user needs, expands through system requirements to design requirements, and sets default values for new entities:
```yaml theme={null}
sources:
- id: user_needs
model: rtm
query:
from: UserNeed
where:
severity:
"!=": "low"
orderBy: title asc
entityFactory:
Status: "Planned"
expand:
- name: systemRequirements
expand:
- name: systemRequirement
entityFactory:
Status: "Draft"
expand:
- name: designRequirements
expand:
- name: designRequirement
```
## Verify Your Configuration
After saving your sheet configuration YAML:
1. Open the Powersheet document in Polarion
2. The sheet should load and display the root entities defined by `query.from`
3. Verify that expansion arrows appear on rows -- clicking them loads related entities at each level
4. Create a new entity to confirm `entityFactory` defaults are applied correctly
5. If using `where` filters, confirm that only matching entities appear
You should now see the sheet populated with your source data and the expansion hierarchy matching your data model relationships.
## See Also
* [Expand Navigation Properties](/powersheet/guides/queries/expand-navigation-properties) -- detailed guide on expansion paths and cardinality patterns
* [Add a Column](/powersheet/guides/sheet-configuration/add-column) -- bind columns to properties from your expanded sources
* [Configure a Relationship](/powersheet/guides/data-model/configure-relationship) -- set up `direct` and `back` navigation properties in the data model
* [Use Model Helper Widget](/powersheet/guides/customization/use-model-helper) -- visual tool for exploring data model structure
* [Configure Dynamic Expressions](/powersheet/guides/sheet-configuration/configure-dynamic-expressions) -- full reference on `() =>` expression syntax and the context object
* [Write an Entity Query](/powersheet/guides/queries/write-entity-query) -- query syntax for `from`, `where`, and `orderBy` clauses
# Create a View
Source: https://learn.nextedy.com/powersheet/guides/sheet-configuration/create-view
Define named views in your Nextedy POWERSHEET sheet configuration to create switchable column visibility presets, allowing users to focus on different analysis perspectives without changing the underlying data.
1. Open your powersheet document
2. Go to **Menu > Configuration > Edit Sheet Configuration**
3. Locate or add a `views` section in the YAML
Each view is a named entry under the `views` section. It specifies which columns to hide by setting their `visible` property to `false`:
```yaml theme={null}
views:
Without V&V:
columns:
validationTestCases.validationTestCase:
visible: false
systemRequirements.systemRequirement.verificationTestCases.verificationTestCase:
visible: false
```
This creates a view called "Without V\&V" that hides the validation and verification test case columns while keeping all other columns visible.
| Property | Description |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| View name (key) | Display name shown in the view switcher (e.g., `Without V&V`) |
| `default` | Set to `true` to apply this view automatically when the document loads. Only one view should be marked as the default. |
| `columns` | Object defining column visibility overrides for this view |
| `columns.` | Column identified by its binding path from the `columns` section |
| `columns..visible` | Set to `false` to hide the column in this view |
Mark a view as the default by adding `default: true` to it; that view then loads automatically instead of the base view. See the [Views reference](/powersheet/reference/sheet-config/views) for full default-view behavior.
**Views only override visibility**
Views control which columns are shown or hidden. They do not change column widths, formatters, or other properties. All columns not mentioned in the view remain visible at their default settings.
Define several views for different analysis needs:
```yaml theme={null}
views:
Full RTM:
columns: {}
Requirements Only:
columns:
hazard:
visible: false
riskControls.riskControl:
visible: false
verificationTestCases.verificationTestCase:
visible: false
validationTestCases.validationTestCase:
visible: false
Risk Analysis:
columns:
systemRequirements.systemRequirement.designRequirements.designRequirement:
visible: false
verificationTestCases.verificationTestCase:
visible: false
validationTestCases.validationTestCase:
visible: false
```
In the sheet UI, users switch views using the view selector in the toolbar. When a view is applied:
1. Column visibility updates immediately based on the view definition
2. To return to the base view, clear the view selection
**Use views for wide sheets with many columns**
Views are especially helpful for RTM configurations with 20+ columns spanning requirements, design, risks, and tests. Define task-specific views so users see only what they need for their current work.
**Binding paths must match exactly**
The column binding paths in the view definition must match the binding paths used in the `columns` section exactly. A mismatch will cause the visibility override to be silently ignored.
## Complete Example
```yaml theme={null}
columns:
title:
title: User Need
width: 200
systemRequirements.systemRequirement:
title: System Req
multiItem: true
display: title
hazard:
title: Hazard
display: title
riskControls.riskControl:
title: Risk Control
multiItem: true
display: title
views:
Requirements Focus:
default: true
columns:
hazard:
visible: false
riskControls.riskControl:
visible: false
Risk Focus:
columns:
systemRequirements.systemRequirement:
visible: false
```
## Verify
After saving the sheet configuration, reload the powersheet document. You should now see:
* The view selector appears in the toolbar with your defined view names
* Selecting a view hides the specified columns immediately
* Clearing the view selection restores all columns to their default visibility
## See Also
* [Add a Column](/powersheet/guides/sheet-configuration/add-column) -- define the columns that views control
* [Configure a Column Group](/powersheet/guides/sheet-configuration/configure-column-group) -- visually organize columns
* [Configure Collapsible Groups](/powersheet/guides/sheet-configuration/configure-collapsible-groups) -- collapse column groups as an alternative to views
* [Assign Configuration to Document](/powersheet/guides/sheet-configuration/assign-config-to-document) -- link configuration to documents
# Download Configuration as YAML
Source: https://learn.nextedy.com/powersheet/guides/sheet-configuration/download-config-as-yaml
Export an existing Nextedy POWERSHEET sheet configuration as a YAML file for offline editing, version control, or migration to another project.
## Prerequisites
* Access to **Administration > Nextedy Powersheet > Configurations** in your Siemens Polarion ALM project
* An existing sheet configuration you want to download
1. Navigate to **Administration > Nextedy Powersheet > Configurations**
2. You will see a list of all available sheet configurations for the current scope (project, project group, or global)
The configuration manager is available at three scope levels:
| Scope | What It Shows |
| ------------------- | ----------------------------------------------- |
| Project | Configurations stored in the project repository |
| Project Group | Configurations shared across a project group |
| Global (Repository) | Configurations available to all projects |
Find the configuration you want to download. Project-specific configurations appear by filename. Global configurations are listed with their full repository path.
**Use the file manager interface**
The configuration manager provides a file manager interface where you can browse, open, and download YAML files. Look for the download or export option for the configuration you want to retrieve.
Open the desired configuration entry. The YAML content is displayed in the editor. You can:
1. **Copy the YAML content** directly from the editor and paste it into your local text editor
2. **Use the file manager download** option if available in your Powersheet version
The downloaded file contains the complete sheet configuration including:
```yaml theme={null}
columnGroups:
Requirements:
groupName: Requirements
groupStyle: blue
collapseTo: systemRequirements.systemRequirement.title
columns:
title:
title: Title
width: 250
hasFocus: true
systemRequirements.systemRequirement.title:
title: Sys Req
width: 200
columnGroup: Requirements
views:
Summary:
title:
visible: true
systemRequirements.systemRequirement.title:
visible: false
formatters:
readOnly:
- expression: "true"
style: readonly
sources:
- id: main
title: User Needs
model: rtm-model
query:
from: UserNeed
expand:
- name: systemRequirements
title: System Requirements
```
**Verify in application**
The exact download mechanism may vary depending on your Powersheet version and the file manager interface. If a direct download button is not available, copy the YAML content from the configuration editor.
Once you have the YAML file locally, you can edit it with any text editor or IDE that supports YAML syntax highlighting. Common modifications include:
* Adding or removing columns
* Adjusting column widths and formatters
* Modifying expansion paths in sources
* Creating new views
**Validate YAML syntax before uploading**
Powersheet does not validate YAML content before saving to the repository. Syntax errors in your YAML (incorrect indentation, missing colons, tab characters) will cause the configuration to fail when loaded. Always validate your YAML with a linter before uploading.
After making changes:
1. Return to **Administration > Nextedy Powersheet > Configurations**
2. Open the configuration you downloaded or create a new entry
3. Paste or upload the modified YAML content
4. Save the configuration
The updated configuration takes effect immediately for any document referencing it. Users need to reload the powersheet document to see changes.
## Verification
After downloading and re-uploading a configuration:
1. Open a LiveDoc that references the configuration
2. You should now see the sheet reflect any changes you made to the YAML
3. Verify that all columns load correctly and data sources return expected results
## See Also
* [Assign Configuration to Document](/powersheet/guides/sheet-configuration/assign-config-to-document) -- link a configuration to a LiveDoc
* [Creating Your First Sheet Configuration](/powersheet/getting-started/first-sheet-configuration) -- build a new configuration from scratch
* [Configure Sources](/powersheet/guides/sheet-configuration/configure-sources) -- define data sources within the YAML
* [Add a Column](/powersheet/guides/sheet-configuration/add-column) -- add columns to your configuration
# Sheet Configuration Guides
Source: https://learn.nextedy.com/powersheet/guides/sheet-configuration/index
These guides cover all aspects of configuring Nextedy POWERSHEET sheet configurations -- from adding columns and defining views to applying styles, formatters, and data sources.
## Column Setup
**[Add a Column](/powersheet/guides/sheet-configuration/add-column)** -- Define columns in your sheet configuration using binding paths to entity properties
**[Add a Computed Column](/powersheet/guides/sheet-configuration/add-computed-column)** -- Derive a column's content from an expression, stored back to a property or displayed only
**[Configure a Column Group](/powersheet/guides/sheet-configuration/configure-column-group)** -- Organize related columns under collapsible group headers with shared styling
**[Configure Collapsible Groups](/powersheet/guides/sheet-configuration/configure-collapsible-groups)** -- Enable collapse/expand behavior for column groups
**[Add External Reference Column](/powersheet/guides/sheet-configuration/add-external-reference-column)** -- Display external reference work items linked through relationships
**[Configure Multi-Item Column](/powersheet/guides/sheet-configuration/configure-multi-item-column)** -- Show and edit one-to-many or many-to-many relationships in a single column
**[Configure Read-Only Column](/powersheet/guides/sheet-configuration/configure-read-only-column)** -- Prevent user editing on specific columns
## Display and Formatting
**[Apply Column Styles](/powersheet/guides/sheet-configuration/apply-style)** -- Use predefined or custom styles for column headers and cells
**[Configure a Formatter](/powersheet/guides/sheet-configuration/configure-formatter)** -- Apply conditional formatting rules with expressions and styles
**[Use JavaScript Display Functions](/powersheet/guides/sheet-configuration/use-javascript-display)** -- Render custom HTML in cells using JavaScript arrow functions
## Views and Layout
**[Create a View](/powersheet/guides/sheet-configuration/create-view)** -- Define named column visibility presets for switching between different analysis perspectives
## Data Sources and Assignment
**[Configure Sources](/powersheet/guides/sheet-configuration/configure-sources)** -- Define data sources, queries, and expansion paths for loading entity hierarchies
**[Assign Configuration to Document](/powersheet/guides/sheet-configuration/assign-config-to-document)** -- Link a sheet configuration to a Polarion LiveDoc
**[Download Configuration as YAML](/powersheet/guides/sheet-configuration/download-config-as-yaml)** -- Export your current sheet configuration for backup or sharing
**Start with a minimal configuration**
Begin with a single entity type, a few columns, and one data source. Extend incrementally -- adding column groups, formatters, and views once the basics are working. See [Incremental Configuration Approach](/powersheet/getting-started/incremental-configuration) for guidance.
## See Also
* [Creating Your First Sheet Configuration](/powersheet/getting-started/first-sheet-configuration) -- step-by-step tutorial
* [Data Model Guides](/powersheet/guides/data-model/index) -- configure the data model referenced by your sheet
* [Reference](/powersheet/reference/index) -- complete property reference for all configuration options
# Open a Scoped Sheet with URL Parameters
Source: https://learn.nextedy.com/powersheet/guides/sheet-configuration/parametrize-sheet-url
Configure a Nextedy POWERSHEET sheet to read values from its URL and scope the Siemens Polarion ALM query server-side, so a single configuration serves many shareable, pre-filtered views.
This guide shows how to make one sheet configuration serve many pre-filtered views by reading values from the URL. Each parametrised URL scopes the query on the server, is shareable, and survives a refresh. For the underlying ideas, see [URL Parameters](/powersheet/concepts/url-parameters) (how values reach the configuration) and [Server-Side Filtering](/powersheet/concepts/server-side-filtering) (how a `where` scopes the query on the server).
## Prerequisites
* A [sheet configuration](/powersheet/guides/sheet-configuration/index) with at least one data source
* Familiarity with [dynamic value expressions](/powersheet/guides/sheet-configuration/configure-dynamic-expressions) (`() => …`)
* A property you want to filter on (a primitive field or an enum id)
In the source `query.where`, replace a fixed value with a dynamic expression that reads a URL parameter. The parameter name (`domain` here) is yours to choose:
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
where:
severity: "() => context.parameters.domain"
```
Each key in a `where` object is combined with **AND**, so you can keep fixed conditions alongside parameter-driven ones.
Append the parameter to the sheet's URL as a normal query parameter:
```
…?_document=&domain=HW
```
The value `HW` is injected into the query before it runs, so Polarion returns only the matching rows. Change `domain=SW` and the same configuration returns the software slice instead. The URL is shareable and reloads to the same data.
**Where the URL is built**
In a typical setup the parametrised link is constructed by the entry point that opens the sheet -- for example a Polarion custom report or a document link that appends the parameter. The sheet itself only reads whatever parameters are present on its URL.
A parameter can also scope a downstream (expanded) entity level, independently of the current document. Add a `query.where` to the expand node:
```yaml theme={null}
sources:
- id: chapters
query:
from: Chapter
expand:
- name: requirements
expand:
- name: requirement
query:
where:
targetSystem: "() => context.parameters.system"
```
Opening the sheet with `…&system=iOS` shows only the expanded requirements whose `targetSystem` is `iOS`, while the parent rows are unaffected. See [Expand Navigation Properties](/powersheet/guides/queries/expand-navigation-properties#filter-an-expanded-level-with-a-subquery) for expand subqueries in depth.
Without a value, a parameter-driven `where` condition is simply dropped and the sheet loads the broader set. When loading everything would be too heavy, declare the parameter in a top-level `parameters` block and mark it `required`, optionally giving it a `default`:
```yaml theme={null}
parameters:
domain:
required: true
ifMissing:
message: "Choose a domain to open this view."
button:
label: "Open selection page"
url: "/polarion/…/select-domain"
status:
default: "open"
```
* A **required** parameter with neither a URL value nor a `default` blocks the sheet and shows the `ifMissing` message and button (administrators additionally get an **Open Configuration** action).
* A **`default`** fills in the value when the URL omits it.
The [sheet header](/powersheet/reference/sheet-config/sheet-header) -- `title`, `subtitle`, and `icon` -- accepts dynamic values too, so it can state which slice a parametrised URL opened. Reflect the parameter in the sheet's name, add the project name, and pick an icon per variant:
```yaml theme={null}
title: "() => context.parameters.viewLabel"
subtitle: "() => `${context.project.name}: Domain ${context.parameters.domain}`"
icon: "() => context.parameters.domain === 'HW' ? 'DeveloperTools' : 'Code'"
```
The whole value must be a single `() => …` expression -- build any surrounding text inside it (a template literal or concatenation) rather than mixing literal text with `() =>`. When an expression resolves to nothing, `title` falls back to the document name, while `subtitle` and `icon` are hidden. See the [Sheet Header reference](/powersheet/reference/sheet-config/sheet-header) for icon glyph-vs-image values and the full fallback rules.
Saved [views](/powersheet/guides/sheet-configuration/create-view) can be selected from the URL with the reserved `_view` system parameter, using the view's id:
```
…?_document=&_view=traceability
```
On load, the sheet applies the referenced view (or the configured default view when `_view` is absent). Because `_view` is part of the URL, the chosen perspective is shareable along with the data scope.
## Verify Your Configuration
1. Open the sheet with a parameter value in the URL and confirm only the matching rows load.
2. Change the value and reload -- the data slice should change accordingly.
3. Remove a **required** parameter from the URL and confirm the sheet shows the missing-parameter message rather than loading everything.
4. Copy the full URL into a new tab and confirm it resolves to the same scoped view.
## See Also
* [URL Parameters](/powersheet/concepts/url-parameters) -- how a URL value reaches the configuration through `context.parameters`
* [Server-Side Filtering](/powersheet/concepts/server-side-filtering) -- why a `where` scopes the query on the server, at the root and on expand levels
* [URL Parameters Reference](/powersheet/reference/sheet-config/url-parameters) -- the `parameters` block schema and reserved names
* [Sheet Header](/powersheet/reference/sheet-config/sheet-header) -- title, subtitle, and icon; glyph-vs-image icons and fallback rules
* [Configure Dynamic Expressions](/powersheet/guides/sheet-configuration/configure-dynamic-expressions) -- the `() => …` syntax
* [Expand Navigation Properties](/powersheet/guides/queries/expand-navigation-properties) -- expand subqueries for downstream levels
* [Create a View](/powersheet/guides/sheet-configuration/create-view) -- saved perspectives selectable via `?_view=`
# Use JavaScript Display Functions
Source: https://learn.nextedy.com/powersheet/guides/sheet-configuration/use-javascript-display
Customize how cell values appear in Nextedy POWERSHEET columns by writing JavaScript arrow functions in the `render`, `display`, and `renderers` configuration properties.
**Advanced topic**
JavaScript display functions are an advanced customization technique. Before using them, ensure you are comfortable with [adding columns](/powersheet/guides/sheet-configuration/add-column) and [configuring formatters](/powersheet/guides/sheet-configuration/configure-formatter).
## Understand render vs display vs renderers
Powersheet offers three properties for controlling cell output. Each serves a distinct purpose:
| Property | Location | Purpose | Modifies data? |
| ----------- | ------------------ | ---------------------------------------------------------------------------------------- | -------------- |
| `display` | Column definition | Select which property of a linked entity to show, or use a JS function for custom output | No |
| `render` | Column definition | Reference a named renderer or inline JS expression for custom HTML | No |
| `renderers` | Root-level section | Define reusable named renderer functions | No |
**render and display are display-only**
Neither `render` nor `display` modify the underlying data -- but neither can supply content of its own either. They restyle whatever the cell already holds.
If you need a **computed** value, use the `value` property on the column instead:
* bind the column to a real property to have the computed result **saved back** to the data source, or
* prefix the binding key with `$` to make the column **unbound**, so the value is computed and shown but never stored.
See [Add a Computed Column](/powersheet/guides/sheet-configuration/add-computed-column).
## Use display for property selection
The simplest use of `display` is selecting which property of a linked entity to show. For scalar navigation properties (n-to-1 relationships), set it to a property name string:
```yaml theme={null}
columns:
hazard:
title: Hazard
display: title
```
This shows the `title` property of the linked `Hazard` entity instead of the default identifier.
## Use display with a JavaScript function
For dynamic cell content, set `display` to a JavaScript arrow function string. The function receives a `context` object and should return an HTML string:
```yaml theme={null}
columns:
systemRequirements.systemRequirement:
title: System Requirement
display: "() => `${context.value.objectId}: ${context.value.title}`"
```
Use the YAML `>` (folded scalar) indicator for multi-line function strings:
```yaml theme={null}
columns:
riskControls.riskControl:
title: Risk Control
display: >
() => `${context.value.objectId}
${context.value.title ? '- ' + context.value.title : ''}`
```
The JavaScript is evaluated in the browser for each cell at render time.
## Use render for custom HTML
The `render` property provides custom HTML rendering for a column. It accepts either an inline JavaScript expression or a reference to a named renderer:
**Inline expression:**
```yaml theme={null}
columns:
title:
title: Title
render: "() => `${context.value} `"
```
**Named renderer reference:**
```yaml theme={null}
columns:
status:
title: Status
render: statusRenderer
```
**`display` vs `render`**
Use `display` when you need to select which property of a navigation property to show, or to format it with JavaScript. Use `render` when you need custom HTML rendering for any column type. When both are set on the same column, `render` takes precedence for visual output.
## Define reusable renderers
The `renderers` section at the root level of the sheet configuration defines named renderer functions. Each renderer is a JavaScript arrow function string with access to the `context` object:
```yaml theme={null}
renderers:
boldName: "() => `${context.value} `"
linkedItems: "() => context.value.map((item) => `${item.name} `).join(', ')"
```
Reference a named renderer from any column's `render` property:
```yaml theme={null}
columns:
title:
title: Title
render: boldName
riskControls.riskControl:
title: Risk Controls
render: linkedItems
multiItem: true
```
**Use named renderers for consistency**
When the same display logic applies to multiple columns, define it once in `renderers` and reference it by name. This avoids duplicating JavaScript across column definitions and makes maintenance easier.
## Customize picker display
The `list.display` property customizes how items appear in dropdown pickers, not in the cell itself:
```yaml theme={null}
columns:
riskControls.riskControl:
title: Risk Control
multiItem: true
list:
search:
- title
- id
display: >
() => `${context.value.objectId}
${context.value.title ? '-- ' + context.value.title : ''}`
```
## Context object reference
Dynamic expressions receive a `context` object. The available properties depend on the evaluation location:
| Property | Available in | Description |
| -------------------------- | ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------- |
| `context.value` | `render`, `display`, `renderers` | The current cell value. It is `undefined` in a `value` expression -- that expression is what produces the value |
| `context.entity` | `render`, `display`, `renderers`, `value`, `formatter` | The entity object for the current row |
| `context.entity.id` | All per-cell contexts | The work item ID |
| `context.entity.projectId` | All per-cell contexts | The project ID |
| `context.document` | `formatter` | Current document information |
| `context.source` | `display`, `value` on an unbound column | Parent entity -- the level the current one was navigated from |
| `context.row` | `value` on an unbound column | The whole row, as `context.row.entities[]` |
**Columns with custom rendering do not show external links**
If a column uses a custom `render` or JavaScript `display` function, the automatic external link (the `hasUrl` feature) will not be displayed for that column. Plan your link rendering within the JavaScript function if you need clickable URLs.
## Complete YAML example
```yaml theme={null}
renderers:
idAndTitle: "() => `${context.value.objectId}: ${context.value.title || ''}`"
boldValue: "() => `${context.value} `"
columns:
outlineNumber:
title: "#"
width: 80
isReadOnly: true
title:
title: Title
width: "*"
hasFocus: true
render: boldValue
hazard:
title: Hazard
display: title
list:
search:
- title
- id
systemRequirements.systemRequirement:
title: System Requirement
render: idAndTitle
list:
search:
- title
- id
display: >
() => `${context.value.objectId}
${context.value.title ? '-- ' + context.value.title : ''}`
riskControls.riskControl:
title: Risk Controls
multiItem: true
render: "() => context.value.map((item) => `${item.objectId} `).join(', ')"
list:
search:
- title
- id
```
## Verify
After saving the sheet configuration, reload the powersheet document. You should now see cells rendering custom HTML content -- bold text, formatted identifiers, or concatenated values -- according to the JavaScript functions you defined. Columns using `render` or `display` functions will show the transformed output instead of raw property values.
## See also
* [Add a Column](/powersheet/guides/sheet-configuration/add-column) -- column basics and property binding
* [Configure a Formatter](/powersheet/guides/sheet-configuration/configure-formatter) -- conditional styling with expressions
* [Configure Dynamic Expressions](/powersheet/guides/sheet-configuration/configure-dynamic-expressions) -- `value`, `() =>` syntax, and the context object
* [Add a Computed Column](/powersheet/guides/sheet-configuration/add-computed-column) -- change what a cell holds, not just how it looks
* [Sheet Configuration Reference](/powersheet/reference/sheet-config/index) -- full property reference
* [Sheet Configuration Guides](/powersheet/guides/sheet-configuration/index)
# Debug Custom Field Issues
Source: https://learn.nextedy.com/powersheet/guides/troubleshooting/debug-custom-field-issues
Diagnose and resolve Nextedy POWERSHEET problems where Polarion custom fields do not appear, display incorrectly, or fail to save in the sheet.
## Identify the Symptom
Custom field issues typically present in one of these ways:
| Symptom | Likely Cause | Jump to |
| ----------------------------------- | ------------------------------------ | ------------------------------------------------------- |
| Column is completely empty | Missing data model property | [Step 1](#step-1-verify-the-data-model-property) |
| Column does not appear at all | Missing sheet configuration column | [Step 2](#step-2-verify-the-sheet-configuration-column) |
| Values display but cannot be edited | Read-only flag or permission issue | [Step 4](#step-4-check-read-only-status) |
| Field type renders incorrectly | Type mapping mismatch | [Step 3](#step-3-verify-type-mapping) |
| Edits do not persist after save | Property name mismatch with Polarion | [Step 5](#step-5-debug-save-failures) |
Custom fields must be declared as properties on the correct entity type in the data model YAML. If the property is missing, the column will appear blank even though work items contain values in Polarion.
Open your data model file and confirm the custom field is listed under the appropriate entity type:
```yaml theme={null}
domainModelTypes:
SystemRequirement:
polarionType: systemRequirement
properties:
description:
severity:
priority:
c_verificationMethod: # Custom field property
```
**Property name must match the Polarion custom field ID exactly**
Polarion custom fields use the `c_` prefix by convention (e.g., `c_riskLevel`, `c_verificationMethod`). The property name in the data model must match the **field ID**, not the display label. Confirm the exact field ID in **Administration > Work Items > Custom Fields**.
If the custom field belongs to a different Polarion work item type than the entity's default, make sure the `polarionType` mapping is set correctly. When the data model entity name differs from the Polarion work item type ID, specify `polarionType` to establish the mapping:
```yaml theme={null}
domainModelTypes:
DesignOutput:
polarionType: designOutput # Maps to Polarion type ID
properties:
c_designCategory:
```
After confirming the data model property exists, verify that a corresponding column is defined in your sheet configuration. Both the model property and the sheet column are required for the field to appear.
Add the column to the sheet configuration using the property name as the column key:
```yaml theme={null}
columns:
c_verificationMethod:
title: "Verification Method"
width: 150
```
For custom fields on **related entities** (accessed via an expansion path), use the full binding path through the relationship:
```yaml theme={null}
columns:
systemRequirements.systemRequirement.c_verificationMethod:
title: "Verification Method"
width: 180
```
**Common first-time mistake: starting too complex**
New users often jump straight to multi-level configurations with custom fields on related entities. Start with a minimal single-entity setup and verify each custom field works before extending to relationships. This approach makes it much easier to isolate which part of the configuration is causing problems.
Powersheet automatically maps Polarion field types to appropriate data types through the metadata system. If your custom field appears but renders incorrectly (for example, a date showing as plain text), check that Polarion recognizes the field type correctly.
The automatic type conversion supports these Polarion types:
| Polarion Type | Mapped Behavior | Common Issue |
| -------------------- | ---------------------- | ------------------------------------- |
| `String` | Text input | Renders correctly by default |
| `Integer` | Numeric input | Ensure saved value is numeric |
| `Float` / `Currency` | Decimal input | Check decimal precision in Polarion |
| `Boolean` | Checkbox toggle | Value must be `true` or `false` |
| `Date` / `DateOnly` | Date picker | Format mismatch if field type changed |
| `Text` | Rich text / multi-line | May need formatter for display |
**Enum fields require matching values**
If your custom field uses an enumeration type, the enum values in Polarion must be correctly defined. Powersheet reads the allowed values from the Polarion type system. If the dropdown is empty or shows unexpected options, verify the enum definition in **Administration > Enumerations** for the correct work item type and project scope.
If the column appears but cannot be edited, check these areas in order:
**1. Column-level `isReadOnly` flag**
Verify the column is not explicitly set to read-only in the sheet configuration:
```yaml theme={null}
columns:
c_verificationMethod:
title: "Verification Method"
width: 150
isReadOnly: false # Default is false; remove or set explicitly
```
**Default is editable**
The `isReadOnly` property defaults to `false`. If you do not set it, the column is editable. If someone set `isReadOnly: true` for debugging and forgot to revert it, the column will silently become read-only.
**2. Entity type permissions**
Check that the entity type's permissions in the data model allow editing. Navigate to **Administration > Nextedy Powersheet > Data Models** and confirm the entity type does not restrict write access for the current user's role.
**3. Expansion path columns**
Columns that display properties from related entities via an expansion path are read-only by default. Editing through expansion paths requires explicit configuration of the relationship's write behavior.
**4. System fields**
Built-in fields like `id` and `outlineNumber` are always read-only regardless of configuration.
If you can edit a custom field in the sheet but changes do not persist after saving, the issue is usually a mismatch between the property name in the data model and the actual Polarion custom field ID.
**Check the browser console** for error responses during save. Powersheet returns structured error information with a `message` field describing what went wrong and an HTTP `statusCode`.
**Common save failure causes:**
1. **Property name typo** -- The property key in the data model must match the Polarion field ID character-for-character, including the `c_` prefix and exact casing
2. **Wrong entity type** -- The custom field is defined on a different Polarion work item type than the one mapped by `polarionType`
3. **Field not enabled for the project** -- The custom field exists globally but is not enabled for the current project's work item type configuration
If all custom field columns are blank across the entire sheet, verify that the `sources.model` property in your sheet configuration matches the name of your custom data model file. A common mistake is leaving the default value when you have created a model with a different name. The model name in `sources` must match exactly.
```yaml theme={null}
sources:
- model: my-custom-model # Must match your .yaml model file name
```
When an entity type links to multiple work item types (for example, `SystemRequirement` links to both `DesignOutput` and `DesignVerification`), the second linked column must use `multiItem: true` in the sheet configuration.
```yaml theme={null}
columns:
designOutputs.designOutput.c_status:
title: "Design Output Status"
width: 120
designVerifications.designVerification.c_status:
title: "Verification Status"
width: 120
multiItem: true # Required for second linked entity column
```
**Non-obvious requirement**
Omitting `multiItem: true` on the second linked column is one of the most common configuration mistakes during initial setup. The column will either not display data or throw errors without a clear indication of the root cause.
## Verification
After applying your fixes, reload the Powersheet widget in Polarion and confirm:
* ✅ The custom field column appears with the correct title
* ✅ Existing values from Polarion display in the column
* ✅ You can edit a value, save, and see it persisted when refreshing
* ✅ The field type renders with the appropriate control (text input, date picker, dropdown, checkbox)
Use the **Review Mode** toggle to verify changes before saving. Review mode highlights modified cells and rows, letting you confirm that your custom field edits are tracked correctly before committing them to Polarion.
## See Also
* [Add a Custom Property](/powersheet/guides/data-model/add-custom-property) -- step-by-step guide for adding properties to the data model
* [Add a Column](/powersheet/guides/sheet-configuration/add-column) -- how to define columns in sheet configurations
* [Configure a Formatter](/powersheet/guides/sheet-configuration/configure-formatter) -- customize how field values render
* [Configure Read-Only Column](/powersheet/guides/sheet-configuration/configure-read-only-column) -- control column editability
* [Configure Multi-Item Column](/powersheet/guides/sheet-configuration/configure-multi-item-column) -- set up columns for multi-linked entities
* [Create an Entity Type](/powersheet/guides/data-model/create-entity-type) -- entity type to work item type mapping
* [Handle Validation Errors](/powersheet/guides/save-operations/handle-validation-errors) -- resolve save-time validation issues
# Fix Model Connection Errors
Source: https://learn.nextedy.com/powersheet/guides/troubleshooting/fix-model-connection-errors
Diagnose and resolve Nextedy POWERSHEET connection failures that prevent the sheet from loading data when the data model cannot be reached or is misconfigured.
## Identify the Error
Model connection errors typically appear when opening a powersheet document. The sheet displays a loading error or the connection status shows **Failed** in the administration interface. Common symptoms include:
* Sheet shows a blank area or error dialog on load
* Connection status in **Administration > Nextedy Powersheet** shows "Failed" instead of "Active"
* Configuration loads but no data appears in the sheet
The `sources.model` property in your sheet configuration must match the name of your data model file. Open your sheet configuration YAML and check the `sources` section:
```yaml theme={null}
sources:
- model: my-custom-model # Must match your model file name
from: UserNeed
expand:
- systemRequirements.systemRequirement
```
**Model name must match exactly**
The `sources.model` property must match your custom data model name -- not the default `rtm`. If you created a model named `my-project-model`, the value must be `my-project-model`, not `rtm` or `model`.
Powersheet resolves model paths using these rules:
| Model Value | Resolved Path |
| ----------------------- | ---------------------------------------- |
| `my-model` | `{projectId}/my-model` (current project) |
| `otherProject/my-model` | `otherProject/my-model` (cross-project) |
| `/my-model` | `_global/my-model` (global scope) |
Verify that your model file exists at the resolved path by navigating to **Administration > Nextedy Powersheet > Data Models**.
**Project-local models silently override same-name global models**
If a global model and a project-local model share the same name, the project-local copy takes precedence -- the sheet may be reading a different model than you expect, with no error. If you intended to use the global model, check for and remove any project-level copy with the same name. See [Troubleshooting FAQ: global vs. project-level configuration](/powersheet/faq/troubleshooting) for details.
Connections go through three lifecycle states:
* **Active**: Connection is operational and serving data
* **Disabled**: Connection intentionally turned off by an administrator
* **Failed**: Connection encountered an error during startup or restart
If the status is **Failed**, the data model configuration contains an error that prevented initialization.
Common data model errors that cause connection failures:
1. **Invalid YAML syntax** -- Check for indentation errors, missing colons, or stray characters
2. **Missing `domainModelTypes`** -- The root `domainModelTypes` key must exist
3. **Duplicate property names** -- Entity types cannot have duplicate property names within the same type
4. **Invalid `polarionType` references** -- Each `polarionType` must match an existing Polarion work item type
```yaml theme={null}
# Correct structure
domainModelTypes:
UserNeed:
polarionType: requirement
properties:
description:
severity:
```
**Save triggers automatic restart**
When you save a connection configuration, Powersheet automatically restarts the connection to apply changes. Check the updated status after saving to confirm the fix.
Ensure the document is bound to the correct connection. Open the document settings and verify:
* The source references a valid connection ID
* The `from` field in the source query specifies a valid entity type from the data model
```yaml theme={null}
sources:
- model: my-custom-model
from: UserNeed # Must be a domainModelTypes key
expand:
- systemRequirements.systemRequirement
```
**Entities configuration validation**
Powersheet validates entity configurations server-side. If duplicate property names are detected, an error dialog will appear and the connection will not be created or restarted.
## Verification
After applying your fix:
1. Save the data model and sheet configuration
2. Navigate to **Administration > Nextedy Powersheet** and confirm the connection status shows **Active**
3. Open the powersheet document
4. You should now see data loading in the sheet without errors
## See Also
* [Validate Your Data Model](/powersheet/guides/data-model/validate-model) -- comprehensive model validation steps
* [Configure Sources](/powersheet/guides/sheet-configuration/configure-sources) -- set up source queries and expansion paths
* [Creating Your First Data Model](/powersheet/getting-started/first-data-model) -- step-by-step model creation
* [Fix Type Name Errors](/powersheet/guides/troubleshooting/fix-type-name-errors) -- related entity type naming issues
***
# Fix Multi-Item Column Errors
Source: https://learn.nextedy.com/powersheet/guides/troubleshooting/fix-multi-item-errors
Resolve Nextedy POWERSHEET issues where columns representing many-to-many or one-to-many relationships display incorrectly, show only a single value, or fail to save in Siemens Polarion ALM.
## Identify the Error
Multi-item column errors manifest as:
* A relationship column shows only one related item instead of multiple
* The cell editor opens as a single-value picker instead of a multi-item picker
* Saving linked work items fails or creates incorrect associations
* The second linked entity type column displays blank cells
The most common cause is a missing `multiItem` property in the sheet configuration. When a column represents a collection (one-to-many or many-to-many relationship), you must explicitly set `multiItem: true`:
```yaml theme={null}
columns:
systemRequirements.systemRequirement.title:
title: "Sys Req Title"
width: 200
hasFocus: true
systemRequirements.systemRequirement.designRequirements.designRequirement.title:
title: "Design Req Title"
width: 200
multiItem: true # Required for collection columns
```
**Second linked entity always needs `multiItem: true`**
When a parent entity links to multiple child entity types (e.g., `SystemRequirement` links to both `DesignRequirement` and `VerificationTestCase`), the second and subsequent linked columns **must** be declared with `multiItem: true` in the sheet configuration. This is a non-obvious requirement that frequently blocks new users.
The `multiItem` property should align with the relationship cardinality in your data model:
| Cardinality | `multiItem` Needed? | Display Behavior |
| -------------- | ------------------- | -------------------------------- |
| `one-to-one` | No | Single-value cell |
| `many-to-one` | No | Single-value cell |
| `one-to-many` | Yes | Multiple items with separators |
| `many-to-many` | Yes | Multiple items with linking mode |
Check your data model `relationships` section:
```yaml theme={null}
relationships:
- from: SystemRequirement
to: DesignRequirement
cardinality: one-to-many # Requires multiItem: true
storage: linkedWorkItems
linkRole: has_parent
direct:
name: designRequirements
back:
name: systemRequirement
```
Multi-item columns require the corresponding expansion path to be defined in the `sources` section. Without expansion, the related entities will not load:
```yaml theme={null}
sources:
- model: my-model
from: UserNeed
expand:
- systemRequirements.systemRequirement:
- designRequirements.designRequirement # Must be expanded
- verificationTestCases.verificationTestCase # Must be expanded
```
Multi-item cells display a list of related items. Control what text appears for each item using the `display` property:
```yaml theme={null}
columns:
systemRequirements.systemRequirement.designRequirements.designRequirement:
title: "Design Requirements"
width: 250
multiItem: true
display: title # Show title of each related item
```
Available `display` values include `id`, `title`, and `titleOrName`.
**Start simple, then extend**
Begin with a single-entity configuration that works correctly, then add multi-item columns one at a time. Jumping directly to complex multi-item configurations makes errors difficult to diagnose.
When `multiItem: true` is set correctly, double-clicking a multi-item cell opens an autocomplete editor with a dropdown for selecting additional items. Each item displays with a separator and an external link icon for navigation.
Multi-item columns also support:
* **Filtering**: Click the filter icon to filter by item combinations
* **Linking mode**: For many-to-many relationships, use linking mode to create associations
## Verification
After applying the fix:
1. Save the sheet configuration
2. Reload the powersheet document
3. You should now see multiple related items displayed in the column, separated by semicolons
4. Double-click the cell to verify the multi-item picker opens with autocomplete functionality
## See Also
* [Configure Multi-Item Column](/powersheet/guides/sheet-configuration/configure-multi-item-column) -- full multi-item setup
* [Configure Many-to-Many Relationships](/powersheet/guides/data-model/configure-many-to-many) -- relationship setup
* [Configure Sources](/powersheet/guides/sheet-configuration/configure-sources) -- expansion path configuration
* [Incremental Configuration Approach](/powersheet/getting-started/incremental-configuration) -- build complexity gradually
***
# Fix Relationship Errors
Source: https://learn.nextedy.com/powersheet/guides/troubleshooting/fix-relationship-errors
Diagnose and resolve data model relationship configuration errors in Nextedy POWERSHEET, including invalid entity references, missing link roles, incorrect cardinality, and mismatched navigation properties.
## Symptom Quick Reference
Use this table to jump to the right fix based on the error you are seeing:
| Symptom | Likely Cause | Jump To |
| ----------------------------------------------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| Sheet fails to load after saving the data model | Invalid `from` or `to` entity reference | [Step 1: Verify Entity Type References](#step-1-verify-entity-type-references) |
| Navigation columns appear empty | Missing or wrong `direct`/`back` name | [Step 2: Check Navigation Property Names](#step-2-check-navigation-property-names) |
| Expansion path produces no child rows | Navigation name mismatch between model and sources | [Step 3: Align Sources with Navigation Names](#step-3-align-sources-with-navigation-names) |
| Links not saved to Polarion | Invalid `linkRole` value | [Step 4: Verify the Link Role](#step-4-verify-the-link-role) |
| Wrong column behavior (multi vs. single) | Cardinality does not match the actual relationship | [Step 5: Validate Cardinality](#step-5-validate-cardinality) |
| Second linked column shows nothing | Missing `multiItem: true` on the column | [Step 6: Fix Multi-Item Column Declarations](#step-6-fix-multi-item-column-declarations) |
Every relationship must reference valid entity type names in its `from` and `to` fields. These names must exactly match keys defined under `domainModelTypes`, including capitalization.
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
description:
severity:
SystemRequirement:
polarionType: sys_req
properties:
description:
severity:
relationships:
- from: UserNeed # Must match a domainModelTypes key exactly
to: SystemRequirement # Must match a domainModelTypes key exactly
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds
back:
name: systemRequirements
```
**Case sensitivity matters**
Entity type names are case-sensitive. `systemRequirement` and `SystemRequirement` are different values. If the `from` value does not match any `domainModelTypes` key, the source side of the relationship is broken. If the `to` value is wrong, the target side is broken. Double-check exact capitalization in both locations.
The `direct` and `back` sections each contain a `name` field that creates a navigation property on the respective entity type. These navigation property names are what you use in column binding paths and source expansion paths throughout the sheet configuration.
* **`direct.name`** -- creates a forward navigation property on the `from` entity type (navigates toward the `to` entity)
* **`back.name`** -- creates a reverse navigation property on the `to` entity type (navigates back toward the `from` entity)
```yaml theme={null}
relationships:
- from: UserNeed
to: SystemRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds # Property on SystemRequirement pointing back to UserNeed
back:
name: systemRequirements # Property on UserNeed pointing forward to SystemRequirement
```
**Missing navigation names**
If either `direct` or `back` is missing its `name` field, the corresponding navigation property will not be created. Any column or expansion path that references that property name will silently return no data.
The `expand` entries in your sheet configuration sources must exactly match the navigation property names defined by `direct.name` or `back.name` in the data model. A mismatch here is one of the most common causes of empty expansion results.
**Many-to-one (N:1) -- single-level expand:**
```yaml theme={null}
# Data model: UserNeed -> Chapter, direct.name = "chapter"
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: chapter # Must match direct.name exactly
```
**One-to-many (1:N) -- collection expand:**
```yaml theme={null}
# Data model: Chapter <- UserNeed, back.name = "userNeeds"
sources:
- id: chapters
query:
from: Chapter
expand:
- name: userNeeds # Must match back.name exactly
```
**Many-to-many (M:N) -- two-level expand through association:**
```yaml theme={null}
# Data model: UserNeed <-> SystemRequirement, back.name = "systemRequirements"
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: systemRequirements # Association level
expand:
- name: systemRequirement # Target entity level
```
**Many-to-many requires two expand levels**
Many-to-many relationships use an association entity between the two types. The source expand must go two levels deep: first the collection navigation property (e.g., `systemRequirements`), then the target entity within the association (e.g., `systemRequirement`). Forgetting the second level is a frequent cause of empty columns.
The `linkRole` must match a link role **ID** defined in your Polarion project configuration, not its display name.
```yaml theme={null}
relationships:
- from: UserNeed
to: SystemRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes # Polarion link role ID, not display name
direct:
name: userNeeds
back:
name: systemRequirements
```
To find valid link role IDs, go to **Administration > Work Items > Link Roles** in Polarion. The **ID** column shows the value to use in your data model YAML.
**Use Polarion link role IDs, not display names**
The `linkRole` value is the link role **ID** (e.g., `decomposes`, `parent`), not the display name (e.g., "Decomposes", "Has Parent"). If the link role ID does not exist in the project, relationships will not persist when users save changes in the sheet.
The `cardinality` value must match the actual relationship between your entity types. Using the wrong cardinality causes incorrect UI behavior -- columns that should allow multiple selections only show one value, or vice versa.
| Cardinality | Source Expand | Column Binding | UI Behavior |
| -------------- | ------------------------------------------------------------- | -------------------------------------- | ----------------------------- |
| `many-to-one` | `- name: chapter` | `chapter`, `chapter.title` | Single-value reference picker |
| `one-to-many` | `- name: userNeeds` | `userNeeds` | Child rows (new sheet level) |
| `many-to-many` | `- name: systemRequirements` then `- name: systemRequirement` | `systemRequirements.systemRequirement` | Multi-item reference picker |
**Cardinality affects column behavior**
A many-to-one column displays a single-value reference picker. A one-to-many expand creates child rows in the sheet. A many-to-many column uses a multi-item picker with association entity binding. If you set the wrong cardinality, the sheet may render but users will encounter errors when trying to edit or save relationships.
When a parent entity links to multiple work item types (for example, a `SystemRequirement` linked to both `DesignRequirement` and `DesignVerification`), the second linked column must include `multiItem: true` in the sheet configuration. This is a non-obvious requirement that frequently blocks first-time configurations.
```yaml theme={null}
columns:
designRequirements.designRequirement:
title: Design Requirement
list:
search:
- title
designVerifications.designVerification:
title: Design Verification
multiItem: true # Required for the second linked entity column
list:
search:
- title
```
**Start with a single-item configuration**
When setting up a new sheet, start with the simplest possible configuration -- one entity type, one relationship. Add additional linked columns incrementally. This approach makes it much easier to isolate which relationship definition is causing errors.
After making corrections, verify the full chain from data model through sources to columns:
1. **Data model** -- confirm `from`/`to` match `domainModelTypes` keys, `linkRole` is a valid Polarion link role ID, and both `direct.name` and `back.name` are present
2. **Sources** -- confirm each `expand` name matches a navigation property name from the data model, and many-to-many expands have two levels
3. **Columns** -- confirm column binding paths use the correct dot-notation from the expand chain, and `multiItem: true` is set where needed
4. **Storage** -- confirm `storage: linkedWorkItems` is used for Polarion link-based relationships
## Verification
After correcting the relationship configuration:
1. Save the data model YAML in **Administration > Nextedy Powersheet > Data Models**
2. Open a powersheet document that uses this data model
3. Expand a row with related entities
4. You should now see child entities appearing correctly under the expansion path, and the reference picker columns displaying valid choices
## See Also
* [Configure a Relationship](/powersheet/guides/data-model/configure-relationship) -- complete relationship setup guide
* [Create Bidirectional Links](/powersheet/guides/data-model/create-bidirectional-links) -- setting up two-way navigation
* [Configure Many-to-Many Relationships](/powersheet/guides/data-model/configure-many-to-many) -- many-to-many relationship configuration
* [Fix Multi-Item Column Errors](/powersheet/guides/troubleshooting/fix-multi-item-errors) -- troubleshooting multi-item column issues
* [Fix Type Name Errors](/powersheet/guides/troubleshooting/fix-type-name-errors) -- resolving entity type naming mismatches
* [Data Model Reference](/powersheet/reference/data-model/index) -- complete data model YAML reference
***
# Fix Type Name Errors
Source: https://learn.nextedy.com/powersheet/guides/troubleshooting/fix-type-name-errors
Resolve Nextedy POWERSHEET data model errors caused by invalid entity type names, including spaces, special characters, and mismatched references between the data model and Siemens Polarion ALM work item types.
## Identify the Error
Type name errors occur when the data model contains entity type names that violate naming rules. Symptoms include:
* Connection status shows **Failed** after saving the data model
* Error messages referencing unrecognized type names
* Sheet configuration `from` field fails to match any entity type
Entity type names in `domainModelTypes` must follow strict rules:
| Rule | Valid | Invalid |
| ---------------------- | ------------------- | ------------------------ |
| Single word, no spaces | `SystemRequirement` | `System Requirement` |
| No special characters | `UserNeed` | `User-Need`, `User_Need` |
| PascalCase recommended | `DesignRequirement` | `designrequirement` |
| Must be unique | One `Hazard` entry | Two `Hazard` entries |
```yaml theme={null}
# CORRECT - single word PascalCase names
domainModelTypes:
UserNeed:
polarionType: requirement
SystemRequirement:
polarionType: systemRequirement
DesignRequirement:
polarionType: designRequirement
```
```yaml theme={null}
# INCORRECT - spaces and special characters
domainModelTypes:
User Need: # Space in name
polarionType: requirement
System-Requirement: # Hyphen in name
polarionType: systemRequirement
```
**Type names must be single words**
Data model entity type names must be single words without spaces or special characters. This is a strict validation rule -- names with spaces will cause the connection to fail silently without a clear error message.
A common mistake is confusing data model entity type names (the YAML keys under `domainModelTypes`) with Polarion work item type IDs (the `polarionType` value):
The `polarionType` maps your data model entity to a Polarion work item type, but all references within the data model (relationships, queries, sources) use the **entity type name** (the YAML key).
When relationship `from` and `to` fields reference an invalid entity type name, you may see "left error" or "right error" messages:
* **"left error"** = the `from` entity type name is invalid
* **"right error"** = the `to` entity type name is invalid
```yaml theme={null}
relationships:
- from: UserNeed # Must match a domainModelTypes key
to: SystemRequirement # Must match a domainModelTypes key
cardinality: one-to-many
storage: linkedWorkItems
linkRole: has_parent
```
**Match YAML keys exactly**
The `from` and `to` values must exactly match the keys under `domainModelTypes` -- including capitalization. `systemRequirement` (lowercase s) will not match `SystemRequirement` (uppercase S).
The `from` field in your sheet configuration sources must also use the entity type name:
```yaml theme={null}
sources:
- model: my-model
from: UserNeed # Entity type name, NOT "requirement" (Polarion type ID)
expand:
- systemRequirements.systemRequirement
```
This is the single most common reason for an empty sheet, and it produces **no error message at all**.
* **Symptom:** The sheet opens but is completely empty -- no rows load, the connection status looks fine, and no error is shown.
* **Cause:** The `polarionType` value does not match the Polarion work item type ID exactly, usually because of wrong casing. For example, using `systemRequirement` (camelCase) when the actual Polarion type ID is `sys_req`. Polarion type IDs are case-sensitive, so a near-miss silently matches zero work items.
* **Fix:** Check the exact work item type ID in your Polarion project (Administration > Work Items > Types) and use that exact string -- including case and underscores -- as the `polarionType` value.
```yaml theme={null}
domainModelTypes:
SystemRequirement:
polarionType: sys_req # CORRECT - exact Polarion type ID
# polarionType: systemRequirement # WRONG - silent empty sheet
```
## Verification
After correcting type names:
1. Save the data model configuration
2. Check that the connection status returns to **Active**
3. Open the powersheet document
4. You should now see data loading correctly with no type-related errors in the sheet
## See Also
* [Create an Entity Type](/powersheet/guides/data-model/create-entity-type) -- entity type setup guide
* [Fix Model Connection Errors](/powersheet/guides/troubleshooting/fix-model-connection-errors) -- diagnose data model connection failures
* [Fix Relationship Errors](/powersheet/guides/troubleshooting/fix-relationship-errors) -- relationship configuration issues
* [Validate Your Data Model](/powersheet/guides/data-model/validate-model) -- full validation checklist
***
# Troubleshooting Guides
Source: https://learn.nextedy.com/powersheet/guides/troubleshooting/index
Find solutions to common Nextedy POWERSHEET configuration and runtime issues.
Resolve connection failures between your sheet configuration and data model, including incorrect model paths and status issues.
Fix data model entity type naming issues such as spaces, special characters, and mismatched type references.
Troubleshoot relationship configuration problems including invalid from/to references and missing link roles.
Resolve issues with multi-item columns displaying incorrectly or failing to save in many-to-many relationships.
Diagnose custom field mapping problems between Polarion fields and data model properties.
Identify and fix validation errors that occur during save operations, including constraint violations and data quality issues.
**Troubleshooting approach**
Start by identifying the error category from the message you see in the sheet. Connection and type name errors appear at load time, while validation and save errors appear when editing data. Use the [Model Helper Widget](/powersheet/guides/customization/use-model-helper) to visualize your data model structure and verify binding paths.
| Symptom | Likely Guide |
| ---------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------- |
| Sheet fails to load, connection status "Failed" | [Fix Model Connection Errors](/powersheet/guides/troubleshooting/fix-model-connection-errors) |
| Error mentions "left" or "right" entity | [Fix Relationship Errors](/powersheet/guides/troubleshooting/fix-relationship-errors) |
| Entity type not recognized | [Fix Type Name Errors](/powersheet/guides/troubleshooting/fix-type-name-errors) |
| Sheet loads but is empty, no error shown (often a wrong-case `polarionType`) | [Fix Type Name Errors](/powersheet/guides/troubleshooting/fix-type-name-errors) |
| Multi-item column shows single value | [Fix Multi-Item Column Errors](/powersheet/guides/troubleshooting/fix-multi-item-errors) |
| Custom field not appearing in sheet | [Debug Custom Field Issues](/powersheet/guides/troubleshooting/debug-custom-field-issues) |
| "My new column is blank / shows no value" | [Debug Custom Field Issues](/powersheet/guides/troubleshooting/debug-custom-field-issues) |
| Save operation fails with numbered errors | [Resolve Validation Errors](/powersheet/guides/troubleshooting/resolve-validation-errors) |
| "My edits don't save" / changes are rejected on save | [Resolve Validation Errors](/powersheet/guides/troubleshooting/resolve-validation-errors) |
# Resolve Validation Errors
Source: https://learn.nextedy.com/powersheet/guides/troubleshooting/resolve-validation-errors
Diagnose and fix Nextedy POWERSHEET save operation errors caused by data validation failures, constraint violations, and entity dependency issues in Siemens Polarion ALM.
## Identify the Error
Validation errors appear when saving changes in the sheet. The error dialog displays one or more numbered error messages describing what failed. Common symptoms include:
* A save error dialog with numbered messages (e.g., "1. Error saving item...")
* Partial saves where some rows succeed but others fail
* Entity dependency errors when creating linked work items
Powersheet saves entities one by one in dependency order. Parent entities are saved before their children to ensure references are valid. This means:
* **Entity errors** are collected across all items and reported as a single aggregated list after the save cycle completes
* **Application errors** (server exceptions) interrupt the save immediately
* **Dependency sort failures** (e.g., circular dependencies) prevent any saves from starting
Before saving, use review mode to identify items with validation problems. For how review mode tracks pending changes, see [Working Sessions](/powersheet/concepts/working-sessions#the-change-buffer).
1. Click the **Review** button in the toolbar (or use the review filter)
2. Select the **Problems** filter to show only rows with validation errors
3. Fix the highlighted issues before attempting to save
The review mode filters show four categories:
| Filter | Description |
| ------------ | --------------------------------- |
| **Added** | Newly created items not yet saved |
| **Modified** | Items changed since last save |
| **Deleted** | Items marked for deletion |
| **Problems** | Items with validation errors |
**Review before saving**
Always use the **Problems** review filter before saving large batches of changes. This lets you identify and fix validation issues proactively rather than discovering them through save error messages.
### Missing Required Fields
If a required Polarion field is empty, the save will fail for that entity:
* Check if mandatory custom fields have values
* Verify that `title` is set for new work items
* Ensure enum fields have valid values from the allowed list
### Type Name Mismatches
The data model `domainModelTypes` keys must match exactly what the server expects. Errors referencing unknown types indicate a naming mismatch:
```yaml theme={null}
domainModelTypes:
UserNeed: # This exact name is used in queries
polarionType: requirement # This maps to the Polarion type
```
**Relationship from/to must use entity type names**
A common source of validation errors is using Polarion work item type IDs (e.g., `requirement`) in relationship `from`/`to` fields instead of data model entity type names (e.g., `UserNeed`). Always use the entity type name from `domainModelTypes`.
### Constraint Violations
If constraints are configured on entity types (load, create, or pick constraints), saving may fail when data violates those constraints:
* **Document constraints**: New items must be created in the specified document
* **Type constraints**: Work items must match the expected document type
* **Component constraints**: Items must belong to the correct component
**Where to find the error detail**
When the on-screen message is not enough, look in two places:
* **Browser DevTools (Network tab)** -- open your browser's developer tools (`F12`), select **Network**, retry the save, and inspect the failing request's response. Powersheet returns a structured error with a `message` field and an HTTP `statusCode`.
* **Polarion server log** -- server-side failures (HTTP `500`) are recorded in the Polarion application log on the server. Ask your Polarion administrator for the log location if you do not have server access.
Error messages from the server include a human-readable message and an HTTP status code. Common codes:
| Status Code | Meaning | Typical Cause |
| ----------- | ------------ | --------------------------------------------- |
| 400 | Bad Request | Invalid data format or missing required field |
| 403 | Forbidden | Insufficient permissions to modify the item |
| 404 | Not Found | Referenced entity does not exist |
| 409 | Conflict | Concurrent modification by another user |
| 500 | Server Error | Internal server issue (check server logs) |
After identifying the error source:
1. Correct the data in the affected cells
2. Use the **Problems** review filter to verify no remaining issues
3. Save again
If multiple errors were reported, address them in dependency order -- fix parent entity issues before child entities.
## Verification
After resolving all validation errors:
1. Click the **Review** button and select **Problems** -- the list should be empty
2. Save the changes
3. You should now see a success notification with no error dialog
4. Verify the saved data in Polarion to confirm persistence
## See Also
* [Handle Validation Errors](/powersheet/guides/save-operations/handle-validation-errors) -- validation handling in save operations
* [Create a Work Item](/powersheet/guides/save-operations/create-work-item) -- creating items with required fields
* [Fix Type Name Errors](/powersheet/guides/troubleshooting/fix-type-name-errors) -- type naming issues
* [Fix Relationship Errors](/powersheet/guides/troubleshooting/fix-relationship-errors) -- relationship configuration errors
***
# Powersheet
Source: https://learn.nextedy.com/powersheet/index
Excel-like traceability matrices with unlimited depth and cross-domain linking.
Welcome to the Nextedy POWERSHEET documentation. Powersheet is a hierarchical sheet app for Siemens Polarion ALM that enables your team to build, navigate, and manage traceability matrices, risk analyses, task boards, custom workflows, and other structured data through configurable sheet configurations and data models.
## Quick Navigation
Install Powersheet, set up navigation, create your first data model and sheet configuration, and build your first document.
Understand the architecture, model-driven design, entity types, relationships, and how configuration layers work together.
Task-oriented guides for data model setup, sheet configuration, queries, server rendering, save operations, and customization.
Complete YAML property reference for data models, sheet configurations, query API, field types, UI components, and example models.
Answers to common questions about configuration, licensing, data models, sheet setup, migration, and troubleshooting.
## Key Features
* **Configurable sheet views** acting as a standalone view on top of Polarion data
* **Data model** defining entity types, relationships, and cardinality in YAML
* **Hierarchical data navigation** via expansion paths across related entities
* **Column-level configuration** with formatters, pickers, and conditional styling
* **Multiple sheet configurations** per project with shared data models
* **Views** providing named column visibility presets for different analysis perspectives
* **Server-side rendering** via Velocity templates for computed properties
* **Save operations** with validation and constraint enforcement
## Documentation Structure
| Section | Purpose | Start Here |
| ---------------------------------------------------- | --------------------------------------------- | ------------------------------------------------------------------------- |
| [Getting Started](/powersheet/getting-started/index) | Install and configure your first powersheet | [Installing Powersheet](/powersheet/getting-started/installation) |
| [Concepts](/powersheet/concepts/index) | Understand architecture and design principles | [Powersheet Architecture](/powersheet/concepts/architecture) |
| [Guides](/powersheet/guides/index) | Step-by-step task instructions | [Create an Entity Type](/powersheet/guides/data-model/create-entity-type) |
| [Reference](/powersheet/reference/index) | YAML properties and API lookup | [Columns](/powersheet/reference/sheet-config/columns) |
| [FAQ](/powersheet/faq/index) | Quick answers to common questions | [General FAQ](/powersheet/faq/general) |
## Common Tasks
* [**Installing Powersheet**](/powersheet/getting-started/installation) -- Deploy Powersheet and apply your license
* [**Creating Your First Data Model**](/powersheet/getting-started/first-data-model) -- Define entity types and relationships
* [**Creating Your First Sheet Configuration**](/powersheet/getting-started/first-sheet-configuration) -- Set up columns, sources, and views
* [**Add a Column**](/powersheet/guides/sheet-configuration/add-column) -- Configure a new column with binding path and formatter
* [**Configure a Relationship**](/powersheet/guides/data-model/configure-relationship) -- Link entity types with cardinality and link roles
* [**Create a View**](/powersheet/guides/sheet-configuration/create-view) -- Define named column presets for different perspectives
* [**Binding Syntax**](/powersheet/reference/sheet-config/binding-syntax) -- Understand dot-separated property paths for columns
Powersheet acts strictly as a standalone view on top of Polarion data. Approval-based review processes and embedded LiveDoc rendering are not supported.
## Need help?
Can't find the answer here? Open a ticket and the Nextedy support team will help you out.
# Browser Compatibility
Source: https://learn.nextedy.com/powersheet/reference/browser-compatibility
Nextedy POWERSHEET runs as a client-side application inside the Siemens Polarion ALM web interface.
## Supported Browsers
Powersheet supports the same browsers that Siemens Polarion ALM officially supports. The client application uses modern web standards including CSS Grid, Flexbox, and ES2015+ JavaScript features.
| Browser | Minimum Version | Support Level | Notes |
| ------------------------- | --------------- | --------------- | --------------------------------------------------------------- |
| Google Chrome | Latest stable | ✅ Full | Recommended browser for best performance |
| Microsoft Edge (Chromium) | Latest stable | ✅ Full | Chromium-based Edge only |
| Mozilla Firefox | Latest stable | ✅ Full | ESR releases also supported |
| Safari | Latest stable | Partial | See [Safari-specific limitations](#safari-specific-limitations) |
| Internet Explorer 11 | N/A | ❌ Not supported | Polarion has deprecated IE 11 support |
| Microsoft Edge (Legacy) | N/A | ❌ Not supported | EdgeHTML engine not supported |
**Use the browser recommended by Polarion**
Always check the [Siemens Polarion ALM release notes](https://docs.sw.siemens.com/en-US/product/226868214/doc/PI1651260043614.xhtml) for the official browser support matrix for your Polarion version. Powersheet inherits these requirements.
## Recommended Browser
**Google Chrome (latest stable release)** is the recommended browser for Powersheet. Chrome consistently delivers the best performance for:
* Large sheets with hundreds or thousands of rows
* Complex expansion paths across multiple entity type levels
* Inline editing with real-time validation
* Export operations (Excel)
* Keyboard shortcut responsiveness
Microsoft Edge (Chromium-based) provides equivalent performance since it shares the same rendering engine.
## Browser Feature Requirements
Powersheet relies on the following browser capabilities. All features listed below are available in current versions of Chrome, Edge, and Firefox.
| Feature | Used For | Minimum Standard |
| -------------------------- | -------------------------------------------- | ----------------------- |
| JavaScript (ES2015+) | Sheet rendering, editing, query execution | ECMAScript 2015 |
| CSS Grid | Sheet layout and column alignment | CSS Grid Level 1 |
| CSS Flexbox | Toolbar, menus, and dialog layout | CSS Flexible Box Layout |
| Fetch API | Server communication for data and metadata | Fetch Living Standard |
| Web Storage (localStorage) | Persisting user preferences (language, view) | Web Storage API |
| Clipboard API | Copy/paste operations in the sheet | Clipboard API |
| SVG rendering | Icons and visual elements | SVG 1.1 |
| CSS Custom Properties | Theming and conditional styling | CSS Custom Properties |
**No browser plugins required**
Powersheet does not require Flash, Java applets, Silverlight, or any other browser plugin. It runs entirely on native browser APIs.
## Polarion Version Compatibility
Powersheet is deployed into Polarion. The Polarion version determines which browsers are supported at the platform level.
| Polarion Version | Browser Policy |
| ------------------------- | ----------------------------------------------------------- |
| Polarion 2310 and later | Latest versions of Chrome, Edge (Chromium), Firefox, Safari |
| Polarion 2304 | Latest versions of Chrome, Edge (Chromium), Firefox, Safari |
| Polarion 2301 and earlier | Check Siemens release notes for your specific version |
**Verify in application**
The exact Polarion version requirements for your Powersheet release are listed in the Powersheet release notes bundled with the installation package. Check the `RELEASE-NOTES.md` or `README` file in your distribution archive.
## Safari-Specific Limitations
Safari is supported for general sheet viewing and editing, but some features may behave differently due to WebKit engine differences.
| Area | Limitation | Workaround |
| ------------------ | ------------------------------------------------------------- | ---------------------------------------------------------------------- |
| Keyboard shortcuts | Some key combinations conflict with macOS system shortcuts | Use Chrome on macOS for full keyboard shortcut support |
| Copy/paste | Clipboard API behavior may differ for rich content | Use plain-text paste (`Cmd+Shift+V`) |
| Large sheets | Memory management differences with very large datasets | Reduce visible rows or use query filtering |
| File download | Export file download dialogs may appear differently | Configure Safari to allow automatic downloads from the Polarion domain |
| CSS rendering | Minor visual differences in cell borders and header alignment | No workaround needed; functionality is not affected |
**Safari Private Browsing**
Safari Private Browsing restricts localStorage access. User preferences such as the selected language in the YAML editor and column visibility presets may not persist between sessions when Private Browsing is active.
## Internet Explorer 11
Internet Explorer 11 is **not supported**. Powersheet uses modern JavaScript features (arrow functions, template literals, destructuring, Promises, `async`/`await`, CSS Grid) that are not available in IE 11. Attempting to load Powersheet in IE 11 results in a blank page or JavaScript errors.
Siemens has also ended IE 11 support in recent Polarion versions. If your organization still requires IE 11, upgrade to Microsoft Edge (Chromium-based) for full compatibility.
## Microsoft Edge (Legacy)
The legacy version of Microsoft Edge using the EdgeHTML engine is **not supported**. Only the Chromium-based Edge (version 79 and later) is compatible. Chromium-based Edge is the default on Windows 10 version 20H2 and later, and all versions of Windows 11.
To check which version of Edge you are running, navigate to `edge://settings/help` in the Edge address bar.
## Screen Resolution and Display
| Parameter | Recommendation |
| ---------------------- | ------------------------------------------------------------------------ |
| Minimum resolution | 1280 x 720 px |
| Recommended resolution | 1920 x 1080 px or higher |
| High-DPI / Retina | Supported -- Powersheet renders correctly at all display scaling factors |
| Zoom level | 80% to 150% (browser zoom) |
| Minimum viewport width | 1024 px for sheets with multiple visible columns |
**Wide monitors for traceability matrices**
When working with requirements traceability matrices (RTM) that span multiple entity types (e.g., `UserNeed` to `SystemRequirement` to `DesignRequirement`), a wide monitor or multi-monitor setup significantly improves usability. Each expanded level adds columns to the right, and horizontal scrolling is reduced with more screen real estate.
## Performance Considerations by Browser
Performance varies based on the number of visible rows, columns, and expanded entity levels. The table below provides general guidance for large sheets.
| Scenario | Chrome / Edge | Firefox | Safari |
| ---------------------------------- | ------------- | --------- | ------------------- |
| Sheet with \< 500 rows | Excellent | Excellent | Excellent |
| Sheet with 500 -- 2,000 rows | Excellent | Good | Good |
| Sheet with 2,000 -- 5,000 rows | Good | Good | Fair |
| Sheet with > 5,000 rows | Fair | Fair | Use query filtering |
| Deep expansion (4+ levels) | Good | Good | Fair |
| 20+ visible columns | Excellent | Excellent | Good |
| Concurrent editing (multiple tabs) | Supported | Supported | Supported |
**Verify in application**
Actual performance depends on Polarion server capacity, network latency, and the complexity of your data model. The values above reflect client-side rendering performance only.
## Browser Cache and Versioning
Powersheet uses version-based cache busting for its JavaScript and CSS assets. When you upgrade Powersheet on the server, the browser automatically loads the new version of client-side files.
| Behavior | Details |
| ------------------ | ------------------------------------------------------ |
| Cache strategy | Versioned URLs with cache-control headers |
| JavaScript files | Cached per version; new version forces fresh download |
| CSS files | Cached per version; new version forces fresh download |
| Configuration data | Not cached in browser; loaded fresh on each sheet open |
| User preferences | Stored in `localStorage`; persist across sessions |
If you experience issues after a Powersheet upgrade, perform a hard refresh:
| Browser | Hard Refresh Shortcut |
| ----------------------- | --------------------- |
| Chrome / Edge (Windows) | `Ctrl+Shift+R` |
| Chrome / Edge (macOS) | `Cmd+Shift+R` |
| Firefox (Windows) | `Ctrl+Shift+R` |
| Firefox (macOS) | `Cmd+Shift+R` |
| Safari | `Cmd+Option+R` |
Alternatively, clear the browser cache for the Polarion domain only:
1. Open browser developer tools (`F12` or `Ctrl+Shift+I`)
2. Right-click the refresh button
3. Select **Empty Cache and Hard Reload** (Chrome/Edge) or clear storage from the Application tab
## Content Security Policy
Powersheet respects the Content Security Policy (CSP) configured on the Polarion server. If your organization enforces a strict CSP, ensure the following are permitted:
| Directive | Requirement |
| ------------- | ---------------------------------------------------------------- |
| `script-src` | Must allow inline scripts or the Powersheet script source domain |
| `style-src` | Must allow inline styles for dynamic cell formatting |
| `connect-src` | Must allow connections to the Polarion server origin |
| `img-src` | Must allow the Polarion server origin for icons and images |
| `font-src` | Must allow font sources used by Polarion |
**Verify in application**
CSP configuration depends on your Polarion deployment and any reverse proxy or web application firewall in front of it. Consult your infrastructure team if Powersheet features are blocked by CSP violations (visible in the browser developer console).
## Network Requirements
Powersheet communicates with the Polarion server over standard HTTP/HTTPS. No additional network ports or protocols are required beyond what Polarion already uses.
| Requirement | Details |
| ------------- | ------------------------------------------------------------ |
| Protocol | HTTPS recommended; HTTP supported |
| WebSocket | Not required |
| Polling | Not used; data loaded on demand |
| Proxy support | Standard HTTP proxy compatible |
| Offline mode | Not supported; requires active connection to Polarion server |
## Accessibility
Powersheet provides keyboard navigation for common sheet operations. Accessibility feature support varies by browser.
| Feature | Chrome / Edge | Firefox | Safari |
| --------------------------- | ------------------ | ------------------ | ------------------ |
| Keyboard cell navigation | Yes | Yes | Yes |
| Tab-based focus management | Yes | Yes | Partial |
| Screen reader compatibility | Basic | Basic | Basic |
| High-contrast mode | Follows OS setting | Follows OS setting | Follows OS setting |
**Verify in application**
Accessibility support is an evolving area. Check the latest Powersheet release notes for updates on WCAG compliance and screen reader compatibility improvements.
## Troubleshooting Browser Issues
| Symptom | Likely Cause | Resolution |
| --------------------------------------- | --------------------------------------- | -------------------------------------------------------------- |
| Blank sheet, no errors | JavaScript blocked by browser extension | Disable ad blockers or script blockers for the Polarion domain |
| Sheet loads but editing is unresponsive | Outdated browser version | Update to the latest stable release |
| Visual glitches in cell borders | Browser zoom not at 100% | Reset zoom to 100% (`Ctrl+0` / `Cmd+0`) |
| Export fails silently | Pop-up blocker preventing download | Allow pop-ups for the Polarion domain |
| Preferences not saved between sessions | Private/incognito browsing mode | Use a standard browsing session |
| Slow initial load after upgrade | Stale browser cache | Perform a hard refresh (`Ctrl+Shift+R` / `Cmd+Shift+R`) |
| "There is an error in the app" message | Client-side error state | Reload the page; check browser console for details |
| Keyboard shortcuts not working | Focus is outside the sheet area | Click inside the sheet, then retry the shortcut |
For additional troubleshooting steps, see [Troubleshooting Guides](/powersheet/guides/troubleshooting/index).
# Cardinality
Source: https://learn.nextedy.com/powersheet/reference/data-model/cardinality
The `cardinality` property in the Nextedy POWERSHEET data model defines the multiplicity of relationships between entity types.
**Powersheet-Only Concept**
Cardinality is a Powersheet data model concept. Polarion link roles do not have a cardinality setting -- Powersheet uses the `cardinality` value to control how the sheet renders and navigates relationship data.
## Cardinality Property
| Name | Type | Default | Description |
| ------------- | -------- | --------------- | ------------------------------------------------------------------------------ |
| `cardinality` | `string` | None (required) | Defines the relationship multiplicity between the `from` and `to` entity types |
The `cardinality` property is declared within each entry of the `relationships` array in the data model YAML. It works together with `from`, `to`, `storage`, `linkRole`, `direct`, and `back` to form a complete relationship definition.
## Supported Cardinality Values
| Value | From Side | To Side | Description |
| -------------- | ----------------- | ----------------- | --------------------------------------------------------- |
| `one-to-many` | Single entity | Multiple entities | Each source entity links to multiple target entities |
| `many-to-one` | Multiple entities | Single entity | Multiple source entities link to one target entity |
| `many-to-many` | Multiple entities | Multiple entities | Multiple source entities link to multiple target entities |
**one-to-one Not Supported**
The `one-to-one` cardinality value is not currently supported. To model a strict 1:1 relationship, use `many-to-one` and enforce the single-target constraint through workflow or validation.
## How the Three Configuration Layers Connect
The data model, sheet sources, and sheet columns are connected through navigation property names. The cardinality of a relationship determines which expand pattern and column binding syntax to use.
* **Data model** defines entity types and relationships (including `cardinality`, `direct`, and `back` navigation property names)
* **Sheet sources** define how to query and expand those relationships using the navigation property names
* **Sheet columns** define how to display the resulting data using binding paths derived from the same navigation property names
## Shared Data Model for Examples
All examples on this page use the following minimal data model:
```yaml theme={null}
domainModelTypes:
Chapter:
polarionType: heading
UserNeed:
polarionType: user_need
properties:
description:
severity:
SystemRequirement:
polarionType: sys_req
properties:
description:
severity:
DesignRequirement:
polarionType: des_req
properties:
description:
relationships:
- from: UserNeed
to: Chapter
cardinality: many-to-one
storage: linkedWorkItems
linkRole: parent
direct:
name: chapter
back:
name: userNeeds
- from: SystemRequirement
to: UserNeed
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds
back:
name: systemRequirements
```
## Many-to-One (N:1)
**Scenario:** Each `UserNeed` belongs to exactly one `Chapter`.
The relationship uses the `direct` direction with `name: chapter` (singular, scalar navigation property). Because the cardinality is `many-to-one`, the navigation property on the "from" side points to a single entity.
### Relationship Definition
```yaml theme={null}
- from: UserNeed
to: Chapter
cardinality: many-to-one
storage: linkedWorkItems
linkRole: parent
direct:
name: chapter
back:
name: userNeeds
```
### Source Configuration
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: chapter
```
The expand uses the `direct` navigation property name `chapter`. Because it is a scalar property (N:1), the expand resolves to a single related entity per row.
### Column Configuration
```yaml theme={null}
columns:
title:
title: Title
hasFocus: true
chapter:
title: Chapter
display: title
list:
search:
- title
chapter.title:
title: Chapter Title
isReadOnly: true
```
| Column Key | Behavior | Description |
| --------------- | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `chapter` | Single-value reference picker | Scalar navigation property renders as a dropdown picker. The `display` property controls the displayed label. The `list.search` array defines searchable fields. |
| `chapter.title` | Read-only display | Dot-notation accesses a property on the referenced entity. Set `isReadOnly: true` to prevent editing. |
**Scalar vs. Collection**
A singular navigation property name (e.g., `chapter`) indicates a N:1 cardinality. The sheet renders this as a single-value reference picker, not an expandable child level.
## One-to-Many (1:N)
**Scenario:** Each `Chapter` has multiple child `UserNeed` items.
This is the **reverse side** of the many-to-one relationship above. It uses the `back` direction with `name: userNeeds` (plural, collection navigation property).
### Relationship Definition
The same relationship entry is used -- the 1:N perspective is simply the `back` direction of the N:1 relationship:
```yaml theme={null}
- from: UserNeed
to: Chapter
cardinality: many-to-one
storage: linkedWorkItems
linkRole: parent
direct:
name: chapter
back:
name: userNeeds
```
When querying from `Chapter`, the `back.name` value `userNeeds` provides the collection navigation property.
### Source Configuration
```yaml theme={null}
sources:
- id: chapters
query:
from: Chapter
expand:
- name: userNeeds
```
The expand uses the `back` navigation property name `userNeeds`. Because it is a collection property (1:N), the expand creates child rows underneath each `Chapter`.
### Column Configuration
```yaml theme={null}
columns:
title:
title: Chapter
hasFocus: true
userNeeds:
title: Title
hasFocus: true
```
| Column Key | Behavior | Description |
| ----------- | ------------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `userNeeds` | Child row expansion | Collection navigation property expands into a new hierarchical level in the sheet. Each child row displays one `UserNeed`. |
**No Dot-Notation for Expansion**
When a collection navigation property is used as a column key, it opens a new sheet level with child rows. No dot-notation is needed -- the expand directly opens the child level.
## Many-to-Many (M:N)
**Scenario:** `UserNeed` items are linked to multiple `SystemRequirement` items, and vice versa.
Many-to-many relationships use an **association entity** as an intermediate layer. The source expand is two levels deep, and column binding uses dot-notation to reach through the association to the target entity.
### Relationship Definition
```yaml theme={null}
- from: SystemRequirement
to: UserNeed
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds
back:
name: systemRequirements
```
### Source Configuration
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: systemRequirement
```
The expand is **two levels**:
1. `systemRequirements` -- navigates to the association entity (collection)
2. `systemRequirement` -- navigates from the association to the actual target entity (scalar)
### Column Configuration
```yaml theme={null}
columns:
title:
title: Title
hasFocus: true
systemRequirements.systemRequirement:
title: System Requirement
list:
search:
- objectId
- title
createNew: true
systemRequirements.systemRequirement.title:
title: SysReq Title
hasFocus: true
```
| Column Key | Behavior | Description |
| -------------------------------------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `systemRequirements.systemRequirement` | Multi-item reference picker | Two-level dot-notation traverses association then target. Renders as a multi-item picker. `list.search` enables search; `createNew: true` allows creating new linked items. |
| `systemRequirements.systemRequirement.title` | Display field on target | Three-level dot-notation accesses a property on the target entity through the association. |
**Two-Level Expand Required**
M:N relationships always require a two-level expand in the source configuration. If you omit the inner expand (`- name: systemRequirement`), the column will bind to the association entity rather than the target entity, and data will not display correctly.
## Navigation Property Naming Conventions
The navigation property names declared in `direct` and `back` follow consistent naming conventions that signal the cardinality:
| Direction | Cardinality Side | Naming Convention | Example |
| --------- | ---------------- | ------------------- | --------------------------------- |
| `direct` | N:1 (scalar) | Singular, camelCase | `chapter`, `systemRequirement` |
| `direct` | M:N (collection) | Plural, camelCase | `userNeeds`, `riskControls` |
| `back` | 1:N (collection) | Plural, camelCase | `userNeeds`, `designRequirements` |
| `back` | M:N (collection) | Plural, camelCase | `systemRequirements`, `hazards` |
**Naming Signals Cardinality**
Singular navigation property names (e.g., `chapter`) indicate scalar references (N:1). Plural names (e.g., `userNeeds`) indicate collections (1:N or M:N). Consistent naming makes sheet configurations easier to read and debug.
## Relationship Context Properties
Each relationship entry that includes a `cardinality` value also requires the following sibling properties:
| Property | Type | Required | Description |
| ------------- | -------- | -------- | ------------------------------------------------------------------------------------------------------ |
| `from` | `string` | Yes | Source entity type name. Must match a key in `domainModelTypes`. |
| `to` | `string` | Yes | Target entity type name. Must match a key in `domainModelTypes`. |
| `cardinality` | `string` | Yes | One of: `one-to-many`, `many-to-one`, `many-to-many`. |
| `storage` | `string` | Yes | Storage mechanism. Typically `linkedWorkItems` for Polarion link-based relationships. |
| `linkRole` | `string` | Yes | Polarion link role identifier (e.g., `parent`, `refines`, `derives_from`, `decomposes`, `mitigates`). |
| `direct` | `object` | Yes | Forward navigation direction. Contains `name` (the navigation property name from `from` to `to`). |
| `back` | `object` | Yes | Reverse navigation direction. Contains `name` (the navigation property name from `to` back to `from`). |
The `direct` and `back` objects each contain a `name` property that defines the navigation property used in source expands and column binding paths.
## Cardinality Summary
| Cardinality | Model | Source Expand | Column Binding | UI Behavior |
| ----------- | ------------------------------------------------------------ | ------------------------------------------------------------- | -------------------------------------- | ----------------------------- |
| **N:1** | `cardinality: many-to-one`, `direct.name: chapter` | `- name: chapter` | `chapter`, `chapter.title` | Single-value reference picker |
| **1:N** | Reverse of N:1, `back.name: userNeeds` | `- name: userNeeds` | `userNeeds` | Child rows (new sheet level) |
| **M:N** | `cardinality: many-to-many`, `back.name: systemRequirements` | `- name: systemRequirements` then `- name: systemRequirement` | `systemRequirements.systemRequirement` | Multi-item reference picker |
## Complete YAML Example
A full data model demonstrating all cardinality patterns with the standard RTM entity set:
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
description:
severity:
SystemRequirement:
polarionType: sys_req
properties:
description:
severity:
DesignRequirement:
polarionType: des_req
properties:
description:
Hazard:
polarionType: hazard
properties:
description:
RiskControl:
polarionType: risk_control
properties:
description:
relationships:
# N:1 — each SystemRequirement derives from one UserNeed
- from: SystemRequirement
to: UserNeed
cardinality: many-to-one
storage: linkedWorkItems
linkRole: refines
direct:
name: userNeed
back:
name: systemRequirements
# 1:N — each UserNeed has many SystemRequirements (reverse of above)
# No separate entry needed; use the back direction of the N:1 above.
# N:1 — each DesignRequirement derives from one SystemRequirement
- from: DesignRequirement
to: SystemRequirement
cardinality: many-to-one
storage: linkedWorkItems
linkRole: derives_from
direct:
name: systemRequirement
back:
name: designRequirements
# M:N — Hazards linked to multiple RiskControls and vice versa
- from: Hazard
to: RiskControl
cardinality: many-to-many
storage: linkedWorkItems
linkRole: mitigates
direct:
name: riskControls
back:
name: hazards
```
## Related Pages
* [Relationships](/powersheet/reference/data-model/relationships) -- Full relationship definition reference
* [Navigation Directions](/powersheet/reference/data-model/navigation-directions) -- Direct and back direction details
* [Link Roles](/powersheet/reference/data-model/link-roles) -- Polarion link role configuration
* [Data Model Types](/powersheet/reference/data-model/domainmodeltypes) -- Entity type definitions
* [Binding Syntax](/powersheet/reference/sheet-config/binding-syntax) -- Column binding path syntax
* [Multi-Item Columns](/powersheet/reference/sheet-config/multi-item-columns) -- Configuring columns for M:N relationships
* [Sources](/powersheet/reference/sheet-config/sources) -- Sheet source and expand configuration
* [Expand Clause](/powersheet/reference/query-api/expand-clause) -- Query expand clause reference
# Constraints
Source: https://learn.nextedy.com/powersheet/reference/data-model/constraints
Constraints in the Nextedy POWERSHEET data model define data scoping rules for entity types.
See also: [Data Model Types](/powersheet/reference/data-model/domainmodeltypes) | [Properties](/powersheet/reference/data-model/properties) | [Relationships](/powersheet/reference/data-model/relationships) | [Cardinality](/powersheet/reference/data-model/cardinality)
## Constraint Stages Overview
Powersheet supports three constraint stages, each applied at a different point in the entity lifecycle:
| Stage | Purpose | When Applied |
| -------- | -------------------------------------------------------------- | ---------------------------- |
| `load` | Filters which entities are loaded and displayed in the sheet | At query/load time |
| `pick` | Filters which entities appear in selection dropdowns (pickers) | When opening a picker dialog |
| `create` | Specifies default values for newly created entities | At entity creation time |
## Stage Cascading
Constraint stages cascade upward -- more specific stages inherit all constraints from less specific ones, combined with AND logic:
* **Load stage**: applies only `load` constraints
* **Pick stage**: applies `load` + `pick` constraints (AND)
* **Create stage**: applies `load` + `pick` + `create` constraints (AND)
**Fallback rule**
If no `create` constraints are defined, the system automatically uses `pick` constraints for the create stage. This means defining `pick` constraints also affects item creation unless explicit `create` constraints override them.
**Practical effect of cascading**
Because `load` constraints propagate to all subsequent stages, a `load` constraint that restricts entities to a specific document will also restrict picker results and creation scope. You only need to define more specific constraints when `pick` or `create` require additional filtering beyond what `load` already provides.
## Constraint Properties Reference
### Top-Level Structure
| Name | Type | Default | Description |
| -------------------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `constraints` | `object` | None | Top-level constraint container for an entity type. Contains `load`, `create`, and/or `pick` sub-objects. Defined within a `domainModelTypes` entry. |
| `constraints.load` | `object` | None | Query constraint defining which entities to load from Polarion. Filters entities based on document properties, work item fields, or other criteria. |
| `constraints.pick` | `object` | None | Picker constraint filtering which entities appear in selection dropdowns when creating or editing relationships. Inherits `load` constraints via cascading. |
| `constraints.create` | `object` | None | Creation constraint specifying initial values or scope for newly created entities. Inherits both `load` and `pick` constraints via cascading. |
### Document Constraint Properties
Each constraint stage accepts a `document` object for document-based filtering. These properties scope entities to specific Polarion LiveDoc documents. All standard document metadata fields are constrainable.
| Name | Type | Default | Description |
| ----------------------- | -------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `document` | `object` | None | Document-based constraint object. Scopes entities to work items within specific LiveDoc documents. |
| `document.moduleFolder` | `string` | None | Polarion space (module folder) containing the document, e.g., `"Requirements"` or `"Risks"`. Supports comparison operators. |
| `document.moduleName` | `string` | None | Polarion document name (module name) within the space. Supports comparison operators. |
| `document.type` | `string` | None | Document type identifier (e.g., `req_specification`, `risk_analysis`). Supports comparison operators. |
| `document.id` | `string` | None | Polarion document ID to constrain entities to. Matches the document's internal identifier (e.g., `"Requirements"`). Supports comparison operators. |
| `document.title` | `string` | None | Polarion document title to constrain entities to. Matches the document's display title. Supports comparison operators. |
| `document.component` | `string` | None | Component or category assigned to the document. Useful for scoping by product component or sub-system. Supports comparison operators. |
**Constrainable document properties**
All document metadata fields -- `moduleFolder`, `moduleName`, `type`, `id`, `title`, and `component` -- can be used in constraint expressions. Combine them within a single `document` block to express precise scoping rules (for example, constraining by space and document type together).
### Field-Level Constraint Properties
In addition to document constraints, each stage can constrain on work item field values:
| Name | Type | Default | Description |
| ------------- | -------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `` | `string` or `object` | None | Constrains the named work item field to a specific value or comparison expression. The field name must match a property defined on the entity type or a built-in Polarion field. |
## Comparison Operators
Constraint values support five comparison operators for flexible matching:
| Operator | Syntax | Description | Example |
| ------------ | ------------------------------ | ---------------------------------------------------------------------- | -------------------------------------- |
| `equals` | `value` or `{ equals: value }` | Exact match (default when a plain string is provided) | `severity: high` |
| `contains` | `{ contains: value }` | Substring match -- true if the field value contains the specified text | `title: { contains: "safety" }` |
| `in` | `{ in: [v1, v2, ...] }` | Set membership -- true if the field value matches any item in the list | `status: { in: [approved, reviewed] }` |
| `startsWith` | `{ startsWith: value }` | Prefix match -- true if the field value starts with the specified text | `id: { startsWith: "REQ-" }` |
| `endsWith` | `{ endsWith: value }` | Suffix match -- true if the field value ends with the specified text | `title: { endsWith: "-draft" }` |
**Default operator**
When a constraint value is a plain string (not an object), it is treated as an `equals` comparison. Use the object syntax only when you need a different operator.
## Logical Operators
### AND Logic (Between Constraints)
Multiple constraints within the same stage are combined with AND logic. All conditions must be true for an entity to pass the constraint:
```yaml theme={null}
domainModelTypes:
SystemRequirement:
polarionType: sys_req
constraints:
load:
severity: high
status: approved
# Result: severity = "high" AND status = "approved"
```
### OR Logic (Within Document Block)
Inside the `document` block, OR logic is supported. An entity passes the constraint if it matches **any** of the document conditions:
```yaml theme={null}
domainModelTypes:
SystemRequirement:
polarionType: sys_req
constraints:
load:
document:
id:
in: [Requirements, SafetyRequirements]
# Result: document.id = "Requirements" OR document.id = "SafetyRequirements"
```
**Combining AND and OR**
Field-level constraints use AND logic between each other, while the `in` operator provides OR semantics within a single field. This combination covers most practical filtering scenarios.
## Dynamic Context Constraints
Constraints can reference the current runtime context using special context expressions. This enables constraints that are resolved dynamically based on the active sheet session.
| Context Variable | Description |
| ------------------------ | --------------------------------------------------------- |
| `$currentDocument.id` | ID of the document currently open in the Polarion LiveDoc |
| `$currentDocument.title` | Title of the currently open document |
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
constraints:
load:
document:
id: $currentDocument.id
pick:
document:
id: $currentDocument.id
```
This configuration ensures that only work items from the currently viewed document are loaded into the sheet and shown in pickers.
**Verify in application**
The full list of available context variables may extend beyond `$currentDocument`. Consult the application release notes for the latest supported context expressions.
For more on context expressions in queries, see [Context Expressions Reference](/powersheet/reference/data-model/context-expressions).
## Constraint Composition
Constraints can be defined at multiple stages simultaneously on the same entity type. When combined, stages cascade as described above.
### Composition Example
```yaml theme={null}
domainModelTypes:
DesignRequirement:
polarionType: des_req
constraints:
load:
document:
id: $currentDocument.id
pick:
status:
in: [approved, reviewed]
create:
severity: medium
```
**Effective constraints at each stage:**
| Stage | Effective Constraints |
| ---------- | ------------------------------------------------------------------------------------------------ |
| **Load** | `document.id = $currentDocument.id` |
| **Pick** | `document.id = $currentDocument.id` AND `status IN [approved, reviewed]` |
| **Create** | `document.id = $currentDocument.id` AND `status IN [approved, reviewed]` AND `severity = medium` |
**Conflicting constraints**
Constraint composition can produce empty results if constraints conflict. For example, a `load` constraint limiting entities to `status: approved` combined with a `pick` constraint for `status: draft` would produce no picker results because both conditions apply simultaneously (AND logic). Review your cascading chain to avoid contradictions.
## Complete YAML Examples
### Load-Only Constraint
Restrict an entity type to only show work items from a specific document:
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
description:
severity:
constraints:
load:
document:
id: Requirements
```
**Effect**: Only `UserNeed` items in the "Requirements" document are loaded into the sheet. Pickers and creation inherit this constraint.
### Pick-Only Constraint
Allow all entities to load but restrict picker options:
```yaml theme={null}
domainModelTypes:
SystemRequirement:
polarionType: sys_req
properties:
description:
severity:
constraints:
pick:
status:
in: [approved, reviewed]
```
**Effect**: All `SystemRequirement` items load normally. Picker dialogs only show items with status `approved` or `reviewed`. Since no `create` constraints are defined, the pick constraints apply as a fallback during creation as well.
### Create-Only Constraint
Set default values when creating new entities without affecting loading or picking:
```yaml theme={null}
domainModelTypes:
Hazard:
polarionType: hazard
properties:
severity:
status:
constraints:
create:
severity: low
status: draft
```
**Effect**: All hazards load normally and all appear in pickers. Newly created hazards default to `severity: low` and `status: draft`.
### Current-Document Scoping
Dynamically scope all stages to the currently open document:
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
description:
severity:
constraints:
load:
document:
id: $currentDocument.id
pick:
document:
id: $currentDocument.id
create:
document:
id: $currentDocument.id
```
**Effect**: Loading, picking, and creation are all scoped to the document currently open in Polarion. This is the most common pattern for document-centric sheets.
### Multi-Stage Composition
A complete example combining all three stages with different scoping:
```yaml theme={null}
domainModelTypes:
Chapter:
polarionType: heading
UserNeed:
polarionType: user_need
properties:
description:
severity:
constraints:
load:
document:
id: $currentDocument.id
pick:
status:
in: [approved, reviewed, draft]
create:
severity: medium
SystemRequirement:
polarionType: sys_req
properties:
description:
severity:
constraints:
load:
document:
id: $currentDocument.id
pick:
severity:
in: [high, critical]
relationships:
- from: SystemRequirement
to: UserNeed
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds
back:
name: systemRequirements
```
**Effect**:
* `UserNeed` items load from the current document, pickers show only approved/reviewed/draft items from that document, and new items default to `severity: medium`
* `SystemRequirement` items load from the current document, pickers show only high/critical severity items from that document
* The `relationships` section connects the two entity types -- picker constraints on `UserNeed` affect which items appear when linking a `SystemRequirement` to user needs
## Constraints and Relationships
Constraints interact with [Relationships](/powersheet/reference/data-model/relationships) through picker behavior. When a sheet column binds to a navigation property (e.g., `userNeeds` or `chapter`), the picker dialog for that column uses the `pick` constraints defined on the **target** entity type.
| Relationship | Column Binding | Picker Constrained By |
| --------------------------------- | -------------- | --------------------------- |
| `SystemRequirement` -> `UserNeed` | `userNeeds` | `UserNeed.constraints.pick` |
| `UserNeed` -> `Chapter` | `chapter` | `Chapter.constraints.pick` |
For details on how cardinality affects column bindings, see [Cardinality](/powersheet/reference/data-model/cardinality). For details on column binding syntax, see [Binding Syntax](/powersheet/reference/sheet-config/binding-syntax).
**Relationship picker filtering**
If a picker shows too many or too few items when linking entities, check the `pick` constraints on the target entity type. Remember that `load` constraints cascade into `pick`, so an overly restrictive `load` constraint will also limit picker results.
## Sheet-Level Constraints
In addition to data model constraints, constraints can also be applied at the sheet configuration level through source queries. Source-level constraints use the `query` and `expand` syntax rather than the `constraints` YAML key.
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: chapter
```
Source-level filtering and data model constraints work together:
* **Data model constraints** (this page) define permanent scoping rules for an entity type across all sheets
* **Source query constraints** restrict which entities appear in a specific sheet configuration
For source query syntax, see [Sources](/powersheet/reference/sheet-config/sources). For query filtering options, see [EntityQuery](/powersheet/reference/query-api/entity-query) and [Document Filtering](/powersheet/reference/query-api/document-filtering).
## Quick Reference
### Constraint Stage Summary
| Stage | Inherits From | Purpose | Fallback |
| -------- | --------------- | ----------------------------- | --------------------------------- |
| `load` | -- | Filter entities at query time | None |
| `pick` | `load` | Filter picker dropdown items | None |
| `create` | `load` + `pick` | Set defaults on new entities | Falls back to `pick` if undefined |
### Operator Summary
| Operator | Syntax | Logic |
| ------------ | ------------------------------ | -------------- |
| `equals` | `field: value` | Exact match |
| `contains` | `field: { contains: value }` | Substring |
| `in` | `field: { in: [a, b] }` | Any match (OR) |
| `startsWith` | `field: { startsWith: value }` | Prefix |
| `endsWith` | `field: { endsWith: value }` | Suffix |
### Cascading Rules
| Rule | Behavior |
| ---------------------------- | --------------------------------- |
| Multiple fields in one stage | AND logic |
| `in` operator values | OR logic (within single field) |
| Cross-stage inheritance | AND with parent stage constraints |
| Missing `create` stage | Falls back to `pick` constraints |
| Conflicting constraints | May produce empty result set |
***
# Context Expressions Reference
Source: https://learn.nextedy.com/powersheet/reference/data-model/context-expressions
Nextedy POWERSHEET configurations support **dynamic value expressions** -- values resolved at runtime based on the current context such as the active document, the logged-in user, URL parameters, or the source entity.
See also: [Constraints](/powersheet/reference/data-model/constraints) | [Properties](/powersheet/reference/data-model/properties) | [Relationships](/powersheet/reference/data-model/relationships) | [Binding Syntax](/powersheet/reference/sheet-config/binding-syntax)
## Two Expression Notations
Powersheet uses two distinct expression notations depending on the configuration layer:
| Notation | Syntax | Used In | Expressiveness |
| ---------------------- | ------------------------ | ------------------------------------------------------ | --------------------------------- |
| **Context expression** | `$context.property.path` | Data model configuration (constraints) | Dot-notation property access only |
| **Dynamic value** | `() => expression` | Sheet configuration (`where`, `value`, `render`, etc.) | Full JavaScript arrow function |
**Rule of thumb**
If you are editing a **data model** YAML file (`domainModelTypes`, `relationships`), use `$context`. If you are editing a **sheet configuration** YAML file (`sources`, `columns`, `formatters`), use `() =>`.
***
## Context Expression (`$context`)
Context expressions use dot-notation to access properties from the runtime context. They are used exclusively in **data model configuration** -- specifically within [constraint](/powersheet/reference/data-model/constraints) definitions on entity types and relationships.
### How It Works
A `$context` expression is a property path that Powersheet resolves by traversing the context object at runtime. No JavaScript logic is supported -- only direct property access via dot-separated keys.
### Where It Is Used
| Configuration Location | Description |
| ------------------------------------ | -------------------------------------------------------------------- |
| `domainModelTypes.*.constraints` | Entity type constraints -- scopes `load`, `pick`, or `create` stages |
| `relationships.*.direct.constraints` | Direct-direction relationship constraints |
| `relationships.*.back.constraints` | Back-direction relationship constraints |
### Available Context Paths
| Path | Type | Description | Example Value |
| --------------------------------------- | -------- | --------------------------------------- | ----------------------------------- |
| `$context.source.type` | `string` | Source entity's Polarion work item type | `"sys_req"` |
| `$context.source.document.id` | `string` | Source entity's document ID | `"Requirements/SRS"` |
| `$context.source.document.moduleName` | `string` | Source entity's document module name | `"UserNeedSpecification"` |
| `$context.source.document.moduleFolder` | `string` | Source entity's document folder path | `"Requirements"` |
| `$context.source.document.component` | `string` | Source entity's document component | `"Braking"` |
| `$context.source.document.type` | `string` | Source entity's document type | `"systemRequirementsSpecification"` |
| `$context.source.document.title` | `string` | Source entity's document title | `"System Requirements"` |
**Per-row evaluation**
Dynamic constraints with `$context` are evaluated **per-row**. Different rows can produce different constraint values depending on their source entity's properties. For example, a `UserNeed` in a "Braking" document produces different constraint values than one in a "Steering" document.
### Context Expression Examples
**Filter linked items to the same document component as the source item:**
```yaml theme={null}
relationships:
- from: DesignRequirement
to: SystemRequirement
back:
name: designRequirements
constraints:
load:
document:
component: $context.source.document.component
```
When viewing a `SystemRequirement` from the "Braking" component, only `DesignRequirement` entities from "Braking" documents are loaded.
**Filter linked items to the same document as the source item:**
```yaml theme={null}
constraints:
load:
document:
moduleName: $context.source.document.moduleName
moduleFolder: $context.source.document.moduleFolder
```
This restricts loaded entities to the exact same LiveDoc document as the source entity, matching on both module name and folder.
**Filter picker options by source document type:**
```yaml theme={null}
constraints:
pick:
document:
type: $context.source.document.type
```
When a user opens a picker dialog, only entities from documents matching the source entity's document type appear as options.
### Complete Data Model Example with Context Expressions
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
description:
severity:
SystemRequirement:
polarionType: sys_req
properties:
description:
severity:
DesignRequirement:
polarionType: des_req
properties:
description:
relationships:
- from: SystemRequirement
to: UserNeed
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds
back:
name: systemRequirements
constraints:
load:
document:
component: $context.source.document.component
- from: DesignRequirement
to: SystemRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: systemRequirements
back:
name: designRequirements
constraints:
load:
document:
moduleName: $context.source.document.moduleName
moduleFolder: $context.source.document.moduleFolder
pick:
document:
type: $context.source.document.type
```
In this model, `SystemRequirement` back-navigation to `DesignRequirement` entities filters by both module name and folder at load time, and additionally restricts picker results by document type.
***
## Dynamic Value (`() => expression`)
Dynamic values use JavaScript arrow function syntax and are used in **sheet configuration** YAML files. They provide full JavaScript expressiveness for computing values, filtering data, and rendering content at runtime.
### How It Works
A `() =>` expression is a JavaScript arrow function that receives a `context` object. Powersheet evaluates the function at runtime and uses the returned value. The expression must be wrapped in quotes within the YAML to preserve the arrow function syntax.
### Where It Is Used
| Sheet Configuration Property | Purpose | Returns |
| ---------------------------- | ------------------------------------------------ | --------------------------------------------------------------------------------- |
| `sources.query.where` | Filter data with dynamic predicates | Value matching the predicate type |
| `sources.entityFactory` | Set initial values for new items | Property value |
| `columns.*.value` | Compute a column's content from other properties | Computed value -- persisted on a bound column, display-only on a `$`-prefixed one |
| `columns.*.formula` | Deprecated spelling of `columns.*.value` | Same as `value` |
| `columns.*.render` | Custom HTML rendering for cells | HTML string |
| `columns.*.display` | Override display value for navigation properties | Display string |
| `renderers.*` | Named renderer definitions | HTML string |
| `formatters.*.expression` | Conditional formatting expressions | Boolean |
**`value` is about data; `render` is about appearance.**
On a column bound to a real property, `value` affects **persisted data** -- the computed result is saved back to that property. Use `render` if you only need to change how a value is **displayed** without modifying the underlying data. If the result should never be stored, prefix the binding key with `$` so the column is [unbound](/powersheet/reference/sheet-config/binding-syntax#unbound-columns).
**Formatter expression syntax**
Formatter expressions use a simplified syntax -- they do **not** start with `() =>`. The expression is evaluated as a boolean condition directly (e.g., `"context.entity.Probability <= 99"`).
### Context Availability by Location
Not all context properties are available in every location. The following table shows which context sub-objects are accessible in each usage location:
| Usage Location | `.user` | `.sources` | `.document` | `.entity` | `.value` | `.source` | `.row` | `.parameters` |
| ---------------------------- | ------- | ---------- | ----------- | --------- | -------- | --------- | ------ | ------------- |
| `where` | ✅ | ✅ | ✅ | -- | -- | -- | -- | ✅ |
| `entityFactory` | ✅ | ✅ | -- | -- | -- | -- | -- | ✅ |
| `value` (bound column) | ✅ | ✅ | -- | ✅ | -- | -- | -- | ✅ |
| `value` (unbound `$` column) | ✅ | ✅ | -- | ✅ | -- | ✅ | ✅ | ✅ |
| `render` / `renderers` | -- | -- | -- | ✅ | ✅ | -- | -- | -- |
| `formatter` | -- | -- | ✅ | ✅ | ✅ | -- | -- | -- |
| `display` | -- | -- | -- | ✅ | ✅ | ✅ | -- | -- |
`context.item` is deprecated because it's ambiguous -- in some cell expressions it's the entity, in others the whole row. Use `context.entity` or `context.row` instead; each always means exactly one thing.
### Dynamic Value Examples
**Where clause -- filter by current document:**
```yaml theme={null}
sources:
- id: requirements
query:
from: Requirement
where:
document:
moduleName:
"==": "() => context.document.moduleName"
```
The sheet loads only `Requirement` entities whose `document.moduleName` matches the current document's module name, scoping results to the active LiveDoc.
**Where clause -- filter by today's date:**
```yaml theme={null}
where:
DueDate:
">": "() => new Date().toISOString()"
```
**Date format**
The resulting value must be in the correct format for the data type. For date fields, use `.toISOString()` to produce the ISO 8601 string that Polarion expects.
**Where clause -- combine multiple parameters:**
```yaml theme={null}
where:
Client:
"==": "() => `${context.parameters.client} ${context.parameters.status}`"
```
Template literal syntax allows concatenating multiple URL parameters into a single filter value.
**Entity factory -- set initial value from the source entity type:**
```yaml theme={null}
sources:
- id: design_requirements
query:
from: DesignRequirement
entityFactory:
sourceType: "() => context.source.type"
```
When a user creates a new `DesignRequirement` entity in this sheet, the `sourceType` field is automatically populated with the Polarion work item type of the parent/source entity.
**Value -- compute a column's content from other entity properties:**
```yaml theme={null}
columns:
total:
value: "() => context.entity.count * context.entity.rate"
```
The `total` column's content is computed by multiplying `count` by `rate`. Because the column binds to a real property, the computed value is persisted to the data source.
**Value on an unbound column -- compute without storing anything:**
```yaml theme={null}
columns:
$riskScore:
title: Risk Score
value: "() => context.entity.Probability * context.entity.Severity"
valueType: number
```
The `$` prefix makes the column unbound: the value is computed on read, shown in the sheet, and never written anywhere.
**Renderer -- custom HTML output:**
```yaml theme={null}
renderers:
linkedItems: "() => context.value.map((item) => `${item.name} `).join(', ')"
```
Renders each linked item name in bold, separated by commas.
**Display -- show a property of a linked entity:**
```yaml theme={null}
columns:
systemRequirement.document:
display: "() => context.document.title"
```
Instead of showing the raw document reference, the column displays the document's human-readable title.
**Formatter -- conditional styling:**
```yaml theme={null}
formatters:
criticalHighlight:
expression: "context.entity.Probability <= 99"
style: warningStyle
```
Applies `warningStyle` to cells where the `Probability` value is 99 or below. Note the simplified syntax without `() =>`.
***
## The Context Object
The context object provides runtime information to dynamic expressions. Its structure is hierarchical, with properties progressively available depending on the evaluation scope.
### Context Object Structure
| Property | Type | Description | Available In |
| -------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------- |
| `context.parameters` | `object` | Parameters read from the sheet's URL query string, as key-value pairs. Access individual parameters via `context.parameters.{paramName}`. Drives server-side scoping -- see [URL Parameters](/powersheet/reference/sheet-config/url-parameters). | `where`, `entityFactory`, `value` |
| `context.parameters.{paramName}` | `string` | Individual URL parameter value (e.g., `context.parameters.client`). A referenced parameter with no URL value drops its `where` condition unless declared `required`. | `where`, `entityFactory`, `value` |
| `context.user` | `object` | Current logged-in Polarion user | `where`, `entityFactory`, `value` |
| `context.user.id` | `string` | User's login ID | `where`, `entityFactory`, `value` |
| `context.user.name` | `string` | User's display name | `where`, `entityFactory`, `value` |
| `context.sources` | `object` | All configured data source definitions from the sheet configuration | `where`, `entityFactory`, `value` |
| `context.document` | `object` | Current document information | `where`, `formatter` |
| `context.document.title` | `string` | Document title | `where`, `formatter` |
| `context.document.type` | `string` | Document type | `where`, `formatter` |
| `context.document.id` | `string` | Document identifier | `where`, `formatter` |
| `context.document.moduleName` | `string` | Document module name | `where`, `formatter` |
| `context.document.moduleFolder` | `string` | Document folder path | `where`, `formatter` |
| `context.document.component` | `string` | Document component | `where`, `formatter` |
| `context.tool` | `object` | Current tool information | See application |
| `context.tool.type` | `string` | Tool type identifier | See application |
| `context.entity` | `object` | Current entity (row) with all its properties. Access fields via `context.entity.{propertyName}`. | `value`, `render`, `formatter`, `display` |
| `context.source` | `object` | Parent/source entity -- the level the current one was navigated from. Access its document via `context.source.document.*`. | `display`, `value` on an unbound column, `$context` expressions |
| `context.row` | `object` | The whole row, as `context.row.entities[]` across every navigation level | `value` on an unbound column |
| `context.value` | `any` | Current cell's display value. A JSON object or array is decoded; any other string is passed through unchanged. `undefined` inside a `value` expression | `render`, `formatter`, `display` |
| `context.item` | `object` | **Deprecated** alias of `context.entity` in cell expressions; the whole row in a dynamic `isReadOnly` expression | Wherever `context.entity` is |
### Context Tree Diagram
```
context
+-- parameters URL and configuration parameters (key-value pairs)
| +-- {paramName} e.g., context.parameters.client
+-- user Current logged-in user
| +-- id
| +-- name
+-- sources All configured data source definitions
+-- document Current document information
| +-- title
| +-- type
| +-- id
| +-- moduleName
| +-- moduleFolder
| +-- component
+-- tool Current tool information
| +-- type
+-- entity Current entity (per-cell contexts only)
| +-- {propertyName} e.g., context.entity.severity
+-- source Parent/source entity -- the level navigated from
| +-- {propertyName} e.g., context.source.document.component
+-- row The whole row across every navigation level
| +-- entities[] e.g., context.row.entities[0]
+-- value Current cell's display value
+-- item Deprecated alias of context.entity
```
**Scope-dependent availability**
* `entity`, `source`, `row`, `value`, and the deprecated `item` are only available in **per-cell** contexts (`value`, `render`, `formatter`, `display`)
* `row` and `source` reach a `value` expression only on an **unbound** (`$`-prefixed) column
* `document` is available in `where` clauses and `formatter` expressions
* In `$context` expressions (data model constraints), only `source` and its sub-properties are available
***
## Notation Comparison
The two expression systems serve complementary purposes. Understanding when to use each prevents configuration errors.
| Aspect | `$context` (Model) | `() =>` (Sheet) |
| ---------------------- | ----------------------------------------------- | ------------------------------------------------------------- |
| **Syntax** | `$context.source.document.component` | `"() => context.document.moduleName"` |
| **Language** | Dot-notation path (no logic) | JavaScript arrow function |
| **Configuration file** | Data model YAML | Sheet configuration YAML |
| **Evaluation** | Per-row, based on source entity | Per-cell or per-query, based on context scope |
| **Capabilities** | Property path access only | Arithmetic, string interpolation, array methods, conditionals |
| **Use cases** | Constraint scoping by document, type, component | Query filtering, computed columns, custom rendering |
| **YAML quoting** | Not required | Required (wrap in double quotes) |
***
## Quick Reference
| I want to... | Notation | Example |
| ------------------------------------------------ | ---------- | ------------------------------------------------------------ |
| Filter relationship by source document component | `$context` | `component: $context.source.document.component` |
| Filter relationship by source document module | `$context` | `moduleName: $context.source.document.moduleName` |
| Filter query by current document | `() =>` | `"==": "() => context.document.moduleName"` |
| Compute a column and store the result | `() =>` | `value: "() => context.entity.count * context.entity.rate"` |
| Compute a column without storing anything | `() =>` | `$total:` with `value: "() => …"` and `valueType: number` |
| Render custom HTML in a cell | `() =>` | `render: "() => '' + context.value + ' '"` |
| Set default value from source type | `() =>` | `entityFactory: { sourceType: "() => context.source.type" }` |
| Conditionally style a cell | expression | `expression: "context.entity.Risk > 50"` |
| Filter by today's date | `() =>` | `">": "() => new Date().toISOString()"` |
| Show linked entity property | `() =>` | `display: "() => context.document.title"` |
***
## Complete Sheet Configuration Example
The following example demonstrates multiple dynamic value expression types in a single sheet configuration:
```yaml theme={null}
sources:
- id: requirements
query:
from: Requirement
where:
document:
moduleName:
"==": "() => context.document.moduleName"
DueDate:
">": "() => new Date().toISOString()"
entityFactory:
sourceType: "() => context.source.type"
columns:
title:
title: Title
hasFocus: true
sourceType:
title: Source Type
isReadOnly: true
count:
title: Count
rate:
title: Rate
total:
title: Total
value: "() => context.entity.count * context.entity.rate"
systemRequirement.document:
display: "() => context.document.title"
renderers:
linkedItems: "() => context.value.map((item) => `${item.name} `).join(', ')"
formatters:
criticalHighlight:
expression: "context.entity.Probability <= 99"
style: warningStyle
```
This configuration:
1. **Filters** the `Requirement` source by the current document's module name and future due dates
2. **Pre-fills** the `sourceType` field on new entities from the parent/source entity's work item type
3. **Computes** `total` from `count` and `rate`, and persists the result
4. **Displays** the document title instead of a raw reference
5. **Renders** linked items with bold formatting
6. **Highlights** rows where `Probability` is 99 or below
***
## See Also
* [Constraints](/powersheet/reference/data-model/constraints) -- full reference on constraint configuration including stages, operators, and composition
* [Columns](/powersheet/reference/sheet-config/columns) -- column configuration properties including `value`, `valueType`, `render`, and `display`
* [Formatters](/powersheet/reference/sheet-config/formatters) -- conditional formatting and style definitions
* [Sources](/powersheet/reference/sheet-config/sources) -- source query configuration including `where` and `entityFactory`
* [Binding Syntax](/powersheet/reference/sheet-config/binding-syntax) -- dot-notation paths for column keys
* [Navigation Directions](/powersheet/reference/data-model/navigation-directions) -- direct and back relationship directions
* [Cardinality](/powersheet/reference/data-model/cardinality) -- how relationship cardinality affects expand patterns and column binding
# Data Model Types
Source: https://learn.nextedy.com/powersheet/reference/data-model/domainmodeltypes
The `domainModelTypes` section is the primary configuration block in the Nextedy POWERSHEET data model YAML.
## Top-Level Structure
`domainModelTypes` is defined as a **map** where each key is the entity type name and the value is the type definition object:
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
description:
severity:
SystemRequirement:
polarionType: sys_req
properties:
description:
component:
```
The map key becomes the entity type `name` automatically. When the data model is loaded, Powersheet copies each map key into the corresponding type object so the name is consistently available regardless of how the type is accessed.
**Map format only**
`domainModelTypes` must be a YAML map. Array format is **not** supported.
## Entity Type Diagram
## Entity Type Configuration Properties
| Property | Type | Default | Description |
| --------------- | ---------------------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name` | `string` | Derived from map key | Unique identifier for the entity type. Set automatically from the YAML map key. Referenced by `relationships[].from` and `relationships[].to`. |
| `pluralName` | `string` | Auto-generated from `name` | Plural form of the entity type name. Auto-generated using standard English pluralization if not specified. |
| `polarionType` | `string` or `string[]` | See application | Maps this entity to one or more Polarion work item type IDs. Accepts a single string or a list for [multi-type entities](/powersheet/guides/data-model/create-entity-type). |
| `polarionProto` | `string` | `IWorkItem.PROTO` | Specifies the Polarion prototype (object type) this entity maps to. Determines which Polarion object class this entity can represent. |
| `properties` | `map` | `{}` | Map of property definitions that define the fields available on this entity type. See [Properties](/powersheet/reference/data-model/properties). |
| `constraints` | `object` | None | Optional data scoping rules. See [Constraints](/powersheet/reference/data-model/constraints). |
**Naming rules**
Entity type names **must** be single words without spaces or special characters. Relationship `from` and `to` fields reference these entity type names -- not Polarion work item type IDs. Using an invalid name causes configuration errors.
**Naming convention**
PascalCase (e.g., `UserNeed`, `SystemRequirement`) is a common convention for entity type names, but it is not a requirement. Names are case-sensitive.
## `name`
The entity type name is the primary identifier used throughout the data model. It is set automatically from the YAML map key and does not need to be specified separately.
```yaml theme={null}
domainModelTypes:
UserNeed: # name = "UserNeed"
polarionType: user_need
SystemRequirement: # name = "SystemRequirement"
polarionType: sys_req
```
Entity type names are used in:
* `relationships[].from` and `relationships[].to` to reference participating types
* Sheet source `query.from` to identify the root entity type
* Expansion paths to navigate between related entities
* Metadata system queries for type-based filtering
## `pluralName`
An optional plural form of the entity type name. When omitted, Powersheet auto-generates it using standard English pluralization rules.
```yaml theme={null}
domainModelTypes:
Hazard:
polarionType: hazard
pluralName: Hazards
```
**Verify in application**
The `pluralName` property has limited support in current versions. Auto-generated pluralization covers most standard English forms.
## `polarionType`
Maps the data model entity to one or more Polarion work item types. This property is critical for Powersheet's integration with Polarion -- it determines which work items this entity type can represent.
**Single type mapping:**
```yaml theme={null}
SystemRequirement:
polarionType: sys_req
```
**Multiple type mapping:**
```yaml theme={null}
Requirement:
polarionType:
- sys_req
- des_req
```
When multiple types are specified, the entity type matches work items of any of the listed Polarion types. This enables a single entity type to aggregate work items across multiple Polarion types. See [Polarion Type Mapping](/powersheet/reference/data-model/polarion-mapping) for details on type resolution.
## `polarionProto`
Specifies the Polarion prototype (object type) this entity maps to. Most entity types use the default work item prototype and do not need to set this property.
| Value | Usage |
| --------------------------- | ------------------------------ |
| `IWorkItem.PROTO` (default) | Standard work items |
| Other prototypes | Non-work-item Polarion objects |
```yaml theme={null}
Document:
polarionProto: IModule.PROTO
```
## `properties`
Defines which fields are available on this entity type. Properties are declared as a **map** where the key is the property name.
```yaml theme={null}
UserNeed:
polarionType: user_need
properties:
description:
severity:
component:
type:
```
An empty value after the property name declares the property with all default settings. To customize a property, provide a configuration object:
```yaml theme={null}
UserNeed:
properties:
title:
readable: true
updatable: true
outlineNumber:
readable: true
updatable: false
renderColumn:
serverName: customRenderField
```
**Map format only**
Properties must be declared as a YAML map. Array format (using `- name:` syntax) is **not** supported.
Properties can represent:
* **Polarion built-in fields** -- standard work item fields like `title`, `description`, `severity`
* **Custom fields** -- Polarion custom fields identified by `customFieldName`
* **Virtual properties** -- properties not backed by any Polarion field, commonly used as targets for [server rendering](/powersheet/reference/server-rendering/velocity-templates) or computed display columns
For detailed property configuration including `serverName`, `customFieldName`, `type`, `storage`, `scalar`, and `navigability`, see [Properties](/powersheet/reference/data-model/properties).
### Built-in Properties
All entity types automatically include these properties without explicit declaration:
| Property | Type | Description |
| ----------- | -------- | ----------------------------------------- |
| `objectId` | `string` | Unique entity identifier (primary key) |
| `id` | `string` | Polarion work item ID |
| `title` | `string` | Work item title |
| `projectId` | `string` | Polarion project identifier (foreign key) |
### Permission Flags on Properties
Individual properties support field-level access control:
| Flag | Type | Default | Description |
| ----------- | --------- | ------- | ------------------------------------------------------------------------------ |
| `readable` | `boolean` | `true` | Whether the property is visible to users in the sheet and available in queries |
| `updatable` | `boolean` | `true` | Whether the property can be modified through save operations |
```yaml theme={null}
SystemRequirement:
properties:
description:
readable: true
updatable: true
outlineNumber:
readable: true
updatable: false
internalStatus:
readable: false
updatable: false
```
Setting `readable: false` hides the property entirely from the metadata system. Setting `updatable: false` makes the property read-only in the sheet while still allowing it to be displayed. See [Permissions](/powersheet/reference/data-model/permissions) for additional access control options.
## `constraints`
Defines data scoping rules at three lifecycle points. Constraints control which work items are loaded, which can be selected in pickers, and how new entities are created. See [Constraints](/powersheet/reference/data-model/constraints) for full reference.
```yaml theme={null}
SystemRequirement:
polarionType: sys_req
constraints:
load:
document:
type: systemSpecification
create:
document:
moduleFolder: Requirements
moduleName: System Specification
pick:
document:
type: systemSpecification
```
| Constraint | Purpose |
| ---------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `load` | Filters which entities are fetched during initial data loading. Applies a Lucene query scope. |
| `create` | Configures defaults for newly created entities: document location, project routing, default field values, and type/relation constraints. |
| `pick` | Restricts which entities appear in picker dialogs when creating or editing relationships. |
**Constraint interaction**
The `load` constraint affects what data is visible in the sheet. The `pick` constraint independently controls what items appear in reference pickers. The `create` constraint controls the full creation workflow including where new items are placed and what defaults they receive.
## Built-in Entity Types
Powersheet provides the `Document` entity type without explicit declaration. All other entity types, including `Chapter`, must be declared in the `domainModelTypes` map.
| Entity Type | Requires Declaration | Description |
| ----------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Document` | No | Represents Polarion documents (LiveDoc modules). Exposes module properties like `moduleName`, `title`, `titleOrName`, `titleWithSpace`, and `allowedWITypes`. Not a work item type. |
| `Project` | No | Represents the Polarion project. Linked to all work item entities via `projectObjectId`. |
| `Chapter` | **Yes** | Represents heading work items in document structures. Must be explicitly declared with `polarionType: heading`. |
**Document entity**
The `Document` entity type is not a work item. It provides navigation access to the containing document's properties for filtering and constraints. It uses a different Polarion prototype than standard entity types.
### Declaring Chapter
To use `Chapter` in your data model, declare it explicitly:
```yaml theme={null}
domainModelTypes:
Chapter:
polarionType: heading
```
Chapters are commonly used in many-to-one relationships where work items belong to a document section:
```yaml theme={null}
relationships:
- from: UserNeed
to: Chapter
cardinality: many-to-one
storage: linkedWorkItems
linkRole: parent
direct:
name: chapter
back:
name: userNeeds
```
## How Entity Types Connect to Sources and Columns
Entity types defined in `domainModelTypes` are referenced throughout the sheet configuration. The connection flows through three layers:
1. **Data model** -- defines entity types and their relationships
2. **Sheet sources** -- queries entity types and expands relationships
3. **Sheet columns** -- binds to entity properties using dot-notation paths
The [cardinality](/powersheet/reference/data-model/cardinality) of a relationship determines the expand pattern and column binding syntax.
### Cardinality Summary
| Cardinality | Source Expand | Column Binding | UI Behavior |
| ---------------------- | ------------------------------------------------------------- | -------------------------------------- | ----------------------------- |
| **N:1** (many-to-one) | `- name: chapter` | `chapter`, `chapter.title` | Single-value reference picker |
| **1:N** (one-to-many) | `- name: userNeeds` | `userNeeds` | Child rows (new sheet level) |
| **M:N** (many-to-many) | `- name: systemRequirements` then `- name: systemRequirement` | `systemRequirements.systemRequirement` | Multi-item reference picker |
See [Relationships](/powersheet/reference/data-model/relationships) for relationship configuration and [Binding Syntax](/powersheet/reference/sheet-config/binding-syntax) for column path resolution.
## Complete YAML Example
A comprehensive data model using the standard RTM entity set:
```yaml theme={null}
domainModelTypes:
Chapter:
polarionType: heading
UserNeed:
polarionType: user_need
properties:
description:
severity:
SystemRequirement:
polarionType: sys_req
properties:
description:
severity:
component:
type:
constraints:
load:
document:
type: systemSpecification
create:
document:
moduleFolder: Requirements
moduleName: System Specification
pick:
document:
type: systemSpecification
DesignRequirement:
polarionType: des_req
properties:
description:
severity:
constraints:
create:
document:
moduleFolder: Design
moduleName: Design Specification
Hazard:
polarionType: hazard
properties:
description:
severity:
RiskControl:
polarionType: riskControl
properties:
description:
relationships:
- from: UserNeed
to: Chapter
cardinality: many-to-one
storage: linkedWorkItems
linkRole: parent
direct:
name: chapter
back:
name: userNeeds
- from: SystemRequirement
to: UserNeed
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds
back:
name: systemRequirements
- from: SystemRequirement
to: DesignRequirement
cardinality: one-to-many
storage: linkedWorkItems
linkRole: refines
direct:
name: designRequirements
back:
name: systemRequirement
- from: Hazard
to: RiskControl
cardinality: many-to-many
storage: linkedWorkItems
linkRole: mitigates
direct:
name: riskControls
back:
name: hazards
```
## Programmatic Access
Powersheet provides several methods for accessing entity type definitions at runtime:
| Method | Return Type | Description |
| ----------------------------- | ----------- | --------------------------------------------------------------------------------------------------------------------- |
| `getDomainModelTypes()` | Collection | Returns all entity type definitions. Ensures type names are mapped before returning. |
| `getDomainModelTypesMap()` | Map | Returns entity types keyed by name for lookup access. |
| `getDomainModelType(name)` | Optional | Retrieves a specific entity type by name. Returns empty if the type does not exist. |
| `getProperty(name)` | Property | Retrieves a specific property definition from an entity type. Returns null if the property does not exist. |
| `addProperty(name, property)` | void | Programmatically adds a property definition to an entity type. Validates that the property name is not null or empty. |
**Verify in application**
Programmatic access is primarily used in server-side extensions and custom Velocity templates. Standard sheet configuration uses the YAML declaration approach.
## Related Pages
* [Relationships](/powersheet/reference/data-model/relationships) -- Relationship definitions between entity types
* [Properties](/powersheet/reference/data-model/properties) -- Property configuration details including `serverName`, `customFieldName`, and `type`
* [Constraints](/powersheet/reference/data-model/constraints) -- Load, create, and pick constraint reference
* [Cardinality](/powersheet/reference/data-model/cardinality) -- How relationship cardinality affects sources and columns
* [Polarion Type Mapping](/powersheet/reference/data-model/polarion-mapping) -- How `polarionType` resolves to work item types
* [Permissions](/powersheet/reference/data-model/permissions) -- Property-level access control
* [Link Roles](/powersheet/reference/data-model/link-roles) -- Polarion link role configuration for relationships
* [Navigation Directions](/powersheet/reference/data-model/navigation-directions) -- Forward and reverse navigation properties
***
# Data Model Reference
Source: https://learn.nextedy.com/powersheet/reference/data-model/index
The Nextedy POWERSHEET data model defines the semantic layer between Siemens Polarion ALM's native data structures and the Powersheet sheet interface.
## How the Data Model Works
The data model is a YAML configuration file that declares three things:
1. **Entity types** -- what kinds of objects exist (e.g., `UserNeed`, `SystemRequirement`, `Hazard`)
2. **Relationships** -- how entity types connect to each other, with cardinality and link roles
3. **Properties** -- which fields each entity type exposes, mapped to Polarion work item fields
These three layers drive everything downstream: sheet sources determine which entities to query, expansion paths follow relationship definitions, and column bindings resolve against properties.
```
┌─────────────────────────────────────────────────────────┐
│ Data Model │
│ │
│ ┌──────────────┐ relationships ┌─────────────┐ │
│ │ EntityType A ├─────────────────────►│ EntityType B │ │
│ │ - properties │ cardinality │ - properties │ │
│ │ - constraints │ linkRole │ - constraints│ │
│ │ - polarionType│ direct / back │ - polarionType│
│ └──────────────┘ └─────────────┘ │
│ │
│ ▼ maps to ▼ ▼ maps to ▼ │
│ Polarion Work Item Types + Link Roles + Fields │
└─────────────────────────────────────────────────────────┘
```
## Entity Type Configuration
* **[Data Model Types](/powersheet/reference/data-model/domainmodeltypes)** -- Entity type definitions: `name`, `polarionType`, nested properties, and plural name generation
* **[Polarion Type Mapping](/powersheet/reference/data-model/polarion-mapping)** -- How `polarionType` maps domain entities to Polarion work item types, including multi-type mappings
## Relationships and Navigation
* **[Cardinality](/powersheet/reference/data-model/cardinality)** -- Relationship multiplicity options (one-to-one, one-to-many, many-to-one, many-to-many) and how each affects source expansion and column binding
* **[Link Roles](/powersheet/reference/data-model/link-roles)** -- Mapping data model relationships to Polarion link role identifiers
* **[Navigation Directions](/powersheet/reference/data-model/navigation-directions)** -- Forward (`direct`) and reverse (`back`) navigation properties, naming conventions, and how directions drive expansion paths
## Constraints and Access Control
* **[Constraints](/powersheet/reference/data-model/constraints)** -- Load, create, and pick constraint rules that scope which Polarion items an entity type includes, using Lucene query syntax
* **[Permissions](/powersheet/reference/data-model/permissions)** -- Entity-level and property-level access control: `readable`, `updatable`, `createable`, and `isReadOnly` flags
* **[Context Expressions Reference](/powersheet/reference/data-model/context-expressions)** -- Dynamic context expressions for runtime evaluation in constraints and filters
## Quick Orientation
| Concept | Key YAML Property | Reference |
| --------------------- | --------------------------- | ------------------------------------------------------------------------------- |
| Define an entity type | `domainModelTypes.TypeName` | [Data Model Types](/powersheet/reference/data-model/domainmodeltypes) |
| Map to Polarion | `polarionType` | [Polarion Type Mapping](/powersheet/reference/data-model/polarion-mapping) |
| Add fields | `properties` | [Properties](/powersheet/reference/data-model/properties) |
| Connect entity types | `relationships[]` | [Relationships](/powersheet/reference/data-model/relationships) |
| Set multiplicity | `cardinality` | [Cardinality](/powersheet/reference/data-model/cardinality) |
| Name navigation paths | `direct.name` / `back.name` | [Navigation Directions](/powersheet/reference/data-model/navigation-directions) |
| Assign Polarion link | `linkRole` | [Link Roles](/powersheet/reference/data-model/link-roles) |
| Restrict loaded items | `constraints` | [Constraints](/powersheet/reference/data-model/constraints) |
| Control editability | `isReadOnly`, `updatable` | [Permissions](/powersheet/reference/data-model/permissions) |
**Building your first data model?**
Start with the [Creating Your First Data Model](/powersheet/getting-started/first-data-model) tutorial for a guided walkthrough, then return here for property-level details. For complete working models, see the [Example Models Reference](/powersheet/reference/example-models/index).
The data model defines *what exists*. [Sheet sources](/powersheet/reference/sheet-config/sources) define *what to query and expand*. [Columns](/powersheet/reference/sheet-config/columns) define *what to display*. Navigation property names from the data model are the thread connecting all three layers. See [Cardinality](/powersheet/reference/data-model/cardinality) for end-to-end examples showing how each cardinality type flows from model through source expansion to column binding.
# Link Roles
Source: https://learn.nextedy.com/powersheet/reference/data-model/link-roles
The `linkRole` property in the Nextedy POWERSHEET data model maps a relationship between entity types to a specific Siemens Polarion ALM link role.
See also: [Relationships](/powersheet/reference/data-model/relationships) | [Navigation Directions](/powersheet/reference/data-model/navigation-directions) | [Cardinality](/powersheet/reference/data-model/cardinality)
## Link Role Property Reference
| Name | Type | Default | Description |
| ---------- | -------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `linkRole` | `string` | None (required) | Polarion link role ID that implements the relationship. Must exactly match a link role defined in the Polarion project configuration. Required when `storage` is `linkedWorkItems`. |
**Must match Polarion configuration**
The `linkRole` value must exactly match a link role ID defined in your Polarion project under **Administration > Work Item Link Roles**. A mismatch causes the relationship to fail silently -- no linked items will appear in the sheet, and no error is displayed to the user.
## How Link Roles Bridge the Data Model and Polarion
The link role is the bridge between the data model's abstract relationship definition and Polarion's concrete work item linking infrastructure. At runtime:
* **Read operations:** Powersheet queries Polarion for work items connected via the specified link role, then populates the sheet with the results.
* **Write operations:** When users create or remove links in the sheet, Powersheet uses the same link role to persist changes to Polarion.
## Where `linkRole` Appears in Configuration
The `linkRole` property is specified on each entry in the `relationships` array of the data model YAML. It sits alongside the structural properties (`from`, `to`, `cardinality`, `storage`) and the navigation direction definitions (`direct`, `back`).
```yaml theme={null}
relationships:
- from: UserNeed
to: Chapter
cardinality: many-to-one
storage: linkedWorkItems
linkRole: parent
direct:
name: chapter
back:
name: userNeeds
```
### Context Within the Relationship
| Property | Type | Default | Description |
| ------------- | -------- | ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `from` | `string` | Required | Source entity type name. Must match a key in `domainModelTypes`. |
| `to` | `string` | Required | Target entity type name. Must match a key in `domainModelTypes`. |
| `cardinality` | `string` | Required | Relationship multiplicity. See [Cardinality](/powersheet/reference/data-model/cardinality). |
| `storage` | `string` | Required | Must be `linkedWorkItems` when using `linkRole`. |
| `linkRole` | `string` | Required | Polarion link role ID. |
| `direct` | `object` | Required | Forward navigation property definition. See [Navigation Directions](/powersheet/reference/data-model/navigation-directions). |
| `direct.name` | `string` | Required | Name of the navigation property on the `from` entity. |
| `back` | `object` | Optional | Reverse navigation property definition. |
| `back.name` | `string` | Required (if `back` provided) | Name of the navigation property on the `to` entity. |
## Link Role and Relationship Direction
A Polarion link role is inherently directional: it has a "from" side and a "to" side. The data model's `from`/`to` entity types and `direct`/`back` navigation properties align with this directionality.
| Aspect | `direct` Direction | `back` Direction |
| ----------------------------- | ------------------ | --------------------- |
| Navigation property placed on | `from` entity type | `to` entity type |
| Traversal direction | Source to target | Target back to source |
| Polarion link side | Forward link | Reverse (backlink) |
The `isBacklink` flag is managed internally by the system. When Powersheet processes a `back` direction, it internally flags the reverse traversal so that Polarion queries use the correct link direction.
**Same link role, two directions**
A single `linkRole` value serves both the `direct` and `back` navigation properties. You do not need to define separate link roles for forward and reverse traversal. Powersheet handles the directionality automatically based on the `direct`/`back` configuration.
## Link Role and Cardinality Interaction
The `linkRole` itself does not encode cardinality -- it is a simple identifier pointing to a Polarion link role. Cardinality is controlled separately by the `cardinality` property. However, the combination of `linkRole` and `cardinality` determines the runtime behavior:
| Cardinality | Direct Property | Back Property | Source Expand Pattern | Column Binding |
| -------------- | ---------------------------- | ---------------------------- | ------------------------------------------------------------------------- | -------------------------------------- |
| `many-to-one` | Scalar (single entity) | Collection | `- name: chapter` | `chapter`, `chapter.title` |
| `one-to-many` | Collection | Scalar | `- name: userNeeds` | `userNeeds` (child rows) |
| `many-to-many` | Collection (via association) | Collection (via association) | Two levels: `- name: systemRequirements` then `- name: systemRequirement` | `systemRequirements.systemRequirement` |
See [Cardinality](/powersheet/reference/data-model/cardinality) for the full reference on each value and its effects across model, source, and column layers.
## Reusing the Same Link Role
A single Polarion link role can appear in multiple relationships. This is common when the same semantic relationship type applies to different entity type pairs.
```yaml theme={null}
relationships:
# decomposes links UserNeed to SystemRequirement
- from: SystemRequirement
to: UserNeed
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds
back:
name: systemRequirements
# decomposes also links SystemRequirement to DesignRequirement
- from: DesignRequirement
to: SystemRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: systemRequirements
back:
name: designRequirements
```
In this example, the `decomposes` link role is reused across two relationship definitions. Each relationship has its own `from`/`to` pairing and its own navigation property names, but they share the same underlying Polarion link role.
**Navigation property names must be unique per entity type**
When reusing a link role across multiple relationships, ensure the navigation property names (`direct.name` and `back.name`) do not collide on the same entity type. Each entity type must have uniquely named navigation properties.
## Permission Control on Relationships
Relationships support permission flags that control whether the link role's operations are available through the sheet:
| Property | Type | Default | Description |
| ------------ | --------- | --------------- | ------------------------------------------------------------------------------- |
| `createable` | `boolean` | See application | Controls whether new links using this role can be created through the sheet. |
| `readable` | `boolean` | See application | Controls whether links using this role are visible in queries and the sheet UI. |
Individual navigation properties (`direct` and `back`) can also have independent permission settings, allowing fine-grained control over which direction of a link role is editable or visible.
```yaml theme={null}
relationships:
- from: UserNeed
to: SystemRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: systemRequirements
back:
name: userNeeds
```
For detailed property-level permission configuration, see [Permissions](/powersheet/reference/data-model/permissions).
## Validation Rules
Powersheet enforces specific rules when processing `linkRole` values:
| Rule | Detail |
| ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| **Required** | Every relationship with `storage: linkedWorkItems` must have a `linkRole` value. |
| **String match** | The value must exactly match a link role ID in the Polarion project configuration. The match is case-sensitive. |
| **Entity type references** | The `from` and `to` fields must reference entity type names defined in `domainModelTypes`, not Polarion work item type IDs. |
| **Navigation property uniqueness** | Within a single entity type, no two navigation properties can share the same name. This applies even when different link roles are used. |
**Case sensitivity**
Link role IDs in Polarion are case-sensitive. A `linkRole: Refines` value will not match a Polarion link role with ID `refines`. Always verify the exact casing in **Administration > Work Item Link Roles**.
## Complete YAML Example
A minimal data model demonstrating `linkRole` across different relationship types:
```yaml theme={null}
domainModelTypes:
Chapter:
polarionType: heading
UserNeed:
polarionType: user_need
properties:
description:
severity:
SystemRequirement:
polarionType: sys_req
properties:
description:
severity:
DesignRequirement:
polarionType: des_req
properties:
description:
relationships:
- from: UserNeed
to: Chapter
cardinality: many-to-one
storage: linkedWorkItems
linkRole: parent
direct:
name: chapter
back:
name: userNeeds
- from: SystemRequirement
to: UserNeed
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds
back:
name: systemRequirements
```
This model demonstrates two different link roles:
* `parent` for the hierarchical `UserNeed` to `Chapter` relationship (many-to-one)
* `decomposes` for the traceability `SystemRequirement` to `UserNeed` relationship (many-to-many)
Each relationship uses `storage: linkedWorkItems` and defines both `direct` and `back` navigation properties for bidirectional traversal.
## Related Pages
* [Relationships](/powersheet/reference/data-model/relationships) -- complete relationship definition reference
* [Cardinality](/powersheet/reference/data-model/cardinality) -- relationship multiplicity options and their effects
* [Navigation Directions](/powersheet/reference/data-model/navigation-directions) -- `direct` and `back` navigation property definitions
* [Constraints](/powersheet/reference/data-model/constraints) -- filtering constraints on navigation directions
* [Permissions](/powersheet/reference/data-model/permissions) -- CRUD permission controls on relationships and properties
* [Polarion Type Mapping](/powersheet/reference/data-model/polarion-mapping) -- entity type to work item type mapping
* [Binding Syntax](/powersheet/reference/sheet-config/binding-syntax) -- using navigation properties in column bindings
* [Sources](/powersheet/reference/sheet-config/sources) -- configuring expand paths that reference navigation properties
# Navigation Directions
Source: https://learn.nextedy.com/powersheet/reference/data-model/navigation-directions
Navigation directions in a Nextedy POWERSHEET data model define how relationships between entity types can be traversed.
See also: [Relationships](/powersheet/reference/data-model/relationships) | [Properties](/powersheet/reference/data-model/properties) | [Binding Syntax](/powersheet/reference/sheet-config/binding-syntax)
## Direction Overview
Every relationship in the data model connects a `from` entity type to a `to` entity type. The `direct` direction creates a navigation property on the `from` entity that points toward the `to` entity. The `back` direction creates a navigation property on the `to` entity that points back toward the `from` entity.
The diagram above shows a relationship from `UserNeed` to `SystemRequirement`. The forward (`direct`) navigation property `systemRequirements` is placed on `UserNeed`, while the reverse (`back`) navigation property `userNeeds` is placed on `SystemRequirement`.
## Direction Properties
### Direct (Forward) Direction
The `direct` property defines the navigation property created on the **source** (`from`) entity type. It controls how the `from` entity navigates toward the `to` entity.
| Name | Type | Default | Description |
| -------------------- | -------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `direct` | `object` | None | Forward navigation property definition created on the source entity type. Required for defining the forward traversal path. |
| `direct.name` | `string` | Required | Navigation property name for traversing from source to target entities. Used in expansion paths, column bindings, and queries. Must be unique within the source entity type. |
| `direct.constraints` | `object` | None | Optional constraint configuration for filtering accessible entities through this direction. Supports `load`, `pick`, and `create` constraint scopes. |
### Back (Reverse) Direction
The `back` property defines the navigation property created on the **target** (`to`) entity type. It enables reverse traversal from the `to` entity back to the `from` entity.
| Name | Type | Default | Description |
| ------------------ | -------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `back` | `object` | None | Reverse navigation property definition created on the target entity type. Required for defining the reverse traversal path. |
| `back.name` | `string` | Required | Navigation property name for traversing from target back to source entities. Used in expansion paths, column bindings, and queries. Must be unique within the target entity type. |
| `back.constraints` | `object` | None | Optional constraint configuration for filtering accessible entities in the reverse direction. Supports `load`, `pick`, and `create` constraint scopes. |
**Both directions are always defined**
Every relationship requires both a `direct` and a `back` definition. Even if you only intend to traverse in one direction, you must provide names for both sides so the data model can fully resolve the bidirectional link.
## Naming Conventions
Navigation property names follow consistent conventions that signal the cardinality and direction of the relationship:
| Cardinality | `direct.name` (on `from`) | `back.name` (on `to`) | Naming Pattern |
| -------------- | ----------------------------------- | --------------------------- | --------------------------------------------------------------- |
| `many-to-one` | Singular (e.g., `chapter`) | Plural (e.g., `userNeeds`) | Direct side is scalar, back side is a collection |
| `one-to-many` | Plural (e.g., `systemRequirements`) | Singular (e.g., `userNeed`) | Direct side is a collection, back side is scalar |
| `many-to-many` | Plural (e.g., `systemRequirements`) | Plural (e.g., `userNeeds`) | Both sides are collections (association entity used internally) |
**Use camelCase consistently**
Navigation property names use camelCase: `systemRequirements`, `userNeeds`, `designRequirements`. Match the entity type name but adjust case and pluralization to reflect the cardinality.
## Relationship Declaration Syntax
The `direct` and `back` objects are nested inside each relationship entry in the `relationships` array of the data model YAML.
### Basic Declaration
```yaml theme={null}
relationships:
- from: UserNeed
to: SystemRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: systemRequirements
back:
name: userNeeds
```
In this declaration:
* `direct.name: systemRequirements` is added to the `UserNeed` entity type, allowing traversal from user needs to their linked system requirements.
* `back.name: userNeeds` is added to the `SystemRequirement` entity type, allowing reverse traversal from system requirements back to user needs.
### Many-to-One Declaration
```yaml theme={null}
relationships:
- from: UserNeed
to: Chapter
cardinality: many-to-one
storage: linkedWorkItems
linkRole: parent
direct:
name: chapter
back:
name: userNeeds
```
Here `direct.name: chapter` is singular because each `UserNeed` belongs to exactly one `Chapter`. The `back.name: userNeeds` is plural because each `Chapter` may contain multiple user needs.
## Navigation with Constraints
The `direct`/`back` syntax supports attaching [constraints](/powersheet/reference/data-model/constraints) to individual navigation directions. Constraints filter which entities are visible when expanding, picking, or creating through a particular direction.
Each direction object supports three constraint scopes:
| Scope | Purpose |
| -------- | -------------------------------------------------------------------------------------------------- |
| `load` | Filters entities loaded during sheet expansion. Controls which related items appear as child rows. |
| `pick` | Filters the picker dialog when a user selects a related entity from a list. |
| `create` | Filters the context when creating a new entity through this navigation direction. |
### Constraint on Back Direction
```yaml theme={null}
relationships:
- from: UserNeed
to: SystemRequirement
cardinality: one-to-many
storage: linkedWorkItems
linkRole: refines
direct:
name: systemRequirements
back:
name: userNeeds
constraints:
load:
document:
component: $context.source.document.component
```
In this example, the `userNeeds` back-navigation property is filtered to only include items from documents that share the same component as the source entity's document. The `$context.source.document.component` expression dynamically resolves the component value at runtime. See [Context Expressions Reference](/powersheet/reference/data-model/context-expressions) for the full expression syntax.
### Constraint on Direct Direction
```yaml theme={null}
relationships:
- from: SystemRequirement
to: DesignRequirement
cardinality: one-to-many
storage: linkedWorkItems
linkRole: refines
direct:
name: designRequirements
constraints:
pick:
document:
moduleFolder: Design
back:
name: systemRequirements
```
Here the `pick` constraint on the `designRequirements` direct-navigation property restricts the picker dialog to only show design requirements from documents in the `Design` module folder.
## How Directions Map to Cardinality
The cardinality of the relationship determines how the navigation property behaves at runtime. The direction (`direct` vs `back`) combined with the cardinality determines whether a property resolves to a single entity or a collection.
| Cardinality | `direct` Resolves To | `back` Resolves To |
| -------------- | ---------------------------------------- | ---------------------------------------- |
| `many-to-one` | Single entity (scalar) | Collection of entities |
| `one-to-many` | Collection of entities | Single entity (scalar) |
| `many-to-many` | Collection of entities (via association) | Collection of entities (via association) |
**Many-to-many uses association entities**
For `many-to-many` relationships, the expansion path requires two levels: first the association collection, then the target entity within it. For example, `systemRequirements` (association) followed by `systemRequirement` (target). See the column binding examples below.
**One-to-one is not supported**
The data model does not support `one-to-one` cardinality. Relationships must be declared as `many-to-one`, `one-to-many`, or `many-to-many`. To model a one-to-one association, use `many-to-one` and enforce uniqueness through constraints or workflow rules.
## Using Navigation Properties in Column Bindings
Navigation property names become the segments of dot-separated binding paths in sheet configuration columns. The binding path pattern depends on the cardinality:
### Scalar Navigation (N:1)
For `many-to-one` relationships using the `direct` direction, the navigation property resolves to a single entity. Column bindings access properties directly:
```yaml theme={null}
columns:
chapter:
title: Chapter
display: title
list:
search:
- title
chapter.title:
title: Chapter Title
isReadOnly: true
```
* `chapter` provides a single-value reference picker (scalar navigation property).
* `chapter.title` accesses the `title` field of the referenced `Chapter` entity.
### Collection Navigation (1:N)
For `one-to-many` relationships, the navigation property expands into child rows:
```yaml theme={null}
columns:
title:
title: Chapter
hasFocus: true
userNeeds:
title: Title
hasFocus: true
```
The `userNeeds` column triggers expansion into a new sheet level showing all child user needs. No dot-notation is needed since the expand directly opens the child level.
### Association Navigation (M:N)
For `many-to-many` relationships, column binding uses a two-part path through the association entity:
```yaml theme={null}
columns:
title:
title: Title
hasFocus: true
systemRequirements.systemRequirement:
title: System Requirement
list:
search:
- objectId
- title
createNew: true
systemRequirements.systemRequirement.title:
title: SysReq Title
hasFocus: true
```
The pattern is `.`. The first segment (`systemRequirements`) navigates to the association collection; the second segment (`systemRequirement`) resolves to the target entity. This acts as a multi-item reference picker.
## Expansion Paths and Sources
Navigation property names are referenced in the `sources` configuration to define which related entities are loaded when the sheet expands. The `expand` list uses `direct.name` or `back.name` values to traverse the entity graph:
```yaml theme={null}
sources:
- id: requirements
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: designRequirements
```
Each `name` in the expand tree must match a navigation property defined by a `direct` or `back` direction on the queried entity type. The nesting depth determines how many levels of related entities are loaded. See [Sources](/powersheet/reference/sheet-config/sources) and [Expand Clause](/powersheet/reference/query-api/expand-clause) for full details.
## Complete YAML Example
The following data model demonstrates navigation directions across a multi-level RTM hierarchy with constraints:
```yaml theme={null}
domainModelTypes:
Chapter:
polarionType: heading
UserNeed:
polarionType: user_need
properties:
description:
severity:
SystemRequirement:
polarionType: sys_req
properties:
description:
severity:
DesignRequirement:
polarionType: des_req
properties:
description:
relationships:
- from: UserNeed
to: Chapter
cardinality: many-to-one
storage: linkedWorkItems
linkRole: parent
direct:
name: chapter
back:
name: userNeeds
- from: SystemRequirement
to: UserNeed
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds
back:
name: systemRequirements
- from: DesignRequirement
to: SystemRequirement
cardinality: one-to-many
storage: linkedWorkItems
linkRole: refines
direct:
name: systemRequirements
constraints:
pick:
document:
moduleFolder: Requirements
back:
name: designRequirements
```
This model creates the following navigation paths:
| Entity Type | Navigation Property | Direction | Leads To | Cardinality |
| ------------------- | -------------------- | --------- | ------------------- | ----------------- |
| `UserNeed` | `chapter` | direct | `Chapter` | N:1 (scalar) |
| `Chapter` | `userNeeds` | back | `UserNeed` | 1:N (collection) |
| `SystemRequirement` | `userNeeds` | direct | `UserNeed` | M:N (association) |
| `UserNeed` | `systemRequirements` | back | `SystemRequirement` | M:N (association) |
| `DesignRequirement` | `systemRequirements` | direct | `SystemRequirement` | 1:N (collection) |
| `SystemRequirement` | `designRequirements` | back | `DesignRequirement` | 1:N (collection) |
## Quick Reference: Direction Summary
| Aspect | `direct` | `back` |
| ----------------- | ------------------------------------------- | ------------------------------------------- |
| Placed on | `from` entity type | `to` entity type |
| Traversal | Source to target | Target back to source |
| Required property | `direct.name` | `back.name` |
| Optional property | `direct.constraints` | `back.constraints` |
| Used in | `sources.expand.name`, column binding paths | `sources.expand.name`, column binding paths |
***
**Related pages:** [Relationships](/powersheet/reference/data-model/relationships) | [Cardinality](/powersheet/reference/data-model/cardinality) | [Binding Syntax](/powersheet/reference/sheet-config/binding-syntax) | [Sources](/powersheet/reference/sheet-config/sources) | [Expand Clause](/powersheet/reference/query-api/expand-clause) | [Constraints](/powersheet/reference/data-model/constraints)
# Permissions
Source: https://learn.nextedy.com/powersheet/reference/data-model/permissions
Permissions in Nextedy POWERSHEET control access at multiple levels within the data model.
See also: [Properties](/powersheet/reference/data-model/properties) | [Data Model Types](/powersheet/reference/data-model/domainmodeltypes) | [Relationships](/powersheet/reference/data-model/relationships)
## Permission Architecture
Powersheet permissions operate at two distinct levels within the data model YAML:
1. **Property-level** -- the `readable` and `updatable` flags on each property definition within an entity type
2. **Navigation property-level** -- permission settings on the `direct` and `back` objects within relationship definitions
Both levels use the same two boolean flags to control access.
## Property-Level Permissions
Individual properties on entity types support `readable` and `updatable` flags that control field-level access. These flags are set within the data model YAML under each entity type's `properties` map.
### Permission Flags
| Name | Type | Default | Description |
| ----------- | --------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `readable` | `boolean` | `true` | Controls whether the property is visible. When set to `false`, the property is excluded from the data payload entirely -- it is not loaded from the server and not transmitted to the client. This provides data-level security, not merely UI hiding. |
| `updatable` | `boolean` | `false` | Controls whether the property can be modified by users. Properties are read-only unless explicitly set to `true` -- omitting the flag does **not** make a property editable. |
**Hidden properties are excluded from data**
Setting `readable: false` does **not** simply hide a column in the UI. The property is completely excluded from the data payload sent to the client. This means the value is never loaded, never transmitted, and never available to column bindings, queries, or client-side logic. Use this for properties that contain sensitive data or internal identifiers that should not leave the server.
### Permission Combinations
| `readable` | `updatable` | Result |
| ---------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `true` | `true` | Property is visible and editable. Requires an explicit `updatable: true` -- this combination is not the default. |
| `true` | `false` | Property is visible but read-only (default behavior when `updatable` is omitted). Users can see the value but cannot modify it. |
| `false` | `true` | Property is hidden from the client entirely. The `updatable` flag has no practical effect since the property is not transmitted. |
| `false` | `false` | Property is hidden from the client entirely. Equivalent to `readable: false` alone. |
**Read-only columns vs. read-only properties**
The `isReadOnly` flag on a [column definition](/powersheet/reference/sheet-config/columns) controls whether a specific column is editable in the sheet UI. The `updatable` flag on a **property** controls whether the underlying data field can be modified at all. If `updatable: false` is set on the property, the field is read-only regardless of the column's `isReadOnly` setting.
## Configuring Property Permissions in YAML
### Basic Example
Properties without explicit permission flags inherit the defaults (`readable: true`, `updatable: false`):
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
title:
description:
severity:
```
All three properties above are visible, but read-only -- to make any of them editable, add `updatable: true` explicitly.
### Mixed Permissions Example
Apply explicit permission flags to restrict individual properties:
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
id:
readable: true
updatable: false
title:
readable: true
updatable: true
outlineNumber:
readable: true
updatable: false
description:
severity:
```
In this configuration:
* `id` -- visible but cannot be edited (system identifier)
* `title` -- explicitly set to visible and editable (`updatable: true` is required here, since editable is not the default)
* `outlineNumber` -- explicitly declared and marked visible but read-only (managed automatically by Polarion)
* `description` and `severity` -- inherit defaults (visible, but read-only)
### Hiding Sensitive Properties
To prevent a property from being transmitted to the client at all, set `readable: false`:
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
title:
description:
severity:
internalClassification:
readable: false
```
The `internalClassification` property is completely excluded from the data payload. No column binding can reference it, and it does not appear in query results returned to the client.
## Built-in Property Permissions
Certain properties have inherent permission characteristics based on their role in the Polarion data model. The following table lists common built-in properties and their typical permission settings:
| Property | Typical `readable` | Typical `updatable` | Notes |
| ------------- | ------------------ | ------------------- | ----------------------------------------------------------------------------------------------------------------- |
| `id` | `true` | `false` | Work item identifier. System-managed, never user-editable. |
| `title` | `true` | `true` | Work item title. Usually made editable via an explicit `updatable: true`. |
| `description` | `true` | `true` | Standard text property. Usually made editable via an explicit `updatable: true` -- it is not editable by default. |
| `severity` | `true` | `true` | Enumeration property. Usually made editable via an explicit `updatable: true` -- it is not editable by default. |
**`outlineNumber` is not a built-in property**
Unlike `id` and `title`, `outlineNumber` is **not** an implicit built-in property of every entity type. To use it, you must explicitly declare it in the entity type's `properties` map in your data model YAML. When declared, it is typically configured as `readable: true, updatable: false` because its value is managed automatically by Polarion based on the document hierarchy.
**Verify in application**
Built-in property behavior may vary depending on the Polarion version and project configuration. Verify the exact behavior of each built-in property in your environment.
## Entity Types and Permission Scoping
Permission flags are scoped to each entity type independently. The same property name can have different permissions on different entity types:
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
severity:
readable: true
updatable: true
SystemRequirement:
polarionType: sys_req
properties:
severity:
readable: true
updatable: false
```
In this example, `severity` is editable on `UserNeed` entities but read-only on `SystemRequirement` entities.
### Special Entity Types
| Entity Type | Purpose | Permission Notes |
| ----------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `Document` | Built-in entity for Polarion LiveDocs | Supports mixed permission settings on properties. Useful for controlling which document-level fields are editable. |
| `Chapter` | Entity type mapped to Polarion `heading` work item type | Properties are typically read-only since headings are structural elements. |
| `Project` | Built-in entity for Polarion project metadata | Minimal property definitions. Permissions rarely customized. |
## Navigation Property Permissions
Relationships in the data model define navigation properties that allow traversal between entity types. Each relationship has a `direct` and optionally a `back` direction, and each direction can carry its own permission settings.
**Feature under active rework**
The navigation property permission system is under active development. The behavior described below reflects the current implementation, but changes are expected. Updated documentation will follow as the feature stabilizes.
### Navigation Direction Properties
| Name | Type | Default | Description |
| ------------- | --------- | --------------- | -------------------------------------------------------------------------------------------- |
| `direct.name` | `string` | *(required)* | Name of the forward navigation property on the source entity. |
| `back.name` | `string` | *(optional)* | Name of the reverse navigation property on the target entity. |
| `createable` | `boolean` | See application | Controls whether new relationship instances can be created through this navigation property. |
| `readable` | `boolean` | See application | Controls whether the navigation property is visible in queries and data payloads. |
### Relationship YAML with Navigation Directions
```yaml theme={null}
relationships:
- from: UserNeed
to: Chapter
cardinality: many-to-one
storage: linkedWorkItems
linkRole: parent
direct:
name: chapter
back:
name: userNeeds
- from: SystemRequirement
to: UserNeed
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds
back:
name: systemRequirements
```
The `direct` object defines the forward navigation property (from source to target), while the `back` object defines the reverse navigation property (from target back to source). Each can have independent permission settings that control whether the navigation path is available and whether new links can be created through it.
## Read-Only Mode
The sheet can enter a global read-only mode through several mechanisms. When read-only mode is active, all properties behave as if `updatable: false` regardless of their individual settings.
| Condition | Effect |
| ------------------------------------- | --------------------------------------------- |
| Configuration `isReadOnly` is `true` | Entire sheet is read-only. |
| User is viewing a historical revision | Sheet is read-only (revisions are immutable). |
| License status is `INVALID` | Restricted access; sheet is read-only. |
**Read-only mode overrides property permissions**
When any of the conditions above is met, the sheet enters read-only mode. Individual `updatable: true` settings on properties are overridden. The sheet displays all readable properties but prevents any modifications.
## Permission Decision Flow
The following table summarizes how the final editability of a field is determined:
| Check | Condition | Result |
| ----------------------- | ------------------------------------------------------------ | ------------------------------------------- |
| 1. Global read-only | `isReadOnly` config, historical revision, or invalid license | All fields read-only |
| 2. Property `readable` | `false` | Property excluded from data payload |
| 3. Property `updatable` | `false` | Property visible but not editable |
| 4. Column `isReadOnly` | `true` | Column display is read-only in the sheet UI |
| 5. All checks pass | -- | Field is visible and editable |
Checks are evaluated in order. A `false` result at any step short-circuits subsequent checks for that field.
## Complete YAML Example
A data model demonstrating permission controls across multiple entity types with varied access levels:
```yaml theme={null}
domainModelTypes:
Chapter:
polarionType: heading
properties:
title:
readable: true
updatable: false
UserNeed:
polarionType: user_need
properties:
id:
readable: true
updatable: false
title:
readable: true
updatable: true
outlineNumber:
readable: true
updatable: false
description:
severity:
internalNotes:
readable: false
SystemRequirement:
polarionType: sys_req
properties:
id:
readable: true
updatable: false
title:
description:
severity:
readable: true
updatable: false
DesignRequirement:
polarionType: des_req
properties:
title:
description:
relationships:
- from: UserNeed
to: Chapter
cardinality: many-to-one
storage: linkedWorkItems
linkRole: parent
direct:
name: chapter
back:
name: userNeeds
- from: SystemRequirement
to: UserNeed
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds
back:
name: systemRequirements
```
This example demonstrates:
* **`Chapter.title`** -- visible but read-only (structural headings should not be edited through the sheet)
* **`UserNeed.id`** -- visible but read-only (system identifier)
* **`UserNeed.outlineNumber`** -- explicitly declared as visible but read-only (auto-managed by Polarion; this property must be declared explicitly to appear in the model)
* **`UserNeed.internalNotes`** -- hidden entirely (`readable: false`); never transmitted to the client
* **`SystemRequirement.severity`** -- visible but read-only (locked for this entity type)
* **`DesignRequirement`** properties -- all defaults (visible, but read-only, since `updatable` was never set to `true`)
## Best Practices
| Practice | Recommendation |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Sensitive data | Use `readable: false` to prevent transmission to the client. Do not rely on column visibility alone. |
| Audit fields | Set `updatable: false` on explicitly declared fields like `id`, `outlineNumber`, and timestamp fields that should not be manually edited. |
| Progressive disclosure | Use [Views](/powersheet/reference/sheet-config/views) to control which columns are visible in different analysis perspectives, rather than using `readable: false` which removes data access entirely. |
| Consistent naming | Keep property names aligned across entity types when they serve the same purpose (e.g., `severity` on both `UserNeed` and `SystemRequirement`). |
| Testing permissions | Verify permission behavior in a test project before deploying to production. Check that hidden properties are truly absent from server responses. |
**Views for visibility, permissions for security**
Use [Views](/powersheet/reference/sheet-config/views) when you want to show or hide columns for different user workflows -- the data is still loaded but specific columns are toggled. Use `readable: false` when the data itself must not leave the server.
***
# Polarion Type Mapping
Source: https://learn.nextedy.com/powersheet/reference/data-model/polarion-mapping
Polarion type mapping connects each entity type in the Nextedy POWERSHEET data model to one or more Siemens Polarion ALM work item types.
See also: [Data Model Types](/powersheet/reference/data-model/domainmodeltypes) | [Properties](/powersheet/reference/data-model/properties) | [Relationships](/powersheet/reference/data-model/relationships)
## Mapping Architecture
## Core Mapping Properties
| Name | Type | Default | Description |
| --------------- | ---------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `polarionType` | `string` or `string[]` | Entity type name | Maps the data model entity type to one or more Polarion work item type IDs. When omitted, the entity type name is used as the Polarion type ID. Accepts both scalar and array formats. |
| `polarionProto` | `string` | `IWorkItem.PROTO` | Specifies the Polarion prototype (object type) this entity maps to. Determines which class of Polarion objects this entity can represent. Valid values are enumerated from the Polarion platform at runtime. |
| `name` | `string` | Derived from map key | Unique identifier for the entity type. Set automatically from the YAML map key. Referenced by `relationships[].from` and `relationships[].to` fields. |
**Implicit type mapping**
When `polarionType` is omitted, the entity type name (the YAML map key) is used as the Polarion work item type ID. For example, an entity named `Task` with no explicit `polarionType` maps to Polarion work item type `Task`.
## `polarionType` Property
### Single Type Mapping (Scalar)
The most common pattern maps one entity type to one Polarion work item type using a scalar string value:
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
title:
description:
severity:
```
In this configuration, the `UserNeed` entity type maps to the Polarion work item type ID `user_need`. All queries for `UserNeed` entities resolve to work items of type `user_need`.
### Multi-Type Mapping (Array)
A single entity type can map to multiple Polarion work item types by providing an array. This enables a unified view over work items of different types:
```yaml theme={null}
domainModelTypes:
Requirement:
polarionType:
- sys_req
- des_req
properties:
title:
description:
severity:
```
When `polarionType` is an array:
* Queries for the `Requirement` entity type return work items matching **any** of the listed types
* The first type in the array is used as the default when creating new work items
* All listed type IDs must exist in the Polarion project configuration
**Multi-type query behavior**
When an entity maps to multiple Polarion types, queries produce a combined result set. Filter predicates and constraints apply uniformly across all mapped types. Properties referenced in column bindings must exist on all mapped types, or the value will be empty for types that lack the field.
For complete guidance on multi-type entity configuration, see [Create an Entity Type](/powersheet/guides/data-model/create-entity-type).
### Omitted `polarionType` (Default Mapping)
When `polarionType` is not specified, the entity type name becomes the Polarion type ID:
```yaml theme={null}
domainModelTypes:
Hazard:
properties:
title:
severity:
```
The `Hazard` entity maps to Polarion work item type `Hazard`. This convention works when the entity type name exactly matches the Polarion work item type ID defined in the project.
## `polarionProto` Property
The `polarionProto` property specifies which Polarion prototype (object class) the entity represents. Most entity types use the default `IWorkItem.PROTO`, but special object types require an explicit prototype.
| `polarionProto` Value | Polarion Object | Use Case |
| --------------------------- | --------------------- | ----------------------------------------------------- |
| `IWorkItem.PROTO` (default) | Work item | Standard entity types (requirements, risks, controls) |
| Other prototype values | Non-work-item objects | Special Polarion object classes |
**Verify in application**
Available prototype values are enumerated from the Polarion platform at runtime. The JSON schema generator reads all valid prototype names to populate the `polarionProto` enum constraint for IDE validation.
```yaml theme={null}
domainModelTypes:
Document:
polarionProto: IModule.PROTO
properties:
title:
type:
```
### Schema Validation
The JSON schema generated by Powersheet validates `polarionProto` values against the set of prototypes available on the Polarion server. When editing data model YAML files with schema support enabled, the IDE provides:
* Autocomplete for valid `polarionProto` values
* Validation errors for unrecognized prototypes
* Type checking for `polarionType` (accepts both string and array)
## Built-in Entity Types
Powersheet recognizes several built-in entity types that map to Polarion objects. These types have specialized handling in the query processor and metadata system.
| Entity Type | Polarion Object | `polarionType` Support | Notes |
| ----------- | ------------------------- | ---------------------- | --------------------------------------------------------------------------------------------- |
| `Document` | Polarion module (LiveDoc) | Yes | When `polarionType` is set, it references a concrete document type. Container for work items. |
| `Project` | Polarion project | N/A | Project-level metadata and properties. |
**Document type mapping**
The `Document` entity type supports `polarionType`. When set, it filters documents to those matching a specific document type ID. This is useful for constraining picker dialogs and queries to a particular class of documents.
### Reserved Properties
Built-in entity types have reserved properties that are always set to `false` in the data model schema:
| Reserved Property | Applies To | Description |
| ----------------- | ---------------- | ----------------------------------------------------------- |
| `project` | All entity types | Always `false`. Project context is resolved automatically. |
| `document` | All entity types | Always `false`. Document context is resolved automatically. |
## Type Mapping in Relationships
Relationship definitions reference entity types by their data model name (the YAML map key), **not** by their Polarion work item type ID:
```yaml theme={null}
relationships:
- from: UserNeed
to: SystemRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: systemRequirements
back:
name: userNeeds
```
**Entity names, not Polarion type IDs**
The `from` and `to` fields in relationships must use data model entity type names (`UserNeed`, `SystemRequirement`), not Polarion work item type IDs (`user_need`, `sys_req`). Powersheet resolves the Polarion type mapping internally when executing queries.
### Relationship Navigation and Type Resolution
When a relationship links two entity types, Powersheet resolves the `polarionType` of each entity to construct the appropriate Polarion query:
1. The `from` entity type's `polarionType` identifies the source work item type
2. The `to` entity type's `polarionType` identifies the target work item type
3. The `linkRole` maps to the Polarion link role connecting them
4. `direct` and `back` properties create navigation properties for traversal in each direction
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
description:
severity:
SystemRequirement:
polarionType: sys_req
properties:
description:
severity:
relationships:
- from: UserNeed
to: SystemRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: systemRequirements
back:
name: userNeeds
```
In this example:
* Navigating `direct` (`systemRequirements`) from a `UserNeed` queries Polarion for `sys_req` work items linked via the `decomposes` link role
* Navigating `back` (`userNeeds`) from a `SystemRequirement` queries Polarion for `user_need` work items linked via the reverse of `decomposes`
## Query Behavior with Type Mappings
The query processor uses `polarionType` mappings when translating data model queries to Polarion Lucene queries:
| Scenario | Query Behavior |
| ----------------------- | --------------------------------------------------------------------- |
| Single `polarionType` | Lucene filter: `type:user_need` |
| Array `polarionType` | Lucene filter: `type:(sys_req OR des_req)` |
| Omitted `polarionType` | Lucene filter uses entity type name as type ID |
| Entity with constraints | Constraints applied as additional Lucene predicates after type filter |
### Security and Permissions
Before any query executes, Powersheet checks that the current user has read permission for the entity type being queried. Entity types can have permission annotations that restrict access. See [Permissions](/powersheet/reference/data-model/permissions) for details.
### Document-Scoped Queries
When a `currentDocConstraint` parameter is provided, the query processor restricts results to work items within a specific document. The constraint can reference either an entity type name or a navigation property path. Combined with `polarionType`, this enables document-scoped views over specific work item types.
## Mapping Validation Rules
**Common configuration mistakes**
These are the most frequent type mapping errors encountered during initial setup:
| Rule | Description |
| ------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `polarionType` must match Polarion configuration | Type IDs must correspond to work item types defined in the Polarion project. Mismatched IDs produce empty query results. |
| Entity type names are case-sensitive | `UserNeed` and `userneed` are different entity types. Use PascalCase consistently. |
| `sources.model` must match model name | The `model` property in sheet sources must reference the correct data model file name, not the default `rtm`. |
| Document constraints use type ID | When configuring document constraints, use the document type ID (e.g., `softwareRequirementsSpecification`), not the display name (e.g., "Software Requirements Specification"). |
| Multi-item columns for duplicate link types | When two different entity types link to the same parent entity via the same link role, the second column must use `multiItem: true` in the sheet configuration. |
## RTM Mapping Example
Standard RTM entity types with their Polarion type mappings:
| Entity Type | `polarionType` | Polarion Work Item Type |
| ------------------- | -------------- | ----------------------- |
| `UserNeed` | `user_need` | User Need |
| `SystemRequirement` | `sys_req` | System Requirement |
| `DesignRequirement` | `des_req` | Design Requirement |
| `Hazard` | `hazard` | Hazard |
| `RiskControl` | `riskControl` | Risk Control |
## Cardinality Impact on Column Binding
The `polarionType` mapping interacts with relationship cardinality to determine how columns display data. The cardinality of the relationship between entity types determines the expand pattern and column binding syntax used in sheet configurations.
| Cardinality | Direct Navigation | Column Binding | UI Behavior |
| -------------- | ---------------------------- | -------------------------------------- | ----------------------------- |
| `many-to-one` | Scalar (single value) | `chapter`, `chapter.title` | Single-value reference picker |
| `one-to-many` | Collection (multiple values) | `userNeeds` | Child rows (new sheet level) |
| `many-to-many` | Collection via association | `systemRequirements.systemRequirement` | Multi-item reference picker |
### Many-to-One Example
Each `UserNeed` belongs to one `Chapter`. The `direct` navigation property `chapter` is scalar:
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: chapter
columns:
chapter:
title: Chapter
display: title
list:
search:
- title
chapter.title:
title: Chapter Title
isReadOnly: true
```
* `chapter` renders as a single-value reference picker
* `chapter.title` displays the referenced entity's title as read-only
### Many-to-Many Example
`UserNeed` links to multiple `SystemRequirement` entities. The `back` navigation property uses a two-level expand:
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: systemRequirement
columns:
systemRequirements.systemRequirement:
title: System Requirement
list:
search:
- objectId
- title
createNew: true
systemRequirements.systemRequirement.title:
title: SysReq Title
hasFocus: true
```
* Many-to-many relationships use an **association entity** between the two types
* Source expand is two levels: `systemRequirements` (association) then `systemRequirement` (target)
* Column binding uses dot notation: `systemRequirements.systemRequirement`
* The `createNew: true` option enables inline creation of new linked work items
## Complete YAML Example
```yaml theme={null}
domainModelTypes:
Document:
polarionProto: IModule.PROTO
properties:
title:
type:
UserNeed:
polarionType: user_need
properties:
title:
description:
severity:
component:
SystemRequirement:
polarionType: sys_req
properties:
title:
description:
severity:
DesignRequirement:
polarionType: des_req
properties:
title:
description:
Hazard:
polarionType: hazard
properties:
title:
description:
severity:
RiskControl:
polarionType: riskControl
properties:
title:
description:
MultiTypeEntity:
polarionType:
- defect
- change_request
properties:
title:
description:
priority:
relationships:
- from: UserNeed
to: SystemRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: systemRequirements
back:
name: userNeeds
- from: SystemRequirement
to: DesignRequirement
cardinality: one-to-many
storage: linkedWorkItems
linkRole: refines
direct:
name: designRequirements
back:
name: systemRequirements
- from: DesignRequirement
to: Hazard
cardinality: many-to-many
storage: linkedWorkItems
linkRole: addresses
direct:
name: hazards
back:
name: designRequirements
- from: Hazard
to: RiskControl
cardinality: one-to-many
storage: linkedWorkItems
linkRole: mitigates
direct:
name: riskControls
back:
name: hazards
```
***
**Related pages:** [Data Model Types](/powersheet/reference/data-model/domainmodeltypes) | [Properties](/powersheet/reference/data-model/properties) | [Relationships](/powersheet/reference/data-model/relationships) | [Cardinality](/powersheet/reference/data-model/cardinality) | [Link Roles](/powersheet/reference/data-model/link-roles) | [Constraints](/powersheet/reference/data-model/constraints)
# Properties
Source: https://learn.nextedy.com/powersheet/reference/data-model/properties
Properties define the fields available on each entity type in a Nextedy POWERSHEET data model.
See also: [Data Model Types](/powersheet/reference/data-model/domainmodeltypes) | [Relationships](/powersheet/reference/data-model/relationships) | [Permissions](/powersheet/reference/data-model/permissions)
## Property Definition Overview
Each entity type contains a `properties` map. Each entry defines a field name, its mapping to Polarion storage, and optional access controls. Properties are resolved at runtime through the metadata system and exposed to sheet columns via [binding paths](/powersheet/reference/sheet-config/binding-syntax).
## Property Configuration Reference
| Name | Type | Default | Description |
| ----------------- | --------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `name` | `string` | *(required)* | Property name as exposed in queries and column bindings. Must be unique within the entity type. Automatically derived from the YAML map key. |
| `serverName` | `string` | Same as `name` | Override for the actual Polarion field name when it differs from the client-facing property name. Allows aliasing Polarion field names to more user-friendly names. |
| `customFieldName` | `string` | None | Polarion custom field ID for properties stored in custom fields. Required when the property maps to a custom field rather than a built-in work item field. |
| `type` | `string` | None | Data type of the property (`string`, `integer`, `date`, etc.). Determines validation and rendering behavior. |
| `storage` | `string` | None | Defines how the property value is persisted in Polarion (e.g., work item field, linked items). Critical for relationship properties. |
| `readable` | `boolean` | `true` | Controls whether the property can be read by users. Set to `false` to hide internal properties. See [Permissions](/powersheet/reference/data-model/permissions). |
| `updatable` | `boolean` | `false` | Controls whether the property can be modified by users. Read-only unless explicitly set to `true`. See [Permissions](/powersheet/reference/data-model/permissions). |
| `scalar` | `boolean` | `true` | Indicates whether property holds a single value (`true`) or a collection (`false`). Affects data binding and query expansion. |
| `navigability` | `string` | None | Defines navigation direction for relationship properties (`unidirectional`, `bidirectional`). Controls whether relationships can be traversed in queries using expand clauses. |
**Name uniqueness**
Property names must be unique within each entity type. The `name` field is automatically set from the YAML map key -- you do not need to specify it explicitly.
## Defining Properties in YAML
Properties are declared within each entity type under the `properties` key. The simplest form uses a null value (empty after the colon) to declare that a property exists with default settings:
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
title:
description:
severity:
```
**Null values**
A property set to `null` (or left empty after the colon) inherits all default settings. The property name is used as the Polarion field name unless `serverName` or `customFieldName` is specified.
### Properties with Explicit Configuration
When a property requires non-default settings, provide an object with the desired attributes:
```yaml theme={null}
domainModelTypes:
SystemRequirement:
polarionType: sys_req
properties:
title:
description:
severity:
internalNotes:
readable: false
updatable: false
```
In this example, `internalNotes` is hidden from users (not readable) and cannot be modified (not updatable). The remaining properties (`title`, `description`, `severity`) use default settings -- visible, but also read-only, since none of them set `updatable: true`.
### Custom Field Mapping
When a property maps to a Polarion custom field rather than a built-in field, use `customFieldName` to specify the Polarion custom field ID:
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
title:
description:
customPriority:
customFieldName: c_priority
```
Here, the data model property `customPriority` maps to the Polarion custom field `c_priority`. In sheet column bindings, you reference the data model name (`customPriority`), not the Polarion field name.
### Server Name Aliasing
Use `serverName` when the Polarion built-in field name differs from the name you want to expose in the data model:
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
title:
itemStatus:
serverName: status
```
The property is referenced as `itemStatus` in column bindings and queries, but resolves to the Polarion `status` field on the server.
## Built-in Properties
All work item entity types automatically include these built-in properties without explicit declaration:
| Property | Type | Description |
| ---------- | -------- | -------------------------------------------------------------------------------------- |
| `objectId` | `string` | Unique primary key identifier for the entity instance. Read-only. |
| `id` | `string` | Polarion work item ID. Read-only. |
| `title` | `string` | Work item title. Applies to work item entity types only (not `Document` or `Chapter`). |
**Implicit availability**
Built-in properties are available on every work item entity type even if not listed in the `properties` map. You can reference them in column bindings (e.g., `id`, `title`) without declaring them in the data model YAML.
## Special Entity Properties
The built-in `Document` and `Chapter` entity types have specialized property behavior distinct from work item entities.
### Document Properties
| Property | Type | Description |
| ---------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
| `moduleFolder` | `string` | Path to the document folder in the repository. Create-only: set during document creation, read-only thereafter. |
| `moduleName` | `string` | Document file name within its folder. Create-only. |
| `title` | `string` | Document title displayed in navigation. |
| `titleOrName` | `string` | Document title when available, otherwise falls back to the module name. Convenient display field when `title` is not set. |
| `titleWithSpace` | `string` | Document title formatted with a leading or padded space, used for display alignment in navigation contexts. |
| `type` | `string` | Document type classification. |
| `allowedWITypes` | `string` (scalar by default) | Work item types permitted within this document. |
**Multi-valued `allowedWITypes`**
`allowedWITypes` is scalar by default (a single string). To treat it as a list of multiple permitted work item types, explicitly override `scalar: false` on this property in the data model YAML.
### Chapter Properties
The `Chapter` entity type maps to Polarion headings (`polarionType: heading`). Chapters represent structural elements in a document hierarchy and are typically used as grouping nodes in expansion paths.
```yaml theme={null}
domainModelTypes:
Chapter:
polarionType: heading
```
Chapters do not require explicit property declarations. They inherit the standard built-in properties and serve primarily as navigation anchors in [relationships](/powersheet/reference/data-model/relationships).
## Property Permissions
Each property supports two permission flags that control field-level access:
| Flag | Default | Effect when `false` |
| ----------- | ------- | ------------------------------------------------------- |
| `readable` | `true` | Property is hidden from users in the sheet. |
| `updatable` | `false` | Property is read-only -- users cannot modify the value. |
### Permission Examples
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: user_need
properties:
title:
description:
readable: true
updatable: true
severity:
readable: true
updatable: false
internalTrackingId:
readable: false
updatable: false
```
| Property | Visible | Editable | Use Case |
| -------------------- | ------- | -------- | ----------------------------------------------------------------------- |
| `title` | Yes | No | Default -- bare declaration, read-only until `updatable: true` is added |
| `description` | Yes | Yes | Explicitly set with `updatable: true` -- editable is not the default |
| `severity` | Yes | No | Users can see but not change |
| `internalTrackingId` | No | No | Completely hidden from the sheet |
For more details on permission inheritance through relationships, see [Permissions](/powersheet/reference/data-model/permissions).
## Navigation Properties and Relationships
Navigation properties represent relationships to other entity types. They are **created automatically** from [Relationships](/powersheet/reference/data-model/relationships) definitions in the data model -- they are not declared inline on entity types.
**Verify in application**
Navigation properties are always derived from `relationships` definitions. To create a navigation property between two entity types, define the relationship in the `relationships` section of the data model YAML.
### How Navigation Properties Are Generated
When a relationship is defined, Powersheet automatically creates navigation properties on both sides:
```yaml theme={null}
relationships:
- from: UserNeed
to: SystemRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds
back:
name: systemRequirements
```
This creates:
* `userNeeds` navigation property on `SystemRequirement` (the `direct` side)
* `systemRequirements` navigation property on `UserNeed` (the `back` side)
Navigation property names are specified in the `direct.name` and `back.name` fields of the relationship definition.
### Navigation Property Attributes
Navigation properties inherit several attributes from their parent relationship:
| Attribute | Source | Description |
| -------------- | -------------------------- | --------------------------------------------------------------------------------------- |
| `cardinality` | Relationship `cardinality` | Determines if the property is scalar (single entity) or collection (multiple entities). |
| `storage` | Relationship `storage` | How the link is persisted in Polarion (e.g., `linkedWorkItems`). |
| `navigability` | Relationship direction | Whether the property can be traversed in queries. |
| `scalar` | Derived from cardinality | `true` for many-to-one (direct side), `false` for one-to-many and many-to-many. |
### Custom Navigation Property Names
Use `direct` and `back` on the relationship to override default navigation property names:
```yaml theme={null}
relationships:
- from: UserNeed
to: Chapter
cardinality: many-to-one
storage: linkedWorkItems
linkRole: parent
direct:
name: chapter
back:
name: userNeeds
```
Here, navigating from `UserNeed` to `Chapter` uses the property name `chapter` (scalar, N:1), while the reverse uses `userNeeds` (collection, 1:N).
## Cardinality and Column Binding
The cardinality of a relationship determines the expand pattern and column binding syntax. This table summarizes how properties connect the data model to sheet sources and columns:
| Cardinality | Navigation Property | Source Expand | Column Binding | UI Behavior |
| ----------- | --------------------------------- | ------------------------------------------------------------- | -------------------------------------- | ----------------------------- |
| **N:1** | `chapter` (scalar) | `- name: chapter` | `chapter`, `chapter.title` | Single-value reference picker |
| **1:N** | `userNeeds` (collection) | `- name: userNeeds` | `userNeeds` | Child rows (new sheet level) |
| **M:N** | `systemRequirements` (collection) | `- name: systemRequirements` then `- name: systemRequirement` | `systemRequirements.systemRequirement` | Multi-item reference picker |
**Dot-notation for nested access**
Use dot-notation in column bindings to access properties on related entities. For example, `chapter.title` displays the `title` property of the related `Chapter` entity. See [Binding Syntax](/powersheet/reference/sheet-config/binding-syntax) for the complete syntax reference.
## Storage Types
The `storage` attribute on a property determines how the value is persisted in Polarion:
| Storage Value | Description | Used For |
| ----------------- | ------------------------------------------- | ------------------------------------------------- |
| `linkedWorkItems` | Value stored as Polarion linked work items. | Navigation properties created from relationships. |
## Complete YAML Example
A full data model demonstrating data properties, custom fields, permissions, and relationships:
```yaml theme={null}
domainModelTypes:
Document:
properties:
title:
type:
Chapter:
polarionType: heading
UserNeed:
polarionType: user_need
properties:
title:
description:
severity:
component:
SystemRequirement:
polarionType: sys_req
properties:
title:
description:
severity:
customPriority:
customFieldName: c_priority
internalNotes:
readable: false
updatable: false
DesignRequirement:
polarionType: des_req
properties:
title:
description:
severity:
relationships:
- from: UserNeed
to: Chapter
cardinality: many-to-one
storage: linkedWorkItems
linkRole: parent
direct:
name: chapter
back:
name: userNeeds
- from: SystemRequirement
to: UserNeed
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds
back:
name: systemRequirements
```
This model defines five entity types with their properties and two relationships. The `SystemRequirement` type includes a custom field mapping (`customPriority` mapped to Polarion custom field `c_priority`) and a hidden property (`internalNotes`). Navigation properties (`chapter`, `userNeeds`, `systemRequirements`) are generated automatically from the relationship definitions.
## Property Type Reference
The `type` attribute accepts the following values:
| Type | Description | Example Values |
| --------- | ------------------------ | ------------------------- |
| `string` | Text values. | `"Requirements document"` |
| `integer` | Whole number values. | `42` |
| `date` | Date or datetime values. | `"2025-01-15"` |
| `boolean` | True/false values. | `true`, `false` |
**Verify in application**
Property type validation behavior depends on the Polarion field definition. The `type` attribute in the data model is primarily informational for the metadata system. Actual validation is enforced by Polarion's field configuration.
## Property Resolution Order
When Powersheet resolves a property name to a Polarion field, it follows this order:
1. **`customFieldName`** -- if specified, maps directly to the named Polarion custom field.
2. **`serverName`** -- if specified, uses this as the Polarion field name instead of the property name.
3. **Property name** -- if neither override is specified, the property name is used directly as the Polarion field name.
```text theme={null}
Property "customPriority"
customFieldName: c_priority --> Polarion field: c_priority
Property "itemStatus"
serverName: status --> Polarion field: status
Property "title"
(no overrides) --> Polarion field: title
```
***
**Related pages:** [Data Model Types](/powersheet/reference/data-model/domainmodeltypes) | [Relationships](/powersheet/reference/data-model/relationships) | [Constraints](/powersheet/reference/data-model/constraints) | [Permissions](/powersheet/reference/data-model/permissions) | [Binding Syntax](/powersheet/reference/sheet-config/binding-syntax)
# Relationships
Source: https://learn.nextedy.com/powersheet/reference/data-model/relationships
The `relationships` array in the Nextedy POWERSHEET data model defines bidirectional associations between entity types.
## Structure
Relationships are defined as a top-level array in the data model YAML, alongside `domainModelTypes`:
```yaml theme={null}
relationships:
- from: UserNeed
to: SystemRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: systemRequirements
back:
name: userNeeds
```
Each entry connects a source entity type (`from`) to a target entity type (`to`), specifies a [cardinality](/powersheet/reference/data-model/cardinality), a storage mechanism, a [link role](/powersheet/reference/data-model/link-roles), and two navigation properties that allow traversal in both directions.
## Relationship Properties
| Property | Type | Default | Description |
| ------------- | -------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `from` | `string` | Required | Source entity type name. Must match a key in `domainModelTypes`. |
| `to` | `string` | Required | Target entity type name. Must match a key in `domainModelTypes`. |
| `cardinality` | `string` | Required | Relationship multiplicity. One of `many-to-one`, `one-to-many`, `many-to-many`. See [Cardinality](/powersheet/reference/data-model/cardinality). |
| `storage` | `string` | Required | Persistence mechanism. Only `linkedWorkItems` is supported. See [Storage](#storage). |
| `linkRole` | `string` | Required | Polarion link role ID used to implement this relationship. Must exist in the project's link role configuration. See [Link Roles](/powersheet/reference/data-model/link-roles). |
| `direct` | `object` | Required | Forward navigation property configuration (from source to target). See [Navigation Properties](#navigation-properties). |
| `direct.name` | `string` | Required | Navigation property name for forward traversal. Used in expansion paths and column bindings. |
| `back` | `object` | Optional | Reverse navigation property configuration (from target back to source). See [Navigation Properties](#navigation-properties). |
| `back.name` | `string` | Required (if `back` provided) | Navigation property name for reverse traversal. |
**from/to reference entity type names**
The `from` and `to` fields must reference names defined in `domainModelTypes` -- **not** Polarion work item type IDs. For example, use `UserNeed` (the entity type name), not `user_need` (the Polarion type ID).
## Navigation Properties
Every relationship creates navigation properties on the participating entity types. These properties enable:
* **Expansion paths** in sheet source configurations
* **Column bindings** using dot-notation in sheet column definitions
* **Query traversal** across related entity types
Navigation properties are defined using the `direct` and `back` objects:
| Direction | Object | Created On | Purpose |
| --------- | -------- | ---------------------- | ----------------------------------- |
| Forward | `direct` | Source (`from`) entity | Navigate from source to target |
| Reverse | `back` | Target (`to`) entity | Navigate from target back to source |
```yaml theme={null}
relationships:
- from: UserNeed
to: Chapter
cardinality: many-to-one
storage: linkedWorkItems
linkRole: parent
direct:
name: chapter
back:
name: userNeeds
```
In this example:
* `UserNeed` gains the navigation property `chapter` (forward, to the `Chapter` entity)
* `Chapter` gains the navigation property `userNeeds` (reverse, back to `UserNeed` entities)
### Naming Conventions
| Cardinality | Direct Name | Back Name | Rationale |
| -------------- | ----------------------------- | -------------------- | ------------------------------------------------------ |
| `many-to-one` | Singular (`chapter`) | Plural (`userNeeds`) | Direct points to one target; back returns many sources |
| `one-to-many` | Plural (`userNeeds`) | Singular (`chapter`) | Direct points to many targets; back returns one source |
| `many-to-many` | Plural (`systemRequirements`) | Plural (`userNeeds`) | Both sides are collections |
**Use camelCase for navigation property names**
Navigation property names follow camelCase convention. Use singular names for scalar references and plural names for collection references. This naming directly maps to source `expand` entries and column binding paths.
## Cardinality Options
The `cardinality` property determines how many entities can participate on each side of the relationship:
| Value | From Side | To Side | Direct Property | Back Property |
| -------------- | ---------------- | ---------------- | ---------------------------- | ---------------------------- |
| `many-to-one` | Single reference | Collection | Scalar | Collection |
| `one-to-many` | Collection | Single reference | Collection | Scalar |
| `many-to-many` | Collection | Collection | Collection (via association) | Collection (via association) |
Cardinality affects three layers of configuration:
1. **Data model** -- determines navigation property type (scalar vs. collection)
2. **Sheet sources** -- determines expand pattern (single-level vs. two-level for M:N)
3. **Sheet columns** -- determines binding syntax and UI behavior (picker vs. child rows)
See [Cardinality](/powersheet/reference/data-model/cardinality) for complete documentation on each option.
## Storage
The `storage` property specifies how the relationship is persisted in Polarion.
| Value | Description |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `linkedWorkItems` | Uses Polarion's native work item link mechanism. Requires `linkRole` to specify which link role implements the association. |
**Only linkedWorkItems is supported**
The `linkedWorkItems` storage mechanism is the only supported option. It leverages Polarion's built-in linked work items infrastructure, which stores relationships as typed links between work items using the configured `linkRole`.
### Link Role Mapping
The `linkRole` value must correspond to a link role defined in the Polarion project configuration. Common link roles used in data models:
| Link Role | Typical Usage |
| ------------ | --------------------------------------------------------------------------- |
| `parent` | Hierarchical parent-child relationships (e.g., `Chapter` to `UserNeed`) |
| `decomposes` | Decomposition relationships (e.g., `SystemRequirement` to `UserNeed`) |
| `refines` | Refinement relationships (e.g., `DesignRequirement` to `SystemRequirement`) |
| `mitigates` | Risk relationships (e.g., `RiskControl` to `Hazard`) |
| `verifies` | Verification relationships (e.g., test cases to requirements) |
See [Link Roles](/powersheet/reference/data-model/link-roles) for detailed documentation on configuring and using Polarion link roles.
## Permission Control
Relationships support permission flags that control CRUD operations through the sheet:
| Property | Type | Default | Description |
| ------------ | --------- | --------------- | ----------------------------------------------------------------------- |
| `createable` | `boolean` | See application | Whether new relationship instances can be created through the sheet. |
| `readable` | `boolean` | See application | Whether relationship instances are visible in queries and the sheet UI. |
**Verify in application**
Permission flag behavior may depend on your Polarion project permissions and Powersheet version. Test in your environment to confirm the exact behavior.
## Navigation Properties in Binding Paths
Navigation property names created by relationships flow directly into sheet configuration. The three configuration layers -- data model, sheet sources, and sheet columns -- are connected through these navigation property names. The cardinality of the relationship determines the expand pattern and column binding syntax.
### Many-to-One (N:1)
A scalar reference from source to a single target entity. Uses the `direct` navigation property.
**Data model:**
```yaml theme={null}
relationships:
- from: UserNeed
to: Chapter
cardinality: many-to-one
storage: linkedWorkItems
linkRole: parent
direct:
name: chapter
back:
name: userNeeds
```
**Source configuration:**
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: chapter
```
**Column bindings:**
```yaml theme={null}
columns:
title:
title: Title
hasFocus: true
chapter:
title: Chapter
display: title
list:
search:
- title
chapter.title:
title: Chapter Title
isReadOnly: true
```
* `chapter` -- single-value reference picker (scalar navigation property, N:1)
* `chapter.title` -- read-only display of the referenced `Chapter`'s title via dot-notation
### One-to-Many (1:N)
A collection of child entities accessible from a parent. Uses the `back` navigation property (reverse side of a many-to-one relationship).
**Source configuration:**
```yaml theme={null}
sources:
- id: chapters
query:
from: Chapter
expand:
- name: userNeeds
```
**Column bindings:**
```yaml theme={null}
columns:
title:
title: Chapter
hasFocus: true
userNeeds:
title: Title
hasFocus: true
```
* `userNeeds` -- expands into child rows, creating a new level in the sheet hierarchy
* No dot-notation needed; the expand directly opens the child level
### Many-to-Many (M:N)
Collections on both sides, navigated through an association entity. Uses a two-level expand.
**Data model:**
```yaml theme={null}
relationships:
- from: SystemRequirement
to: UserNeed
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds
back:
name: systemRequirements
```
**Source configuration:**
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: systemRequirement
```
**Column bindings:**
```yaml theme={null}
columns:
title:
title: Title
hasFocus: true
systemRequirements.systemRequirement:
title: System Requirement
list:
search:
- objectId
- title
createNew: true
systemRequirements.systemRequirement.title:
title: SysReq Title
hasFocus: true
```
* M:N relationships use an **association entity** between the two types
* Source expand is two levels: `systemRequirements` (association) then `systemRequirement` (target entity)
* Column binding uses dot-notation: `systemRequirements.systemRequirement`
* Acts as a multi-item reference picker in the sheet UI
## Cardinality Summary
| Cardinality | Model | Source Expand | Column Binding | UI Behavior |
| ----------- | ------------------------------------------------------------ | ------------------------------------------------------------- | -------------------------------------- | ----------------------------- |
| **N:1** | `cardinality: many-to-one`, `direct.name: chapter` | `- name: chapter` | `chapter`, `chapter.title` | Single-value reference picker |
| **1:N** | Reverse of N:1, `back.name: userNeeds` | `- name: userNeeds` | `userNeeds` | Child rows (new sheet level) |
| **M:N** | `cardinality: many-to-many`, `back.name: systemRequirements` | `- name: systemRequirements` then `- name: systemRequirement` | `systemRequirements.systemRequirement` | Multi-item reference picker |
## Complete YAML Example
A full data model demonstrating all relationship cardinalities across the standard RTM entity types:
```yaml theme={null}
domainModelTypes:
Chapter:
polarionType: heading
UserNeed:
polarionType: user_need
properties:
description:
severity:
SystemRequirement:
polarionType: sys_req
properties:
description:
severity:
DesignRequirement:
polarionType: des_req
properties:
description:
Hazard:
polarionType: hazard
properties:
description:
RiskControl:
polarionType: riskControl
properties:
description:
relationships:
# N:1 -- each UserNeed belongs to one Chapter
- from: UserNeed
to: Chapter
cardinality: many-to-one
storage: linkedWorkItems
linkRole: parent
direct:
name: chapter
back:
name: userNeeds
# M:N -- UserNeeds decompose into SystemRequirements
- from: SystemRequirement
to: UserNeed
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds
back:
name: systemRequirements
# M:N -- SystemRequirements refine into DesignRequirements
- from: DesignRequirement
to: SystemRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: refines
direct:
name: systemRequirements
back:
name: designRequirements
# M:N -- Hazards linked to DesignRequirements
- from: Hazard
to: DesignRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: refines
direct:
name: designRequirements
back:
name: hazards
# M:N -- RiskControls mitigate Hazards
- from: RiskControl
to: Hazard
cardinality: many-to-many
storage: linkedWorkItems
linkRole: mitigates
direct:
name: hazards
back:
name: riskControls
```
This model creates a full traceability chain: `Chapter` > `UserNeed` > `SystemRequirement` > `DesignRequirement` > `Hazard` > `RiskControl`. Each relationship uses `linkedWorkItems` storage with an appropriate Polarion link role, and defines both `direct` and `back` navigation properties for bidirectional traversal.
## Related Pages
* [Cardinality](/powersheet/reference/data-model/cardinality) -- detailed rules for each cardinality option
* [Link Roles](/powersheet/reference/data-model/link-roles) -- configuring Polarion link roles for relationships
* [Data Model Types](/powersheet/reference/data-model/domainmodeltypes) -- entity type definitions referenced by `from` and `to`
* [Navigation Directions](/powersheet/reference/data-model/navigation-directions) -- how direction properties work internally
* [Binding Syntax](/powersheet/reference/sheet-config/binding-syntax) -- using navigation properties in column bindings
* [Sources](/powersheet/reference/sheet-config/sources) -- configuring expand paths that use navigation properties
* [Constraints](/powersheet/reference/data-model/constraints) -- filtering constraints applied to entity types in relationships
# Aerospace Safety Model
Source: https://learn.nextedy.com/powersheet/reference/example-models/aerospace-safety
A complete requirements traceability matrix for aerospace safety certification, covering DO-178C software assurance, ARP 4754A system development, and ARP 4761 safety assessment.
**Industry context:** Aerospace systems must demonstrate bidirectional traceability from customer needs through system decomposition to design implementation and V\&V coverage. Standards such as ARP 4754A Section 5 require this chain to be auditable at every level.
## Data Model
Seven entity types covering the full aerospace V-model from customer requirements through design characteristics and failure modes. Each entity maps to a Polarion work item type, with safety classification (`sc`/`cc`) propagated at every level.
```yaml theme={null}
domainModelTypes:
Document:
properties:
type:
Chapter:
polarionType: heading
CustomerRequirement:
polarionType: customerRequirement
properties:
outlineNumber:
description:
classification: # sc (Safety-Critical) or cc (Certification-Critical)
SystemRequirement:
polarionType: systemRequirement
properties:
outlineNumber:
description:
classification:
documentReference: # Source specification (SRS doc name)
SubsystemRequirement:
polarionType: subsystemRequirement
properties:
outlineNumber:
description:
classification:
documentReference:
DesignRequirement:
polarionType: designRequirement
properties:
outlineNumber:
description:
classification:
documentReference: # Source specification (DRS doc name)
Characteristic:
polarionType: characteristic
properties:
targetValue:
tolerance:
classification:
FailureMode:
polarionType: failureMode
properties:
severity:
occurrence:
detection:
relationships:
- from: CustomerRequirement
to: SystemRequirement
cardinality: one-to-many
- from: SystemRequirement
to: SubsystemRequirement
cardinality: one-to-many
- from: SubsystemRequirement
to: DesignRequirement
cardinality: one-to-many
- from: DesignRequirement
to: Characteristic
cardinality: one-to-many
- from: Characteristic
to: FailureMode
cardinality: one-to-many
```
## Sheet Configuration
Four color-coded column groups provide instant visual orientation across the 4-level hierarchy. Each group uses `collapseTo` so reviewers can collapse an entire requirement level into a single summary column.
```yaml theme={null}
columnGroups:
customerRequirements:
groupName: Customer Requirements
groupStyle: darkgreen
headerStyle: green
collapseTo: title
systemRequirements:
groupName: System Requirements
groupStyle: darkpurple
headerStyle: purple
collapseTo: systemRequirements.systemRequirement.description
subsystemRequirements:
groupName: Subsystem Requirements
groupStyle: darkteal
headerStyle: teal
collapseTo: subsystemRequirements.subsystemRequirement.description
designRequirements:
groupName: Design Requirements
groupStyle: darkblue
headerStyle: blue
collapseTo: designRequirements.designRequirement.description
sortBy:
- columnId: outlineNumber
direction: asc
columns:
outlineNumber:
title: "#"
width: 80
formatter: readOnly
columnGroup: customerRequirements
title:
title: Title
hasFocus: true
width: 170
formatter: boldTitle
columnGroup: customerRequirements
classification:
title: SC/CC
width: 70
formatter: classificationRenderer
columnGroup: customerRequirements
systemRequirements.systemRequirement:
title: ID
width: 100
columnGroup: systemRequirements
systemRequirements.systemRequirement.description:
title: Description
width: 200
columnGroup: systemRequirements
systemRequirements.systemRequirement.classification:
title: SC/CC
width: 70
formatter: classificationRenderer
columnGroup: systemRequirements
systemRequirements.systemRequirement.testCases.testCase:
title: System Tests
multiItem: true
columnGroup: systemRequirements
header: &orange
style: orange
subsystemRequirements.subsystemRequirement:
title: ID
width: 100
columnGroup: subsystemRequirements
subsystemRequirements.subsystemRequirement.description:
title: Description
width: 200
columnGroup: subsystemRequirements
designRequirements.designRequirement:
title: ID
width: 100
columnGroup: designRequirements
designRequirements.designRequirement.description:
title: Description
width: 200
columnGroup: designRequirements
designRequirements.designRequirement.testCases.testCase:
title: Design Tests
multiItem: true
columnGroup: designRequirements
header: *orange
```
## Formatter Examples
Renders safety classification as color-coded pills -- orange for Safety-Critical (SC), red for Certification-Critical (CC).
```yaml theme={null}
formatters:
classificationRenderer:
- expression: "context.value == 'sc'"
style: scStyle
- expression: "context.value == 'cc'"
style: ccStyle
styles:
scStyle:
backgroundColor: orange100
color: orange700
fontWeight: 600
ccStyle:
backgroundColor: red100
color: red700
fontWeight: 600
```
Color-codes severity values across the safety assessment hierarchy. Applied to failure mode severity columns in ARP 4761 views.
```yaml theme={null}
formatters:
severityFormatter:
- expression: "context.value >= 4"
style: sevCritical # red -- immediate safety concern
- expression: "context.value == 3"
style: sevMajor # orange -- significant impact
- expression: "context.value == 2"
style: sevMinor # yellow -- limited impact
- expression: "context.value <= 1 && context.value > 0"
style: sevNegligible # green -- no safety effect
styles:
sevCritical:
backgroundColor: red100
color: red700
fontWeight: 700
sevMajor:
backgroundColor: orange100
color: orange800
sevMinor:
backgroundColor: yellow100
color: yellow900
sevNegligible:
backgroundColor: green100
color: green800
```
Tracks certification objective status per DAL level. Used in DO-178C and DO-254 compliance matrices.
```yaml theme={null}
formatters:
objectiveStatus:
- expression: "context.value == 'satisfied'"
style: statusSatisfied # green
- expression: "context.value == 'inProgress'"
style: statusInProgress # orange
- expression: "context.value == 'notStarted'"
style: statusNotStarted # red
- expression: "context.value == 'notApplicable'"
style: statusNA # grey
- expression: "context.value == 'waived'"
style: statusWaived # blue
styles:
statusSatisfied:
backgroundColor: green100
color: green800
statusInProgress:
backgroundColor: orange100
color: orange800
statusNotStarted:
backgroundColor: red100
color: red700
statusNA:
backgroundColor: grey200
color: grey600
statusWaived:
backgroundColor: blue100
color: blue700
```
## Named Views
Four views serve different audit and review scenarios:
```yaml theme={null}
views:
Full RTM:
# Default view showing all 4 levels with all columns visible
DAL A Only:
# Filters to DAL A requirements only -- for the highest assurance level
columns:
subsystemRequirements.subsystemRequirement:
visible: false
# Hides subsystem level for focused system-to-design view
Without V&V:
# Hides test case columns -- requirements-only view for design reviews
columns:
systemRequirements.systemRequirement.testCases.testCase:
visible: false
designRequirements.designRequirement.testCases.testCase:
visible: false
Summary:
# Executive view -- collapses all groups and hides detail columns
columns:
description:
visible: false
```
## Key Patterns
* **4-level entity nesting** -- the deepest hierarchy demonstrated. Each level has its own color-coded column group for instant orientation during audits.
* **YAML anchors for DRY styling** -- `&orange` / `*orange` reuse header styles across V\&V columns at multiple levels, avoiding repetition.
* **`collapseTo` on every group** -- reviewers collapse entire requirement levels into a single summary column, switching between detailed and overview modes without changing views.
* **`multiItem: true`** for test cases -- many-to-many relationships between requirements and test cases are rendered as expandable lists within cells.
* **SC/CC classification at all levels** -- safety classification propagates from customer through design requirements with consistent visual formatting.
* **`groupBy: chapter`** -- document-structured navigation groups rows by document headings for familiar organization.
## See Also
* [RTM Model](/powersheet/reference/example-models/rtm-model) -- standard 3-level RTM model configuration
* [Columns](/powersheet/reference/sheet-config/columns) -- column configuration options
* [Formatters](/powersheet/reference/sheet-config/formatters) -- formatter and style definitions
* [Sources Configuration](/powersheet/reference/sheet-config/sources) -- expand paths and query configuration
# Example Models Reference
Source: https://learn.nextedy.com/powersheet/reference/example-models/index
Nextedy POWERSHEET ships with several example data models that demonstrate different use cases and configuration patterns.
Requirements Traceability Matrix model with multi-level hierarchy from user needs through design requirements.
Risk analysis model with hazards, risk controls, and custom field storage for severity and probability.
4-level requirements hierarchy for DO-178C / ARP 4754A certification with SC/CC classification, test case branches, and compliance formatters.
Component-scoped V-model traceability for ISO 14971 / IEC 62304 with validation and verification branches at each level.
**Choosing an Example Model**
## Model Comparison
| Model | Entity Types | Relationships | Key Feature |
| ----------------------------------------------------------------------------------- | --------------------------------------------------------- | --------------------------- | ------------------------------------ |
| [RTM Model](/powersheet/reference/example-models/rtm-model) | 5+ (UserNeed, SystemRequirement, DesignRequirement, etc.) | Multi-level hierarchy | Constraints, expansion paths |
| [Risk Management Model](/powersheet/reference/example-models/risk-management-model) | Hazard, RiskControl, etc. | Cross-domain linking | Custom fields, enum properties |
| [Aerospace Safety](/powersheet/reference/example-models/aerospace-safety) | 7 (CustomerReq through FailureMode) | 4-level hierarchy with V\&V | SC/CC formatters, 5-state compliance |
| [Medical Device RTM](/powersheet/reference/example-models/medical-device-rtm) | 3 (UserNeed, SystemReq, DesignReq) | V-model with V\&V branches | Component scoping, YAML anchors |
## Related Resources
* [Data Model Reference](/powersheet/reference/data-model/index) -- property-level reference for all data model YAML keys
* [Creating Your First Data Model](/powersheet/getting-started/first-data-model) -- step-by-step tutorial
# Medical Device RTM Model
Source: https://learn.nextedy.com/powersheet/reference/example-models/medical-device-rtm
A component-scoped requirements traceability matrix for medical device development following ISO 14971 (risk management) and IEC 62304 (software lifecycle) standards.
**Industry context:** Medical device manufacturers must demonstrate that user needs trace through system requirements to design requirements, with validation evidence (did we build the right thing?) and verification evidence (did we build it right?) at each level. Regulatory submissions to FDA and Notified Bodies require this traceability chain.
## Data Model
Three core entity types forming the requirements V-model, plus use steps for operational context and test case links for V\&V evidence.
```yaml theme={null}
domainModelTypes:
Document:
properties:
type:
Chapter:
polarionType: heading
UserNeed:
polarionType: userNeed
properties:
outlineNumber:
description:
severity:
component:
type:
SystemRequirement:
polarionType: systemRequirement
properties:
outlineNumber:
description:
classification:
DesignRequirement:
polarionType: designRequirement
properties:
outlineNumber:
description:
relationships:
- from: UserNeed
to: SystemRequirement
cardinality: one-to-many
- from: SystemRequirement
to: DesignRequirement
cardinality: one-to-many
- from: UserNeed
to: UseStep
cardinality: one-to-many
```
## Sheet Configuration -- Whole RTM
The whole-project RTM expands all three levels with V\&V branches at each, using color-coded column groups for visual orientation.
```yaml theme={null}
columnGroups:
userNeeds:
groupName: User Needs
groupStyle: darkgreen
headerStyle: green
collapseTo: title
systemRequirements:
groupName: System Requirements
groupStyle: darkpurple
headerStyle: purple
collapseTo: systemRequirements.systemRequirement.description
designRequirements:
groupName: Design Requirements
groupStyle: darkblue
headerStyle: blue
collapseTo: >-
systemRequirements.systemRequirement
.designRequirements.designRequirement.description
sortBy:
- columnId: outlineNumber
direction: asc
columns:
outlineNumber:
title: "#"
width: 80
formatter: readOnly
columnGroup: userNeeds
title:
title: Title
hasFocus: true
width: 170
formatter: boldTitle
columnGroup: userNeeds
description:
title: Rationale
width: 230
columnGroup: userNeeds
useSteps.useStep:
title: Use Step
multiItem: true
width: 230
columnGroup: userNeeds
validationTestCases.validationTestCase:
title: Validation Plan
multiItem: true
columnGroup: userNeeds
header: &orange
style: orange
systemRequirements.systemRequirement:
title: ID
width: 100
columnGroup: systemRequirements
systemRequirements.systemRequirement.description:
title: Description
formatter: boldTitle
width: 200
columnGroup: systemRequirements
systemRequirements.systemRequirement.verificationTestCases.verificationTestCase:
title: Verification Plan
multiItem: true
columnGroup: systemRequirements
header: *orange
systemRequirements.systemRequirement.designRequirements.designRequirement:
title: ID
width: 100
columnGroup: designRequirements
systemRequirements.systemRequirement.designRequirements.designRequirement.description:
title: Description
formatter: boldTitle
width: 200
columnGroup: designRequirements
systemRequirements.systemRequirement.designRequirements.designRequirement.verificationTestCases.verificationTestCase:
title: Verification Plan
multiItem: true
columnGroup: designRequirements
header: *orange
```
## Source Configuration
The expand paths define how the RTM query traverses the entity hierarchy, pulling linked items from across multiple documents. V\&V branches are nested at each level.
```yaml theme={null}
sources:
- id: "Powersheet RTM Template"
title: User Need
model: rtm
query:
from: UserNeed
expand:
- name: chapter
- name: useSteps
expand:
- name: useStep
- name: systemRequirements
expand:
- name: systemRequirement
title: System Req.
expand:
- name: designRequirements
expand:
- name: designRequirement
title: Design Req.
expand:
- name: verificationTestCases
expand:
- name: verificationTestCase
- name: verificationTestCases
expand:
- name: verificationTestCase
- name: validationTestCases
expand:
- name: validationTestCase
```
## Component-Scoped RTM
The same configuration pattern supports component-level views. Using `applyCurrentDocumentTo`, a single YAML config serves multiple SRS documents -- each showing only the requirements belonging to that subsystem.
```yaml theme={null}
# Component RTM -- reusable across subsystem SRS documents
sources:
- id: "Powersheet RTM Template"
title: System Req.
model: rtm
query:
from: SystemRequirement
constraints:
applyCurrentDocumentTo: SystemRequirement
expand:
- name: userNeeds
expand:
- name: userNeed
title: User Need
- name: designRequirements
expand:
- name: designRequirement
title: Design Req.
columns:
objectId:
title: ID
formatter: readOnly
width: 100
columnGroup: systemRequirements
description:
title: Description
width: 250
hasFocus: true
columnGroup: systemRequirements
userNeeds.userNeed:
title: User Needs
multiItem: true
width: 250
columnGroup: systemRequirements
header: &green
style: green
designRequirements.designRequirement:
title: ID
width: 100
columnGroup: designRequirements
designRequirements.designRequirement.description:
title: Description
width: 250
columnGroup: designRequirements
```
## Key Patterns
* **3-level V-model hierarchy** with V\&V test case branches at each level -- validation at user needs, verification at system and design requirements.
* **YAML anchors** (`&orange` / `*orange`) for reusing header styles across V\&V columns at multiple levels without repetition.
* **`applyCurrentDocumentTo`** -- a single YAML configuration serves multiple component SRS documents, each automatically scoped to its own requirements.
* **Cross-document tracing** -- the expand paths pull System Requirements from SRS documents and Design Requirements from DRS documents via the RTM model relationships.
* **Collapsible column groups** -- each group collapses to its key column for stakeholder-appropriate detail levels.
* **`multiItem: true`** for V\&V plan columns -- renders multiple linked test cases as expandable lists within a single cell.
## See Also
* [RTM Model](/powersheet/reference/example-models/rtm-model) -- standard RTM model configuration
* [Aerospace Safety Model](/powersheet/reference/example-models/aerospace-safety) -- 4-level aerospace hierarchy with SC/CC classification
* [Sources Configuration](/powersheet/reference/sheet-config/sources) -- expand paths and query configuration
* [Columns](/powersheet/reference/sheet-config/columns) -- all available column configuration options
* [Binding Syntax](/powersheet/reference/sheet-config/binding-syntax) -- dot-notation path expressions for nested entity access
# Risk Management Model
Source: https://learn.nextedy.com/powersheet/reference/example-models/risk-management-model
The risk management data model defines entity types and relationships for hazard analysis and risk control workflows within Siemens Polarion ALM.
**Verify in application**
This model reference is derived from source code configuration. Verify entity type names and property mappings against your project configuration.
## Entity Types
Entity types are declared as a map under `domainModelTypes`, keyed by type name. Each entry specifies a `polarionType` mapping and its properties.
| Entity Type | Polarion Type | Purpose |
| ---------------- | ---------------- | -------------------------------------------------------- |
| `Hazard` | `hazard` | Risk items identified during hazard analysis |
| `RiskControl` | `riskControl` | Mitigation measures applied to reduce risk |
| `RiskAssessment` | `riskAssessment` | Evaluated risk levels combining severity and probability |
### Property Configuration
Each entity type declares its properties as a map. Property names are used in queries, column bindings, and data display.
```yaml theme={null}
domainModelTypes:
Hazard:
polarionType: hazard
properties:
description:
severity:
probability:
riskLevel:
RiskControl:
polarionType: riskControl
properties:
description:
controlType:
effectiveness:
RiskAssessment:
polarionType: riskAssessment
properties:
description:
residualRisk:
acceptability:
```
A property set to `null` (empty after the colon) inherits all default settings. The property name is used as the Polarion field name unless `serverName` or `customFieldName` is specified.
## Relationships
Relationships define how entity types are connected. Each relationship specifies the Polarion `linkRole` and navigation property names using `direct` (forward) and `back` (reverse) notation.
```yaml theme={null}
relationships:
- from: Hazard
to: RiskControl
linkRole: mitigates
cardinality: one-to-many
storage: linkedWorkItems
direct:
name: riskControls
back:
name: hazards
- from: Hazard
to: RiskAssessment
linkRole: has_assessment
cardinality: one-to-many
storage: linkedWorkItems
direct:
name: riskAssessments
back:
name: hazard
```
| Property | Description |
| ------------- | ------------------------------------------------------------------------ |
| `from` / `to` | Source and target entity type names (must match `domainModelTypes` keys) |
| `linkRole` | Polarion link role ID implementing this relationship |
| `cardinality` | Multiplicity: `one-to-many`, `many-to-one`, or `many-to-many` |
| `storage` | Must be `linkedWorkItems` (Polarion native linking) |
| `direct.name` | Navigation property on the source entity for forward traversal |
| `back.name` | Navigation property on the target entity for reverse traversal |
## Complete YAML Example
```yaml theme={null}
domainModelTypes:
Hazard:
polarionType: hazard
properties:
description:
severity:
probability:
riskLevel:
RiskControl:
polarionType: riskControl
properties:
description:
controlType:
effectiveness:
RiskAssessment:
polarionType: riskAssessment
properties:
description:
residualRisk:
acceptability:
relationships:
- from: Hazard
to: RiskControl
linkRole: mitigates
cardinality: one-to-many
storage: linkedWorkItems
direct:
name: riskControls
back:
name: hazards
- from: Hazard
to: RiskAssessment
linkRole: has_assessment
cardinality: one-to-many
storage: linkedWorkItems
direct:
name: riskAssessments
back:
name: hazard
```
**Custom Field Naming**
Polarion custom field IDs typically use the `c_` prefix (e.g., `c_probability`). Use the `customFieldName` property when the Nextedy POWERSHEET property name differs from the Polarion field ID.
## See Also
* [RTM Model](/powersheet/reference/example-models/rtm-model) -- standard requirements traceability model
* [Properties](/powersheet/reference/data-model/properties) -- full property configuration reference
* [Cardinality](/powersheet/reference/data-model/cardinality) -- relationship multiplicity options
* [Data Model Types](/powersheet/reference/data-model/domainmodeltypes) -- entity type definitions
# RTM Model
Source: https://learn.nextedy.com/powersheet/reference/example-models/rtm-model
The Requirements Traceability Matrix (RTM) model is the standard Nextedy POWERSHEET data model for managing multi-level requirements hierarchies.
## Entity Types
The RTM model defines entity types under the `domainModelTypes` root key. Each entity type maps to a Polarion work item type via `polarionType`.
| Property | Type | Default | Description |
| -------------------------------------- | ------ | ------- | -------------------------------------------------------------------------------------------- |
| `domainModelTypes` | object | None | Root container defining all entity types in the data model. Each key is an entity type name. |
| `domainModelTypes[].name` | string | None | Unique identifier for the entity type. Used in relationships and queries. |
| `domainModelTypes[].polarionType` | string | None | Maps this entity to a Polarion work item type. If omitted, uses a generic work item type. |
| `domainModelTypes[].properties` | array | None | List of properties available on this entity type. Each maps to a Polarion work item field. |
| `domainModelTypes[].properties[].name` | string | None | Name of the property. Must correspond to a Polarion work item field (built-in or custom). |
### Standard RTM Entity Types
```yaml theme={null}
domainModelTypes:
Document:
Chapter:
UserNeed:
polarionType: userNeed
properties:
description:
severity:
component:
type:
SystemRequirement:
polarionType: systemRequirement
properties:
description:
severity:
component:
type:
DesignRequirement:
polarionType: designOutput
properties:
description:
severity:
component:
type:
```
**Built-in Entity Types**
`Document` is a built-in entity type representing Polarion LiveDoc modules and does not require a `polarionType` mapping. `Chapter` represents document headings and **must** be explicitly declared with `polarionType: heading`.
## Relationships
Relationships define navigable links between entity types using Polarion link roles.
| Property | Type | Default | Description |
| ----------------------------- | ------ | ------- | -------------------------------------------------------------------------- |
| `relationships` | array | `[]` | Defines all navigable relationships between entity types. |
| `relationships[].from` | string | None | Source entity type. Must match a `domainModelTypes` key. |
| `relationships[].to` | string | None | Target entity type. Must match a `domainModelTypes` key. |
| `relationships[].cardinality` | string | None | Relationship multiplicity: `one-to-many`, `many-to-one`, `many-to-many`. |
| `relationships[].storage` | string | None | Persistence mechanism. Use `linkedWorkItems` for Polarion work item links. |
| `relationships[].linkRole` | string | None | Polarion link role ID. Must exist in project configuration. |
| `relationships[].direct` | string | None | Navigation property name on source entity to traverse to target. |
| `relationships[].back` | string | None | Navigation property name on target entity to traverse back to source. |
### Standard RTM Relationships
```yaml theme={null}
relationships:
- from: UserNeed
to: SystemRequirement
cardinality: one-to-many
storage: linkedWorkItems
linkRole: relates_to
direct: systemRequirements
back: userNeeds
- from: SystemRequirement
to: DesignRequirement
cardinality: one-to-many
storage: linkedWorkItems
linkRole: relates_to
direct: designRequirements
back: systemRequirements
```
## Constraints
Entity types support three constraint types for scoping data loading and entity creation.
| Constraint | Description |
| ---------- | ----------------------------------------------------------------------------- |
| `load` | Query filter defining which entities to load. Filters by document properties. |
| `create` | Default values applied when creating new entities of this type. |
| `pick` | Picker filter controlling which entities appear in selection dropdowns. |
```yaml theme={null}
UserNeed:
polarionType: userNeed
properties:
description:
severity:
constraints:
pick:
document:
moduleFolder: Requirements
type: requirementsDocument
create:
document:
moduleFolder: Requirements
moduleName: User Needs
```
**Dynamic Constraints**
Use `$context.source.document.component` in pick constraints to dynamically filter by the source entity's component value. This ensures related entities are scoped to the same component.
## Expansion Paths
In the sheet configuration, the RTM model supports multi-level expansion through navigation properties:
```yaml theme={null}
sources:
- id: rtm
title: RTM
model: rtm
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: designRequirements
```
This loads `UserNeed` entities and expands two levels deep through `SystemRequirement` to `DesignRequirement`, enabling a full RTM hierarchy view in the sheet.
## Complete YAML Example
```yaml theme={null}
domainModelTypes:
Document:
Chapter:
UserNeed:
polarionType: userNeed
properties:
description:
severity:
component:
type:
constraints:
pick:
document:
moduleFolder: Requirements
type: requirementsDocument
SystemRequirement:
polarionType: systemRequirement
properties:
description:
severity:
component:
type:
constraints:
pick:
document:
type: requirementsDocument
DesignRequirement:
polarionType: designOutput
properties:
description:
severity:
component:
type:
constraints:
pick:
document:
type: designDocument
relationships:
- from: UserNeed
to: SystemRequirement
cardinality: one-to-many
storage: linkedWorkItems
linkRole: relates_to
direct: systemRequirements
back: userNeeds
- from: SystemRequirement
to: DesignRequirement
cardinality: one-to-many
storage: linkedWorkItems
linkRole: relates_to
direct: designRequirements
back: systemRequirements
```
## Automotive Safety RTM (Extended Example)
Production automotive projects typically extend the basic RTM with subsystem decomposition, verification at multiple levels, and characteristics traceability. The following example demonstrates a 4-level requirements hierarchy used for ISO 26262 compliance.
```yaml theme={null}
domainModelTypes:
Document:
properties:
type:
subsystem:
Chapter:
polarionType: heading
CustomerRequirement:
polarionType: customerRequirement
properties:
description:
outlineNumber:
classification:
constraints:
create:
document:
moduleFolder: Requirements
moduleName: CUSTOMER-REQS
SystemRequirement:
polarionType: sysReq
properties:
description:
classification:
constraints:
pick:
document:
type: systemRequirementsSpecification
SubsystemRequirement:
polarionType: sysReq
properties:
description:
classification:
constraints:
pick:
document:
type: subsystemRequirementsSpecification
DesignRequirement:
polarionType: desReq
properties:
description:
classification:
subType:
constraints:
pick:
document:
type: designRequirementsSpecification
TestCase:
polarionType: testCase
Characteristic:
polarionType: characteristic
properties:
targetValue:
tolerance:
classification:
FailureMode:
polarionType: failureMode
properties:
description:
fmSeverity:
premitigationFMOccurrence:
postmitigationFMOccurrence:
postmitigationAP:
relationships:
- from: CustomerRequirement
to: Chapter
cardinality: many-to-one
storage: linkedWorkItems
linkRole: parent
direct:
name: chapter
back:
name: customerRequirements
- from: SystemRequirement
to: CustomerRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: refines
direct:
name: customerRequirements
back:
name: systemRequirements
- from: SubsystemRequirement
to: SystemRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: refines
direct:
name: systemRequirements
back:
name: subsystemRequirements
- from: DesignRequirement
to: SubsystemRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: refines
direct:
name: subsystemRequirements
back:
name: designRequirements
constraints:
pick:
document:
subsystem: $context.source.document.subsystem
- from: TestCase
to: CustomerRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: validates
direct:
name: customerRequirements
back:
name: testCases
- from: TestCase
to: SystemRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: verifies
direct:
name: systemRequirements
back:
name: testCases
constraints:
create:
document:
moduleFolder: Testing
moduleName: SystemReqsVerification
- from: TestCase
to: DesignRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: verifies
direct:
name: designRequirements
back:
name: testCases
- from: Characteristic
to: DesignRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: refines
direct:
name: designRequirements
back:
name: characteristics
- from: FailureMode
to: Characteristic
cardinality: many-to-many
storage: linkedWorkItems
linkRole: assesses
direct:
name: characteristics
back:
name: failureModes
```
This sheet configuration renders the full traceability chain with color-coded column groups and collapsible sections:
```yaml theme={null}
columnGroups:
customerRequirements:
groupName: Customer Requirements
groupStyle: darkgreen
headerStyle: green
collapseTo: title
systemRequirements:
groupName: System Requirements
groupStyle: darkpurple
headerStyle: purple
collapseTo: systemRequirements.systemRequirement.description
subsystemRequirements:
groupName: Subsystem Requirements
groupStyle: darkteal
headerStyle: teal
collapseTo: >-
systemRequirements.systemRequirement
.subsystemRequirements.subsystemRequirement.description
designRequirements:
groupName: Design Requirements
groupStyle: darkblue
headerStyle: blue
collapseTo: >-
systemRequirements.systemRequirement
.subsystemRequirements.subsystemRequirement
.designRequirements.designRequirement.description
sortBy:
- columnId: outlineNumber
direction: asc
columns:
chapter:
display: title
title: Chapter
width: 150
groupBy: true
formatter: readOnly
outlineNumber:
title: "#"
width: 80
formatter: readOnly
columnGroup: customerRequirements
title:
title: Title
sort: asc
hasFocus: true
width: 230
formatter: boldTitle
columnGroup: customerRequirements
classification:
title: Classification
width: 150
columnGroup: customerRequirements
formatter: classification
render: classificationRenderer
description:
title: Description
hasFocus: true
width: 230
columnGroup: customerRequirements
testCases.testCase:
title: Validation Plan
sort: asc
minWidth: 230
multiItem: true
columnGroup: customerRequirements
header: &orange
style: orange
systemRequirements.systemRequirement:
title: ID
width: 100
columnGroup: systemRequirements
systemRequirements.systemRequirement.description:
title: Description
formatter: boldTitle
width: 200
columnGroup: systemRequirements
hasFocus: true
systemRequirements.systemRequirement.testCases.testCase:
title: Verification Plan
sort: asc
minWidth: 230
multiItem: true
columnGroup: systemRequirements
header: *orange
views:
- title: Full RTM
- title: Without V&V
hiddenColumns:
- testCases.testCase
- systemRequirements.systemRequirement.testCases.testCase
- title: Summary
hiddenColumns:
- description
- document
```
Key patterns in this configuration:
* **YAML anchors** (`&orange` / `*orange`) avoid repeating the same header style across verification columns
* **`collapseTo`** lets users collapse entire requirement levels to a single description column
* **`multiItem: true`** on test case columns renders multiple linked test cases in a single cell
* **`groupBy: true`** on the chapter column organizes rows by document chapter structure
* **Named views** provide pre-configured column visibility for different audiences
## See Also
* [Data Model Types](/powersheet/reference/data-model/domainmodeltypes) -- full property reference for `domainModelTypes`
* [Relationships](/powersheet/reference/data-model/relationships) -- relationship configuration reference
* [Constraints](/powersheet/reference/data-model/constraints) -- constraint types and syntax
* [Risk Management Model](/powersheet/reference/example-models/risk-management-model) -- alternative model for risk analysis
* [Creating Your First Data Model](/powersheet/getting-started/first-data-model) -- tutorial for building a model from scratch
# Type Conversion
Source: https://learn.nextedy.com/powersheet/reference/field-types/type-conversion
Nextedy POWERSHEET automatically converts between Siemens Polarion ALM field types and its internal data type system.
## Polarion to Powersheet Type Mapping
The metadata system automatically maps Polarion custom field types to internal data types when processing data model configurations.
| Polarion Type | Internal Data Type | Notes |
| -------------- | ------------------ | ------------------------------------------------ |
| `String` | `String` | Plain text values |
| `Text` | `String` | Multi-line text content |
| `Integer` | `Int32` | Whole number values |
| `Float` | `Double` | Floating-point decimal values |
| `Currency` | `Double` | Monetary values, stored as decimal |
| `Boolean` | `Boolean` | True/false values |
| `Date` | `DateTime` | Full date and time with timezone |
| `DateOnly` | `DateTime` | Date without time component |
| `TimeOnly` | `DateTime` | Time without date component |
| `DurationTime` | `String` | Duration values as formatted string |
| `Enum` | Enum | Constrained option set with ID and display label |
| `List` | Collection | Sets `scalar` to `false` for multi-value fields |
## Conversion Rules
### Primitive Type Conversion
Properties defined in the data model without an explicit `type` are automatically typed from Polarion metadata:
1. The metadata system reads the Polarion field type from custom field configuration
2. The type is mapped to the corresponding internal data type (see table above)
3. The mapped type determines column display behavior, editing controls, and query operators
### Enum Type Conversion
Enum properties receive additional metadata beyond the base type:
| Property | Description |
| ---------------------- | ----------------------------------------------------------------------- |
| Enumeration ID | Polarion enum definition identifier |
| Full qualified enum ID | Dot-separated scoped identifier |
| Query keys | Context keys for loading options (proto, project, polarionType, enumId) |
| Default value | Inferred from Polarion or explicit data model configuration |
**Multi-value enums are not supported**
A single-value enum field maps as described above. A multi-value (multi-select) enum, meaning a Polarion enum custom field that allows more than one value, is not currently supported as a Powersheet enum column.
### List Type Conversion
When a Polarion field type is a list (collection), the property is marked with `scalar: false`. This affects:
| Aspect | Scalar (`true`) | Collection (`false`) |
| ---------------- | ---------------------- | ---------------------- |
| Data binding | Single value display | Multi-value display |
| Query expansion | Direct property access | Requires expand clause |
| Column rendering | Standard cell | Multi-item cell |
## Property Type Information
Each column in Powersheet carries combined type information that determines its rendering and editing behavior:
| Type Category | Description |
| ----------------- | ------------------------------------------------------------- |
| Column type | Overall column behavior type (text, number, date, enum, etc.) |
| Column value type | Specific value format within the column type |
| Property type | Combined intersection of column type and value type |
## Built-In Property Types
All work item entity types include these automatically typed built-in properties:
| Property | Type | Read-Only |
| ----------- | -------- | ----------------- |
| `objectId` | `String` | Yes (primary key) |
| `id` | `String` | Yes |
| `title` | `String` | No |
| `projectId` | `String` | Yes (foreign key) |
### Document Entity Read-Only Fields
Document entity types have additional create-only fields that cannot be modified after the document is created:
| Property | Access |
| ---------------- | ----------- |
| `moduleFolder` | Create-only |
| `moduleName` | Create-only |
| `title` | Create-only |
| `type` | Create-only |
| `allowedWITypes` | Create-only |
**Verify in application**
Some Document entity implementations expose `outlineNumber` as a read-only property when explicitly declared in the data model. It is not part of the default built-in Document property set — verify in your project's metadata before relying on it.
## Security and Type Interaction
Server-rendered properties (computed fields) interact with the type system:
| Configuration | Effect on Type |
| ---------------------- | --------------------------------------------------------- |
| `serverRender` enabled | Property is always non-editable regardless of `updatable` |
| `readable: false` | Property excluded from metadata; not available to client |
| Entity-level read-only | Intersected with property-level `updatable` |
## Default Value Resolution by Type
| Type | Default Resolution |
| ------------------------------- | ------------------------------------------------------------------- |
| Primitive (String, Int32, etc.) | `null` unless explicit default in data model |
| Enum | Explicit data model default > Polarion enumeration default > `null` |
| Boolean | `null` unless configured |
| DateTime | `null` unless configured |
## Complete YAML Example
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: userNeed
properties:
title: ~
description: ~
priority:
customFieldName: priority
storyPoints:
customFieldName: c_storyPoints
isApproved:
customFieldName: c_isApproved
targetDate:
customFieldName: c_targetDate
estimatedEffort:
customFieldName: c_estimatedEffort
verificationMethod:
customFieldName: c_verificationMethod
enumValues:
- analysis
- inspection
- test
SystemRequirement:
polarionType: systemRequirement
properties:
title: ~
severity:
customFieldName: severity
relationships:
- from: UserNeed
to: SystemRequirement
cardinality: many-to-many
storage: linkedWorkItems
linkRole: relates_to
direct:
name: systemRequirements
back:
name: userNeeds
```
**Automatic Type Detection**
In most configurations, you do not need to specify the `type` property explicitly. Powersheet infers types from Polarion metadata. Only specify `type` when you need to override automatic detection or when the property is not backed by a Polarion field.
## Related Pages
* [Polarion Type Mapping](/powersheet/reference/data-model/polarion-mapping) -- Entity type to Polarion mapping
# Reference
Source: https://learn.nextedy.com/powersheet/reference/index
**[Data Model Reference](data-model/index.md)** -- Entity types, relationships, properties, constraints, cardinality, link roles, permissions, and Polarion type mapping.
## Data Model
**[Data Model Reference](/powersheet/reference/data-model/index)** -- Entity types, relationships, properties, constraints, cardinality, link roles, permissions, and Polarion type mapping.
* **[Data Model Types](/powersheet/reference/data-model/domainmodeltypes)** -- `domainModelTypes` property reference
* **[Relationships](/powersheet/reference/data-model/relationships)** -- Relationship definitions with cardinality and navigation
* **[Properties](/powersheet/reference/data-model/properties)** -- Entity type property definitions
* **[Constraints](/powersheet/reference/data-model/constraints)** -- Load, create, and pick constraint rules
* **[Cardinality](/powersheet/reference/data-model/cardinality)** -- Relationship multiplicity options
* **[Link Roles](/powersheet/reference/data-model/link-roles)** -- Polarion link role mapping
* **[Permissions](/powersheet/reference/data-model/permissions)** -- Entity and property-level access control
* **[Polarion Type Mapping](/powersheet/reference/data-model/polarion-mapping)** -- Entity to work item type mapping
* **[Navigation Directions](/powersheet/reference/data-model/navigation-directions)** -- Forward and reverse navigation properties
## Sheet Configuration
**[Sheet Configuration Reference](/powersheet/reference/sheet-config/index)** -- Column layout, views, styles, formatters, sources, and display options.
* **[Columns](/powersheet/reference/sheet-config/columns)** -- Column definitions and configuration
* **[Column Groups](/powersheet/reference/sheet-config/column-groups)** -- Visual grouping with collapse behavior
* **[Views](/powersheet/reference/sheet-config/views)** -- Named column visibility presets
* **[Styles](/powersheet/reference/sheet-config/styles)** -- Custom style definitions
* **[Formatters](/powersheet/reference/sheet-config/formatters)** -- Conditional formatting rules
* **[Sources](/powersheet/reference/sheet-config/sources)** -- Data source query definitions
* **[Sort By](/powersheet/reference/sheet-config/sortby)** -- Default sort order configuration
* **[Display Property](/powersheet/reference/sheet-config/display-property)** -- Display format options
* **[Render Property](/powersheet/reference/sheet-config/render-property)** -- Custom render configurations
* **[Binding Syntax](/powersheet/reference/sheet-config/binding-syntax)** -- Dot-notation binding path reference
* **[Multi-Item Columns](/powersheet/reference/sheet-config/multi-item-columns)** -- Multi-reference column configuration
## Query API
**[Query API Reference](/powersheet/reference/query-api/index)** -- Entity queries, predicates, operators, expansion, and filtering.
* **[EntityQuery](/powersheet/reference/query-api/entity-query)** -- Query structure and execution
* **[Predicates](/powersheet/reference/query-api/predicates)** -- Filter predicate types and operators
* **[Expand Clause](/powersheet/reference/query-api/expand-clause)** -- Navigation property expansion
* **[Query Context](/powersheet/reference/query-api/query-context)** -- Context parameters
* **[Document Filtering](/powersheet/reference/query-api/document-filtering)** -- Document-scoped queries
* **[Baseline and Revision Queries](/powersheet/reference/query-api/baseline-and-revision-queries)** -- Historical data queries
## Server Rendering
* **[Velocity Templates](/powersheet/reference/server-rendering/velocity-templates)** -- Server-side template rendering
* **[Context Variables](/powersheet/reference/server-rendering/context-variables)** -- Available template variables
* **[Polarion Services](/powersheet/reference/server-rendering/polarion-services)** -- Accessible Polarion services
* **[JavaScript Functions](/powersheet/reference/server-rendering/javascript-functions)** -- Client-side functions
## Field Types
**Field Types** -- Reference for Nextedy POWERSHEET field type handling and conversion.
* **[Type Conversion](/powersheet/reference/field-types/type-conversion)** -- Automatic type mapping
## Example Models
**[Example Models Reference](/powersheet/reference/example-models/index)** -- Complete working data model examples.
* **[RTM Model](/powersheet/reference/example-models/rtm-model)** -- Requirements Traceability Matrix
* **[Risk Management Model](/powersheet/reference/example-models/risk-management-model)** -- Risk analysis model
**Start with concepts**
If you are new to Powersheet configuration, read the [Concepts](/powersheet/concepts/index) section first to understand the architecture before diving into property-level reference details.
# Keyboard Shortcuts
Source: https://learn.nextedy.com/powersheet/reference/keyboard-shortcuts
Nextedy POWERSHEET provides keyboard shortcuts for efficient sheet interaction. All shortcuts require the sheet to have focus and a valid cell to be selected.
**Cross-Platform Support**
Powersheet uses a unified command key detection (`Ctrl` on Windows/Linux, `Cmd` on macOS) for all shortcuts listed below. The sheet automatically adapts to the current operating system.
***
## Quick Reference
***
## Row Operations
Shortcuts for adding, removing, and managing rows within the sheet. Row operations are also available as toolbar icons in the work items tree (Add , Delete ).
| Shortcut | Action | Description |
| ---------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Ctrl+Space` | Add row | Inserts a new row at the same hierarchy level as the currently selected cell. Default values are pre-filled from the entity factory configuration. |
| `Ctrl+Backspace` | Delete row | Marks the selected row for deletion. Displays a confirmation dialog before removing. The row can be restored with undo before saving. |
| `Ctrl+Delete` | Delete row (alternate) | Same behavior as `Ctrl+Backspace`. |
| `Ctrl+Z` | Undo | Reverts the last change, including edits, row additions, deletions, and link operations. The undo stack is scoped to the current session. |
| `Ctrl+Y` | Redo | Reapplies the last undone change. Available only when an undo has been performed. |
**Undo Scope**
The undo/redo history is scoped to the current sheet session. Navigating away from the sheet clears the history. Save operations cannot be undone from the client side -- once changes are saved to Polarion, they are committed.
***
## Column Freezing
Shortcuts for pinning columns to keep them visible during horizontal scrolling.
| Shortcut | Action | Description |
| -------------- | ---------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `Ctrl+F` | Freeze columns | Freezes columns up to the currently selected column. Frozen columns remain visible when scrolling horizontally. |
| `Ctrl+Alt+F` | Freeze up to selected column | Freezes all columns from the left edge up to and including the selected column. |
| `Ctrl+Shift+F` | Unfreeze all columns | Removes all column freezing and restores free horizontal scrolling. |
**Default Frozen Columns**
Frozen columns can also be set in the sheet configuration YAML using the `frozen` property on individual columns. Keyboard freezing overrides the configured default for the current session. See [Columns](/powersheet/reference/sheet-config/columns) for configuration details.
***
## Row Grouping
Shortcuts for organizing rows into collapsible groups based on column values.
| Shortcut | Action | Description |
| -------------- | ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `Ctrl+G` | Group by column | Groups all rows by the values in the currently selected column. Displays collapsible group headers with item counts (e.g., "Open: (5 items)"). |
| `Ctrl+Alt+G` | Add to existing groups | Adds the selected column as an additional grouping level without clearing existing groups. Builds hierarchical multi-column grouping. |
| `Ctrl+Shift+G` | Clear all groups | Removes all row grouping and restores the flat row display. |
The `showGroupRowCounter` configuration property controls whether the item count is displayed in group headers.
***
## Column Sorting
Shortcuts for ordering rows by column values.
| Shortcut | Action | Description |
| -------------------------- | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Click column header | Sort ascending/descending | Clicking a column header toggles the sort direction: ascending, descending, then unsorted. |
| `Ctrl+Click` column header | Multi-column sort | Adds the clicked column to the existing sort chain as a secondary (or tertiary, etc.) sort criterion. Small sort-order numbers appear in column headers. |
**Default Sort**
The default sort order defined in the [Sort By](/powersheet/reference/sheet-config/sortby) configuration is always re-applied after user sorting to maintain hierarchy consistency. User sort criteria are applied on top of the configured default.
***
## Cell Editing
Shortcuts for entering, committing, and canceling cell edits.
| Shortcut | Action | Description |
| -------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `Double-click` | Enter edit mode | Opens the cell for editing. For dropdown columns, a picklist appears. For text columns, the cell becomes an editable input. |
| `F2` | Enter edit mode (alternate) | Same as double-click -- enters edit mode on the currently selected cell. |
| `Enter` | Commit edit | Commits the current cell value and moves the selection down to the next row. |
| `Escape` | Cancel edit | Discards the current edit and restores the original cell value. Also exits linking mode if active. |
| Type directly | Quick edit | Start typing while a cell is selected to overwrite the current value. The cell enters edit mode automatically. |
**Read-Only Cells**
Cells protected by the `isReadOnly` column property, document permissions, or workflow rules cannot be edited. Read-only cells display a distinct visual indicator (different marquee style) when selected. See [Permissions](/powersheet/reference/data-model/permissions) for details.
***
## Copy and Paste
Shortcuts for transferring cell data within the sheet.
| Shortcut | Action | Description |
| -------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `Ctrl+C` | Copy | Copies the selected cell or cell range to the clipboard. A toast notification confirms the number of cells copied (e.g., "5 cells copied"). |
| `Ctrl+V` | Paste | Pastes clipboard content into the selected cells. A toast notification confirms the target (e.g., "Pasted to 2 Requirements"). |
**Cross-Level Paste Restriction**
Pasting across different hierarchy levels is not supported. If you attempt to paste cells from one entity type level to a different level, the sheet displays a warning and the paste operation is blocked. Only cells at the same hierarchy level can be pasted together.
***
## Cell Navigation
Shortcuts for moving between cells and selecting ranges.
| Shortcut | Action | Description |
| --------------------------- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------------- |
| Arrow keys | Move between cells | Moves the active cell selection one cell in the pressed direction (up, down, left, right). |
| `Tab` | Move to next cell | Advances the selection to the next cell in the row. |
| `Enter` (outside edit mode) | Move down | Moves the selection down to the next row in the same column. |
| Click | Select single cell | Selects the clicked cell, showing a blue selection border (marquee). |
| Click and drag | Select range | Selects a rectangular range of cells. When numeric cells are selected, the status bar shows aggregate statistics (Sum, Avg, Min, Max). |
**Active Cell Focus**
Only the active cell has keyboard focus (`tabindex="0"`). All other cells have `tabindex="-1"` for accessibility. The active cell is indicated by the `.wj-state-active` visual class.
***
## Excel Export
| Shortcut | Action | Description |
| -------- | --------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Ctrl+E` | Export to Excel | Downloads the current sheet view as an Excel (`.xlsx`) file. The export includes all visible columns, applied filters, current sort order, and row grouping. Hidden columns are excluded. |
**Export Performance**
Large sheets with many rows or complex grouping may take several seconds to generate the Excel file. The export reflects the exact view state at the time the shortcut is pressed.
***
## Linking Mode
Shortcuts specific to the work item linking workflow.
| Shortcut | Action | Description |
| ----------------------- | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Escape` | Exit linking mode | Cancels the active linking operation and returns to normal selection mode. |
| Click (in linking mode) | Link target cell | While in linking mode, clicking a valid target cell creates a link between the source and target work items. Valid targets are highlighted with a green marquee. |
Linking mode is activated via the **Link** toolbar button. It supports only many-to-many relationships defined in the [data model](/powersheet/reference/data-model/relationships). All link operations support undo/redo.
***
## Search
| Shortcut | Action | Description |
| ------------------ | -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| Type in search box | Filter and highlight | Enter text in the toolbar search box to find and highlight matching cells across all columns. Matches are highlighted with a yellow background. |
| Clear button | Clear search | Click the clear button (or select all text with `Ctrl+A` and press `Backspace`) in the search box to remove the search filter and restore all rows. |
***
## Complete Shortcut Table
A consolidated reference of all keyboard shortcuts sorted by category.
| Category | Shortcut | Action |
| ------------------- | --------------------- | ------------------------------- |
| **Row Operations** | `Ctrl+Space` | Add row at current level |
| | `Ctrl+Backspace` | Delete selected row |
| | `Ctrl+Delete` | Delete selected row (alternate) |
| | `Ctrl+Z` | Undo last change |
| | `Ctrl+Y` | Redo last undone change |
| **Column Freezing** | `Ctrl+F` | Freeze columns |
| | `Ctrl+Alt+F` | Freeze up to selected column |
| | `Ctrl+Shift+F` | Unfreeze all columns |
| **Row Grouping** | `Ctrl+G` | Group by selected column |
| | `Ctrl+Alt+G` | Add column to existing groups |
| | `Ctrl+Shift+G` | Clear all row grouping |
| **Sorting** | Click header | Toggle sort direction |
| | `Ctrl+Click` header | Add to multi-column sort |
| **Cell Editing** | `Double-click` / `F2` | Enter edit mode |
| | `Enter` | Commit edit, move down |
| | `Escape` | Cancel edit / exit linking |
| | Type directly | Quick-edit cell |
| **Clipboard** | `Ctrl+C` | Copy selected cells |
| | `Ctrl+V` | Paste cells |
| **Navigation** | Arrow keys | Move between cells |
| | `Tab` | Move to next cell |
| | Click | Select cell |
| | Click + drag | Select range |
| **Export** | `Ctrl+E` | Export to Excel |
***
## Shortcut Availability
Keyboard shortcuts are only active when the following conditions are met:
| Condition | Requirement |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Sheet focus | The sheet must have keyboard focus. Click anywhere within the sheet to ensure focus. |
| Valid cell selected | A cell must be actively selected (blue marquee visible). |
| Edit mode state | Some shortcuts (e.g., `Ctrl+Space`, `Ctrl+G`) require the cell to not be in edit mode. |
| Permissions | Row operations (`Ctrl+Space`, `Ctrl+Backspace`) respect entity-level permissions. If the entity type is not deletable, the delete shortcut shows a warning toast. |
| Linking mode | During active linking mode, only `Escape` and click-to-link are available. Other shortcuts are suspended until linking mode is exited. |
***
## macOS Equivalents
On macOS, Powersheet automatically maps `Ctrl` to `Cmd` for all shortcuts.
| Windows / Linux | macOS |
| ---------------- | --------------- |
| `Ctrl+Space` | `Cmd+Space` |
| `Ctrl+Backspace` | `Cmd+Backspace` |
| `Ctrl+Z` | `Cmd+Z` |
| `Ctrl+Y` | `Cmd+Y` |
| `Ctrl+C` | `Cmd+C` |
| `Ctrl+V` | `Cmd+V` |
| `Ctrl+E` | `Cmd+E` |
| `Ctrl+G` | `Cmd+G` |
| `Ctrl+Shift+G` | `Cmd+Shift+G` |
| `Ctrl+Alt+G` | `Cmd+Option+G` |
| `Ctrl+F` | `Cmd+F` |
| `Ctrl+Shift+F` | `Cmd+Shift+F` |
| `Ctrl+Alt+F` | `Cmd+Option+F` |
| `Ctrl+Click` | `Cmd+Click` |
***
## Related Pages
* [Columns](/powersheet/reference/sheet-config/columns) -- Column configuration including `frozen` and `isReadOnly` properties
* [Sort By](/powersheet/reference/sheet-config/sortby) -- Default sort order configuration
* [Views](/powersheet/reference/sheet-config/views) -- Named column visibility presets
* [Permissions](/powersheet/reference/data-model/permissions) -- Entity and property-level access control
* [Relationships](/powersheet/reference/data-model/relationships) -- Relationship definitions for linking mode
# Baseline and Revision Queries
Source: https://learn.nextedy.com/powersheet/reference/query-api/baseline-and-revision-queries
Nextedy POWERSHEET supports querying historical data from Siemens Polarion ALM baselines and revisions.
## Revision Query Flow
## Revision Parameter
| Parameter | Type | Default | Description |
| ---------- | --------- | ------- | ------------------------------------------------------------------------------ |
| `revision` | `integer` | `null` | Document revision number to query. `null` means HEAD (latest). Must be `>= 0`. |
### URL Parameter
The revision is specified via the `_revision` URL query parameter:
```
/polarion/#/project/MyProject/powersheet?_document=Requirements/SystemReqs&_revision=42
```
Starting with Powersheet 26.7.2, this is the underscore-prefixed [system parameter](/powersheet/concepts/url-parameters#system-parameters) Powersheet generates. The older bare `revision` name is still honored as a legacy alias, so existing links keep working.
| Value | Behavior |
| ----------------------- | ------------------------------------ |
| Not specified | Shows latest data (HEAD) |
| `0` or positive integer | Shows data at the specified revision |
### Setting Revision Programmatically
The revision can be changed without a full page reload. The URL parameters are updated and the data is re-fetched at the new revision.
**Revision Picker**
Use the revision picker in the Powersheet UI to navigate between document revisions. Pass `undefined` to clear the revision and return to HEAD.
## Read-Only Mode
Historical revisions are always displayed in read-only mode. The sheet enters read-only mode when any of these conditions is true:
| Condition | Description |
| ------------------------------ | ----------------------------------- |
| `revision` is set | Viewing a historical revision |
| `config.isReadOnly` is `true` | Configuration flag forces read-only |
| User has `readOnly` permission | Permission-based restriction |
**No Editing on Historical Revisions**
When viewing a historical revision, all editing operations (cell editing, row creation, row deletion, save) are disabled. The sheet displays data as it existed at the specified revision.
## Query Execution with Revision
The query processor handles revisions at two levels:
### 1. Query Parameter Revision
The `revision` parameter in the entity query controls which historical version of the data is queried:
| Parameter Source | Priority | Description |
| -------------------------- | -------- | ----------------------------------------- |
| Query parameter `revision` | Highest | Explicitly set on the query |
| Context baseline | Lower | Inherited from the query context baseline |
### 2. Configuration Processing
When a revision is active, the configuration processor:
* Injects the `revision` parameter into the main data source query
* Appends the revision number to the document display name (e.g., `SystemReqs (Rev 42)`)
* Sets the sheet to read-only mode
## Document Context with Revision
| Property | Type | Description |
| ----------------- | --------- | ------------------------------------------------------------------ |
| `document.full` | `string` | Full document path (`folder/name`). Does not change with revision. |
| `document.folder` | `string` | Document folder/space component |
| `document.name` | `string` | Document name component |
| `revision` | `integer` | Current revision number, or `null` for HEAD |
The document display name includes the revision when viewing historical data:
```
SystemReqs (42)
```
## Configuration URL with Revision
The configuration URL includes a cache-busting timestamp. When the revision changes, the configuration is re-fetched to ensure the correct version of the sheet configuration is loaded.
**Verify in application**
Configuration re-fetching on revision change depends on the server's handling of revision-aware configuration. Verify that your Polarion server supports revision-specific configuration retrieval.
## Entity Metadata at Revision
Entity query results at a specific revision include standard metadata fields:
| Field | Type | Description |
| ----------- | ---------- | ----------------------------------------------------- |
| `objectId` | `string` | Unique entity identifier |
| `id` | `string` | Polarion work item ID |
| `title` | `string` | Work item title at the specified revision |
| `updated` | `datetime` | Last modification timestamp at or before the revision |
| `projectId` | `string` | Project foreign key |
## Baseline vs. Revision
| Concept | Description |
| ------------ | ---------------------------------------------------------------------------- |
| **Revision** | A specific SVN revision number representing a point in the project's history |
| **Baseline** | A named project baseline that maps to a specific revision number |
The query processor supports both approaches. The revision can come from an explicit query parameter or from a project baseline associated with the query context.
**Verify in application**
The relationship between Polarion project baselines and SVN revision numbers depends on your Polarion server configuration. Consult your administrator for baseline-to-revision mapping.
## Complete YAML Example
```yaml theme={null}
sources:
- id: requirements
title: System Requirements
model: rtm
query:
from: UserNeed
where: "type = 'UserNeed'"
constraints:
applyCurrentDocumentTo: UserNeed
expand:
- name: systemRequirements
title: System Requirements
expand:
- name: systemRequirement
columns:
id:
width: 80
sort: asc
title:
width: 300
hasFocus: true
systemRequirements.systemRequirement.title:
width: 250
systemRequirements.systemRequirement.severity:
width: 100
```
When this configuration is loaded with `?_revision=42` in the URL, the query processor:
1. Fetches `UserNeed` entities as they existed at revision 42
2. Expands `systemRequirements.systemRequirement` at the same revision
3. Displays the sheet in read-only mode
4. Shows the document name with revision suffix
## Related Pages
* [Query Context](/powersheet/reference/query-api/query-context) -- query parameter reference
* [EntityQuery](/powersheet/reference/query-api/entity-query) -- query structure and parameters
* [Document Filtering](/powersheet/reference/query-api/document-filtering) -- document-level query constraints
***
# Document Filtering
Source: https://learn.nextedy.com/powersheet/reference/query-api/document-filtering
Nextedy POWERSHEET supports document-level query filtering to scope data retrieval to work items within a specific Siemens Polarion ALM LiveDoc.
This reference covers the `applyCurrentDocumentTo` constraint, document scoping behavior for root and downstream entity types, and how filtering interacts with expansion paths and new entity creation.
## Document Filtering Overview
Document filtering is a constraint-based mechanism. When the `applyCurrentDocumentTo` constraint is defined on a data source, Powersheet automatically restricts results to items that belong to the LiveDoc in which the widget is rendered. The filter operates by matching the document's `moduleFolder` and `moduleName` properties against the current LiveDoc context.
***
## applyCurrentDocumentTo Constraint
The `applyCurrentDocumentTo` property is defined within the `constraints` block of a data source configuration. It specifies which entity type should be restricted to only items contained within the current LiveDoc.
**Dynamic value support**
`applyCurrentDocumentTo` accepts a [dynamic expression](/powersheet/reference/sheet-config/dynamic-expressions) (`() => …`) that resolves to an entity type name, so the scoped type can be chosen from a [URL parameter](/powersheet/reference/sheet-config/url-parameters). When the expression resolves to nothing (for example a missing parameter), the key is dropped and no document scoping is applied; a non-string result raises an error.
| Property | Type | Default | Description |
| ------------------------------------ | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `constraints.applyCurrentDocumentTo` | `string` | `null` | Entity type name that should be filtered to only include items belonging to the current document. When the Powersheet widget is rendered inside a LiveDoc, this constraint automatically restricts the named entity type to items within that document. |
**When to Use Document Filtering**
Use `applyCurrentDocumentTo` whenever the Powersheet widget is embedded in a LiveDoc and you want the sheet to display only items that belong to that specific document. Without this constraint, the query returns all matching items across the entire project.
### Constraint Properties Reference
| Property | Type | Default | Description |
| ------------------------------------ | -------- | --------------- | --------------------------------------------------------------------------------------------------------------- |
| `constraints` | `object` | `null` | Container for all constraint definitions on a data source. |
| `constraints.applyCurrentDocumentTo` | `string` | `null` | Entity type name to scope to the current document. Must match a valid entity type in the referenced data model. |
| `constraints.project` | `string` | See application | Project constraint for filtering. Can use dynamic context labels for resolution. |
| `constraints.document` | `string` | See application | Document constraint for filtering. Can use dynamic context labels for resolution. |
**Constraint Resolution**
Constraints on entity types combine with constraints defined on relationships. When both an entity type and a relationship define project or document constraints, they are merged with AND logic before query execution.
***
## Root Entity Filtering
When `applyCurrentDocumentTo` matches the root entity type specified in `query.from`, the document filter applies directly to the primary query. This is the most common pattern: the sheet displays items of a single type that live in the current document.
```yaml theme={null}
sources:
- id: requirements
title: System Requirements
model: rtm
query:
from: SystemRequirement
where: "type = 'UserNeed'"
constraints:
applyCurrentDocumentTo: SystemRequirement
expand:
- name: designRequirements
title: Design Requirements
expand:
- name: designRequirement
```
In this configuration:
* `SystemRequirement` is both the root query entity and the document-filtered entity
* Only `SystemRequirement` items that belong to the current LiveDoc are returned
* Expanded `DesignRequirement` items are fetched through the relationship regardless of which document they belong to
### How Root Filtering Works
1. The widget reads the current LiveDoc context (module folder and module name)
2. The constraint system detects that `applyCurrentDocumentTo` matches the `query.from` entity type
3. A document filter predicate is automatically injected into the query's where clause
4. The query returns only items from the specified document
***
## Downstream Entity Filtering
When `applyCurrentDocumentTo` targets a related entity type (not the root `query.from` entity), the constraint applies to the downstream entity within the expansion path. The root entity type is queried without document restriction.
```yaml theme={null}
sources:
- id: needs
title: User Needs
model: rtm
query:
from: UserNeed
where: "type = 'UserNeed'"
constraints:
applyCurrentDocumentTo: SystemRequirement
expand:
- name: systemRequirements
title: System Requirements
expand:
- name: systemRequirement
```
In this configuration:
* `UserNeed` is the root entity type and is **not** document-filtered
* `SystemRequirement` is the downstream entity type scoped to the current document
* The sheet shows all `UserNeed` items matching the where clause, but only expands to `SystemRequirement` items that belong to the current LiveDoc
**Entity Type Must Exist in Data Model**
The entity type name specified in `applyCurrentDocumentTo` must be a valid entity type defined in the referenced data model. If the entity type is not found, the constraint is silently ignored and no document filtering is applied.
### Downstream Filtering Scenarios
| Root Entity | Filtered Entity | Behavior |
| ----------- | ------------------- | -------------------------------------------------------------------------------------------------------- |
| `UserNeed` | `UserNeed` | Root filtering -- only `UserNeed` items in current document |
| `UserNeed` | `SystemRequirement` | Downstream filtering -- all `UserNeed` items, but `SystemRequirement` expansion scoped to document |
| `UserNeed` | `DesignRequirement` | Deep downstream -- `UserNeed` and `SystemRequirement` unfiltered, `DesignRequirement` scoped to document |
| `Hazard` | `RiskControl` | Risk model -- all `Hazard` items shown, `RiskControl` expansion scoped to document |
***
## Document Context Variables
When document filtering is active, the following context information is available for use within query expressions and dynamic value resolution:
| Variable | Description |
| ----------------------- | -------------------------------------------------------------------------------------- |
| `document.moduleFolder` | The space (folder) of the current LiveDoc in Polarion (e.g., `Requirements`) |
| `document.moduleName` | The name of the current LiveDoc (e.g., `SystemRequirements`) |
| `document.id` | Full document path combining folder and name (e.g., `Requirements/SystemRequirements`) |
These variables are automatically populated when the Powersheet widget is rendered inside a LiveDoc. They are used internally by the document filter and are also available via `$context.document.id` expressions in dynamic value configurations.
**Verify in Application**
The exact format of `document.id` depends on the Polarion space configuration. For documents in the default space (`_default`), the space prefix may be omitted from the document ID.
***
## Document Filtering with New Entities
When `applyCurrentDocumentTo` is configured and a user creates a new entity through the sheet, the document constraint is automatically applied to the new item's initial values. This ensures newly created items are scoped to the current document without manual intervention.
| Behavior | Description |
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| Automatic document assignment | New entities of the type specified in `applyCurrentDocumentTo` receive the current document's `documentId` as an initial property value |
| Scope inheritance | The new entity is created within the same LiveDoc context as the current document, maintaining document-centric data integrity |
| Constraint enforcement | If `applyCurrentDocumentTo` targets the root entity type, new items are automatically assigned to the current document |
```yaml theme={null}
sources:
- id: requirements
title: Requirements
model: rtm
query:
from: SystemRequirement
constraints:
applyCurrentDocumentTo: SystemRequirement
expand:
- name: designRequirements
title: Design Requirements
expand:
- name: designRequirement
```
With this configuration, when a user adds a new `SystemRequirement` through the sheet, it is automatically placed in the current LiveDoc.
***
## Constraint Propagation
Document constraints defined on entity types propagate to related navigation properties during query expansion. This propagation determines how document scoping applies across the full expansion path.
| Source | Propagation Rule |
| ------------------------------- | ----------------------------------------------------------------------------------------- |
| Entity type constraints | Extracted from constraint annotations on the entity type |
| Navigation property constraints | Merged from both the navigation property annotation and the target entity type annotation |
| Combined result | AND-combined predicate validated against entity type metadata |
When both an entity type and its relationship define document constraints, the system merges them. For many-to-many relationships traversed through association types, the constraint resolver unwraps the association to reach the target entity type and applies the combined constraint there.
***
## Data Model Constraint Configuration
Document constraints can also be defined at the entity type level in the data model YAML, independent of the sheet configuration's `applyCurrentDocumentTo`. These constraints apply to all queries against the entity type across every sheet configuration that references the model.
```yaml theme={null}
domainModelTypes:
SystemRequirement:
polarionType: systemRequirement
constraints:
load:
document:
moduleFolder: Requirements
type: requirements_specification
pick:
document:
moduleFolder: Requirements
moduleName: Categorized
```
| Constraint Level | Purpose | Applied When |
| ----------------- | ---------------------------------------------- | ------------------------------------------- |
| `load.document` | Filters entities during initial data loading | Sheet loads data for display |
| `pick.document` | Filters entities in picker dropdown selections | User opens a relationship picker |
| `create.document` | Sets default document values for new entities | User creates a new entity through the sheet |
**Constraint Levels vs. applyCurrentDocumentTo**
Data model constraints (`load`, `pick`, `create`) define **static** document filters based on known folder or document names. In contrast, `applyCurrentDocumentTo` is **dynamic** -- it uses the current LiveDoc context at runtime. Both mechanisms can coexist; they are combined with AND logic.
See [Constraints](/powersheet/reference/data-model/constraints) for the full constraint configuration reference.
***
## Complete YAML Example
The following example demonstrates a full sheet configuration with document filtering applied to a requirements traceability matrix (RTM):
```yaml theme={null}
sources:
- id: user-needs
title: User Needs
model: rtm
query:
from: UserNeed
where: "type = 'UserNeed'"
constraints:
applyCurrentDocumentTo: UserNeed
expand:
- name: systemRequirements
title: System Requirements
expand:
- name: systemRequirement
expand:
- name: designRequirements
title: Design Requirements
expand:
- name: designRequirement
- id: hazards
title: Hazards
model: risk
query:
from: Hazard
where: "type = 'UserNeed'"
constraints:
applyCurrentDocumentTo: Hazard
expand:
- name: riskControls
title: Risk Controls
expand:
- name: riskControl
columns:
id:
width: 80
sort: asc
title:
width: 300
hasFocus: true
systemRequirements.systemRequirement.title:
width: 250
systemRequirements.systemRequirement.severity:
width: 100
```
This configuration defines two data sources:
1. **User Needs** source with root-level document filtering on `UserNeed` and a three-level expansion path: `UserNeed` > `SystemRequirement` > `DesignRequirement`
2. **Hazards** source with root-level document filtering on `Hazard` and a single-level expansion to `RiskControl`
Both sources restrict their root entity type to items within the current LiveDoc while allowing expanded entities to come from any document.
***
## Interaction with Other Constraints
Document filtering via `applyCurrentDocumentTo` works alongside other constraint types defined in the data model and sheet configuration:
| Constraint Type | Interaction with Document Filtering |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Project constraints | Applied independently. Both project and document constraints must be satisfied for an item to appear. |
| Entity type constraints | Merged with AND logic. Data model constraints on the entity type combine with the document filter. |
| Relationship constraints | Navigation property constraints on project or document are combined with entity-level constraints when expanding related items. |
| Security permissions | Checked before any query execution. If the current user lacks read permission (`isReadOnly`) for the entity type, the query is rejected regardless of document filtering. |
**Constraint Merging**
When both an entity type and its relationship define document constraints, the constraints are combined. Ensure that the constraint definitions do not conflict or create overly restrictive filters that return empty results.
***
## Constraint Resolution with Navigation Properties
When document filtering targets a downstream entity type, the constraint must be resolved through the expansion path. The system resolves the path from the root entity type to the filtered entity type by traversing navigation properties defined in the data model.
```yaml theme={null}
# Data model relationship (direct direction)
relationships:
- name: systemRequirements
source: UserNeed
target: SystemRequirement
type: manyToMany
```
For the expansion path `UserNeed` > `systemRequirements` > `systemRequirement`, the constraint resolver:
1. Starts at the root entity type (`UserNeed`)
2. Follows the `systemRequirements` navigation property (direct direction)
3. Reaches `SystemRequirement` and applies the document filter
The resolution supports multi-level dot-notation paths (e.g., `systemRequirements.systemRequirement.designRequirements`) for deep navigation hierarchies.
***
## Behavior Without Document Context
When the Powersheet widget is rendered outside a LiveDoc context (for example, in a Wiki page or a standalone widget), the document filter has no effect:
| Scenario | Behavior |
| -------------------------- | ------------------------------------------------------------------------------------- |
| Widget in LiveDoc | `applyCurrentDocumentTo` actively filters by current document |
| Widget in Wiki page | No document context available; constraint is ignored, all matching items returned |
| Widget with URL parameters | URL parameters (e.g., `masterItemId`) are applied independently of document filtering |
**Testing Without Document Context**
When developing sheet configurations outside a LiveDoc, remember that document filtering is inactive. Validate filtering behavior by embedding the widget in the target LiveDoc.
***
## Related Pages
* [EntityQuery](/powersheet/reference/query-api/entity-query) -- query structure and `from` clause reference
* [Predicates](/powersheet/reference/query-api/predicates) -- where clause predicate syntax
* [Expand Clause](/powersheet/reference/query-api/expand-clause) -- expansion path configuration
* [Query Context](/powersheet/reference/query-api/query-context) -- context variables and parameter passing
* [Constraints](/powersheet/reference/data-model/constraints) -- data model constraint definitions
* [Sources](/powersheet/reference/sheet-config/sources) -- data source configuration reference
* [Navigation Directions](/powersheet/reference/data-model/navigation-directions) -- direct and back relationship traversal
***
# EntityQuery
Source: https://learn.nextedy.com/powersheet/reference/query-api/entity-query
The EntityQuery is the top-level query object in Nextedy POWERSHEET that encapsulates all parameters for retrieving data from Siemens Polarion ALM.
***
## Query Properties
| Name | Type | Default | Description |
| --------- | -------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `from` | `string` | **Required** | Root entity type to query. Must match a valid entity type defined in the [data model](/powersheet/reference/data-model/domainmodeltypes) (e.g., `UserNeed`, `SystemRequirement`, `Hazard`). |
| `where` | `object` | `None` | Filter [predicates](/powersheet/reference/query-api/predicates) applied to query results. Supports property comparisons and composite AND/OR logic. |
| `expand` | `array` | `None` | [Expand clause](/powersheet/reference/query-api/expand-clause) specifying navigation properties to load inline. Supports nested expansion for multi-level relationships. |
| `orderBy` | `array` | `None` | Sorting clause with property paths and sort direction. Ascending is the default; append `desc` for descending order. |
EntityQuery does not support a `select` clause for projecting specific properties. All properties defined for the entity type in the data model are returned automatically.
***
## The `from` Clause
The `from` clause specifies the root entity type for the query. The value must exactly match an entity type name defined in the `domainModelTypes` section of the data model YAML. Entity type names use PascalCase.
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
```
The server resolves the `from` value against the metadata system to locate the entity type definition, including its mapped Polarion work item type, properties, and available navigation properties. If the entity type is not found in the metadata registry, the query fails with a validation error.
**Common entity types** (using the standard RTM example model):
| Entity Type | Polarion Type | Typical Use |
| ------------------- | -------------- | --------------------------- |
| `UserNeed` | `user_need` | Top-level requirements |
| `SystemRequirement` | `sys_req` | System-level requirements |
| `DesignRequirement` | `des_req` | Design-level requirements |
| `Hazard` | `hazard` | Risk analysis entities |
| `RiskControl` | `risk_control` | Risk mitigation measures |
| `Chapter` | `heading` | Document structure headings |
For the complete list of entity type properties and Polarion type mappings, see [Data Model Types](/powersheet/reference/data-model/domainmodeltypes) and [Polarion Type Mapping](/powersheet/reference/data-model/polarion-mapping).
***
## The `where` Clause
The `where` clause defines filter predicates that restrict the result set. Predicates are split during execution into two categories:
* **Lucene-compatible predicates** -- translated to Polarion Lucene queries and executed server-side for performance
* **In-memory post-filters** -- complex predicates that cannot be expressed in Lucene, applied after the initial fetch
This splitting is transparent to the query author. See [Predicates](/powersheet/reference/query-api/predicates) for the full predicate syntax and [Query Splitting](/powersheet/reference/query-api/query-splitting) for details on how predicates are categorized.
```yaml theme={null}
sources:
- id: active_requirements
query:
from: SystemRequirement
where:
status:
ne: "rejected"
```
**Known Limitation: Null Checks Not Functional**
Filtering entities by null presence (using `eq: null` or `ne: null` to find entities where a property is or is not null) is **not currently supported**. The null check predicate is not functional in the current release and should not be used in production sheet configurations. To filter on field presence, use an explicit value comparison (for example, `ne: ""` for non-empty strings) or apply the filter via a downstream post-processing step. This limitation will be addressed in a future release.
For composite filtering with AND/OR logic, see the [Predicates](/powersheet/reference/query-api/predicates) reference.
***
## The `expand` Clause
The `expand` clause specifies which navigation properties to load inline with the query results. Navigation properties represent [relationships](/powersheet/reference/data-model/relationships) between entity types defined in the data model. The expand syntax differs based on the relationship cardinality.
### Many-to-One (N:1) Expansion
For many-to-one relationships, the expand loads a single related entity. Uses the `direct` navigation property name from the relationship definition.
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: chapter
```
This loads the parent `Chapter` for each `UserNeed`. In the data model, the relationship defines `direct.name: chapter` on the many side.
### One-to-Many (1:N) Expansion
For one-to-many relationships (the reverse of N:1), the expand loads a collection of child entities. Uses the `back` navigation property name.
```yaml theme={null}
sources:
- id: chapters
query:
from: Chapter
expand:
- name: userNeeds
```
This loads all child `UserNeed` entities for each `Chapter`. In the sheet, these appear as expandable child rows creating a new hierarchy level.
### Many-to-Many (M:N) Expansion
Many-to-many relationships require a **two-level expand** that traverses through an association entity to reach the target entity.
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: systemRequirement
```
The first level (`systemRequirements`) navigates to the association entities. The second level (`systemRequirement`) navigates from each association to the actual target `SystemRequirement` entity. This two-level pattern is required because the data model represents M:N links through an intermediate association.
For complete expand syntax including nested multi-level expansion, see [Expand Clause](/powersheet/reference/query-api/expand-clause).
***
## The `orderBy` Clause
The `orderBy` clause defines the sort order for query results. Each item specifies a property path and an optional sort direction.
| Property | Type | Default | Description |
| -------------- | -------- | -------- | -------------------------------------------------------------------------------------------------------------------- |
| Property path | `string` | Required | Dot-notation path to the property to sort by (e.g., `title`, `severity`, `chapter.title`). |
| Sort direction | `string` | `asc` | Append `desc` after the property path for descending order. Ascending is the default when no direction is specified. |
```yaml theme={null}
sources:
- id: sorted_requirements
query:
from: SystemRequirement
orderBy:
- severity desc
- title
```
**Property path syntax** supports both direct properties and navigation paths using dot notation. The path is validated against the entity type metadata to ensure it references a valid property.
The `orderBy` clause in the source configuration maps to the `sortBy` property in the sheet configuration, which uses a slightly different format:
```yaml theme={null}
sortBy:
- id: severity
direction: desc
- id: title
direction: asc
```
**Sort Order Validation**
All property paths in the `orderBy` clause are validated against the entity type metadata during query construction. If a property path references a non-existent property, the query returns a validation error. Use property names exactly as defined in the data model.
## Query Execution Flow
The server API processes an EntityQuery through the following stages:
1. **Metadata resolution** -- The `from` clause is resolved against the metadata registry to identify the target entity type, its Polarion work item type mapping, and available properties.
2. **Security enforcement** -- The server verifies the current user has read permission for the entity type. If the entity type is not readable, the query fails immediately.
3. **Predicate splitting** -- The `where` clause predicates are analyzed and split into Lucene-compatible server queries and in-memory post-filters.
4. **Document pre-filtering** -- If document-level predicates exist in the `where` clause, documents are pre-resolved to narrow the work item query scope.
5. **Lucene query execution** -- Lucene-compatible predicates are translated and executed against Polarion to fetch matching work items.
6. **Post-filtering** -- In-memory filters are applied to the fetched results to handle predicates that cannot be expressed in Lucene.
7. **Constraint application** -- Data model constraints and project scoping rules are enforced on the result set.
8. **Navigation property expansion** -- Properties specified in the `expand` clause are loaded for each result entity, following the relationship paths defined in the data model.
9. **Sorting** -- Results are ordered per the `orderBy` clause.
10. **Result assembly** -- The final result set is returned with entity metadata.
***
## Query Result Structure
Each entity returned by an EntityQuery includes standard metadata fields alongside the data model properties:
| Field | Type | Description |
| ---------------- | ---------- | -------------------------------------------------------------------- |
| `$type` | `string` | Fully qualified entity type name from the metadata system. |
| `entityTypeName` | `string` | Data model entity type name (e.g., `UserNeed`, `SystemRequirement`). |
| `id` | `string` | Polarion work item ID. |
| `title` | `string` | Work item title. |
| `updated` | `datetime` | Last modification timestamp. |
| `project` | `object` | Project foreign key reference. |
Additional fields depend on the properties defined for the entity type in the data model. Custom fields, enum properties, and computed (server-rendered) properties are included when defined.
**Server-Rendered Properties**
Properties backed by Velocity templates are evaluated server-side during query execution. The Velocity context includes variables `item`, `tx`, `context`, and `pObject` for template evaluation. See [Velocity Templates](/powersheet/reference/server-rendering/velocity-templates) and [Context Variables](/powersheet/reference/server-rendering/context-variables).
***
## Primitive Field Type Mapping
When entity properties are returned in query results, Polarion custom field types are mapped to their runtime equivalents:
| Polarion Field Type | Runtime Type | Notes |
| ------------------- | ------------ | ------------------------ |
| `string` | `string` | Plain text values |
| `text` | `string` | Multi-line text |
| `richtext` | `string` | HTML-formatted rich text |
| `boolean` | `boolean` | `true` / `false` |
| `integer` | `number` | Whole numbers |
| `float` | `number` | Decimal numbers |
| `currency` | `number` | Currency values |
| `date` | `datetime` | Date values |
| `time` | `datetime` | Time values |
| `duration` | `string` | Duration representation |
***
## Enum Property Resolution
When the metadata system discovers enum properties on an entity type, Powersheet automatically creates data sources for loading the available enum options. This powers dropdown pickers in the sheet without manual source configuration.
The auto-generated enum source uses the following resolution pattern:
* **Source ID**: `system.enums.` (e.g., `system.enums.severity`)
* **Query construction**: Filters by `polarionProto`, `polarionType`, `projectId`, and `enumId` from the entity metadata
* **Display mapping**: Each enum option provides a display label and internal value for the picker
This process is triggered during metadata initialization and completes before any user queries execute.
***
## Complete YAML Example
A complete source configuration demonstrating all EntityQuery properties within a sheet configuration:
```yaml theme={null}
sources:
- id: rtm_matrix
query:
from: UserNeed
where:
status:
ne: "rejected"
orderBy:
- severity desc
- title
expand:
- name: chapter
- name: systemRequirements
expand:
- name: systemRequirement
expand:
- name: designRequirements
expand:
- name: designRequirement
columns:
title:
title: User Need
hasFocus: true
width: 250
severity:
title: Severity
width: 80
chapter:
title: Chapter
display: title
isReadOnly: true
list:
search:
- title
chapter.title:
title: Chapter Title
isReadOnly: true
systemRequirements.systemRequirement:
title: System Req
list:
search:
- objectId
- title
createNew: true
systemRequirements.systemRequirement.title:
title: SysReq Title
hasFocus: true
systemRequirements.systemRequirement.designRequirements.designRequirement:
title: Design Req
list:
search:
- objectId
- title
systemRequirements.systemRequirement.designRequirements.designRequirement.title:
title: DesReq Title
hasFocus: true
```
This configuration demonstrates:
* **Root query** with `from`, `where`, and `orderBy` on `UserNeed`
* **N:1 expansion** via `chapter` (direct navigation property)
* **M:N expansion** via `systemRequirements.systemRequirement` (two-level association traversal)
* **Deep nesting** continuing through `designRequirements.designRequirement` for a full traceability chain
* **Column bindings** using dot-notation matching the expansion path structure
* **Picker configuration** with `list.search` and `list.createNew` on reference columns
***
## Cardinality and Query Pattern Summary
| Cardinality | Data Model | Source Expand | Column Binding | Sheet Behavior |
| ----------- | ------------------------------------------------------------ | ------------------------------------------------------------- | -------------------------------------- | -------------------------------- |
| **N:1** | `cardinality: many-to-one`, `direct.name: chapter` | `- name: chapter` | `chapter`, `chapter.title` | Single-value reference picker |
| **1:N** | Reverse of N:1, `back.name: userNeeds` | `- name: userNeeds` | `userNeeds` | Child rows (new hierarchy level) |
| **M:N** | `cardinality: many-to-many`, `back.name: systemRequirements` | `- name: systemRequirements` then `- name: systemRequirement` | `systemRequirements.systemRequirement` | Multi-item reference picker |
***
## Related Pages
* [Predicates](/powersheet/reference/query-api/predicates) -- filter syntax for `where` clauses
* [Expand Clause](/powersheet/reference/query-api/expand-clause) -- detailed expand syntax and nesting rules
* [Query Context](/powersheet/reference/query-api/query-context) -- runtime parameter reference
* [Document Filtering](/powersheet/reference/query-api/document-filtering) -- document-scoped query patterns
* [Baseline and Revision Queries](/powersheet/reference/query-api/baseline-and-revision-queries) -- historical data queries
* [Data Model Types](/powersheet/reference/data-model/domainmodeltypes) -- entity type definitions
* [Relationships](/powersheet/reference/data-model/relationships) -- relationship and navigation property configuration
* [Sources](/powersheet/reference/sheet-config/sources) -- sheet source configuration referencing EntityQuery
# Expand Clause
Source: https://learn.nextedy.com/powersheet/reference/query-api/expand-clause
The expand clause in Nextedy POWERSHEET defines which related entities are loaded inline when querying data from Siemens Polarion ALM.
## Expand Configuration Properties
Each entry in the `sources[].expand` array accepts the following properties:
| Name | Type | Default | Description |
| ------------- | -------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name` | `string` | Required | Navigation property name from the [data model relationships](/powersheet/reference/data-model/relationships). Must match a `direct.name` or `back.name` value on the parent entity type. |
| `title` | `string` | None | Display title for the expanded entity group in the sheet header row. If omitted, the navigation property name is used. |
| `expand` | `array` | None | Nested expand definitions for multi-level hierarchies. Each entry follows the same schema recursively. |
| `query.where` | `object` | None | Subquery filter applied to this expand level only, independent of the current document. Supports the same operators as a root `query.where`, and [dynamic values](/powersheet/reference/sheet-config/dynamic-expressions) such as `() => context.parameters.`. See [Expand Subquery Filtering](#expand-subquery-filtering). |
**Required Property**
The `name` property is mandatory. An expand entry without `name` is invalid and will prevent the sheet from loading related data.
## Expansion Path Syntax
Expansion paths follow navigation properties defined in the data model. Each `name` value must correspond to a relationship property on the parent entity type.
### Single-Level Expansion
Load direct related entities of the root entity type:
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: chapter
```
This loads the `Chapter` entity associated with each `UserNeed` via the many-to-one `chapter` navigation property.
### Multi-Level Expansion
Load deeper levels by nesting `expand` arrays inside each other:
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: systemRequirement
expand:
- name: designRequirements
expand:
- name: designRequirement
```
Each nested `expand` resolves relative to its parent entity type.
### Parallel Branches
A single entity type can expand multiple navigation properties at the same level. List multiple entries in the same `expand` array:
```yaml theme={null}
expand:
- name: systemRequirements
expand:
- name: systemRequirement
- name: chapter
```
This loads both `SystemRequirement` entities (via the association) and the parent `Chapter` alongside each `UserNeed`.
## Expand Subquery Filtering
An expand node may carry a `query.where` that filters that level by its own attributes, independently of the current document. The `where` is applied to the level it is attached to; ancestor rows are not affected.
```yaml theme={null}
sources:
- id: chapters
query:
from: Chapter
expand:
- name: requirements
expand:
- name: requirement
query:
where:
targetSystem: iOS
```
* A `where` can be attached to any expand node, whether the navigation is scalar (N:1) or a collection (1:N, M:N).
* Multiple keys in a single `where` are combined with AND.
* A value may be a [dynamic expression](/powersheet/reference/sheet-config/dynamic-expressions). When it reads a URL parameter that has no value, the condition is dropped and the level expands unfiltered -- see [URL Parameters](/powersheet/reference/sheet-config/url-parameters).
A subquery `where` on an expand level also constrains the reference picker for that level: only candidates satisfying the same filter (projected onto the picked entity along the binding path) are offered, so a picked item will not vanish on the next load.
**New rows inherit the subquery filter**
Creating an item at a filtered expand level pre-fills the fields the subquery pins by **equality**, so the new row satisfies the filter it was created under and does not disappear on the next load. Only equality (`type: Electrical` or `type: { eq: … }`) seeds a default -- fuzzy operators (`contains`, `in`, `ne`, `or`) do not, since they do not pin a single value. An explicit [`entityFactory`](/powersheet/reference/sheet-config/sources) default always wins over a filter-derived one, and a subquery scoped to the current document also creates the new item in that document.
## Cardinality and Expansion Patterns
The relationship cardinality defined in the data model determines the expand syntax and the resulting UI behavior in the sheet.
### Many-to-One (N:1)
Each child entity references exactly one parent. The navigation property is scalar (singular name).
**Data model relationship:**
```yaml theme={null}
relationships:
- from: UserNeed
to: Chapter
cardinality: many-to-one
storage: linkedWorkItems
linkRole: parent
direct:
name: chapter
back:
name: userNeeds
```
**Source expand:**
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: chapter
```
**Column binding:**
```yaml theme={null}
columns:
title:
title: Title
hasFocus: true
chapter:
title: Chapter
display: title
list:
search:
- title
chapter.title:
title: Chapter Title
isReadOnly: true
```
* `chapter` renders as a single-value reference picker (scalar navigation property).
* `chapter.title` renders the referenced `Chapter` entity's title as a read-only column.
### One-to-Many (1:N)
A parent entity has a collection of children. This is the reverse side of a many-to-one relationship. The navigation property is plural (collection name).
**Source expand:**
```yaml theme={null}
sources:
- id: chapters
query:
from: Chapter
expand:
- name: userNeeds
```
**Column binding:**
```yaml theme={null}
columns:
title:
title: Chapter
hasFocus: true
userNeeds:
title: User Need
hasFocus: true
```
* `userNeeds` expands into child rows in the sheet, creating a new hierarchical level.
* No dot-notation is needed for the expand itself; the expand directly opens the child level.
### Many-to-Many (M:N)
Many-to-many relationships use an **association entity** between the two types. The expansion requires two nested levels: first to the association collection, then through to the target entity.
**Verify in application**
Many-to-many expansion patterns use an implicit association entity generated by the data model. The exact association entity structure depends on how the relationship is defined. Consult a domain expert when configuring complex M:N expansions for the first time.
**Data model relationship:**
```yaml theme={null}
relationships:
- from: SystemRequirement
to: UserNeed
cardinality: many-to-many
storage: linkedWorkItems
linkRole: decomposes
direct:
name: userNeeds
back:
name: systemRequirements
```
**Source expand (two-level):**
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: systemRequirement
```
**Column binding:**
```yaml theme={null}
columns:
title:
title: Title
hasFocus: true
systemRequirements.systemRequirement:
title: System Requirement
list:
search:
- objectId
- title
createNew: true
systemRequirements.systemRequirement.title:
title: SysReq Title
hasFocus: true
```
* The source expand uses two levels: `systemRequirements` (association collection) followed by `systemRequirement` (target entity).
* Column binding uses dot-notation matching the expand path: `systemRequirements.systemRequirement`.
* The column renders as a multi-item reference picker.
**Bidirectional Navigation**
Many-to-many expansions are bidirectional. The same relationship can be navigated from either end:
* `UserNeed` expands `systemRequirements.systemRequirement` to reach `SystemRequirement`
* `SystemRequirement` expands `userNeeds.userNeed` to reach `UserNeed`
The navigation property names come from the `direct.name` and `back.name` values in the data model relationship definition.
## Cardinality Summary
| Cardinality | Model Definition | Source Expand | Column Binding | UI Behavior |
| ----------- | ------------------------------------------------------------ | -------------------------------------------------------------------- | -------------------------------------- | ----------------------------- |
| **N:1** | `cardinality: many-to-one`, `direct.name: chapter` | `- name: chapter` | `chapter`, `chapter.title` | Single-value reference picker |
| **1:N** | Reverse of N:1, `back.name: userNeeds` | `- name: userNeeds` | `userNeeds` | Child rows (new sheet level) |
| **M:N** | `cardinality: many-to-many`, `back.name: systemRequirements` | `- name: systemRequirements` then nested `- name: systemRequirement` | `systemRequirements.systemRequirement` | Multi-item reference picker |
## Expand and Column Binding Alignment
Every column with a navigation [binding path](/powersheet/reference/sheet-config/binding-syntax) must have a corresponding expansion in the source configuration. The expand hierarchy must match the column binding path structure.
| Column Binding Path | Required Expand |
| -------------------------------------------- | ------------------------------------------------------------------------------- |
| `title` | None (direct property on root entity) |
| `chapter` | `expand: [{ name: chapter }]` |
| `chapter.title` | `expand: [{ name: chapter }]` |
| `systemRequirements.systemRequirement` | `expand: [{ name: systemRequirements, expand: [{ name: systemRequirement }] }]` |
| `systemRequirements.systemRequirement.title` | Same as above |
**Missing Expand Causes Empty Columns**
If a column references a navigation property that is not expanded in the source configuration, the column cells will remain empty. The related entities are simply not loaded and no error is shown.
## Query Execution
The expand clause is converted to dot-notation strings for query execution. Nested expand arrays are recursively flattened:
| YAML Expand | Dot-Notation Query |
| -------------------------------------------------------------------- | -------------------------------------- |
| `- name: chapter` | `chapter` |
| `- name: systemRequirements` with nested `- name: systemRequirement` | `systemRequirements.systemRequirement` |
This enables loading all related entities in a single server request rather than multiple round-trips. The query engine pre-fetches all expanded entities so the data is available when the sheet renders.
### Validation
Expand property paths are validated against the data model metadata at query time. If a `name` references a navigation property that does not exist on the entity type, the query fails with a validation error.
### Document Context
When a source defines `constraints.applyCurrentDocumentTo`, the expand clause operates within the document scope. Expanded entities are filtered to those associated with the current document context. See [Document Filtering](/powersheet/reference/query-api/document-filtering) for details.
## Performance Considerations
| Factor | Impact | Recommendation |
| ---------------------- | ------------------------------------------------------ | ----------------------------------------------------- |
| Expand depth | Each level adds query overhead | Keep to 3-4 levels for responsive loading |
| Entity count per level | Large collections at each level multiply data volume | Use predicates to filter root entities |
| Parallel branches | Multiple expands at the same level fetch independently | Combine into views to show only needed branches |
| M:N associations | Association entities add an extra level | Account for the association level when planning depth |
**Verify in application**
Maximum supported expand depth and performance characteristics depend on the Polarion server configuration and the number of entities at each level.
## Complete YAML Example
A full requirements traceability matrix (RTM) configuration showing multi-level and parallel expand paths:
```yaml theme={null}
sources:
- id: rtm-traceability
title: Full RTM View
query:
from: UserNeed
constraints:
applyCurrentDocumentTo: UserNeed
expand:
- name: chapter
title: Chapter
- name: systemRequirements
title: System Requirements
expand:
- name: systemRequirement
expand:
- name: designRequirements
title: Design Requirements
expand:
- name: designRequirement
columns:
title:
title: User Need
width: 300
hasFocus: true
chapter:
title: Chapter
display: title
list:
search:
- title
chapter.title:
title: Chapter Title
isReadOnly: true
systemRequirements.systemRequirement:
title: System Requirement
list:
search:
- objectId
- title
createNew: true
systemRequirements.systemRequirement.title:
title: SysReq Title
width: 250
systemRequirements.systemRequirement.designRequirements.designRequirement:
title: Design Requirement
list:
search:
- objectId
- title
systemRequirements.systemRequirement.designRequirements.designRequirement.title:
title: DesReq Title
width: 250
```
This configuration:
1. Queries `UserNeed` entities scoped to the current document.
2. Expands the parent `Chapter` (N:1) for each user need.
3. Expands `SystemRequirement` entities through the M:N association (`systemRequirements.systemRequirement`).
4. Further expands `DesignRequirement` entities through another M:N association at the next level.
5. Binds columns to display titles at each level with appropriate pickers.
## Related Pages
* [Server-Side Filtering](/powersheet/concepts/server-side-filtering) -- the concept behind expand subquery `where`: filtering each level on the server so only the matching slice loads
* [EntityQuery](/powersheet/reference/query-api/entity-query) -- top-level query structure containing the expand clause
* [Sources](/powersheet/reference/sheet-config/sources) -- source configuration including expand, constraints, and query settings
* [Binding Syntax](/powersheet/reference/sheet-config/binding-syntax) -- column binding paths that must align with expand paths
* [Relationships](/powersheet/reference/data-model/relationships) -- data model relationships defining available navigation properties
* [Navigation Directions](/powersheet/reference/data-model/navigation-directions) -- direct and back navigation direction semantics
* [Cardinality](/powersheet/reference/data-model/cardinality) -- relationship cardinality rules governing expand patterns
* [Document Filtering](/powersheet/reference/query-api/document-filtering) -- how document constraints interact with expanded data
***
# Query API Reference
Source: https://learn.nextedy.com/powersheet/reference/query-api/index
The Nextedy POWERSHEET query API controls how data is retrieved from Siemens Polarion ALM.
Top-level query object that combines a resource type, predicates, expand clauses, and ordering into a single data request against the server API.
Filter conditions for the `where` clause including equality, comparison, null checks, and composite AND/OR logic with support for property paths.
Load related entities inline via expansion paths, supporting one-to-many, many-to-one, and many-to-many relationships through navigation properties.
Scope query results to items within a specific Polarion LiveDoc using `applyCurrentDocumentTo` constraints in the data model.
Query historical data at specific project baselines or revisions to view the state of entities at a point in time.
**Configuration vs. API**
Most query behavior is configured declaratively through the `sources` section of your sheet configuration YAML. You rarely need to write queries directly -- Powersheet translates your YAML sources into the query structures described here. See [Sources](/powersheet/reference/sheet-config/sources) for the configuration reference.
## How Queries Flow
```
┌─────────────────────────────────────┐
│ Sheet Configuration │
│ sources: │
│ - type: UserNeed │
│ expand: │
│ - systemRequirements │
│ where: │
│ status: { ne: deleted } │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ EntityQuery │
│ from: UserNeed │
│ where: Predicates │
│ expand: Expand Clause │
│ context: Query Context │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Server API (Lucene) │
│ Translates predicates to Lucene │
│ Resolves expansion paths │
│ Applies project + document scope │
└──────────────┬──────────────────────┘
│
▼
┌─────────────────────────────────────┐
│ Polarion Data Service │
│ Executes Lucene search │
│ Returns work items + linked items │
└─────────────────────────────────────┘
```
The query engine translates your YAML `sources` configuration into `EntityQuery` objects. Predicates from the `where` clause are split into Lucene-compatible server queries and in-memory post-filters where needed. Expansion paths resolve navigation properties defined in your data model to load related entities in a single request.
## Related References
| Topic | Where to look |
| ----------------------------------------- | -------------------------------------------------------------------------- |
| Configuring data sources in YAML | [Sources](/powersheet/reference/sheet-config/sources) |
| Data model entity types and relationships | [Data Model Reference](/powersheet/reference/data-model/index) |
| Column binding paths that drive queries | [Binding Syntax](/powersheet/reference/sheet-config/binding-syntax) |
| Server-rendered computed properties | [Server Rendering Reference](/powersheet/reference/server-rendering/index) |
# Predicates
Source: https://learn.nextedy.com/powersheet/reference/query-api/predicates
Predicates in Nextedy POWERSHEET define filter conditions within the `where` clause of an [EntityQuery](entity-query.md).
## Predicate Types
| Type | Description | Operators |
| --------------------- | --------------------------------------------------------------- | ---------------------------------------------- |
| Binary predicate | Compares a single property value against a constant | `eq`, `ne`, `gt`, `ge`, `lt`, `le`, `contains` |
| Composite predicate | Combines multiple predicates with logical AND or OR | `and`, `or` |
| Collection quantifier | Evaluates a predicate across multi-valued navigation properties | `any`, `all` |
***
## Binary Predicates
A binary predicate compares one entity property against a value using a comparison operator.
### Syntax
Full form:
```yaml theme={null}
propertyName:
operator: "value"
```
Shorthand equality form (equivalent to `eq`):
```yaml theme={null}
propertyName: "value"
```
### Comparison Operators
| Operator | Alias | Supported Types | Description |
| ---------- | ----- | ------------------------------------ | --------------------------------------------------------------------------------------------- |
| `eq` | `==` | String, number, boolean | Exact equality. Case-sensitive for strings. |
| `ne` | `!=` | String, number, boolean | Inequality. |
| `gt` | `>` | Number (Integer, Double, Long), date | Greater than. |
| `ge` | `>=` | Number, date | Greater than or equal. |
| `lt` | `<` | Number, date | Less than. |
| `le` | `<=` | Number, date | Less than or equal. |
| `contains` | -- | String | Case-sensitive whole-word (token) match -- matches complete tokens, not arbitrary substrings. |
**Numeric Types Only**
The `gt`, `ge`, `lt`, and `le` operators work with Integer, Double, and Long values. They are not applicable to string or boolean properties.
### Examples
**Equality** -- exact match on a property value:
```yaml theme={null}
title:
eq: "System Requirement 1"
```
Shorthand form produces the same result:
```yaml theme={null}
title: "System Requirement 1"
```
Both translate to the Lucene query `title:"System Requirement 1"`.
**Inequality** -- exclude a specific value:
```yaml theme={null}
status:
ne: "rejected"
```
**Numeric comparison** -- range filtering on numeric properties:
```yaml theme={null}
priority:
gt: 3
```
**Inclusive upper bound**:
```yaml theme={null}
severity:
le: 5
```
**String contains** -- whole-word (token) search, case-sensitive. It matches complete tokens within the field, not arbitrary substrings:
```yaml theme={null}
title:
contains: "safety"
```
***
## Null Predicates
Null checks test whether a property has a value or is empty. Use `eq` or `ne` with a `null` value.
**Known Limitation**
Null predicates (`eq: null` and `ne: null`) are currently non-functional in this release. The syntax below describes the intended behavior, but predicates that compare against a `null` value will not produce correct query results until this is resolved. Avoid relying on null predicates in production sheet configurations. Track this limitation through your support channel for status updates.
**Property has no value (intended behavior):**
```yaml theme={null}
title:
eq: null
```
**Property has a value (intended behavior):**
```yaml theme={null}
title:
ne: null
```
| Expression | Lucene Translation (intended) | Meaning |
| -------------------- | ----------------------------- | -------------------- |
| `prop: { eq: null }` | `NOT HAS_VALUE:prop` | Property is empty |
| `prop: { ne: null }` | `HAS_VALUE:prop` | Property has a value |
**Lucene Translation**
The `HAS_VALUE` pseudo-field is a Polarion-specific Lucene construct for checking property existence. When the null predicate feature is operational, the server API translates null predicates into this syntax automatically.
***
## Composite Predicates
Composite predicates combine multiple sub-predicates using logical AND or OR operators.
### AND Predicate
All sub-predicates must match. Wrap conditions in an `and` array:
```yaml theme={null}
and:
- status:
eq: "approved"
- priority:
gt: 2
```
Translates to Lucene: `(status:"approved") AND (priority:{2 TO *})`
### OR Predicate
Any sub-predicate may match. Wrap conditions in an `or` array:
```yaml theme={null}
or:
- status: "draft"
- status: "in_review"
```
Translates to Lucene: `(status:"draft") OR (status:"in_review")`
### Nested Composites
AND and OR predicates can be nested to build complex filtering logic:
```yaml theme={null}
and:
- priority:
ge: 3
- or:
- status: "approved"
- status: "in_review"
```
Resulting Lucene: `(priority:[3 TO *]) AND ((status:"approved") OR (status:"in_review"))`
**Operator Precedence**
AND binds more tightly than OR. Each operand in composite predicates is parenthesized during Lucene translation to maintain correct evaluation order. Use explicit nesting when combining AND and OR to ensure predictable results.
***
## Collection Quantifiers
Collection quantifiers evaluate predicates against multi-valued navigation properties (related entity collections).
| Quantifier | Alias | Description |
| ---------- | ------- | ------------------------------------------------------------------------- |
| `any` | `some` | Returns `true` if **any** element in the collection matches the condition |
| `all` | `every` | Returns `true` if **all** elements in the collection match the condition |
`any` uses short-circuit evaluation -- it stops at the first match for performance.
`all` returns `false` at the first non-match. It is used in validation rules and completeness checks.
**Verify in application**
Collection quantifiers are used for filtering across related entity collections. The exact query syntax for `any` and `all` with nested property conditions depends on the entity type metadata and the relationship configuration in the data model.
***
## ObjectId Predicates
Query a specific entity by its Polarion work item ID:
```yaml theme={null}
objectId: "UN-001"
```
With project prefix:
```yaml theme={null}
objectId: "myProject/UN-001"
```
The project prefix format `project/id` expands to a compound query: `project.id:"myProject" AND id:"UN-001"`.
***
## Data Property Predicates
Predicates on entity data properties are validated against the entity type schema before execution. Only scalar (non-navigation) properties are supported in direct predicates. The server API processes the `where` clause by:
1. Extracting all property names from the predicate
2. Matching each property against the entity type metadata
3. Rejecting predicates that reference unknown or navigation properties
4. Combining validated predicates with AND logic
**Property Validation**
If a predicate references a property that does not exist in the entity type metadata, the query will fail with a validation error. Always use property names exactly as defined in the data model.
For navigation property filtering (document or project scoping), use the dedicated constraint system. See [Document Filtering](/powersheet/reference/query-api/document-filtering) and [Query Context](/powersheet/reference/query-api/query-context).
***
## Document and Project Predicates
Document and project predicates filter by navigation properties and are extracted separately from data property predicates.
**Document filtering:**
```yaml theme={null}
document:
moduleName: "Requirements"
moduleFolder: "Specifications"
```
**Project filtering:**
```yaml theme={null}
project:
id: "myProject"
```
**Single-Project Queries Only**
Cross-project queries are not supported. All queries execute within a single project scope. The `project` predicate is used to specify which project to query, not to query across multiple projects simultaneously.
When the project predicate contains only an `id` field, the server API uses a simplified Lucene query (`project.id:value`). More complex project predicates undergo full predicate evaluation against the Project entity type metadata.
***
## Where Clause Merging
When multiple filter conditions are combined (for example, from user-applied filters and sheet configuration constraints), Powersheet merges them using these rules:
| Scenario | Merge Behavior |
| ------------------ | ------------------------------------------ |
| Two AND predicates | Arrays are concatenated |
| Two OR predicates | Arrays are concatenated |
| AND + OR | The OR predicate is wrapped inside the AND |
| Property conflicts | The second value overrides the first |
| Empty/undefined | Ignored silently |
***
## Lucene Translation Summary
Predicates are translated to Polarion Lucene query syntax before execution against the data store.
| Predicate | Lucene Output |
| -------------------- | ------------------------------------------------------------------------- |
| `name: "John"` | `name:"John"` |
| `count: 5` | `count:5` |
| `prop: { ne: "X" }` | `NOT prop:"X"` |
| `prop: { gt: 3 }` | `prop:{3 TO *}` |
| `prop: { ge: 3 }` | `prop:[3 TO *]` |
| `prop: { lt: 10 }` | `prop:{* TO 10}` |
| `prop: { le: 10 }` | `prop:[* TO 10]` |
| `prop: { eq: null }` | `NOT HAS_VALUE:prop` (intended; see [known limitation](#null-predicates)) |
| `prop: { ne: null }` | `HAS_VALUE:prop` (intended; see [known limitation](#null-predicates)) |
| `and: [...]` | `(...) AND (...)` |
| `or: [...]` | `(...) OR (...)` |
***
## Complete YAML Example
A source configuration with predicates applied through the `where` clause:
```yaml theme={null}
sources:
- id: filtered-requirements
title: Active Requirements
model: rtm
query:
from: UserNeed
where:
and:
- title:
contains: "Safety"
- or:
- status: approved
- status: in_review
- priority:
ge: 3
expand:
- name: systemRequirements
constraints:
applyCurrentDocumentTo: UserNeed
```
This query:
* Targets `UserNeed` entities
* Requires `title` to contain the whole word `Safety` (token match, not an arbitrary substring)
* Limits results to `approved` or `in_review` status
* Requires priority of 3 or higher
* Expands the `systemRequirements` navigation property
* Scopes results to the current document
***
## Predicate Type Compatibility
The following table summarizes which Polarion custom field types are compatible with each operator:
| Field Type | `eq` / `ne` | `gt` / `ge` / `lt` / `le` | `contains` | Null checks |
| ---------- | :---------: | :-----------------------: | :--------: | :---------: |
| `string` | ✅ | -- | ✅ | ✅ |
| `integer` | ✅ | ✅ | -- | ✅ |
| `float` | ✅ | ✅ | -- | ✅ |
| `boolean` | ✅ | -- | -- | ✅ |
| `date` | ✅ | ✅ | -- | ✅ |
| `richtext` | ✅ | -- | ✅ | ✅ |
| `currency` | ✅ | ✅ | -- | ✅ |
| `duration` | ✅ | ✅ | -- | ✅ |
***
## Related Pages
* [EntityQuery](/powersheet/reference/query-api/entity-query) -- top-level query structure with `from`, `where`, `expand`, and `orderBy`
* [Expand Clause](/powersheet/reference/query-api/expand-clause) -- loading related entities inline
* [Query Context](/powersheet/reference/query-api/query-context) -- runtime parameters for query execution
* [Document Filtering](/powersheet/reference/query-api/document-filtering) -- scoping queries to specific documents
* [Binding Syntax](/powersheet/reference/sheet-config/binding-syntax) -- property path syntax used in predicate property names
* [Sources](/powersheet/reference/sheet-config/sources) -- configuring data sources that use predicates
***
# Query Context
Source: https://learn.nextedy.com/powersheet/reference/query-api/query-context
The query context in Nextedy POWERSHEET is the runtime object that dynamic expressions and constraints resolve against when queries execute.
## Context Object Structure
The context object is a hierarchical namespace that Powersheet populates at runtime. Different properties become available depending on where the expression is evaluated.
```
context
+-- parameters Configuration-supplied parameters
| +-- model Dynamic data model ID (e.g. context.parameters.model)
+-- user Current logged-in user
| +-- id, name
+-- sources All configured data source definitions
+-- document Current document information
| +-- title, type, id, moduleName, moduleFolder, component
+-- tool Current tool information
| +-- type
+-- entity Current entity (available in per-cell contexts)
| +-- {propertyName} e.g. context.entity.severity
+-- source Parent/source entity -- the level navigated from
| +-- type, {propertyName} e.g. context.source.type, context.source.document.component
+-- row The whole row across every navigation level
| +-- entities[] e.g. context.row.entities[0]
+-- value Current cell's display value
+-- item Deprecated alias of context.entity
```
### Context Properties Reference
| Property | Type | Description |
| ------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------- |
| `context.parameters` | `object` | Configuration-injected parameters surfaced to the runtime |
| `context.parameters.model` | `string` | Dynamic data model identifier used to select an RTM model at runtime |
| `context.user` | `object` | Current authenticated Polarion user |
| `context.user.id` | `string` | Polarion user ID |
| `context.user.name` | `string` | Display name of the current user |
| `context.sources` | `object` | All configured data source definitions from the sheet configuration |
| `context.document` | `object` | Current Polarion LiveDoc document metadata |
| `context.document.title` | `string` | Document title |
| `context.document.type` | `string` | Document type identifier |
| `context.document.id` | `string` | Full document path in `folder/name` format |
| `context.document.moduleName` | `string` | Document module name |
| `context.document.moduleFolder` | `string` | Document folder path |
| `context.document.component` | `string` | Document component (e.g., `"Braking"`) |
| `context.tool` | `object` | Current tool information |
| `context.tool.type` | `string` | Tool type identifier |
| `context.entity` | `object` | Current row entity with all properties accessible by name |
| `context.entity.{propertyName}` | `varies` | Any property of the current entity (e.g., `context.entity.severity`, `context.entity.title`) |
| `context.source` | `object` | Parent/source entity -- the level the current one was navigated from |
| `context.source.type` | `string` | Parent entity's work item type (e.g., `"systemRequirement"`) |
| `context.row` | `object` | The whole row, as `context.row.entities[]` across every navigation level |
| `context.value` | `varies` | Current cell's resolved display value. A JSON object or array is decoded; any other string is passed through unchanged |
| `context.item` | `object` | **Deprecated** alias of `context.entity` in cell expressions |
## Two Expression Notations
Powersheet uses two distinct notations for dynamic expressions, each tied to a specific configuration context.
| Notation | Syntax | Used In |
| ---------------------- | ------------------------ | ------------------------------------------------------------------------ |
| **Context expression** | `$context.property.path` | Data model configuration (constraints) |
| **Dynamic value** | `() => expression` | Sheet configuration (`where`, `value`, `render`, `formatter`, `display`) |
**Rule of Thumb**
If you are editing a **data model** YAML file (`domainModelTypes`, `relationships`), use `$context`. If you are editing a **sheet configuration** YAML file (`sources`, `columns`, `formatters`), use `() =>`.
### Context Expression (`$context`)
Context expressions use dot-notation to access properties from the runtime context. They are used exclusively in data model constraint definitions. No JavaScript logic is supported --- only direct property access.
**Where it is used:**
* `domainModelTypes.*.constraints` --- entity type constraints
* `relationships.*.direct.constraints` / `relationships.*.back.constraints` --- relationship constraints
**Available `$context` paths:**
| Path | Description | Example Value |
| --------------------------------------- | ------------------------------------ | ----------------------------------- |
| `$context.source.type` | Source entity's work item type | `"sys_req"` |
| `$context.source.document.id` | Source entity's document ID | `"Requirements/SRS"` |
| `$context.source.document.moduleName` | Source entity's document module name | `"UserNeedSpecification"` |
| `$context.source.document.moduleFolder` | Source entity's document folder | `"Requirements"` |
| `$context.source.document.component` | Source entity's document component | `"Braking"` |
| `$context.source.document.type` | Source entity's document type | `"systemRequirementsSpecification"` |
| `$context.source.document.title` | Source entity's document title | `"System Requirements"` |
**Per-Row Evaluation**
Dynamic constraints with `$context` are evaluated **per-row**. Different rows can produce different constraint values depending on their source entity's properties.
### Dynamic Value (`() => expression`)
Dynamic values use JavaScript arrow function syntax and are evaluated in sheet configuration contexts. They receive the `context` object and offer full JavaScript expressiveness for computing values, filtering data, and rendering content at runtime.
**Where it is used:**
| Sheet Configuration Property | Purpose |
| ---------------------------- | --------------------------------------------------------------------------------------- |
| `sources.query.where` | Filter data with dynamic predicates |
| `sources.entityFactory` | Set initial values for new items |
| `columns.*.value` | Compute a column's content from other properties (`formula` is the deprecated spelling) |
| `columns.*.render` | Custom HTML rendering for cells |
| `columns.*.display` | Override display value for navigation properties |
| `renderers.*` | Named renderer definitions |
| `formatters.*.expression` | Conditional formatting expressions |
## Context Availability Reference
Not all context properties are available in every expression location. The following reference shows which properties are accessible where:
| Usage Location | `.user` | `.sources` | `.document` | `.entity` | `.value` | `.source` | `.row` |
| ---------------------------- | ------- | ---------- | ----------- | --------- | -------- | --------- | ------ |
| `where` | ✅ | ✅ | ✅ | --- | --- | --- | --- |
| `entityFactory` | ✅ | ✅ | --- | --- | --- | ✅ | --- |
| `value` (bound column) | ✅ | ✅ | --- | ✅ | --- | --- | --- |
| `value` (unbound `$` column) | ✅ | ✅ | --- | ✅ | --- | ✅ | ✅ |
| `render` / `renderers` | --- | --- | --- | ✅ | ✅ | --- | --- |
| `formatter` | --- | --- | ✅ | ✅ | ✅ | --- | --- |
| `display` | --- | --- | --- | ✅ | ✅ | ✅ | --- |
`context.item` is deprecated because it's ambiguous -- in some cell expressions it's the entity, in others the whole row. Use `context.entity` or `context.row` instead; each always means exactly one thing. `context.value` is the value already in the cell, so it is `undefined` inside a `value` expression.
**Accessing Unavailable Properties**
Referencing a context property that is not available in the current location returns `undefined`. This does not produce an error but may cause unexpected behavior in your expressions. Always consult the table above.
## Document Context
Powersheet automatically provides document context information to queries and expressions. When a sheet is embedded in a Polarion LiveDoc, the `context.document` properties are populated from the hosting document. The two most commonly used properties in dynamic `where` clauses are `context.document.moduleName` and `context.document.moduleFolder`, which identify the hosting document by name and folder path.
### Document Scoping in Constraints
The `applyCurrentDocumentTo` constraint property controls whether queries are automatically filtered to the current document:
```yaml theme={null}
sources:
- id: requirements
model: rtm
query:
from: UserNeed
constraints:
applyCurrentDocumentTo: UserNeed
```
When `applyCurrentDocumentTo` matches the query's `from` entity type, the query engine injects predicates for `document.moduleFolder` and `document.moduleName` to restrict results to items within the current document.
### Document ID in Dynamic Expressions
The document ID is available as `context.document.id` in dynamic value expressions and as a query parameter for server-side resolution:
```yaml theme={null}
sources:
- id: scoped-items
query:
from: SystemRequirement
where:
documentId:
"==": "() => context.document.id"
```
For details on document constraint variants, see [Document Filtering](/powersheet/reference/query-api/document-filtering).
## Project Scoping
All queries executed through Powersheet are automatically scoped to the current Polarion project. The query engine adds a `project.id` filter to every Lucene query, ensuring results only include entities from the active project. This scoping is applied transparently and does not require explicit configuration.
## Dynamic Value Examples
### Filtering by Current Document (Module Name)
The most common dynamic `where` clause restricts a query to items in the hosting LiveDoc. Use `context.document.moduleName` to match the document by name:
```yaml theme={null}
sources:
- id: in-document
query:
from: SystemRequirement
where:
moduleName:
"==": "() => context.document.moduleName"
```
For a more precise match that also pins the folder path, combine `moduleName` with `moduleFolder`:
```yaml theme={null}
where:
moduleName:
"==": "() => context.document.moduleName"
moduleFolder:
"==": "() => context.document.moduleFolder"
```
### Using `column.display` for Document and Chapter References
The `column.display` option is the standard way to control how a navigation property is rendered in a cell. For document references, `display: titleOrName` renders the document's title when available and falls back to the module name:
```yaml theme={null}
columns:
systemRequirement.document:
display: titleOrName
```
For chapter references, `display: title` renders the chapter heading text:
```yaml theme={null}
columns:
systemRequirement.chapter:
display: title
```
These named display modes are preferred over dynamic expressions whenever a column simply needs a standard label for a linked entity.
### Filtering by Date
Dynamic date calculations use JavaScript date functions. The resulting value must match the data type format --- for dates, use `.toISOString()`:
```yaml theme={null}
sources:
- id: upcoming
query:
from: Task
where:
DueDate:
">": "() => new Date().toISOString()"
```
### Setting Initial Values for New Entities
The `entityFactory` property sets default values when creating new work items. The factory re-evaluates dynamically based on the parent entity, so context-sensitive defaults are typically derived from `context.source`:
```yaml theme={null}
sources:
- id: verification
entityFactory:
title: '() => context.source.type + "_VerificationTestCase"'
```
Here, the new test case title is composed from the parent entity's work item type, so creating a verification case under different sources produces different default titles.
### Computed Column Values
The `value` property computes a column's content from other properties on the current entity:
```yaml theme={null}
columns:
total:
value: "() => context.entity.count * context.entity.rate"
```
Prefix the binding key with `$` to compute a value that is displayed but never stored. Such a column is unbound, so declare its result type with `valueType`:
```yaml theme={null}
columns:
$riskScore:
title: Risk Score
value: "() => context.entity.Probability * context.entity.Severity"
valueType: number
```
**A bound `value` persists data.**
On a column bound to a real property, `value` writes the computed result back to the data source. Use `render` if you only need to change how an existing value is displayed; use a `$`-prefixed key if the result should never be stored at all. See [Add a Computed Column](/powersheet/guides/sheet-configuration/add-computed-column).
### Custom Cell Rendering
The `render` property and named `renderers` produce custom HTML output:
```yaml theme={null}
renderers:
linkedItems: "() => context.value.map((item) => `${item.name} `).join(', ')"
```
### Display Override for Navigation Properties
When the standard `display: titleOrName` / `display: title` shorthands are not sufficient, the `display` property accepts a dynamic expression that overrides what is shown for a linked entity column:
```yaml theme={null}
columns:
systemRequirement.document:
display: "() => context.document.title"
```
### Conditional Formatting
Formatter expressions use a simplified syntax without the `() =>` prefix. The expression is evaluated as a boolean condition:
```yaml theme={null}
formatters:
criticalHighlight:
expression: "context.entity.Probability <= 99"
style: warningStyle
```
**Formatter Syntax Difference**
Formatter expressions do **not** start with `() =>`. They are evaluated directly as boolean conditions against the context object.
## Context Expression Examples (Data Model)
### Filter by Source Document Component
Restrict linked items to the same document component as the source entity:
```yaml theme={null}
relationships:
- from: DesignRequirement
to: SystemRequirement
back:
name: designRequirements
constraints:
load:
document:
component: $context.source.document.component
```
When viewing a `SystemRequirement` from the "Braking" component, only `DesignRequirement` items from "Braking" documents are loaded.
### Filter by Source Document Identity
Restrict to the exact same document as the source entity:
```yaml theme={null}
constraints:
load:
document:
moduleName: $context.source.document.moduleName
moduleFolder: $context.source.document.moduleFolder
```
### Filter by Source Document Type
Restrict picker results to documents of the same type as the source entity's document:
```yaml theme={null}
constraints:
pick:
document:
type: $context.source.document.type
```
## Quick Reference
| Goal | Notation | Example |
| ----------------------------------------- | ---------- | ---------------------------------------------------------------- |
| Filter relationship by source document | `$context` | `component: $context.source.document.component` |
| Filter query by current document | `() =>` | `"==": "() => context.document.moduleName"` |
| Compute a column and store the result | `() =>` | `value: "() => context.entity.count * context.entity.rate"` |
| Compute a column without storing anything | `() =>` | `$total:` with `value: "() => …"` and `valueType: number` |
| Render custom HTML in a cell | `() =>` | `render: "() => '' + context.value + ' '"` |
| Display label for a linked entity | shorthand | `display: titleOrName` |
| Set default value for new items | `() =>` | `entityFactory: { title: "() => context.source.type + '_VTC'" }` |
| Conditionally style a cell | expression | `expression: "context.entity.Risk > 50"` |
## Related Pages
* [EntityQuery](/powersheet/reference/query-api/entity-query) --- query construction and execution
* [Predicates](/powersheet/reference/query-api/predicates) --- filtering operators for `where` clauses
* [Expand Clause](/powersheet/reference/query-api/expand-clause) --- loading related entities in queries
* [Document Filtering](/powersheet/reference/query-api/document-filtering) --- document-scoping mechanisms
* [Baseline and Revision Queries](/powersheet/reference/query-api/baseline-and-revision-queries) --- querying historical data
* [Dynamic Value Expressions Reference](/powersheet/reference/sheet-config/dynamic-expressions) --- complete dynamic expression syntax
* [Context Expressions Reference](/powersheet/reference/data-model/context-expressions) --- `$context` path reference for data models
* [Constraints](/powersheet/reference/data-model/constraints) --- constraint configuration including stages and operators
* [Columns](/powersheet/reference/sheet-config/columns) --- column-level configuration for `value`, `valueType`, `render`, and `display`
* [Formatters](/powersheet/reference/sheet-config/formatters) --- conditional formatting with expression syntax
# Query Splitting
Source: https://learn.nextedy.com/powersheet/reference/query-api/query-splitting
Nextedy POWERSHEET splits entity query predicates into two execution stages: Lucene-compatible predicates that execute as database queries, and complex predicates that execute as in-memory post-filters.
## Splitting Strategy
## Predicate Classification
| Predicate Type | Execution Stage | Lucene-Compatible |
| --------------------------------- | --------------- | ----------------- |
| Equality (`eq`) | Lucene query | Yes |
| Inequality (`ne`, `!=`) | Lucene query | Yes |
| AND composite | Lucene query | Yes |
| OR composite | Lucene query | Yes |
| NOT (unary) | Lucene query | Yes |
| Object ID with project prefix | Lucene query | Yes |
| Complex navigation predicates | Post-filter | No |
| Predicates on expanded properties | Post-filter | No |
**Null check predicates not currently functional**
Null check predicates (for example, `HAS_VALUE` in Lucene syntax) are not currently functional in Powersheet query splitting. Do not rely on null-check predicates in `where` clauses until this is restored — use alternative filtering strategies such as explicit value matches or post-filter logic.
**Performance Implication**
Predicates that can be translated to Lucene execute at the database level, reducing the number of entities fetched from Polarion. Post-filter predicates require all candidate entities to be loaded first, then filtered in memory.
## Query Execution Pipeline
The query processor follows this execution order:
1. **Predicate analysis** -- Classify each predicate as Lucene-compatible or post-filter
2. **Lucene query construction** -- Combine Lucene-compatible predicates with type and project constraints
3. **Database execution** -- Execute Lucene query against Polarion `IDataService`
4. **Post-filter application** -- Apply remaining predicates in memory on the result set
5. **Expansion path resolution** -- Load related entities via expansion paths
6. **Security enforcement** -- Verify entity-level read permissions
## Document Query Optimization
When the `where` clause contains document-level predicates (e.g., filtering by document properties), the query processor extracts these predicates and pre-resolves matching documents before querying work items. This reduces the work item query scope by restricting it to items within specific documents.
| Step | Action | Result |
| ---- | ----------------------------------------------- | ------------------------ |
| 1 | Extract document predicates from `where` clause | Document filter criteria |
| 2 | Resolve matching documents | List of document IDs |
| 3 | Add `document.id` constraint to work item query | Scoped Lucene query |
| 4 | Execute constrained work item query | Reduced result set |
**Verify in application**
The exact set of predicates classified as document-level depends on the query structure. Verify query execution plans using the `explain` query parameter when available.
## Query Parameters
The query processor extracts parameters that control query behavior.
| Parameter | Type | Default | Description |
| ---------------------- | --------- | ------- | -------------------------------------------------- |
| `revision` | `string` | `null` | Execute query against a specific baseline revision |
| `currentDoc` | `string` | `null` | Document ID filter for document-scoped queries |
| `currentDocConstraint` | `string` | `null` | Entity type or expansion path for document scoping |
| `explain` | `boolean` | `false` | Enable debug output for query execution |
See [Query Context](/powersheet/reference/query-api/query-context) and [Baseline and Revision Queries](/powersheet/reference/query-api/baseline-and-revision-queries) for parameter details.
## Security Enforcement
Before any query executes, the processor verifies that the current user has read permission for the queried entity type. Queries against unauthorized entity types fail immediately without executing the Lucene query.
**Permission Check**
Entity-level security is checked before any query execution. If the current user does not have `READABLE` permission for the entity type, the query returns an error immediately.
## Constraint Annotations
The query processor applies constraint annotations from the data model to queries:
* **Project constraints** from entity type annotations are merged into the Lucene query
* **Document constraints** from entity type and expansion path annotations are merged into document filters
* **Navigation property constraints** combine both the expansion path and target entity type constraints
See [Constraints](/powersheet/reference/data-model/constraints) for data model constraint configuration.
## Complete YAML Example
```yaml theme={null}
sources:
- id: requirements
title: System Requirements
model: rtm
query:
from: UserNeed
where: "type:userNeed"
constraints:
applyCurrentDocumentTo: UserNeed
expand:
- name: systemRequirements
title: System Requirements
expand:
- name: systemRequirement
expand:
- name: designRequirements
expand:
- name: designRequirement
```
In this configuration:
* The `where` clause contains a Lucene-compatible equality predicate (`type:`)
* The `applyCurrentDocumentTo` constraint restricts results to the current document context
* Expansion paths load related entities after the primary query executes
## Related Pages
* [Predicates](/powersheet/reference/query-api/predicates) -- predicate types and syntax
* [Document Filtering](/powersheet/reference/query-api/document-filtering) -- document-level query constraints
* [Expand Clause](/powersheet/reference/query-api/expand-clause) -- expansion path configuration
* [Query Context](/powersheet/reference/query-api/query-context) -- query parameters and execution context
# Context Variables
Source: https://learn.nextedy.com/powersheet/reference/server-rendering/context-variables
Nextedy POWERSHEET Velocity templates have access to a set of context variables that provide work item data, document context, and Siemens Polarion ALM platform services.
## Variable Summary
| Variable | Type | Availability | Description |
| ---------- | ----------------- | ------------------------ | ----------------------------------------------------------------------------- |
| `$item` | ModelObject | All entities | Primary work item accessor with property access methods |
| `$wi` | IWorkItem | Work item entities only | Legacy Polarion work item API for low-level operations |
| `$tx` | Transaction | All evaluations | Current transaction object for query operations |
| `$module` | IModule | Document-scoped entities | Document (LiveDoc) containing the work item; `null` for non-document entities |
| `$context` | PowersheetContext | All evaluations | Powersheet-specific context: project, document scope, query helpers |
| `$pObject` | IPObject | All entities | Raw Polarion persistent object |
## \$item (ModelObject)
The primary accessor for work item data. Available for all entity types.
| Property / Method | Return Type | Description |
| ----------------- | ----------- | --------------------------------- |
| `$item.title` | `string` | Work item title |
| `$item.status` | `object` | Status object with `.id` property |
| `$item.author` | `object` | Author user object |
| `$item.created` | `datetime` | Creation timestamp |
| `$item.updated` | `datetime` | Last modification timestamp |
| `$item.uri` | `string` | Polarion URI for the work item |
### Example
```velocity theme={null}
$item.title - $item.status.id
```
**Preferred Variable**
Use `$item` as the primary work item accessor. It provides a higher-level API than `$wi` and is available for all entity types.
## \$wi (IWorkItem)
Legacy Polarion work item API. Only available when the entity is a work item (not for documents or other entity types).
| Property / Method | Return Type | Description |
| -------------------------- | ------------ | -------------------------------------- |
| `$wi.getLinkedWorkItems()` | `collection` | Returns all linked work items |
| `$wi.getCustomField(name)` | `object` | Returns custom field value by field ID |
| `$wi.getProjectId()` | `string` | Returns the project ID |
### Example
```velocity theme={null}
#set($links = $wi.getLinkedWorkItems())
$links.size() linked items
```
**Availability**
`$wi` is only set for work item entities. For `Document` or other non-work-item entity types, `$wi` is `null`. Use `$item` for cross-entity-type templates.
## \$tx (Transaction)
Current transaction object for transactional queries and read-only operations.
| Property / Method | Return Type | Description |
| ----------------- | ----------- | --------------------------------------------- |
| Transaction scope | object | Access to transaction-scoped data and queries |
### Example
```velocity theme={null}
#set($related = $trackerService.getWorkItemByUri($item.uri))
$related.title
```
**Read-Only Operations**
Server-rendered templates should perform read-only operations only. Modifying data within a template evaluation can cause unexpected side effects.
## \$module (IModule)
The LiveDoc containing the current work item. `null` for entities not within a document.
| Property / Method | Return Type | Description |
| ---------------------- | ----------- | -------------------------- |
| `$module.moduleFolder` | `string` | Document folder/space path |
| `$module.moduleName` | `string` | Document name |
| `$module.space` | `string` | Polarion space identifier |
### Example
```velocity theme={null}
#if($module)
Document: $module.moduleName in $module.moduleFolder
#else
No document context
#end
```
**Null Check Required**
Always check `#if($module)` before accessing module properties. Entities that are not contained within a document will have `$module` set to `null`.
## \$context (PowersheetContext)
Powersheet-specific context providing access to project scope, document scope, and query capabilities.
| Property / Method | Return Type | Description |
| --------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------ |
| Project context | object | Current project information |
| Document scope | object | Current document filtering context |
| Query helpers | object | Query execution utilities |
| `$context.parameters` | map | The current sheet URL's query parameters, keyed by name (`$context.parameters.`). Starting with Powersheet 26.7.2. |
### Example
```velocity theme={null}
$context.projectId
```
**Verify in application**
The exact methods available on `$context` depend on the Powersheet version. Consult the server logs for available context properties.
### `$context.parameters` — reading URL query parameters
Starting with Powersheet 26.7.2, a `serverRender` template can read the query parameters of the sheet's own URL through `$context.parameters`. Each parameter present on the URL is available under `$context.parameters.`, keyed by the name it has in the URL:
```velocity theme={null}
$!context.parameters.testrun
```
For a sheet opened at `…&testrun=v13`, `$context.parameters.testrun` resolves to the string `v13`. This lets a single data model drive different server-computed values from a shareable, bookmarkable link — the same URL parameters the sheet configuration reads client-side (see [URL Parameters](/powersheet/concepts/url-parameters)) are also visible to server-side rendering.
**Worked example.** A test-status column normally shows a rolling summary of a test case's most recent runs. Passing `?testrun=` on the URL narrows that column to a single run, so the sheet reports each test case's result *for that specific run* rather than the last few. The template reads the run from the URL and branches on it:
```velocity theme={null}
#set($run = "$!context.parameters.testrun")
#if($run != "")
## …render only the result for the run named $run…
#else
## …render the default rolling summary…
#end
```
Because the run id lives in the URL, the narrowed view is shareable: send a colleague `…&testrun=v13` and they see exactly the same slice.
**Use the quiet reference for optional parameters**
Read a URL parameter with Velocity's **quiet reference** form — `$!context.parameters.testrun`, with the `!` right after the `$`. Plain `$context.parameters.testrun` renders the **literal text** `$context.parameters.testrun` into the cell whenever the parameter is absent from the URL (Velocity's default behavior for any reference that resolves to null). The quiet form degrades to blank instead, which is what you want for an optional parameter.
**Parameter-driven templates stay read-only**
`$context.parameters` only feeds values *into* a template; it does not relax the read-only contract. A `serverRender` script — including one driven by URL parameters — can read Polarion data but cannot modify it. Keep templates to read-only operations, as with any server-rendered property.
## \$pObject (IPObject)
The raw Polarion persistent object underlying the entity.
| Property / Method | Return Type | Description |
| -------------------- | ----------- | ---------------------------- |
| `$pObject.uri` | `string` | Polarion URI |
| `$pObject.contextId` | `string` | Context (project) identifier |
## Client-Side Context Variables
In addition to server-side Velocity variables, Powersheet supports client-side `$context` expressions for dynamic value resolution in YAML configuration.
| Context Path | Description |
| ------------------------------------ | ------------------------------------- |
| `$context.document.id` | Current document path (`folder/name`) |
| `$context.source.document.component` | Source entity's document component |
| `$context.source.project.id` | Source entity's project ID |
These are resolved at configuration processing time, not during Velocity template evaluation. See [JavaScript Functions](/powersheet/reference/server-rendering/javascript-functions) for client-side expressions.
## Complete YAML Example
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: userNeed
properties:
title:
status:
documentPath:
serverRender: |
#if($module)$module.moduleFolder/$module.moduleName#else(unscoped)#end
authorName:
serverRender: "$item.author.name"
linkCount:
serverRender: |
#set($links = $wi.getLinkedWorkItems())
$links.size()
```
## Related Pages
* [Velocity Templates](/powersheet/reference/server-rendering/velocity-templates) -- template syntax and evaluation
* [Polarion Services](/powersheet/reference/server-rendering/polarion-services) -- platform service variables
* [Properties](/powersheet/reference/data-model/properties) -- data model property definitions
***
# Server Rendering Reference
Source: https://learn.nextedy.com/powersheet/reference/server-rendering/index
Nextedy POWERSHEET uses server-side rendering to compute dynamic property values using Velocity templates executed on the Siemens Polarion ALM server.
Velocity template syntax for defining server-rendered property expressions, including template patterns and error handling.
Variables available in the Velocity evaluation context: `$item`, `$module`, `$tx`, `$context`, and `$wi`.
Platform services injected into Velocity templates: `$trackerService`, `$txService`, `$repositoryService`, and `$securityService`.
Client-side function expressions and dynamic value resolution using `$context` references.
**Server Rendering vs. Client Rendering**
Server-rendered properties execute Velocity templates on the Polarion server during data retrieval. The computed values are returned as read-only fields in the query response. Client-side rendering uses column formatters and display properties configured in the sheet configuration YAML.
## Related Sections
* [Sheet Configuration Reference](/powersheet/reference/sheet-config/index) -- column configuration including `render` property
* [Data Model Reference](/powersheet/reference/data-model/index) -- data model property definitions
* [Query API Reference](/powersheet/reference/query-api/index) -- query execution and parameters
# Velocity Server Rendering
Source: https://learn.nextedy.com/powersheet/reference/server-rendering/javascript-functions
Nextedy POWERSHEET server-rendered properties support Velocity template expressions that execute on the Polarion server.
## Server Rendering Context
When a property is configured with `serverRender`, the server evaluates the expression using Velocity templates with automatically injected Polarion services. These services are available as context variables in all server-rendered expressions.
### Injected Polarion Services
| Service Variable | Purpose | Common Use Cases |
| -------------------- | --------------------------- | -------------------------------------------------------------------------------- |
| `$trackerService` | Access work item data | Querying work items, running Lucene queries, accessing tracker metadata |
| `$txService` | Transaction management | Understanding execution context, managing Polarion transactions |
| `$repositoryService` | Repository-level operations | Accessing project metadata, users, roles, repository configuration |
| `$securityService` | Permission checking | Checking user permissions, role-based visibility, enforcing security constraints |
**All Services Are Auto-Injected**
These services are automatically available in every server-rendered expression. No additional configuration is required to access them.
## Server-Rendered Property Configuration
Properties configured with `serverRender` in the data model are evaluated on the server before being sent to the client. This affects both how the property value is computed and its editability.
### Property Definition
| Name | Type | Default | Description |
| ----------------- | --------- | --------------- | --------------------------------------------------------------------------------------- |
| `name` | `string` | Required | Property name exposed in the Powersheet client |
| `serverName` | `string` | Same as `name` | Override for the actual Polarion field name when it differs from the client-facing name |
| `customFieldName` | `string` | `null` | Polarion custom field ID for properties stored in custom fields |
| `type` | `string` | See application | Data type of the property (`string`, `integer`, `date`, `enum`, etc.) |
| `storage` | `string` | See application | How the property value is persisted in Polarion |
| `readable` | `boolean` | `true` | Controls whether the property can be read by clients |
| `updatable` | `boolean` | `true` | Controls whether the property can be modified by clients |
| `scalar` | `boolean` | `true` | Whether property holds a single value (`true`) or collection (`false`) |
**Server-Rendered Fields Are Read-Only**
Properties with `serverRender` enabled are automatically marked as non-editable in the sheet, regardless of the `updatable` setting. The server computes the value on each query; client-side edits would be overwritten.
## Velocity Template Context Variables
Server-rendered expressions have access to these context variables during template execution:
| Variable | Description |
| ---------- | ------------------------------------------------------------- |
| `$item` | The current work item being rendered |
| `$tx` | The current transaction context |
| `$context` | The query context including project, document, and parameters |
| `$pObject` | The Polarion persistent object reference |
## Service Usage Patterns
### Tracker Service
Use `$trackerService` to query work items, access tracker metadata, and run Lucene queries within server-rendered expressions.
Run a Lucene search through the project the service hands back:
```velocity theme={null}
#set($project = $trackerService.getTrackerProject($context.projectId))
$project.queryWorkItems("type:requirement", "id")
```
**Search through `getTrackerProject`, not directly on the service.** The services exposed to a template are read-only proxies, and they admit only methods whose names begin with `get`, `is`, `has`, `find`, `search`, `list`, `count` or `exists`. `queryWorkItems` matches none of those, so calling `$trackerService.queryWorkItems(…)` is refused and the cell renders `#SERVER_RENDER_ERROR`.
`getTrackerProject` is an allowed read, and the project it returns carries the same query method — which is why the two-line form above works while the one-line form does not.
### Security Service
Use `$securityService` to implement role-based visibility and conditional content in server-rendered fields.
```velocity theme={null}
#if($securityService.canPerformActionOnWorkItem($item, "modify"))
editable
#else
read-only
#end
```
### Repository Service
Use `$repositoryService` to access project metadata, user information, and repository configuration.
```velocity theme={null}
$repositoryService.getProjectByID("myProject").getName()
```
## Security Considerations
Server-rendered properties interact with the Powersheet security model:
| Aspect | Behavior |
| ----------------------- | ----------------------------------------------------------------------------------- |
| Editability | Server-rendered fields are always read-only in the client |
| Permission inheritance | Entity-level `readable`/`updatable` settings intersect with property-level settings |
| System read-only fields | `id`, `outlineNumber` are always read-only regardless of configuration |
**Verify in application**
The exact list of available service methods depends on the Polarion server version. Consult the Polarion SDK documentation for the full API reference of each injected service.
## Complete YAML Example
```yaml theme={null}
domainModelTypes:
UserNeed:
polarionType: userNeed
properties:
title:
severity:
computedStatus:
serverRender: |
#set($project = $trackerService.getTrackerProject($context.projectId))
#set($linkedItems = $project.queryWorkItems("type:systemRequirement", "id"))
#if($linkedItems.size() > 0)
Linked
#else
Unlinked
#end
readable: true
updatable: false
SystemRequirement:
polarionType: systemRequirement
properties:
title:
priority:
```
## Related Pages
* [Velocity Templates](/powersheet/reference/server-rendering/velocity-templates) -- Template syntax and expression language
* [Context Variables](/powersheet/reference/server-rendering/context-variables) -- All variables available in server rendering context
* [Polarion Services](/powersheet/reference/server-rendering/polarion-services) -- Detailed reference for each injected service
* [Properties](/powersheet/reference/data-model/properties) -- Data model property configuration
* [Permissions](/powersheet/reference/data-model/permissions) -- Security model for properties and entities
# Polarion Services
Source: https://learn.nextedy.com/powersheet/reference/server-rendering/polarion-services
Nextedy POWERSHEET server-rendered properties execute inside an Apache Velocity template engine on the Siemens Polarion ALM server.
**When to Use Polarion Services**
Server-rendered properties let you compute read-only column values that depend on data outside the current work item -- related items, project metadata, repository information, or the current user's permissions. Configure them via the `serverRender` key in the data model YAML and display them in sheet columns marked as read-only.
## Service Injection Architecture
The server renderer populates two layers of Velocity context:
| Layer | Lifetime | Variables |
| ------------------- | ---------------------------- | ------------------------------------------------------------------------- |
| **Static (cached)** | Server process lifetime | `$trackerService`, `$txService`, `$repositoryService`, `$securityService` |
| **Per-item** | One evaluation per work item | `$item`, `$wi`, `$tx`, `$module`, `$context` |
The static context is built once and stored in a cached base context object. All platform service references are then reused across every template evaluation without re-initialization, which keeps rendering fast even for large sheets.
## Service Summary
| Variable | Polarion Interface | Purpose |
| -------------------- | --------------------- | --------------------------------------------------------------- |
| `$trackerService` | `ITrackerService` | Query work items, access project metadata, run Lucene searches |
| `$txService` | `ITransactionService` | Transaction management within templates |
| `$repositoryService` | `IRepositoryService` | Access project metadata, users, roles, repository configuration |
| `$securityService` | `ISecurityService` | Check permissions, implement role-based visibility |
***
## \$trackerService
| Property | Value |
| ---------------------- | ---------------------------------------------------- |
| **Variable name** | `$trackerService` |
| **Polarion interface** | `ITrackerService` |
| **Scope** | Static (cached) |
| **Primary use** | Work item queries, Lucene searches, project metadata |
Provides access to work item queries, project-level tracker metadata, and Lucene search operations. This is the most commonly used platform service in server-rendered properties because it enables cross-item lookups and data aggregation across the project.
### Common Operations
| Operation | Method | Return Type |
| --------------------------- | ----------------------- | -------------- |
| Retrieve work item by URI | `getWorkItemByUri(uri)` | `IWorkItem` |
| Access Lucene query service | `getDataService()` | `IDataService` |
| Access project by ID | `getProject(projectId)` | `IProject` |
### Example: Retrieve a Work Item by URI
```velocity theme={null}
#set($related = $trackerService.getWorkItemByUri($item.uri))
Related title: $related.title
```
### Example: Run a Lucene Query
```velocity theme={null}
#set($ds = $trackerService.getDataService())
#set($results = $ds.searchInstances("WorkItem", "type:systemRequirement AND project.id:MyProject", "title", -1))
Found $results.size() system requirements
```
### Example: Access Project Metadata
```velocity theme={null}
#set($proj = $trackerService.getProject("MyProject"))
Project: $proj.name
```
### Example: Count Linked Design Requirements
This pattern queries for all design requirements linked to the current work item:
```velocity theme={null}
#set($ds = $trackerService.getDataService())
#set($q = "type:designRequirement AND linkedWorkItem:$item.id")
#set($results = $ds.searchInstances("WorkItem", $q, "id", -1))
$results.size()
```
**Performance**
Lucene queries inside `serverRender` execute **once per row** in the sheet. On a sheet with 500 work items, a single Lucene query in a server-rendered column runs 500 times. Keep queries simple and avoid them on large datasets. Test on a filtered subset first.
***
## \$txService
| Property | Value |
| ---------------------- | -------------------------- |
| **Variable name** | `$txService` |
| **Polarion interface** | `ITransactionService` |
| **Scope** | Static (cached) |
| **Primary use** | Transaction context access |
Provides access to Polarion transaction management. In the context of server-rendered properties, templates execute within a read-only evaluation context. The transaction service is primarily useful for understanding the execution context rather than performing write operations.
**Verify in application**
The `$txService` variable is available in all templates. Its available methods depend on the Polarion server version. Consult the Polarion API documentation for the `ITransactionService` interface. Server-rendered expressions should not use this service to initiate write transactions -- they run in a read-only evaluation context.
***
## \$repositoryService
| Property | Value |
| ---------------------- | -------------------------------------------------------- |
| **Variable name** | `$repositoryService` |
| **Polarion interface** | `IRepositoryService` |
| **Scope** | Static (cached) |
| **Primary use** | Project metadata, users, roles, repository configuration |
Provides access to repository-level operations: project metadata, user information, roles, and repository configuration. Useful for templates that need to display data from outside the current work item's project scope or that need to resolve user or role information.
### Example: Access Project Name
```velocity theme={null}
#set($proj = $repositoryService.getProjectById($item.projectId))
Project: $proj.name
```
### Example: Resolve a User ID to Display Name
```velocity theme={null}
#set($user = $repositoryService.getUserById($item.author.id))
Author: $user.getName()
```
**Verify in application**
Available methods depend on the Polarion server version. The repository service provides read-only access to repository-level resources. Consult the Polarion API documentation for `IRepositoryService`.
***
## \$securityService
| Property | Value |
| ---------------------- | ------------------------------------------------------------- |
| **Variable name** | `$securityService` |
| **Polarion interface** | `ISecurityService` |
| **Scope** | Static (cached) |
| **Primary use** | Permission checks, role-based visibility, user identification |
Enables permission checking, role-based visibility, and user identification within templates. Use this service to conditionally render content based on the logged-in user's identity or to verify access rights before displaying sensitive data.
### Example: Show Current User
```velocity theme={null}
#set($user = $securityService.getCurrentUser())
Evaluated by: $user.getId()
```
### Example: Permission-Based Visibility
```velocity theme={null}
#if($securityService.canRead($item))
$item.title
#else
[Restricted]
#end
```
### Example: Role-Based Content
```velocity theme={null}
#set($user = $securityService.getCurrentUser())
#if($user.hasRole("project_admin"))
Admin view: $item.title ($item.status.id)
#else
$item.title
#end
```
**Role-Based Columns**
Combine `$securityService` with conditional Velocity logic to build columns that display different content depending on the current user's role or permissions. The rendered value is computed server-side, so the user cannot bypass the check client-side.
***
## Per-Item Context Variables
In addition to the static platform services, the server renderer injects per-item variables for each work item during evaluation. These are documented in detail on the [Context Variables](/powersheet/reference/server-rendering/context-variables) page. The summary:
| Variable | Type | Description |
| ---------- | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `$item` | ModelObject | Primary work item accessor. Properties: `.title`, `.status`, `.author`, `.created`, `.updated`, `.uri` |
| `$wi` | IWorkItem | Legacy Polarion API. Only available for work item entities. Use for: `$wi.getCustomField("fieldId")`, `$wi.getLinkedWorkItems()` |
| `$tx` | Transaction | Current transaction context. Templates see the transaction state at evaluation time |
| `$module` | IModule | Document (LiveDoc) containing the work item. `null` for entities outside a document. Properties: `.moduleFolder`, `.moduleName`, `.space` |
| `$context` | PowersheetContext | Server API context with project scope and query capabilities |
**Choosing Between `$item` and `$wi`**
Prefer `$item` (ModelObject) for accessing standard work item properties. Use `$wi` (IWorkItem) only when you need methods not available on `$item`, such as `getCustomField()` or `getLinkedWorkItems()`. The `$wi` variable is only set for work item entities -- it is `null` for non-work-item entity types.
***
## Caching Behavior
| Aspect | Detail |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| **Cache scope** | Static base context instance built at first evaluation |
| **Lifetime** | Persists for the lifetime of the Polarion server process |
| **Thread safety** | Service instances are thread-safe; shared across all concurrent evaluations |
| **Extension** | Per-item variables (`$item`, `$wi`, `$module`, `$context`, `$tx`) are layered on top of the cached context for each evaluation |
| **Additional services** | Additional context services may be injected beyond the four core platform services |
***
## Error Handling
When a Velocity template evaluation fails, the server renderer returns the constant error marker:
```
#SERVER_RENDER_ERROR
```
If this value appears in a sheet column, the `serverRender` expression for that property contains an error. Check the Polarion server logs for one of these exceptions:
| Exception | Cause |
| --------------------------- | ----------------------------------------------------------------------------------------------------------- |
| `ParseErrorException` | Invalid Velocity syntax in the template (mismatched directives, bad variable references) |
| `MethodInvocationException` | A method call on a service or object threw an exception (null pointer, permission denied, invalid argument) |
| `ResourceNotFoundException` | A referenced Velocity resource (macro, include file) does not exist |
| `IOException` | I/O failure during template processing |
**Debugging Server-Rendered Errors**
The `#SERVER_RENDER_ERROR` marker is the only client-visible indicator of a problem. To diagnose the root cause, check the Polarion server logs (`logs/polarion*.log`) where the full stack trace is logged with the template pattern and exception details. Common causes include referencing a null property without an `#if` guard, calling a method with the wrong argument type, or using incorrect Velocity syntax.
***
## Data Model Configuration
Server-rendered properties are configured in the data model YAML using the `serverRender` key on a property definition. The value is an Apache Velocity template that is evaluated for each work item when the sheet loads.
### Property Definition
| Key | Type | Description |
| -------------- | -------- | ------------------------------------------------------------------------------------------------------- |
| `serverRender` | `string` | Velocity template pattern evaluated per work item. The result replaces the property value in the sheet. |
Properties with `serverRender` are automatically marked as read-only -- the computed value cannot be edited by users.
### Single-Line Expression
```yaml theme={null}
domainModelTypes:
SystemRequirement:
polarionType: systemRequirement
properties:
evaluatedBy:
serverRender: "$securityService.getCurrentUser().getId()"
```
### Multi-Line Template
Use YAML block scalar syntax (`|`) for templates with conditional logic or multiple statements:
```yaml theme={null}
domainModelTypes:
SystemRequirement:
polarionType: systemRequirement
properties:
projectName:
serverRender: |
#set($proj = $repositoryService.getProjectById($item.projectId))
$proj.name
```
***
## Complete YAML Example
The following data model and sheet configuration demonstrate all four platform services used in server-rendered properties within a standard RTM entity type.
**Data model YAML:**
```yaml theme={null}
domainModelTypes:
SystemRequirement:
polarionType: systemRequirement
properties:
title:
severity:
evaluatedBy:
serverRender: "$securityService.getCurrentUser().getId()"
projectName:
serverRender: |
#set($proj = $repositoryService.getProjectById($item.projectId))
$proj.name
linkedCount:
serverRender: |
#set($links = $wi.getLinkedWorkItems())
$links.size()
relatedReqCount:
serverRender: |
#set($ds = $trackerService.getDataService())
#set($q = "type:designRequirement AND linkedWorkItem:$item.id")
#set($results = $ds.searchInstances("WorkItem", $q, "id", -1))
$results.size()
```
**Sheet configuration YAML:**
```yaml theme={null}
columns:
id:
width: 80
title:
width: 300
evaluatedBy:
width: 150
isReadOnly: true
projectName:
width: 150
isReadOnly: true
linkedCount:
width: 80
isReadOnly: true
relatedReqCount:
width: 100
isReadOnly: true
sources:
- id: requirements
title: System Requirements
model: rtm
query:
from: SystemRequirement
```
**Read-Only Display**
Server-rendered properties are always read-only in the sheet. The `serverRender` value is computed on each query and cannot be edited by the user. Mark the corresponding sheet columns with `isReadOnly: true` to communicate this in the UI.
***
## Best Practices
| Practice | Rationale |
| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| Keep templates simple | Every `serverRender` expression executes per row. Complex logic multiplies server load. |
| Avoid nested Lucene queries | A Lucene query inside `serverRender` on a 500-row sheet runs 500 times. Pre-compute if possible. |
| Use `$item` over `$wi` | ModelObject (`$item`) is the modern API. Fall back to `$wi` only for custom field access or linked work item traversal. |
| Test with small datasets | Validate templates on a filtered query before applying to the full document. |
| Check for `#SERVER_RENDER_ERROR` | If a column shows this marker, check server logs for the exception type and template pattern. |
| Use `#if` for null safety | Wrap service calls in `#if` guards: `#if($item.projectId)...#end` to avoid null pointer exceptions. |
| Avoid write operations | Templates run in a read-only context. Do not use `$txService` to start write transactions. |
| Prefer standard properties first | Only use `serverRender` when a standard property, formula, or display expression cannot provide the needed value. |
***
## Service Availability Quick Reference
Use the following decision table to determine which service fits your use case:
| Use Case | Service | Example Pattern |
| ---------------------------------- | ----------------------------------------- | ------------------------------------------------------- |
| Look up a related work item | `$trackerService` | `$trackerService.getWorkItemByUri($item.uri)` |
| Search for work items by query | `$trackerService` | `$trackerService.getDataService().searchInstances(...)` |
| Access project metadata | `$trackerService` or `$repositoryService` | `$trackerService.getProject("projectId")` |
| Get current user identity | `$securityService` | `$securityService.getCurrentUser().getId()` |
| Check user permissions | `$securityService` | `$securityService.canRead($item)` |
| Conditionally show content by role | `$securityService` | `$user.hasRole("role_name")` |
| Resolve user details | `$repositoryService` | `$repositoryService.getUserById("userId")` |
| Access repository configuration | `$repositoryService` | `$repositoryService.getProjectById("projectId")` |
***
## Related Pages
* [Velocity Templates](/powersheet/reference/server-rendering/velocity-templates) -- template syntax and evaluation flow
* [Context Variables](/powersheet/reference/server-rendering/context-variables) -- per-item context variables (`$item`, `$wi`, `$module`, `$context`, `$tx`)
* [Properties](/powersheet/reference/data-model/properties) -- data model property definitions
* [Permissions](/powersheet/reference/data-model/permissions) -- entity-level security settings
***
# Velocity Templates
Source: https://learn.nextedy.com/powersheet/reference/server-rendering/velocity-templates
Nextedy POWERSHEET uses Apache Velocity templates to render dynamic property values on the Siemens Polarion ALM server.
## Template Evaluation
## Context Variables
The following variables are available in every Velocity template evaluation.
| Variable | Type | Description |
| ---------- | ----------------- | --------------------------------------------------------------------------------------------------------------- |
| `$item` | ModelObject | Primary work item accessor. Provides access to all work item properties and methods. |
| `$wi` | IWorkItem | Legacy Polarion work item API. Only available for work item entities. Use for methods not available on `$item`. |
| `$tx` | Transaction | Current transaction object for transactional queries and read-only operations. |
| `$module` | IModule | Document (LiveDoc) containing the work item. `null` for entities not within a document. |
| `$context` | PowersheetContext | Powersheet-specific context providing access to project scope, document scope, and query capabilities. |
| `$pObject` | IPObject | Raw Polarion persistent object underlying the entity (`.uri`, `.contextId`). |
### Examples
`$item` (ModelObject) exposes work item fields directly; `$wi` (IWorkItem) is the low-level Polarion API for operations not surfaced on `$item`, such as link traversal:
```velocity theme={null}
## $item -- high-level field access
$item.id - $item.title ($item.status.id)
## $wi -- low-level API for methods not on $item
#set($links = $wi.getLinkedWorkItems())
$links.size() linked items
```
See [Context Variables](/powersheet/reference/server-rendering/context-variables) for detailed documentation on each variable, including the full `$item`, `$wi`, and `$pObject` member lists.
### `$context` members
The `$context` (PowersheetContext) variable groups the Powersheet-specific scope and query helpers. Access members by name, for example `$context.document.id`:
| Member | Description |
| ------------------- | ------------------------------------------------------------------------- |
| `$context.document` | Current document scope -- `.id` returns the document path (`folder/name`) |
| `$context.project` | Current project information (e.g. `.id`) |
| Query helpers | Utilities for executing scoped queries within the template |
**Verify in application**
The exact members available on `$context` depend on the Powersheet version. Consult the Polarion server logs for the available context properties if a member does not resolve.
## Platform Services
Platform services are cached and pre-injected into every template evaluation.
| Variable | Service | Purpose |
| -------------------- | ------------------- | --------------------------------------------------------------- |
| `$trackerService` | ITrackerService | Query work items, access project metadata, run Lucene searches |
| `$txService` | ITransactionService | Transaction management within templates |
| `$repositoryService` | IRepositoryService | Access project metadata, users, roles, repository configuration |
| `$securityService` | ISecurityService | Check permissions, implement role-based visibility |
The method examples shown for these services throughout this page are **illustrative** -- the exact method set on each service depends on your Polarion server version (see [Verify in application](#method-calls) below). See [Polarion Services](/powersheet/reference/server-rendering/polarion-services) for detailed service documentation.
## Template Syntax
Velocity templates use standard Apache Velocity syntax.
### Variable References
```velocity theme={null}
$item.title
$item.status.id
$wi.getLinkedWorkItems()
```
### Conditional Logic
```velocity theme={null}
#if($item.status.id == "approved")
Approved
#else
Pending
#end
```
### Method Calls
```velocity theme={null}
$trackerService.getWorkItemByUri($item.uri)
$securityService.getCurrentUser().getId()
```
**Verify in application**
The exact methods available on each service depend on the Polarion server version. The authoritative, version-matched reference is the **Polarion SDK Javadoc**, which ships with your installation -- open `[POLARION_INSTALL]/polarion/SDK/doc/sdk/index.html` (the interfaces above, such as `ITrackerService` and `ISecurityService`, are documented there). Always confirm method signatures against the SDK for **your** server version rather than relying on the illustrative examples here.
A stable public URL for the Polarion Javadoc is intentionally not linked here, because Siemens does not publish a version-agnostic permalink and the API surface differs between releases. Use the locally shipped SDK Javadoc above, or the official Siemens Polarion developer documentation for your specific version.
## Error Handling
| Error Type | Behavior |
| ----------------------- | --------------------------------------- |
| Parse error | Returns `#SERVER_RENDER_ERROR` constant |
| Method invocation error | Returns `#SERVER_RENDER_ERROR` constant |
| Resource not found | Returns `#SERVER_RENDER_ERROR` constant |
**Error Marker**
When a Velocity template fails to evaluate, the cell displays `#SERVER_RENDER_ERROR`. Check the Polarion server logs for the specific error details (parse errors, method invocation errors, or missing resources).
## Template Performance
| Aspect | Detail |
| ----------------------- | --------------------------------------------------------------------------------------------------------------------- |
| Service context caching | Platform services (`$trackerService`, etc.) are cached in a static context and reused across all template evaluations |
| Per-item context | `$item`, `$wi`, `$module`, and `$context` are set per work item evaluation |
| Evaluation scope | Templates execute once per work item per query |
**Performance Consideration**
Server-rendered templates execute for every work item returned by a query. Avoid expensive operations (e.g., complex Lucene queries within templates) that multiply across large result sets.
## Server-Rendered Property Configuration
Server-rendered properties are defined in the data model using the `serverRender` annotation. When a property has `serverRender` configured, it becomes read-only (not updatable) regardless of other permission settings. This is part of the broader read-only resolution behavior documented canonically in [Configure Read-Only Column](/powersheet/guides/sheet-configuration/configure-read-only-column#how-read-only-resolution-works).
| Property | Type | Default | Description |
| -------------- | --------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `serverRender` | `string` | `null` | Velocity template pattern to evaluate. When set, property is automatically marked read-only. |
| `readable` | `boolean` | `true` | Whether the property is visible to clients |
| `updatable` | `boolean` | `false` (and always forced to `false` when `serverRender` is set) | The general default for `updatable` is already `false`; for a server-rendered property Powersheet still forces the effective value to `false` and ignores any `updatable: true` you set, so an explicit override never applies there |
### Test Context Validation
The server renderer validates that the Velocity context contains the required variables:
| Required Variable | Type |
| ----------------- | ------------------------------ |
| `item` | ModelObject (work item) |
| `tx` | Transaction |
| `context` | PowersheetContext |
| `pObject` | IPObject (raw Polarion object) |
## Document Parameters in Templates
Document parameters can be used within Velocity templates via the `$context` variable:
```velocity theme={null}
$context.document.id
```
See [JavaScript Functions](/powersheet/reference/server-rendering/javascript-functions) for client-side `$context` expressions.
## Complete YAML Example
Data model with a server-rendered property:
```yaml theme={null}
domainModelTypes:
SystemRequirement:
polarionType: systemRequirement
properties:
title:
severity:
computedStatus:
serverRender: |
#if($item.status.id == "approved")Approved#else$item.status.id#end
```
Sheet configuration referencing the computed property:
```yaml theme={null}
columns:
id:
width: 80
title:
width: 300
hasFocus: true
computedStatus:
width: 120
formatter: readOnly
sources:
- id: requirements
title: System Requirements
model: rtm
query:
from: SystemRequirement
where: "type = 'UserNeed'"
```
## Related Pages
* [Render Property](/powersheet/reference/sheet-config/render-property) -- sheet-level render configuration
* [Properties](/powersheet/reference/data-model/properties) -- data model property definitions
* [Configure Read-Only Column](/powersheet/guides/sheet-configuration/configure-read-only-column) -- how `serverRender` properties resolve as read-only
(The [Context Variables](/powersheet/reference/server-rendering/context-variables) and [Polarion Services](/powersheet/reference/server-rendering/polarion-services) references are linked inline from the sections above.)
***
# Binding Syntax
Source: https://learn.nextedy.com/powersheet/reference/sheet-config/binding-syntax
In a Nextedy POWERSHEET sheet configuration, the **binding path** (also called **column key**) is the YAML key that defines each column in the `columns` section.
**Binding paths connect three layers**
The data model defines entity types and relationships. Sources define how to query and expand those relationships. Column binding paths define how to display the resulting data. All three layers are connected through navigation property names.
***
## Binding Path Patterns
| Pattern | Type | Example | Description |
| ------------------------------------------ | ------------------ | --------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `` | Simple | `title` | Binds to a direct property of the root entity type |
| `` | Scalar reference | `chapter` | Navigates a many-to-one relationship (picker column) |
| `.` | One-level | `chapter.title` | Navigates one relationship and reads a property |
| `.` | Collection entity | `systemRequirements.systemRequirement` | Navigates through an association entity (new level or multi-item) |
| `..` | Two-level | `systemRequirements.systemRequirement.title` | Navigates through a relationship to a child entity property |
| `....` | Multi-level | `systemRequirements.systemRequirement.designRequirements.designRequirement.title` | Deep navigation through multiple relationship levels |
| `$` | Unbound | `$riskScore` | Names a column that binds to no property. Its content comes from a `value` expression and is never stored. See [Unbound Columns](#unbound-columns) |
| `..$` | Unbound at a level | `systemRequirements.systemRequirement.$coverage` | Same, anchored to an expanded level -- the path before `$` decides which entity the column reads from |
***
## Binding Path Structure
***
## Simple Property Binding
Binds directly to a property of the root entity type defined in `sources[].query.from`. No navigation is involved.
```yaml theme={null}
columns:
id:
title: ID
width: 80
isReadOnly: true
title:
title: User Need
width: 200
hasFocus: true
outlineNumber:
title: "#"
width: 80
severity:
title: Severity
width: 100
description:
title: Description
width: 140
```
**Resolution:** Each key (`id`, `title`, `severity`, etc.) maps to a property defined in the `properties` section of the root entity type in the data model. The source query `from: UserNeed` determines the root context.
| Element | Value | Meaning |
| ------------- | ---------------- | ------------------------------------ |
| Binding | `title` | Root entity property |
| Source needed | `from: UserNeed` | Root query only |
| Expand needed | None | No relationship traversal |
| UI behavior | Direct edit | Editable cell bound to root property |
***
## Scalar Navigation Binding (Many-to-One)
When the data model defines a `many-to-one` relationship, the `direct` navigation property name resolves to a single referenced entity (scalar reference). Two binding forms apply.
### Reference Picker
Use the navigation property name alone to create a reference picker column:
```yaml theme={null}
columns:
chapter:
title: Chapter
display: title
list:
search:
- title
```
The `display` property controls which field of the referenced entity appears in the cell. The `list.search` array defines which fields are searchable in the picker dropdown.
### Read-Only Property Access
Append a property name to the navigation property with dot notation to display a specific field from the referenced entity:
```yaml theme={null}
columns:
chapter.title:
title: Chapter Title
isReadOnly: true
```
| Element | Value | Meaning |
| ------------- | ------------------------------------------------------- | ---------------------------------------- |
| Binding | `chapter` | Scalar reference picker (N:1) |
| Binding | `chapter.title` | Read-only display of referenced property |
| Source expand | `- name: chapter` | Single-level expand |
| Data model | `cardinality: many-to-one`, `direct: { name: chapter }` | Defines the navigation |
**Source configuration:**
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: chapter
```
***
## Collection Navigation Binding (One-to-Many)
The `back` direction of a many-to-one relationship produces a one-to-many collection. The navigation property name creates a new hierarchical level in the sheet.
```yaml theme={null}
columns:
title:
title: Chapter
hasFocus: true
userNeeds:
title: User Need Title
hasFocus: true
```
No dot notation is needed. The expand in the source directly opens the child level.
**Source configuration:**
```yaml theme={null}
sources:
- id: chapters
query:
from: Chapter
expand:
- name: userNeeds
```
| Element | Value | Meaning |
| ------------- | --------------------------- | ----------------------------------------------- |
| Binding | `userNeeds` | Collection navigation (1:N, creates child rows) |
| Source expand | `- name: userNeeds` | Single-level expand |
| Data model | `back: { name: userNeeds }` | Reverse of the many-to-one relationship |
| UI behavior | Child rows | Expands into a new grid level |
***
## Association Entity Binding (Many-to-Many)
Many-to-many relationships use an **association entity** between the two types. Both the source expand and the column binding require two levels of navigation.
### Source Expand (Two Levels)
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: systemRequirement
```
The first level (`systemRequirements`) navigates to the association entity. The second level (`systemRequirement`) navigates from the association to the target entity.
### Column Binding
```yaml theme={null}
columns:
systemRequirements.systemRequirement:
title: System Requirement
list:
search:
- objectId
- title
systemRequirements.systemRequirement.title:
title: SysReq Title
hasFocus: true
systemRequirements.systemRequirement.severity:
title: Severity
width: 100
```
| Element | Value | Meaning |
| ------------- | ----------------------------------------------------------------- | -------------------------------------- |
| Binding | `systemRequirements.systemRequirement` | Association entity reference (M:N) |
| Binding | `systemRequirements.systemRequirement.title` | Property of the target entity |
| Source expand | Two levels: `systemRequirements` then `systemRequirement` | Traverses association |
| Data model | `cardinality: many-to-many`, `back: { name: systemRequirements }` | Defines the relationship |
| UI behavior | Multi-item reference picker | Picker bound to the association target |
***
## Deep Multi-Level Binding
Navigation paths can chain multiple relationships to reach deeply nested entities. Each additional relationship adds another `.` segment.
```yaml theme={null}
columns:
systemRequirements.systemRequirement.designRequirements.designRequirement.title:
title: Design Requirement
hasFocus: true
systemRequirements.systemRequirement.designRequirements.designRequirement.description:
title: DR Description
width: 180
```
**Corresponding source expand:**
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: systemRequirement
expand:
- name: designRequirements
expand:
- name: designRequirement
```
**Performance consideration**
Each additional expansion level increases the amount of data loaded from the server. Limit deep navigation to three or four levels for optimal performance.
***
## Unbound Columns
Every pattern above resolves to a property in the data model. Prefixing the **last** segment with `$` does the opposite: it declares a column that binds to no property at all. The column has no stored value, is always read-only, and takes its content from a `value` expression.
```yaml theme={null}
columns:
# anchored at the root entity
$riskScore:
title: Risk Score
value: "() => context.entity.Probability * context.entity.Severity"
valueType: number
# anchored at an expanded level
systemRequirements.systemRequirement.$coverage:
title: Coverage
value: "() => `${context.entity.verifiedCount} / ${context.entity.totalCount}`"
```
**Resolution:** the segments *before* the marker are an ordinary binding path and must resolve in the data model -- they decide which entity the column reads from, which the expression sees as `context.entity`. The marked leaf resolves to nothing; it is just the column's name.
| Element | Value | Meaning |
| ------------- | ------------------------------------------------ | ---------------------------------------------- |
| Binding | `$riskScore` | Unbound column on the root entity |
| Binding | `systemRequirements.systemRequirement.$coverage` | Unbound column on the expanded target entity |
| Source expand | As for the path before `$` | The anchor still needs its expansions |
| Data model | No property required for the `$` leaf | The marked leaf names a column, not a property |
| UI behavior | Read-only derived cell | Nothing is stored and nothing is saved |
### Marker Rules
| Rule | Invalid example | Error |
| -------------------------------------------- | --------------------------------------------- | ------------------------------------------------------ |
| The marker belongs on the last segment only | `$systemRequirements.systemRequirement.title` | `The '$' marker is only allowed on the last segment.` |
| The marker needs a name after it | `$` | `The '$' marker needs a name (eg. '$riskScore').` |
| The path before the marker must resolve | `noSuchPath.$score` | `The path before '$score' does not resolve.` |
| An unbound column needs a `value` expression | `$riskScore` with no `value` | `has no 'value' expression to derive its content from` |
**`$total` and `total` can coexist.**
The marker stays part of the column's internal identity, so an unbound `$total` does not collide with a real `total` property in the same sheet.
**The header drops the marker.**
An unbound column with no explicit `title` shows the marker-stripped name -- `$riskScore` displays as `riskScore`. Set `title` for anything more readable.
For the `value` expression itself and the properties an unbound column rejects, see [Computed Columns](/powersheet/reference/sheet-config/columns#computed-columns).
***
## Binding Path Segments Reference
Each segment of a dot-separated binding path corresponds to a specific element from the data model or entity type definition.
| Segment Position | Resolves To | Source |
| ------------------------------------------ | ------------------------------- | -------------------------------------------------------------------------------------------------- |
| First segment (e.g., `systemRequirements`) | Navigation property name | `direct.name` or `back.name` from a [relationship](/powersheet/reference/data-model/relationships) |
| Second segment (e.g., `systemRequirement`) | Target entity name (singular) | Entity type from `domainModelTypes` |
| Subsequent pairs | Repeat of nav property + entity | Additional relationships in the chain |
| Final segment (e.g., `title`) | Property name | `properties` section of the target entity type |
***
## Binding and Source Alignment
The column binding path must exactly mirror the expansion hierarchy defined in the source configuration. Mismatches produce empty or missing columns.
| Column Binding | Required Source Expand | Relationship |
| ------------------------------------------------ | ------------------------------------------ | ------------------------------- |
| `title` | None (root property) | Direct property |
| `chapter` | `- name: chapter` | N:1 scalar |
| `chapter.title` | `- name: chapter` | N:1 property access |
| `userNeeds` | `- name: userNeeds` | 1:N collection |
| `systemRequirements.systemRequirement` | `systemRequirements` > `systemRequirement` | M:N association |
| `systemRequirements.systemRequirement.title` | `systemRequirements` > `systemRequirement` | M:N property |
| `$riskScore` | None (root anchor) | Unbound -- computed, not stored |
| `systemRequirements.systemRequirement.$coverage` | `systemRequirements` > `systemRequirement` | Unbound at an expanded level |
**Naming convention**
Navigation property names follow the data model exactly. Collection properties use plural names (e.g., `systemRequirements`). Entity references in association paths use singular names (e.g., `systemRequirement`). Property names match the `properties` section of the entity type definition.
***
## Cardinality Summary
| Cardinality | Data Model | Source Expand | Column Binding | UI Behavior |
| ----------- | ----------------------------------------------------------------- | ---------------------------------------------------------- | -------------------------------------- | ----------------------------- |
| **N:1** | `cardinality: many-to-one`, `direct: { name: chapter }` | `- name: chapter` | `chapter` or `chapter.title` | Single-value reference picker |
| **1:N** | Reverse of N:1, `back: { name: userNeeds }` | `- name: userNeeds` | `userNeeds` | Child rows (new grid level) |
| **M:N** | `cardinality: many-to-many`, `back: { name: systemRequirements }` | `- name: systemRequirements` > `- name: systemRequirement` | `systemRequirements.systemRequirement` | Multi-item reference picker |
***
## Column Properties Affecting Binding Behavior
These column properties interact directly with how the binding path resolves and displays data.
| Property | Type | Default | Description |
| ---------------- | --------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| `display` | string | `id` | Which property of the referenced entity to show in a scalar reference column (N:1). Common values: `title`, `titleOrName`, or a custom property path |
| `multiItem` | boolean | `false` | When `true`, treats a collection binding as a multi-item picker instead of expanding to child rows |
| `list` | object | `null` | Configures the picker dropdown for reference columns |
| `list.search` | string\[] | -- | Array of property names searchable in the picker dropdown |
| `list.createNew` | boolean | `false` | Enables creating new entities directly from the picker |
| `isReadOnly` | boolean | `false` | Forces the column to read-only regardless of permissions. Commonly used on `.` bindings |
| `hasFocus` | boolean | `false` | Marks the primary focus column for a given hierarchy level. If multiple levels exist, each can have its own `hasFocus` column |
| `value` | string | -- | Computes the column's content. Required on a `$`-prefixed binding; optional on a bound one, where the result is stored in the property |
| `valueType` | string | `string` | Result type of an unbound column's `value`: `string`, `number`, or `date`. Rejected on a bound binding |
***
## Multi-Item vs. Expansion
A collection navigation property can either expand into child rows (default) or render as a multi-item picker. The `multiItem` property controls this behavior.
| Configuration | Binding | Behavior |
| ------------------------ | -------------------------------------- | ------------------------------------------------------------------ |
| Default (no `multiItem`) | `systemRequirements.systemRequirement` | Creates child rows with a new grid level |
| `multiItem: true` | `systemRequirements.systemRequirement` | Renders as a multi-item picker column without creating a new level |
```yaml theme={null}
columns:
systemRequirements.systemRequirement:
title: Linked SysReqs
multiItem: true
display: title
list:
search:
- objectId
- title
```
For full details on multi-item behavior, see [Multi-Item Columns](/powersheet/reference/sheet-config/multi-item-columns).
***
## Complete YAML Example
A full sheet configuration demonstrating all binding patterns with the standard RTM entity hierarchy (`UserNeed` > `SystemRequirement` > `DesignRequirement`):
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: chapter
- name: systemRequirements
expand:
- name: systemRequirement
expand:
- name: designRequirements
expand:
- name: designRequirement
columns:
# Simple property binding (root entity)
id:
title: ID
width: 80
isReadOnly: true
title:
title: User Need
width: 200
hasFocus: true
severity:
title: Severity
width: 100
# Scalar reference binding (N:1)
chapter:
title: Chapter
display: title
list:
search:
- title
# Scalar property access (N:1 read-only)
chapter.title:
title: Chapter Title
isReadOnly: true
# Association entity binding (M:N)
systemRequirements.systemRequirement:
title: System Requirement
list:
search:
- objectId
- title
systemRequirements.systemRequirement.title:
title: SysReq Title
width: 180
hasFocus: true
systemRequirements.systemRequirement.severity:
title: SysReq Severity
width: 100
# Deep multi-level binding (M:N > M:N)
systemRequirements.systemRequirement.designRequirements.designRequirement:
title: Design Requirement
list:
search:
- objectId
- title
systemRequirements.systemRequirement.designRequirements.designRequirement.title:
title: DesReq Title
width: 180
hasFocus: true
systemRequirements.systemRequirement.designRequirements.designRequirement.description:
title: DesReq Description
width: 200
# Unbound binding -- computed, never stored
$riskScore:
title: Risk Score
width: 100
value: "() => context.entity.Probability * context.entity.Severity"
valueType: number
views:
Without Design:
columns:
systemRequirements.systemRequirement.designRequirements.designRequirement:
visible: false
systemRequirements.systemRequirement.designRequirements.designRequirement.title:
visible: false
systemRequirements.systemRequirement.designRequirements.designRequirement.description:
visible: false
sortBy:
- columnId: severity
direction: desc
```
***
## Related Pages
* [Columns](/powersheet/reference/sheet-config/columns) -- full column property reference
* [Sources](/powersheet/reference/sheet-config/sources) -- source query and expand configuration
* [Relationships](/powersheet/reference/data-model/relationships) -- data model relationship definitions
* [Navigation Directions](/powersheet/reference/data-model/navigation-directions) -- `direct` and `back` direction reference
* [Cardinality](/powersheet/reference/data-model/cardinality) -- relationship cardinality rules
* [Multi-Item Columns](/powersheet/reference/sheet-config/multi-item-columns) -- multi-item picker configuration
* [Views](/powersheet/reference/sheet-config/views) -- view overrides using binding paths
* [Display Property](/powersheet/reference/sheet-config/display-property) -- controlling display values for reference columns
* [Dynamic Value Expressions Reference](/powersheet/reference/sheet-config/dynamic-expressions) -- runtime expressions in column values
* [Add a Computed Column](/powersheet/guides/sheet-configuration/add-computed-column) -- step-by-step guide to bound and unbound computed columns
# Column Groups
Source: https://learn.nextedy.com/powersheet/reference/sheet-config/column-groups
Column groups in Nextedy POWERSHEET visually organize related columns under shared header rows with styling and optional collapse behavior.
See also: [Columns](/powersheet/reference/sheet-config/columns) | [Styles](/powersheet/reference/sheet-config/styles)
## Column Group Structure
In the rendered sheet, column groups appear as a second header row above the regular column headers, merging cells across all columns that share the same `columnGroup`. The group header includes the group name and, when `collapseTo` is set, a toggle button to expand or collapse the group.
## Column Group Properties
| Name | Type | Default | Description |
| ------------- | -------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `groupName` | `string` | Required | Display name for the column group header. Shown in the merged group header row. |
| `groupStyle` | `string` | None (white) | Color identifier applied to the grouped columns' background. Must be a predefined style name or a custom style defined in the `styles` section. |
| `headerStyle` | `string` | None (white) | Color identifier applied to all sub-headers of the group. Can be overridden by `header.style` defined on individual columns. |
| `collapseTo` | `string` | None | Binding path of the column to display when the group is collapsed. If the specified column is hidden, the last visible column in the group is shown instead. |
**Collapse behavior**
When `collapseTo` is not specified, the group does not provide a collapse option. The collapse toggle button appears in the group header only when `collapseTo` is configured.
## Defining Column Groups
Column groups are defined in the top-level `columnGroups` section. Each key is a group ID referenced by individual columns:
```yaml theme={null}
columnGroups:
requirements:
groupName: Requirements
groupStyle: darkblue
headerStyle: blue
collapseTo: title
testing:
groupName: Testing
groupStyle: darkgreen
headerStyle: green
collapseTo: validationTestCases.validationTestCase
```
## Assigning Columns to Groups
Add the `columnGroup` property to individual column definitions, referencing the group ID:
```yaml theme={null}
columns:
title:
title: Title
width: 200
columnGroup: requirements
severity:
title: Severity
width: 100
columnGroup: requirements
validationTestCases.validationTestCase:
title: Validation Tests
width: 180
columnGroup: testing
multiItem: true
```
## Predefined Styles for Groups
Use any of the predefined style names for `groupStyle` and `headerStyle`:
| Style Name | Text Color | Background Color |
| ------------- | ----------- | ---------------- |
| `none` | none | none |
| `boldTitle` | -- | -- |
| `darkgrey` | `grey700` | `grey200` |
| `grey` | `grey700` | `grey100` |
| `darkred` | `red700` | `red200` |
| `red` | `red700` | `red100` |
| `darkorange` | `orange700` | `orange200` |
| `orange` | `orange700` | `orange100` |
| `darkgreen` | `green700` | `green200` |
| `green` | `green700` | `green100` |
| `lightgreen` | `green700` | `primaryalt100` |
| `darkblue` | `blue700` | `blue200` |
| `blue` | `blue700` | `blue100` |
| `lightblue` | `blue700` | `teal100` |
| `darkteal` | `teal700` | `teal200` |
| `teal` | `teal700` | `teal100` |
| `darkpurple` | `purple700` | `purple200` |
| `purple` | `purple700` | `purple100` |
| `lightpurple` | `purple700` | `primary100` |
See [Styles](/powersheet/reference/sheet-config/styles) for the full style reference with color tokens.
## Collapse and Expand
When a group is configured with `collapseTo`, users can toggle the group between expanded and collapsed states:
* **Expanded**: All columns in the group are visible
* **Collapsed**: Only the `collapseTo` column is visible; other columns are hidden
The collapse toggle button appears in the group header row.
```yaml theme={null}
columnGroups:
sysReq:
groupName: System Requirements
groupStyle: darkblue
headerStyle: blue
collapseTo: systemRequirements.systemRequirement.title
```
**Collapse target fallback**
If the column specified in `collapseTo` is hidden (not visible), the last visible column in the group is used as the collapse target instead.
## Ungrouped Columns
Columns without an explicit `columnGroup` assignment display a blank group header. The two-row header structure (group row + column row) is maintained consistently whether groups are defined or not.
## Exporting Column Groups
Column group headers are exported to Excel when using the export feature. Merged cells span all columns in the group, displaying the group name once in the exported file.
## Complete YAML Example
```yaml theme={null}
columnGroups:
userNeed:
groupName: User Needs
groupStyle: darkpurple
headerStyle: purple
sysReq:
groupName: System Requirements
groupStyle: darkblue
headerStyle: blue
collapseTo: systemRequirements.systemRequirement.title
testing:
groupName: Testing
groupStyle: darkgreen
headerStyle: green
collapseTo: validationTestCases.validationTestCase
columns:
outlineNumber:
title: "#"
width: 80
title:
title: User Need
width: 200
hasFocus: true
columnGroup: userNeed
severity:
title: Severity
width: 100
columnGroup: userNeed
systemRequirements.systemRequirement.title:
title: Sys Req Title
width: 200
columnGroup: sysReq
hasFocus: true
systemRequirements.systemRequirement.severity:
title: Sys Req Severity
width: 100
columnGroup: sysReq
validationTestCases.validationTestCase:
title: Validation Tests
width: 180
multiItem: true
display: title
columnGroup: testing
systemRequirements.systemRequirement.verificationTestCases.verificationTestCase:
title: Verification Tests
width: 180
multiItem: true
display: title
columnGroup: testing
styles:
readOnlyStyle:
backgroundColor: grey100
formatters:
readonly:
- expression: 'true'
style: readOnlyStyle
sources:
- id: rtm
model: rtm
query:
from: UserNeed
expand:
- name: systemRequirements
title: System Requirements
expand:
- name: designRequirements
title: Design Requirements
- name: verificationTestCases
title: Verification Tests
- name: validationTestCases
title: Validation Tests
```
***
**Related pages:** [Columns](/powersheet/reference/sheet-config/columns) | [Styles](/powersheet/reference/sheet-config/styles) | [Views](/powersheet/reference/sheet-config/views)
# Columns
Source: https://learn.nextedy.com/powersheet/reference/sheet-config/columns
Columns are the primary configuration element in a Nextedy POWERSHEET sheet configuration. Each column maps a data model property path -- the **binding path** -- to a visual column in the sheet.
This page is the exhaustive property reference for column definitions. For binding path syntax details, see [Binding Syntax](/powersheet/reference/sheet-config/binding-syntax). For column grouping, see [Column Groups](/powersheet/reference/sheet-config/column-groups). For multi-value columns, see [Multi-Item Columns](/powersheet/reference/sheet-config/multi-item-columns).
***
## Column Configuration Hierarchy
All column types share the same set of properties described in this reference. The **binding path** (the YAML key) determines which entity and property the column is bound to. Every segment of a navigation path must have a corresponding `expand` entry in the [Sources](/powersheet/reference/sheet-config/sources) configuration.
***
## Column Properties Reference
| Name | Type | Default | Description |
| ------------- | ---------------------- | -------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `title` | `string` | Binding path (e.g. `0.UserNeed.title`) | Display label for the column header. If omitted, defaults to the level index, entity type, and property name derived from the binding path. |
| `width` | `number` or `string` | `'*'` | Column width. Numeric values are in pixels. String values support star-sizing (e.g. `'2*'` for double proportional width). |
| `minWidth` | `number` | `150` | Minimum column width in pixels. Prevents the column from being resized below this value. |
| `visible` | `boolean` | `true` | Controls whether the column is shown by default. Can be overridden per-view in [Views](/powersheet/reference/sheet-config/views). |
| `hasFocus` | `boolean` | `false` | Designates this column as the primary focus column for its entity level. See [Focus and URL Resolution](#focus-and-url-resolution). |
| `hasUrl` | `boolean` | `false` | Designates this column to display a link to the record in the target platform. See [Focus and URL Resolution](#focus-and-url-resolution). |
| `formatter` | `string` or `string[]` | None | References a formatter name (or array of names) from the `formatters` section. See [Formatters](/powersheet/reference/sheet-config/formatters). |
| `columnGroup` | `string` | None | Assigns the column to a visual column group. Value must be a key defined in `columnGroups`. See [Column Groups](/powersheet/reference/sheet-config/column-groups). |
| `multiItem` | `boolean` | `false` | Turns the column into a multi-item picker for many-to-many relationships. Does not create a new hierarchy level. See [Multi-Item Columns](#multi-item-columns). |
| `display` | `string` | `id` | Specifies which property of a referenced entity to display. Accepts any property path on the entity object, or a dynamic expression starting with `() =>`. See [Display vs. Render](#display-vs-render). |
| `render` | `string` | None | Server-side rendered output via a renderer or JavaScript expression. Display-only -- does not affect underlying data. See [Display vs. Render](#display-vs-render). |
| `sort` | `string` | None | Default sort direction for this column: `asc` or `desc`. Applied in addition to the global [Sort By](/powersheet/reference/sheet-config/sortby) configuration. |
| `groupBy` | `boolean` or `object` | `false` | Enables row grouping by this column's values. Can be a boolean or `{ hideCounter: boolean }`. See [Row Grouping](#row-grouping-groupby). |
| `isReadOnly` | `boolean` | `false` | Makes the column read-only regardless of user permissions or document-level settings. Use a `readOnly` formatter separately to apply visual styling. |
| `isRequired` | `boolean` | `false` | Marks the column as required. Creates custom validation before save -- a save is blocked if this column has no value. |
| `header` | `object` | None | Custom styling for the column header. Contains a `style` property referencing a named style from the `styles` section. See [Header Styling](#header-styling). |
| `list` | `object` | None | Configuration for picker/dropdown behavior when selecting related entities. See [Picker Configuration](#picker-configuration-list). |
| `frozen` | `boolean` | `false` | Freezes the column so it remains visible during horizontal scrolling. If multiple columns have `frozen: true`, the freeze boundary is set at the last frozen column. |
| `aggregate` | `string` | `sum` | Defines the calculation for the aggregate row. Accepted values: `sum`, `avg`, `min`, `max`, `count`. If omitted or invalid, defaults to `sum`. |
| `filter` | `object` | None | Defines an initial client-side value filter. See [Client-Side Filtering](#client-side-filtering-filter). |
| `format` | `string` | None | Data format string for numeric or date values (e.g. `c0$` for currency). |
| `value` | `string` | None | JavaScript arrow function that computes the column's content. On a bound column the result is stored in the property; on an unbound (`$`-prefixed) column it is displayed only. Either way the column is read-only. See [Computed Columns](#computed-columns). |
| `valueType` | `string` | `string` | Result type of an unbound column's `value`: `string`, `number`, or `date`. Only valid on an unbound column -- a bound column takes its type from the data model. See [Computed Columns](#computed-columns). |
| `formula` | `string` | None | Deprecated spelling of `value`. Identical behaviour; existing configurations keep working. Declaring both `value` and `formula` on one column is rejected. |
| `multiLine` | `boolean` | `true` | Controls whether the cell editor supports multi-line text input. |
| `wordWrap` | `boolean` | `true` | Controls whether text wraps within the cell or is clipped. |
| `type` | `string` | None | Overrides the column data type. Use `enum` for enumeration columns. |
***
## Basic Column Definition
The YAML key under `columns:` is the **binding path** -- a dot-separated path from the root entity to the target property:
```yaml theme={null}
columns:
title:
title: Title
width: 200
hasFocus: true
description:
title: Description
width: 300
multiLine: true
severity:
title: Severity
width: 100
isReadOnly: true
```
Direct property columns bind to a property on the root entity type defined in the first source.
***
## Navigation Path Columns
To display properties from related entities, use a navigation path. Each segment alternates between the **navigation property name** (the relationship) and the **entity type name** (from the data model):
```yaml theme={null}
columns:
systemRequirements.systemRequirement.title:
title: System Req Title
width: 200
hasFocus: true
systemRequirements.systemRequirement.designRequirements.designRequirement.title:
title: Design Req Title
width: 200
```
Every navigation segment in a column binding must have a corresponding `expand` entry in the [Sources](/powersheet/reference/sheet-config/sources) configuration. If you define a column with binding `systemRequirements.systemRequirement.designRequirements.designRequirement.title`, the sources must expand both `systemRequirements` and `designRequirements`:
```yaml theme={null}
sources:
- id: UserNeed
query:
from: UserNeed
expand:
- name: systemRequirements
target: systemRequirement
expand:
- name: designRequirements
target: designRequirement
```
For the complete binding syntax rules, see [Binding Syntax](/powersheet/reference/sheet-config/binding-syntax).
***
## Display vs. Render
Powersheet provides two distinct properties for controlling what a column shows. They serve different purposes and should not be confused.
| Aspect | `display` | `render` |
| --------------- | ---------------------------------------------------- | ----------------------------------------------------- |
| **Execution** | Client-side | Server-side (Velocity) or client-side (JS expression) |
| **Purpose** | Select which property of a referenced entity to show | Custom HTML or computed output for display only |
| **Data effect** | Reads from the entity property | No effect on underlying data |
| **Syntax** | Property name or arrow function `() => ...` | Renderer name or JavaScript expression |
| **Editability** | Column remains editable (unless `isReadOnly`) | Display-only output |
### Display Property
The `display` property controls which property of a referenced entity appears in the cell. It accepts:
* **A property name** on the entity object: `title`, `titleOrName`, `id`, `severity`, or any custom property path
* **A dynamic expression** starting with `() =>`: a JavaScript arrow function that returns the desired display value
```yaml theme={null}
columns:
systemRequirements.systemRequirement:
title: System Requirement
display: titleOrName
width: 250
hazards.hazard:
title: Hazard
display: "() => context.entity.title + ' [' + context.entity.id + ']'"
width: 300
```
For the full reference, see [Display Property](/powersheet/reference/sheet-config/display-property).
### Render Property
The `render` property references a renderer defined in the `renderers` section or provides an inline JavaScript expression. The output is display-only HTML and does not affect the data model. This is an important difference from `value` on a bound column, which does affect the data -- see [Computed Columns](#computed-columns).
```yaml theme={null}
columns:
customSummary:
title: Summary
render: summaryRenderer
renderers:
summaryRenderer: "() => `${context.entity.title} (${context.entity.status})`"
```
Each renderer has access to `context`:
* `item` -- the current entity
* `value` -- the cell value
For the full reference, see [Render Property](/powersheet/reference/sheet-config/render-property).
***
## Focus and URL Resolution
The `hasFocus` and `hasUrl` properties control which column receives keyboard focus and which column displays the external platform link.
### Focus Column (`hasFocus`)
* Defines the primary focus column for a given entity level. When a new row is created, focus moves to this column.
* If multiple columns at the same level have `hasFocus: true`, only the first one found is accepted.
* If no column has `hasFocus`, the first column with `hasUrl` is used as the focus column.
* If neither `hasFocus` nor `hasUrl` is set, the first editable column at that level receives focus.
### URL Column (`hasUrl`)
* Defines the column that displays a clickable link to the record in Polarion (or other target platform).
* The link is only displayed if the record has a `targetLink` defined.
* Multiple columns can have `hasUrl: true` to show the link in several places.
* If no column has `hasUrl` but a column has `hasFocus` and is valid, the link appears there instead.
* If neither is configured, the first valid column for that level displays the link.
Only `string` and `number` columns are supported for URL display. Columns with `multiLine: true` are not supported. Columns with custom rendering also do not show the external link.
```yaml theme={null}
columns:
title:
title: Title
width: 200
hasFocus: true
hasUrl: true
```
***
## Computed Columns
The `value` property defines a computed column whose content is calculated from an expression instead of read directly from a stored property. It must be a valid JavaScript arrow function starting with `() =>`.
Whether the result is stored is decided by the **binding key**, not by `value`:
| Binding | `value` | Result |
| ------------ | ------- | -------------------------------------------------------------------------------------------------------------- |
| `riskScore` | not set | Ordinary stored column, editable by the user |
| `riskScore` | set | Computed **and stored** -- the result is written to the property, marks the row modified, and persists on save |
| `$riskScore` | set | Computed and **displayed only** -- nothing is stored and nothing is saved |
| `$riskScore` | not set | Configuration error -- an unbound column has no expression to derive its content from |
A computed column is always read-only to the user, in both forms.
```yaml theme={null}
columns:
# stored: the result is written back to the riskScore property
riskScore:
title: Risk Score
value: "() => context.entity.Probability * context.entity.Severity"
width: 100
# display-only: no property behind it, nothing is stored
$weightedScore:
title: Weighted Score
value: "() => context.entity.Probability * context.entity.Severity * 1.5"
valueType: number
format: "n1"
width: 100
```
For the `$` binding rules, see [Binding Syntax](/powersheet/reference/sheet-config/binding-syntax#unbound-columns). For the `context` object and where each expression runs, see [Dynamic Value Expressions](/powersheet/reference/sheet-config/dynamic-expressions). For a step-by-step walkthrough, see [Add a Computed Column](/powersheet/guides/sheet-configuration/add-computed-column).
**`value` is about data; `render` is about appearance.**
`value` decides what the cell contains -- and, on a bound column, what gets saved. `render` produces display-only HTML from whatever the cell already holds. To show a calculated value without storing it, use an unbound `$` column with `value`, not `render`.
**`formula` is deprecated. Use `value`.**
Both names mean the same thing and existing configurations keep working unchanged, but `formula` is deprecated -- use `value` in new configurations. Declaring both on one column is rejected with `declares both 'value' and 'formula'`.
### Unbound Column Constraints
An unbound column stores nothing and resolves no metadata, so these properties are rejected on it: `isRequired`, `multiItem`, and `list`. `aggregate` requires `valueType: number`. `valueType` itself is rejected on a *bound* column.
`render`, `renderers`, `format`, `groupBy`, `sort`, `filter`, `columnGroup`, and the styling properties all work normally, and unbound columns take part in grouping, sorting, filtering, sheet search, and Excel export.
***
## Multi-Item Columns
Setting `multiItem: true` turns a column into a multi-item picker. This is used for **many-to-many** relationships where multiple related entities should be displayed and selectable without creating an additional hierarchy level.
```yaml theme={null}
columns:
testCases.testCase:
title: Test Cases
multiItem: true
display: title
list:
search:
- title
- id
```
Multi-item columns do not support one-to-many relationships at this time. Use navigation path columns with `expand` to display one-to-many relationships as separate hierarchy levels instead.
For the full reference, see [Multi-Item Columns](/powersheet/reference/sheet-config/multi-item-columns).
***
## Picker Configuration (`list`)
The `list` property configures the dropdown picker behavior when a column is bound to a reference (related entity).
| Sub-property | Type | Default | Description |
| ---------------- | ---------- | ------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `list.search` | `string[]` | None | Array of property names to search when filtering entities in the picker dropdown. Enables search across the specified fields. |
| `list.createNew` | `boolean` | `false` | Enables or disables creating a new entity directly from the dropdown picker. |
```yaml theme={null}
columns:
systemRequirements.systemRequirement:
title: System Requirement
display: title
list:
search:
- title
- id
- description
createNew: true
```
***
## Client-Side Filtering (`filter`)
The `filter` property defines an initial client-side value filter applied when the sheet loads. Only rows matching the filter values are shown; all other values are hidden.
```yaml theme={null}
columns:
status:
title: Status
filter:
values:
- Open
- In Progress
```
| Sub-property | Type | Description |
| --------------- | ---------- | ------------------------------------------------------------- |
| `filter.values` | `string[]` | Array of values to display. All values not listed are hidden. |
### Interactive sort and filter controls
Beyond the configured initial filter, users can sort and filter any column at runtime. Selecting a column in the work items tree reveals sort arrows and a funnel filter icon next to the column title:
Clicking the funnel opens a filter dialog with two tabs: **Value** (pick the specific values to keep visible) and **Condition** (define a filter expression). The dialog supports a search field, Select All, an eraser to clear the filter, and Cancel/Apply buttons.
Once a filter is active, the funnel icon in the column header turns green, and the toolbar shows the filtered row count (e.g. **17 / 54 rows**) alongside a global funnel indicator:
To remove all active filters at once, use **Menu > Filter & Sort > Clear all filters**:
***
## Row Grouping (`groupBy`)
The `groupBy` property enables grouping rows by the column's values. It supports two forms:
**Boolean (legacy):**
```yaml theme={null}
columns:
category:
title: Category
groupBy: true
```
**Object with options:**
```yaml theme={null}
columns:
category:
title: Category
groupBy:
hideCounter: true
```
When `hideCounter` is `true`, the item count next to each group header is hidden. By default, the group row counter visibility is controlled by the root-level `showGroupRowCounter` property.
***
## Header Styling
The `header` property controls the visual appearance of the column header. It references a named style from the `styles` section.
```yaml theme={null}
columns:
severity:
title: Severity
header:
style: dangerHeader
styles:
dangerHeader:
color: red700
backgroundColor: red100
```
The `header.style` value can be shared across columns using YAML anchors:
```yaml theme={null}
columns:
probability:
title: Probability
header: &riskHeader
style: riskStyle
severity:
title: Severity
header: *riskHeader
```
The `headerStyle` value from the column's `columnGroup` is applied by default and can be overridden by `header.style` on the individual column.
For the full style reference, see [Styles](/powersheet/reference/sheet-config/styles).
***
## Frozen Columns
Setting `frozen: true` freezes the column so it remains visible when scrolling horizontally. If multiple columns have `frozen: true`, the freeze boundary is placed at the **last** frozen column -- all columns up to and including that column are frozen.
```yaml theme={null}
columns:
id:
title: ID
width: 80
frozen: true
title:
title: Title
width: 200
frozen: true
```
***
## Aggregate Row
The `aggregate` property defines a calculation displayed in the aggregate (summary) row at the bottom of the sheet.
| Value | Calculation |
| ------- | --------------------------- |
| `sum` | Sum of all values (default) |
| `avg` | Average of all values |
| `min` | Minimum value |
| `max` | Maximum value |
| `count` | Count of non-empty values |
```yaml theme={null}
columns:
storyPoints:
title: Story Points
aggregate: sum
probability:
title: Probability
aggregate: avg
```
***
## Column with Formatter
Reference a formatter to apply conditional styling or enforce read-only behavior:
```yaml theme={null}
columns:
outlineNumber:
title: "#"
width: 80
formatter: readonly
isReadOnly: true
```
The referenced formatter must be defined in the `formatters` section:
```yaml theme={null}
formatters:
readonly:
expression: "true"
style: readOnlyStyle
```
A column can also reference multiple formatters using an array:
```yaml theme={null}
columns:
severity:
title: Severity
formatter:
- severityHighlight
- readonly
```
See [Formatters](/powersheet/reference/sheet-config/formatters) for the full formatter reference.
***
## Complete YAML Example
A complete sheet configuration demonstrating the key column properties in a requirements traceability context:
```yaml theme={null}
columnGroups:
userNeeds:
groupName: User Needs
groupStyle: indigo
headerStyle: indigo
sysReqs:
groupName: System Requirements
groupStyle: purple
headerStyle: purple
collapseTo: systemRequirements.systemRequirement.title
designReqs:
groupName: Design Requirements
groupStyle: orange
headerStyle: orange
columns:
outlineNumber:
title: "#"
width: 80
sort: asc
formatter: readonly
isReadOnly: true
frozen: true
title:
title: User Need
width: 250
hasFocus: true
hasUrl: true
columnGroup: userNeeds
wordWrap: true
severity:
title: Severity
width: 100
columnGroup: userNeeds
formatter: severityFormatter
description:
title: Description
width: 300
visible: false
multiLine: true
systemRequirements.systemRequirement.title:
title: System Req
width: 200
hasFocus: true
hasUrl: true
columnGroup: sysReqs
display: titleOrName
header: &sysReqHeader
style: purple
systemRequirements.systemRequirement.status:
title: Status
width: 100
columnGroup: sysReqs
groupBy: true
header: *sysReqHeader
filter:
values:
- Open
- In Review
systemRequirements.systemRequirement.designRequirements.designRequirement.title:
title: Design Req
width: 200
hasFocus: true
columnGroup: designReqs
display: title
list:
search:
- title
- id
riskScore:
title: Risk Score
width: 80
value: "() => context.entity.Probability * context.entity.Severity"
aggregate: avg
$weightedScore:
title: Weighted Score
width: 80
value: "() => context.entity.Probability * context.entity.Severity * 1.5"
valueType: number
aggregate: avg
sortBy:
- columnId: severity
direction: desc
sources:
- id: UserNeed
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: designRequirements
formatters:
severityFormatter:
expression: "context.entity.severity === 'Critical'"
style: criticalStyle
readonly:
expression: "true"
style: readOnlyStyle
styles:
criticalStyle:
color: red700
backgroundColor: red100
readOnlyStyle:
backgroundColor: grey100
views:
Without Design Reqs:
columns:
systemRequirements.systemRequirement.designRequirements.designRequirement.title:
visible: false
Critical Only:
default: true
columns:
severity:
filter:
values:
- Critical
```
Start with a minimal single-entity configuration (one source, a few direct property columns) and extend gradually. Adding navigation path columns, formatters, and views incrementally makes configuration errors easier to diagnose.
***
## Column Property Categories
### Display Properties
| Property | Type | Default | Description |
| ---------- | ------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `title` | string | None | Display label for the column header |
| `width` | number/string | `"*"` | Column width in pixels (number) or proportional width (string with `*`, e.g., `"*"`, `"2*"`) |
| `minWidth` | number | `150` | Minimum column width in pixels for responsive layouts |
| `visible` | boolean | `true` | Controls whether the column is shown in the default view. Can be overridden in [views](/powersheet/reference/sheet-config/views). |
| `display` | string | `id` | Specifies which property of a referenced entity to display. See [Display Property](/powersheet/reference/sheet-config/display-property). |
| `render` | string | None | Custom HTML rendering function or predefined renderer name. See [Render Property](/powersheet/reference/sheet-config/render-property). |
### Behavior Properties
| Property | Type | Default | Description |
| ------------ | ------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `hasFocus` | boolean | `false` | Indicates this column receives initial focus for user interaction. Auto-configured to first editable column if not set. |
| `isReadOnly` | boolean | `false` | Prevents user editing of this column. To also apply visual read-only styling (greyed-out background), add a separate `formatter: readOnly` reference. |
| `multiItem` | boolean | `false` | Indicates this column displays multiple related items. See [Multi-Item Columns](/powersheet/reference/sheet-config/multi-item-columns). |
| `sort` | string | None | Default sort direction for this column. Values: `"asc"`, `"desc"`. |
| `groupBy` | boolean | `false` | Enables row grouping by this column's values |
### Styling Properties
| Property | Type | Default | Description |
| -------------- | ------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `header` | object | None | Custom styling for the column header. Contains `style` sub-property referencing a named style. |
| `header.style` | string | None | Name of a predefined or custom [style](/powersheet/reference/sheet-config/styles) to apply to the column header |
| `formatter` | string | None | References a formatter name from the [formatters](/powersheet/reference/sheet-config/formatters) section to apply conditional styling |
| `columnGroup` | string | None | Assigns the column to a visual [column group](/powersheet/reference/sheet-config/column-groups) |
### Picker Properties
| Property | Type | Default | Description |
| ---------------- | ------- | ------- | ------------------------------------------------------------------------------- |
| `list` | object | None | Configuration for picker/dropdown lists when selecting related entities |
| `list.search` | array | None | Array of property names to search when filtering entities in picker dropdowns |
| `list.display` | string | None | JavaScript function string for custom dropdown item rendering |
| `list.createNew` | boolean | `false` | Whether to allow creating new linked items directly from the dropdown |
| `list.options` | string | None | For enum types, references a query ID from sources that provides enum values |
| `list.value` | string | None | For enums, the property name from the options source to use as the actual value |
| `list.order` | string | None | For enums, the property name from the options source to sort the list by |
### Example: Simple Column
```yaml theme={null}
columns:
id:
width: 80
title:
title: Title
width: 200
hasFocus: true
```
### Example: Navigation Column
```yaml theme={null}
columns:
systemRequirements.systemRequirement.title:
title: System Requirement
width: 180
columnGroup: sysReq
header:
style: blue
```
### Example: Reference Column with Picker
```yaml theme={null}
columns:
hazard:
title: Hazard
display: title
list:
search:
- title
- id
```
### Example: Multi-Item Column
```yaml theme={null}
columns:
riskControls.riskControl:
title: Risk Controls
width: 160
multiItem: true
display: title
list:
search:
- title
- id
```
***
## Property Quick Reference
For related configuration sections:
| Section | Reference |
| --------------------- | ----------------------------------------------------------------------------------- |
| Binding syntax | [Binding Syntax](/powersheet/reference/sheet-config/binding-syntax) |
| Column groups | [Column Groups](/powersheet/reference/sheet-config/column-groups) |
| Views | [Views](/powersheet/reference/sheet-config/views) |
| Formatters | [Formatters](/powersheet/reference/sheet-config/formatters) |
| Styles | [Styles](/powersheet/reference/sheet-config/styles) |
| Sources and expansion | [Sources](/powersheet/reference/sheet-config/sources) |
| Sort configuration | [Sort By](/powersheet/reference/sheet-config/sortby) |
| Display property | [Display Property](/powersheet/reference/sheet-config/display-property) |
| Render property | [Render Property](/powersheet/reference/sheet-config/render-property) |
| Multi-item columns | [Multi-Item Columns](/powersheet/reference/sheet-config/multi-item-columns) |
| Dynamic expressions | [Dynamic Value Expressions](/powersheet/reference/sheet-config/dynamic-expressions) |
| Computed columns | [Add a Computed Column](/powersheet/guides/sheet-configuration/add-computed-column) |
# Display Property
Source: https://learn.nextedy.com/powersheet/reference/sheet-config/display-property
The `display` property in a Nextedy POWERSHEET column configuration controls which property of a referenced entity is shown in the cell when the column is bound to a navigation property (a relationship).
## Property Definition
| Property | Type | Default | Description |
| ----------------------- | ------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `columns..display` | string | `id` | Specifies which property of a referenced entity to display. Accepts a property name (`title`, `titleOrName`, `id`) or a JavaScript arrow function string for custom rendering. |
## Display Values
| Value | Description |
| ------------------ | --------------------------------------------------------------------- |
| `id` | Shows the entity's ID (default) |
| `title` | Shows the entity's title property |
| `titleOrName` | Shows the title if available, otherwise falls back to the entity name |
| Custom property | Any valid property name from the referenced entity type |
| JS function string | Arrow function returning custom HTML (see below) |
## Display Resolution Flow
## Simple Property Display
Show the `title` property of a referenced `Hazard` entity:
```yaml theme={null}
columns:
hazard:
title: Hazard
display: title
```
Show the `titleOrName` property with fallback:
```yaml theme={null}
columns:
hazard:
title: Hazard
display: titleOrName
```
## JavaScript Function Display
Use a JavaScript arrow function string to return custom HTML. The function has access to a `context` object.
### Context Object
| Variable | Description |
| --------------------------------------- | ------------------------------------------------------------------------------ |
| `context.value` | The current cell value (the referenced entity or property value) |
| `context.entity` | The entity at the column's level, with properties such as `projectId` and `id` |
| `context.polarionModel.polarionBaseUrl` | Base URL of the Polarion server |
### Example: Icon with Link
```yaml theme={null}
columns:
riskControls.riskControl:
title: Risk Control
display: >
() => `
${context.value.objectId}
`
```
**Multi-Line YAML Strings**
Use the `>` (folded scalar) indicator for multi-line JavaScript function strings in YAML. The function is evaluated in the browser at render time.
## Display vs Render
Both `display` and [render](/powersheet/reference/sheet-config/render-property) can accept JavaScript function strings, but they serve different purposes:
| Property | Primary Use | When to Use |
| --------- | ---------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `display` | Property name selection for navigation columns | Use when you need to select which property of a referenced entity to show, or when using a simple JS function |
| `render` | Custom HTML cell rendering | Use when `display` is already used for property selection and you need additional rendering control. Can also reference predefined renderer names. |
**display and render Interaction**
When both `display` and `render` are set on the same column, `render` typically takes precedence for visual output. Use `display` for property selection and `render` for custom HTML when both are needed.
## Complete YAML Example
```yaml theme={null}
columns:
outlineNumber:
title: "#"
width: 80
title:
title: User Need
width: 200
hasFocus: true
hazard:
title: Hazard
display: title
list:
search:
- title
- id
riskControls.riskControl:
title: Risk Control
width: 160
multiItem: true
display: >
() => `
${context.value.objectId}
`
list:
search:
- title
- id
display: >
() => `
${context.value.objectId} ${context.value.title ? '- ' + context.value.title : ''}`
sources:
- id: main
model: rtm
query:
from: UserNeed
where: "type = 'UserNeed'"
expand:
- name: hazards
title: Hazards
expand:
- name: riskControls
title: Risk Controls
```
## Related Pages
* [Render Property](/powersheet/reference/sheet-config/render-property) -- custom HTML rendering as an alternative to `display`
* [Columns](/powersheet/reference/sheet-config/columns) -- full column property reference
* [Binding Syntax](/powersheet/reference/sheet-config/binding-syntax) -- column key patterns for navigation properties
* [Multi-Item Columns](/powersheet/reference/sheet-config/multi-item-columns) -- display for collections
***
# Dynamic Value Expressions Reference
Source: https://learn.nextedy.com/powersheet/reference/sheet-config/dynamic-expressions
Nextedy POWERSHEET configurations support **dynamic value expressions** — values resolved at runtime based on the current context such as the active document, logged-in user, URL parameters, or the source entity.
## Expression Notations Overview
Powersheet uses two distinct expression notations depending on the configuration file type:
| Notation | Syntax | Configuration File | Purpose |
| ---------------------- | ------------------------ | ------------------------------------------------------- | ------------------------------------------- |
| **Context expression** | `$context.property.path` | Data model YAML (constraints) | Dot-notation property access, no JavaScript |
| **Dynamic value** | `() => expression` | Sheet configuration YAML (sources, columns, formatters) | Full JavaScript arrow function |
**Rule of Thumb**
If you are editing a **data model** YAML file (`domainModelTypes`, `relationships`), use `$context`. If you are editing a **sheet configuration** YAML file (`sources`, `columns`, `formatters`), use `() =>`.
***
## Context Expression (`$context`)
Context expressions use **dot-notation** to access properties from the runtime context object. They are used exclusively in **data model configuration** — specifically in [constraint](/powersheet/reference/data-model/constraints) definitions. No JavaScript logic is supported; only direct property path access.
### Where `$context` Is Used
| Configuration Location | Description |
| ------------------------------------ | ------------------------------- |
| `domainModelTypes.*.constraints` | Entity type constraints |
| `relationships.*.direct.constraints` | Direct relationship constraints |
| `relationships.*.back.constraints` | Back relationship constraints |
### Available Context Paths
| Path | Type | Description | Example Value |
| --------------------------------------- | -------- | ------------------------------------ | ----------------------------------- |
| `$context.source.type` | `string` | Source entity's work item type | `"sys_req"` |
| `$context.source.document.id` | `string` | Source entity's document ID | `"Requirements/SRS"` |
| `$context.source.document.moduleName` | `string` | Source entity's document module name | `"UserNeedSpecification"` |
| `$context.source.document.moduleFolder` | `string` | Source entity's document folder | `"Requirements"` |
| `$context.source.document.component` | `string` | Source entity's document component | `"Braking"` |
| `$context.source.document.type` | `string` | Source entity's document type | `"systemRequirementsSpecification"` |
| `$context.source.document.title` | `string` | Source entity's document title | `"System Requirements"` |
**Per-Row Evaluation**
Dynamic constraints with `$context` are evaluated **per-row**. Different rows can produce different constraint values depending on their source entity's properties.
### `$context` Examples
**Filter linked items to the same document component as the source item:**
```yaml theme={null}
relationships:
- from: DesignRequirement
to: SystemRequirement
back:
name: designRequirements
constraints:
load:
document:
component: $context.source.document.component
```
When viewing a `SystemRequirement` from the "Braking" component, only `DesignRequirement` items from "Braking" documents are loaded.
**Filter linked items to the same document as the source item:**
```yaml theme={null}
constraints:
load:
document:
moduleName: $context.source.document.moduleName
moduleFolder: $context.source.document.moduleFolder
```
**Filter by source entity's document type (pick constraint):**
```yaml theme={null}
constraints:
pick:
document:
type: $context.source.document.type
```
***
## Dynamic Value (`() => expression`)
Dynamic values use **JavaScript arrow function** syntax and are used in **sheet configuration** YAML. They provide full JavaScript expressiveness for computing values, filtering data, and rendering content at runtime.
### How It Works
A `() =>` expression is a JavaScript arrow function that receives a `context` object. Powersheet evaluates the function at runtime and uses the returned value. The expression must be enclosed in quotes in the YAML configuration.
```yaml theme={null}
# General syntax
propertyName: "() => expression using context"
```
### Where `() =>` Is Used
| Sheet Configuration Property | Purpose | Example |
| ---------------------------- | -------------------------------------------------------------- | ------------------------------------------------------- |
| `sources[].query.where` | Filter data with dynamic predicates | `"() => context.document.moduleName"` |
| `sources[].entityFactory` | Set initial values for new items | `"() => context.source.type + '_VerificationTestCase'"` |
| `columns.*.value` | Compute a column's content from other properties | `"() => context.entity.count * context.entity.rate"` |
| `columns.*.formula` | Deprecated spelling of `columns.*.value` — identical behaviour | `"() => context.entity.qty * context.entity.price"` |
| `columns.*.render` | Custom HTML rendering for cells | `"() => '' + context.value + ' '"` |
| `columns.*.display` | Override display value for navigation properties | `"() => context.entity.titleOrName"` |
| `renderers.*` | Named renderer definitions | `"() => context.value.map(...)"` |
| `formatters.*.expression` | Conditional formatting expressions | `"context.entity.Probability <= 99"` |
**`value` is about data; `render` and `display` are about appearance.**
On a column bound to a real property, `value` affects **persisted data** — the computed result is saved back to that property. Use `render` if you only need to change how a value is **displayed** without modifying the underlying data. If the result should never be stored at all, prefix the binding key with `$` to make the column [unbound](/powersheet/reference/sheet-config/binding-syntax#unbound-columns).
**`formula` is deprecated. Use `value`.**
Both names mean exactly the same thing, and existing configurations keep working unchanged, but `formula` is deprecated. Write `value` in new configurations. Declaring both on one column is rejected. See [Computed Columns](/powersheet/reference/sheet-config/columns#computed-columns).
**Formatter Exception**
Formatter expressions use a simplified syntax — they do **not** start with `() =>`. The expression is evaluated as a boolean condition directly (e.g., `"context.entity.Risk > 50"`).
***
## The Context Object
The context object provides runtime information to dynamic expressions. Its structure is hierarchical, and properties are progressively available depending on the evaluation scope.
```
context
+-- parameters Configuration parameters (e.g. model ID)
| +-- model e.g. context.parameters.model
+-- user Current logged-in user
| +-- id, name
+-- sources All configured data source definitions
+-- document Current document information
| +-- title, type, id, moduleName, moduleFolder, component
+-- tool Current tool information
| +-- type
+-- entity Current entity (per-cell contexts only)
| +-- {propertyName} e.g. context.entity.severity
+-- source Parent/source entity — the level navigated from
| +-- type, document.* e.g. context.source.type
+-- row The whole row across every level
| +-- entities[] e.g. context.row.entities[0]
+-- value Current cell's display value
+-- item Deprecated alias of context.entity
```
### Context Availability by Location
Not all context properties are available in every expression location. The following table shows which properties are accessible where:
| Usage Location | `context.user` | `context.sources` | `context.document` | `context.entity` | `context.value` | `context.source` | `context.row` | `context.item` |
| ---------------------------- | :------------: | :---------------: | :----------------: | :--------------: | :-------------: | :--------------: | :-----------: | :------------: |
| `where` (source query) | ✅ | ✅ | ✅ | — | — | — | — | — |
| `entityFactory` | ✅ | ✅ | — | — | — | ✅ | — | — |
| `value` on a bound column | ✅ | ✅ | — | ✅ | — | — | — | ✅ |
| `value` on an unbound column | ✅ | ✅ | — | ✅ | — | ✅ | ✅ | ✅ |
| `render` / `renderers` | — | — | — | ✅ | ✅ | — | — | ✅ |
| `formatter` | — | — | ✅ | ✅ | ✅ | — | — | ✅ |
| `display` | — | — | — | ✅ | ✅ | ✅ | — | ✅ |
`context.item` is deprecated because it's ambiguous — in some cell expressions it's the entity, in others the whole row. Use `context.entity` or `context.row` instead; each always means exactly one thing.
**A computed column starts from no cell value.**
`context.value` is `undefined` inside a `value` expression, whether the column is bound or unbound, because the cell has nothing stored yet. Read what you need from `context.entity` instead.
Only an **unbound** column's `value` expression receives `context.row` and `context.source`. A bound `value` column is evaluated as a calculated property of the entity alone, with no row behind it.
### Context Properties Reference
| Property | Type | Description |
| ------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `context.parameters` | `object` | Configuration parameters bag |
| `context.parameters.model` | `string` | Data model identifier for the active sheet configuration |
| `context.user` | `object` | Current logged-in user information |
| `context.user.id` | `string` | User identifier |
| `context.user.name` | `string` | Display name of the current user |
| `context.sources` | `array` | All configured data source definitions from the sheet configuration |
| `context.document` | `object` | Current document metadata |
| `context.document.title` | `string` | Document title |
| `context.document.type` | `string` | Document type identifier |
| `context.document.id` | `string` | Document ID |
| `context.document.moduleName` | `string` | LiveDoc module name |
| `context.document.moduleFolder` | `string` | LiveDoc module folder path |
| `context.document.component` | `string` | Document component identifier |
| `context.tool` | `object` | Current tool information |
| `context.tool.type` | `string` | Tool type identifier |
| `context.entity` | `object` | Current entity being processed (per-cell only). For a column with a navigation binding path, this is the entity the path resolves to |
| `context.entity.{propertyName}` | `any` | Any property of the current entity, accessed by name |
| `context.source` | `object` | Parent/source entity — the level the current one was navigated from |
| `context.source.type` | `string` | Parent entity's work item type |
| `context.row` | `object` | The whole row the cell belongs to |
| `context.row.entities` | `array` | One entry per navigation level, indexed from the root; an entry is `undefined` where the row has no entity at that level |
| `context.value` | `any` | Current cell's resolved display value. A JSON object or array is decoded; any other string is passed through unchanged |
| `context.item` | `object` | **Deprecated.** Alias of `context.entity` in cell expressions. Kept so existing configurations keep working |
***
## Expression Examples by Use Case
### Source Query Filtering (`where`)
**Filter to items in the current document module:**
```yaml theme={null}
sources:
- id: requirements
query:
from: SystemRequirement
where:
document.moduleName:
"==": "() => context.document.moduleName"
```
This restricts the source query to work items that belong to the same LiveDoc module as the document the sheet is embedded in.
**Filter by today's date (future items only):**
```yaml theme={null}
sources:
- id: tasks
query:
from: Task
where:
DueDate:
">": "() => new Date().toISOString()"
```
**Date Formatting**
The resulting value must be in the correct format for the data type. For date fields, always use `.toISOString()` to produce the expected ISO 8601 string.
### Entity Factory (Default Values for New Items)
**Derive default values from the parent (source) entity:**
```yaml theme={null}
sources:
- id: verificationTestCases
query:
from: VerificationTestCase
entityFactory:
title: "() => context.source.type + '_VerificationTestCase'"
status: Draft
```
In nested or relationship-driven contexts, `entityFactory` uses `context.source` to access properties of the parent entity that triggered the row creation. Static values (like `status: Draft` above) and dynamic expressions can be mixed freely in the same `entityFactory` block.
### Column Value (Computed Columns)
**Compute a value from other entity properties and store it in the bound property:**
```yaml theme={null}
columns:
total:
value: "() => context.entity.count * context.entity.rate"
title: Total Price
```
A computed column is read-only by definition — its content comes from the expression, so there is no need to declare `isReadOnly`.
**Concatenate string properties:**
```yaml theme={null}
columns:
fullName:
value: "() => `${context.entity.firstName} ${context.entity.lastName}`"
title: Full Name
```
**Compute a value that is displayed but never stored:**
Prefix the binding key with `$` to make the column unbound. It has no property behind it, so declare the result type with `valueType`:
```yaml theme={null}
columns:
$riskScore:
title: Risk Score
value: "() => context.entity.Probability * context.entity.Severity"
valueType: number
```
**Reach the level above, or the whole row, from an unbound column:**
```yaml theme={null}
columns:
systemRequirements.systemRequirement.$origin:
title: Origin
value: "() => `${context.source.id} → ${context.entity.id}`"
```
See [Add a Computed Column](/powersheet/guides/sheet-configuration/add-computed-column) for the full walkthrough and [Computed Columns](/powersheet/reference/sheet-config/columns#computed-columns) for the property reference.
### Column Render (Display-Only HTML)
**Bold rendering of a cell value:**
```yaml theme={null}
columns:
title:
render: "() => `${context.value} `"
```
### Named Renderers
**Render a collection of linked items as a comma-separated list:**
```yaml theme={null}
renderers:
linkedItems: "() => context.value.map((item) => `${item.name} `).join(', ')"
```
Reference the renderer by name from a column:
```yaml theme={null}
columns:
systemRequirements.systemRequirement.title:
render: linkedItems
```
### Column Display (Navigation Property Override)
The `display` property overrides what users see for a navigation column without changing the underlying data binding. It is the most common location for short, focused `() =>` expressions.
**Show the linked entity's title or fall back to its name:**
```yaml theme={null}
columns:
systemRequirements.systemRequirement:
display: "() => context.entity.titleOrName"
```
`titleOrName` is a convenient idiom for entities that may have either a `title` (work items with rich descriptions) or only a `name` (lightweight reference entities).
**Show only the title of the linked entity:**
```yaml theme={null}
columns:
systemRequirements.systemRequirement:
display: "() => context.entity.title"
```
**Show the linked entity's parent document title instead of the entity itself:**
```yaml theme={null}
columns:
systemRequirement.document:
display: "() => context.document.title"
```
**Compose a display string from multiple properties of the linked entity:**
```yaml theme={null}
columns:
designRequirements.designRequirement:
display: "() => `${context.entity.id} — ${context.entity.title}`"
```
This pattern is useful when a column shows a single linked item but you want a richer label (for example, an ID prefix followed by a human-readable title).
### Conditional Formatting (Formatters)
**Highlight rows where probability is below a threshold:**
```yaml theme={null}
formatters:
criticalHighlight:
expression: "context.entity.Probability <= 99"
style: warningStyle
styles:
warningStyle:
color: red700
backgroundColor: red100
textDecoration: line-through
```
Formatter expressions do **not** use the `() =>` prefix. They are evaluated directly as boolean conditions. The formatter references a [style](/powersheet/reference/sheet-config/styles) definition.
***
## Complete YAML Example
A full sheet configuration demonstrating multiple dynamic expression patterns:
```yaml theme={null}
sources:
- id: userNeeds
query:
from: UserNeed
where:
Status:
"!=": "() => 'Rejected'"
DueDate:
">": "() => new Date().toISOString()"
document.moduleName:
"==": "() => context.document.moduleName"
entityFactory:
Status: Draft
expand:
- name: systemRequirements
expand:
- name: designRequirements
columns:
id:
title: ID
width: 80
isReadOnly: true
title:
title: User Need
width: 200
hasFocus: true
priority:
title: Priority
width: 100
formatter: highPriority
riskScore:
title: Risk Score
width: 120
value: "() => context.entity.severity * context.entity.probability"
$riskBand:
title: Risk Band
width: 100
value: "() => context.entity.severity * context.entity.probability > 50 ? 'High' : 'Low'"
valueType: string
systemRequirements.systemRequirement:
title: System Requirement
width: 220
display: "() => context.entity.titleOrName"
systemRequirements.systemRequirement.designRequirements.designRequirement:
title: Design Requirement
width: 220
display: "() => context.entity.title"
renderers:
linkedItems: "() => context.value.map((item) => `${item.name} `).join(', ')"
formatters:
highPriority:
expression: "context.entity.priority === 'Critical'"
style: criticalStyle
styles:
criticalStyle:
color: red700
backgroundColor: red100
views:
Without Design:
columns:
systemRequirements.systemRequirement.designRequirements.designRequirement:
visible: false
sortBy:
- columnId: priority
direction: desc
- columnId: title
direction: asc
```
***
## Quick Reference
| I want to... | Notation | Example |
| ------------------------------------------- | ---------- | ----------------------------------------------------------- |
| Filter relationship by source document | `$context` | `component: $context.source.document.component` |
| Filter query by current document module | `() =>` | `"==": "() => context.document.moduleName"` |
| Filter query by current date | `() =>` | `">": "() => new Date().toISOString()"` |
| Compute a column and store the result | `() =>` | `value: "() => context.entity.count * context.entity.rate"` |
| Compute a column without storing anything | `() =>` | `$total:` with `value: "() => …"` and `valueType: number` |
| Read the level above from a computed column | `() =>` | `value: "() => context.source.id"` |
| Render custom HTML in a cell | `() =>` | `render: "() => '' + context.value + ' '"` |
| Set default from parent entity | `() =>` | `title: "() => context.source.type + '_TC'"` |
| Conditionally style a cell | expression | `expression: "context.entity.Risk > 50"` |
| Display linked entity title-or-name | `() =>` | `display: "() => context.entity.titleOrName"` |
| Display the linked document title | `() =>` | `display: "() => context.document.title"` |
| Render a collection as HTML | `() =>` | `"() => context.value.map(i => i.name).join(', ')"` |
***
## Common Patterns and Edge Cases
### Combining Static and Dynamic Values
In `entityFactory`, static and dynamic values coexist. Only values with the `() =>` prefix are evaluated at runtime:
```yaml theme={null}
entityFactory:
status: Draft # Static — always this value
title: "() => context.source.type + '_TC'" # Dynamic — resolved at runtime
```
### Multiple `$context` Constraints
You can combine multiple `$context` paths in a single constraint block to narrow the filter:
```yaml theme={null}
constraints:
load:
document:
moduleName: $context.source.document.moduleName
moduleFolder: $context.source.document.moduleFolder
component: $context.source.document.component
```
### Display Variants for the Same Navigation Column
A single navigation column can render very differently depending on the `display` expression. The same binding `systemRequirements.systemRequirement` can show:
```yaml theme={null}
# Variant A: short — falls back to name when title is missing
display: "() => context.entity.titleOrName"
# Variant B: explicit — title only (blank if missing)
display: "() => context.entity.title"
# Variant C: composed — ID and title together
display: "() => `${context.entity.id} — ${context.entity.title}`"
```
Use `display` whenever you need to change only how a linked entity appears in a cell, without changing the underlying binding path or affecting other views.
### Date Handling
Date comparisons require ISO 8601 format. Always call `.toISOString()` on Date objects:
```yaml theme={null}
where:
CreatedDate:
">=": "() => new Date(Date.now() - 7 * 24 * 60 * 60 * 1000).toISOString()"
```
The example above filters for items created within the last 7 days.
### Nested Navigation in Render Expressions
When rendering values from expanded entities, `context.value` contains the resolved data. For collections, use `.map()` and `.join()`:
```yaml theme={null}
renderers:
testResults: "() => context.value.map((tc) => `${tc.name}: ${tc.status}`).join(' ')"
```
***
## Related Pages
* [Binding Syntax](/powersheet/reference/sheet-config/binding-syntax) — column key path structure, navigation patterns, and the `$` unbound marker
* [Columns](/powersheet/reference/sheet-config/columns) — full column property reference including `value`, `valueType`, `render`, and `display`
* [Add a Computed Column](/powersheet/guides/sheet-configuration/add-computed-column) — step-by-step guide to stored and display-only computed columns
* [Formatters](/powersheet/reference/sheet-config/formatters) — conditional formatting configuration and style references
* [Styles](/powersheet/reference/sheet-config/styles) — style definitions used by formatters and column headers
* [Sources](/powersheet/reference/sheet-config/sources) — data source configuration including `query.where` and `entityFactory`
* [Render Property](/powersheet/reference/sheet-config/render-property) — detailed reference for custom rendering
* [Display Property](/powersheet/reference/sheet-config/display-property) — display override for navigation property columns
* [Constraints](/powersheet/reference/data-model/constraints) — constraint configuration where `$context` expressions are used
* [Context Expressions Reference](/powersheet/reference/data-model/context-expressions) — extended reference on `$context` paths in data models
# Formatters
Source: https://learn.nextedy.com/powersheet/reference/sheet-config/formatters
The `formatters` section of a Nextedy POWERSHEET sheet configuration defines named conditional formatting rules.
See also: [Styles](/powersheet/reference/sheet-config/styles) | [Columns](/powersheet/reference/sheet-config/columns) | [Column Groups](/powersheet/reference/sheet-config/column-groups)
## How Formatters Work
Formatters provide conditional cell styling based on runtime data. Each formatter is a named array of rules. When a cell renders, Powersheet evaluates each rule's `expression` against the current cell context. If the expression returns `true`, the associated `style` is applied to that cell.
## Formatter Definition
| Property | Type | Default | Description |
| -------------------------------- | ---------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `columns..formatter` | `string` or `string[]` | -- | Name of a formatter (or array of formatter names) defined in the `formatters` section. Assigns the formatter(s) to that column. |
| `formatters` | object | `{}` | Top-level section containing named formatter definitions. Each key is a formatter name referenced by columns via the `formatter` property. |
| `formatters.` | array | `[]` | Array of conditional rules for this formatter. Rules are evaluated in order; all matching rules apply their styles. |
| `formatters.[].expression` | string | Required | JavaScript expression returning a boolean. When `true`, the associated style is applied to the cell. Has access to the `context` object. |
| `formatters.[].style` | string or object | Required | Name of a style defined in the [styles](/powersheet/reference/sheet-config/styles) section, **or** an inline style object with CSS properties. Applied when the expression evaluates to `true`. |
### YAML Structure
```yaml theme={null}
formatters:
formatterName:
- expression: "context.entity.Probability <= 99"
style: referenceToStylesKey
```
The `formatters` section is a root-level key in the sheet configuration, alongside `columns`, `styles`, `sources`, `views`, `columnGroups`, `renderers`, and `sortBy`.
```yaml theme={null}
# Root-level sheet configuration structure
columnGroups: {}
columns: {}
sources: []
renderers: {}
formatters: {}
styles: {}
views: {}
sortBy: []
```
## Expression Context
Every formatter expression has access to the `context` object. This is the same context available to [renderers](/powersheet/reference/sheet-config/render-property) and [dynamic value expressions](/powersheet/reference/sheet-config/dynamic-expressions).
| Context Property | Type | Description |
| ------------------ | ------ | ------------------------------------------------------------------------------------------------------- |
| `context.document` | object | The document data object containing document-level metadata |
| `context.entity` | object | The current entity (row) being rendered. Access entity properties by name, e.g. `context.entity.Status` |
| `context.value` | any | The current cell value for the column being formatted |
### Expression Types
Formatter expressions support two notation types:
**Simple boolean expression** (recommended):
```yaml theme={null}
formatters:
riskHighlight:
- expression: "context.entity.Probability <= 99"
style: warningStyle
```
**Formatter syntax difference**
Unlike other dynamic expressions, a formatter `expression` is a bare boolean expression (e.g., `value > 100`). It does **not** use the `() =>` prefix; it is evaluated as a direct boolean condition.
**Inline style object** (the style property supports the same CSS properties as [Styles](/powersheet/reference/sheet-config/styles)):
```yaml theme={null}
formatters:
riskHighlight:
- expression: "context.entity.Severity == 'High'"
style:
color: red700
backgroundColor: red100
textDecoration: line-through
```
**Complex Expressions**
Complex JavaScript expressions in formatters are not recommended. Keep expressions simple -- use straightforward property comparisons and boolean logic. Complex multi-line expressions may cause rendering issues.
## Referencing Formatters from Columns
Columns reference formatters by name using the `formatter` property. The value must match a key defined in the `formatters` section.
```yaml theme={null}
columns:
severity:
title: Severity
width: 120
formatter: severityFormat
formatters:
severityFormat:
- expression: "context.entity.Severity == 'Critical'"
style: darkred
- expression: "context.entity.Severity == 'High'"
style: red
- expression: "context.entity.Severity == 'Medium'"
style: orange
- expression: "context.entity.Severity == 'Low'"
style: green
```
The `formatter` column property also accepts an array of formatter names for composing multiple formatting rule sets:
```yaml theme={null}
columns:
title:
title: Title
width: 300
formatter:
- boldTitle
- statusHighlight
```
**Formatter Name Must Match**
The `formatter` value on a column must exactly match a key defined in the `formatters` section. A mismatched name results in no formatting being applied with no error message.
## Unconditional Formatters
A formatter with `expression: 'true'` always applies its style. This is useful for marking columns as visually distinct without conditions.
### Read-Only Column Styling
```yaml theme={null}
formatters:
readonly:
- expression: 'true'
style: readOnlyStyle
styles:
readOnlyStyle:
backgroundColor: grey100
columns:
outlineNumber:
title: "#"
width: 80
formatter: readonly
isReadOnly: true
```
**Formatter vs isReadOnly**
The `isReadOnly` column property and formatters serve different purposes. Use `isReadOnly: true` on a column to prevent editing regardless of formatting. Use a formatter with `style: readOnly` for visual read-only indication. The `isReadOnly` value may be overwritten by user permissions or global document configuration.
### Bold Title Styling
```yaml theme={null}
formatters:
boldTitle:
- expression: 'true'
style: boldTitleStyle
styles:
boldTitleStyle:
fontWeight: 600
```
## Conditional Formatters
Conditional formatters evaluate entity properties at render time and apply styles only when conditions are met.
### Status-Based Formatting
```yaml theme={null}
formatters:
statusFormat:
- expression: "context.entity.Status == 'Approved'"
style: green
- expression: "context.entity.Status == 'Draft'"
style: grey
- expression: "context.entity.Status == 'Rejected'"
style: red
- expression: "context.entity.Status == 'Obsolete'"
style: unsupported
columns:
status:
title: Status
width: 120
formatter: statusFormat
```
### Numeric Threshold Formatting
```yaml theme={null}
formatters:
probabilityFormat:
- expression: "context.entity.Probability > 80"
style: darkred
- expression: "context.entity.Probability > 50"
style: orange
- expression: "context.entity.Probability <= 50"
style: green
```
### Null / Empty Value Formatting
```yaml theme={null}
formatters:
missingValue:
- expression: "!context.value"
style: warningStyle
styles:
warningStyle:
backgroundColor: orange100
color: orange700
```
## Multiple Rules per Formatter
A formatter can contain multiple rules. All rules are evaluated in order, and **each matching rule applies its style**. When multiple rules match, the later rule's style properties override earlier ones for the same CSS property.
```yaml theme={null}
formatters:
multiRule:
- expression: "context.entity.Priority == 'High'"
style: red
- expression: "context.entity.IsBlocked == true"
style:
textDecoration: line-through
```
In this example, a high-priority blocked item receives both the `red` style (background and text color) and the `line-through` text decoration.
## Predefined Styles for Formatters
Formatters reference styles by name. Powersheet provides 20 built-in styles that can be used directly without defining a custom `styles` section. See [Styles](/powersheet/reference/sheet-config/styles) for the full list.
Commonly used predefined styles with formatters:
| Style Name | Visual Effect | Typical Use |
| ------------- | --------------------------------------- | -------------------------------- |
| `readOnly` | Read-only cell indicator | Mark non-editable columns |
| `boldTitle` | `fontWeight: 600` | Emphasize key columns |
| `unsupported` | Grey background + `line-through` | Deprecated or unsupported values |
| `red` | Red text on light red background | High severity / critical status |
| `darkred` | Red text on darker red background | Very high severity |
| `orange` | Orange text on light orange background | Medium severity / warning |
| `darkorange` | Orange text on darker orange background | Elevated severity |
| `green` | Green text on light green background | Low severity / approved status |
| `darkgreen` | Green text on darker green background | Confirmed / verified status |
| `blue` | Blue text on light blue background | Informational highlights |
| `grey` | Grey text on light grey background | Inactive or informational |
| `darkgrey` | Grey text on darker grey background | Disabled or archived |
| `teal` | Teal text on light teal background | Secondary categorization |
**Custom Styles Override Built-In**
When a formatter references a style name, Powersheet first checks custom styles defined in the `styles` section, then falls back to built-in styles. A custom style with the same name as a built-in style overrides the built-in.
## Row-Level Formatting
Formatters are typically applied at the column level. When a formatter is referenced from a column that spans the full row (such as an outline number column), the visual effect appears to apply to the entire row.
```yaml theme={null}
columns:
outlineNumber:
title: "#"
width: 80
formatter: rowStatus
isReadOnly: true
formatters:
rowStatus:
- expression: "context.entity.Status == 'Obsolete'"
style: unsupported
```
## Interaction with Views
[Views](/powersheet/reference/sheet-config/views) can override column properties including the `formatter` reference. A view can assign a different formatter to a column or remove formatting entirely.
```yaml theme={null}
views:
Simple View:
columns:
severity:
visible: true
Risk Analysis:
default: true
columns:
severity:
formatter: severityFormat
visible: true
```
The Base View is the state defined by the root `columns` section. Views extend the Base View by overriding specific column properties. If no views are defined or no default view is specified, the Base View is applied automatically.
## Relationship Between Formatters, Styles, and Columns
The three sections work together in a clear chain:
| Configuration Section | Purpose | References |
| ------------------------- | ------------------------------------------ | ------------------------------------------- |
| `columns..formatter` | Assigns a formatter to a column | Formatter name (string or array of strings) |
| `formatters.` | Defines conditional rules with expressions | Style name or inline style object |
| `styles.` | Defines visual CSS properties | Color tokens (`red700`, `grey100`, etc.) |
## Formatter Naming Conventions
Choose formatter names that describe their purpose. Common patterns in Powersheet configurations:
| Pattern | Example | Purpose |
| ------------- | -------------------- | -------------------------------------------- |
| Feature-based | `severityFormat` | Format by specific domain property |
| State-based | `statusHighlight` | Highlight based on workflow state |
| Visual intent | `readonly` | Describe the visual effect |
| Entity-scoped | `hazardSeverity` | Format for a specific entity type's property |
| Combined | `probabilityWarning` | Property name + visual intent |
## Complete YAML Example
A requirements traceability sheet configuration with formatters for severity, status, and read-only columns using the standard RTM entity hierarchy (`UserNeed` > `SystemRequirement` > `DesignRequirement` > `Hazard` > `RiskControl`):
```yaml theme={null}
formatters:
readonly:
- expression: 'true'
style: readOnlyStyle
boldTitle:
- expression: 'true'
style: boldTitleStyle
severityFormat:
- expression: "context.entity.Severity == 'Critical'"
style: darkred
- expression: "context.entity.Severity == 'High'"
style: red
- expression: "context.entity.Severity == 'Medium'"
style: orange
- expression: "context.entity.Severity == 'Low'"
style: green
statusHighlight:
- expression: "context.entity.Status == 'Approved'"
style: green
- expression: "context.entity.Status == 'Draft'"
style: grey
- expression: "context.entity.Status == 'Rejected'"
style: red
- expression: "context.entity.Status == 'Obsolete'"
style: unsupported
probabilityWarning:
- expression: "context.entity.Probability > 80"
style: darkred
- expression: "context.entity.Probability > 50"
style: darkorange
- expression: "context.entity.Probability <= 50"
style: green
styles:
readOnlyStyle:
backgroundColor: grey100
boldTitleStyle:
fontWeight: 600
columns:
outlineNumber:
title: "#"
width: 80
formatter: readonly
isReadOnly: true
title:
title: Title
width: 300
hasFocus: true
formatter: boldTitle
severity:
title: Severity
width: 120
formatter: severityFormat
status:
title: Status
width: 120
formatter: statusHighlight
systemRequirements.systemRequirement.title:
title: System Requirement
width: 250
columnGroup: sysReq
systemRequirements.systemRequirement.verificationTestCases.verificationTestCase.title:
title: Verification Test
width: 200
hazards.hazard.severity:
title: Hazard Severity
width: 130
formatter: severityFormat
riskControls.riskControl.probability:
title: Residual Probability
width: 140
formatter: probabilityWarning
columnGroups:
sysReq:
groupName: System Requirements
groupStyle: darkblue
headerStyle: blue
collapseTo: systemRequirements.systemRequirement.title
```
## Best Practices
✅ **Use predefined styles** whenever possible rather than defining custom inline styles. The 20 built-in styles cover most color coding needs.
✅ **Keep expressions simple.** Use straightforward property comparisons (`==`, `<=`, `>`, `!`) and avoid multi-line or deeply nested JavaScript.
✅ **Name formatters descriptively.** A name like `severityFormat` is clearer than `fmt1` when reviewing configuration.
✅ **Separate concerns.** Define styles in the `styles` section and reference them from formatters rather than using inline style objects. This promotes reuse across multiple formatters.
✅ **Order rules intentionally.** When multiple rules can match, later rules override earlier ones for the same CSS property. Place higher-priority styles last.
⚠️ **Avoid complex expressions.** Simple boolean expressions are recommended. Complex JavaScript in formatter expressions may cause unexpected behavior.
⚠️ **Do not confuse `formatter` and `render`.** The `formatter` property controls cell styling (colors, fonts). The `render` property controls cell content rendering (custom HTML output). See [Render Property](/powersheet/reference/sheet-config/render-property).
## Conditional Formatting Chain
The full conditional formatting system connects three configuration sections in a chain: the column references a formatter by name, the formatter evaluates expressions and references a style, and the style defines the visual properties.
## Style Properties Quick Reference
When defining custom styles for use with formatters, these are the supported CSS properties:
| Property | Type | Default | Description |
| ------------------------------- | ------ | ------- | -------------------------------------------------- |
| `styles..backgroundColor` | string | None | Background color token (e.g., `grey100`, `red200`) |
| `styles..color` | string | None | Text color token (e.g., `grey700`, `red700`) |
| `styles..fontWeight` | number | None | Font weight (e.g., `600`) |
| `styles..textDecoration` | string | None | Text decoration (e.g., `line-through`) |
## All Predefined Styles
All 20 predefined styles can be used in formatter rules without defining them in the `styles` section:
| Style | Appearance |
| ------------------------------------- | ---------------------------------- |
| `none` | No styling |
| `boldTitle` | Font weight 600 |
| `readOnly` | Read-only visual indicator |
| `unsupported` | Grey background with strikethrough |
| `grey`, `darkgrey` | Grey shades |
| `red`, `darkred` | Red shades |
| `orange`, `darkorange` | Orange shades |
| `green`, `darkgreen`, `lightgreen` | Green shades |
| `blue`, `darkblue`, `lightblue` | Blue shades |
| `teal`, `darkteal` | Teal shades |
| `purple`, `darkpurple`, `lightpurple` | Purple shades |
## Decision Matrix: Choosing the Right Approach
| Requirement | Approach | Example |
| -------------------------------------------- | ------------------------------------------------- | --------------------------------------------------------------------- |
| Always apply same style | Unconditional formatter with `expression: 'true'` | Read-only columns |
| Style based on cell value | Conditional expression | Severity coloring |
| Color-code column headers | Use `header.style` instead | See [Styles](/powersheet/reference/sheet-config/styles) |
| Color-code the column-group bar | Use `groupStyle` on the column group | See [Column Groups](/powersheet/reference/sheet-config/column-groups) |
| Color-code the headers of columns in a group | Use `headerStyle` on the column group | See [Column Groups](/powersheet/reference/sheet-config/column-groups) |
## Related Pages
* [Styles](/powersheet/reference/sheet-config/styles) -- Named style definitions referenced by formatters
* [Columns](/powersheet/reference/sheet-config/columns) -- Column configuration including the `formatter` property
* [Render Property](/powersheet/reference/sheet-config/render-property) -- Custom content rendering (distinct from formatting)
* [Dynamic Value Expressions](/powersheet/reference/sheet-config/dynamic-expressions) -- Full reference on the `context` object and expression syntax
* [Views](/powersheet/reference/sheet-config/views) -- View-level overrides for column formatting
* [Column Groups](/powersheet/reference/sheet-config/column-groups) -- Visual grouping with `groupStyle` and `headerStyle`
* [Keyboard Shortcuts](/powersheet/reference/keyboard-shortcuts) -- Keyboard navigation in the sheet
***
# Sheet Configuration Reference
Source: https://learn.nextedy.com/powersheet/reference/sheet-config/index
The Nextedy POWERSHEET sheet configuration is a YAML file that defines how data model data is displayed and interacted with in the sheet.
## Column Layout
**[Columns](/powersheet/reference/sheet-config/columns)** -- Column definitions mapping property paths to display settings including title, width, formatters, focus, visibility, and edit behavior.
**[Column Groups](/powersheet/reference/sheet-config/column-groups)** -- Visual grouping of related columns under shared headers with color styling and collapse behavior.
**[Binding Syntax](/powersheet/reference/sheet-config/binding-syntax)** -- Dot-separated path syntax for mapping columns to data model properties and navigation paths across entity relationships.
**[Multi-Item Columns](/powersheet/reference/sheet-config/multi-item-columns)** -- Configuration for columns displaying many-to-many relationships using the `multiItem` property.
## Display and Rendering
**[Display Property](/powersheet/reference/sheet-config/display-property)** -- Controls which property of a referenced entity appears in a column on the client side (e.g., showing `title` instead of `id`).
**[Render Property](/powersheet/reference/sheet-config/render-property)** -- Controls server-side rendering of column content via Velocity templates, complementing the client-side `display` property for cases requiring custom HTML output.
## Styling and Formatting
**[Styles](/powersheet/reference/sheet-config/styles)** -- Named style definitions (CSS classes and colors) that can be referenced by formatters or column headers.
**[Formatters](/powersheet/reference/sheet-config/formatters)** -- Named formatter definitions with conditional rules that apply styles based on data values or expressions. Formatters also control read-only behavior and cell appearance. For expression syntax details used within formatter conditions, see [Dynamic Value Expressions Reference](/powersheet/reference/sheet-config/dynamic-expressions).
## Data and Queries
**[Sources](/powersheet/reference/sheet-config/sources)** -- Data source definitions specifying the root entity type to query, filtering criteria, and expansion paths for loading related entities across the data model hierarchy.
**[Sort By](/powersheet/reference/sheet-config/sortby)** -- Default sort order configuration specifying column and direction (`asc`/`desc`) for initial row ordering.
## View Management
**[Views](/powersheet/reference/sheet-config/views)** -- Named view presets that override default column visibility and widths, letting users switch between different perspectives on the same data.
## Expressions
**[Dynamic Value Expressions Reference](/powersheet/reference/sheet-config/dynamic-expressions)** -- Reference for `$context` expressions, computed values, and dynamic defaults used in sources, formatters, and entity factories.
**Getting started with sheet configuration**
Start with a minimal single-source configuration and extend incrementally. For a step-by-step introduction, see the [Sheet Configuration Guides](/powersheet/guides/sheet-configuration/index). Common first-time mistakes include mismatching the `sources.model` property with the data model name and forgetting `multiItem: true` when a parent entity links to multiple child entity types.
## Configuration Structure Overview
A sheet configuration YAML file contains these top-level sections:
```yaml theme={null}
# Top-level structure of a sheet configuration file
columnGroups: # Visual column grouping with shared headers
sortBy: # Default sort order (column + direction)
columns: # Column definitions (required)
views: # Named view presets
formatters: # Conditional formatting rules
styles: # Custom style definitions
sources: # Data source queries and expansion paths
```
Each section is documented in detail on its dedicated reference page above.
```
+---------------------------+
| Sheet Configuration |
| (YAML file) |
+---------------------------+
|
+---------+---------+----------+---------+
| | | | |
v v v v v
sources columns views formatters styles
| | | |
| +---------+ | |
| | | +---------+
| v v |
| binding display/ v
| syntax render conditional
| formatting
v
expansion
paths (data model)
```
***
**Related pages:** [Reference](/powersheet/reference/index) | [Data Model Reference](/powersheet/reference/data-model/index) | [Query API Reference](/powersheet/reference/query-api/index) | [Server Rendering Reference](/powersheet/reference/server-rendering/index)
# Multi-Item Columns
Source: https://learn.nextedy.com/powersheet/reference/sheet-config/multi-item-columns
Multi-item columns in Nextedy POWERSHEET display and manage collections of related entities within a single column cell.
## `multiItem` Property
| Name | Type | Default | Description |
| ----------- | --------- | ------- | --------------------------------------------------------------------------------------------------------------------------- |
| `multiItem` | `boolean` | `false` | Indicates this column displays multiple related items (many-to-many relationship). Enables multi-value display and editing. |
When `multiItem` is set to `true`, the column cell renders all linked entities for the current row, rather than a single value. Users can add, remove, and browse multiple related items through a dedicated picker interface.
## When to Use Multi-Item Columns
Multi-item columns are required in these scenarios:
| Scenario | Example Binding Path | Description |
| ----------------------------------- | --------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------- |
| Second linked entity on same parent | `systemRequirements.systemRequirement.designRequirements.designRequirement` | When a parent entity links to two different entity types via separate relationships |
| Verification/validation test cases | `systemRequirements.systemRequirement.verificationTestCases.verificationTestCase` | Test case collections linked to requirements |
| External references | `designRequirements.designRequirement.externalReferences.externalReference` | External system links attached to design items |
**Required for Second Linked Entity Types**
When a sheet has two work item types linked to the same parent entity (e.g., design outputs and design verifications both linked to system requirements), the **second** linked column must be declared with `multiItem: true`. This is a non-obvious requirement that commonly blocks new users during initial setup.
## Column Configuration Properties
The following properties apply when configuring a multi-item column:
| Name | Type | Default | Description |
| ------------- | --------- | ------- | ------------------------------------------------------------------------------------------------------------------------ |
| `multiItem` | `boolean` | `false` | Enables multi-item display and editing for the column |
| `title` | `string` | None | Display label for the column header |
| `width` | `number` | None | Column width in pixels |
| `header` | `string` | None | YAML anchor reference to reusable header styling configuration |
| `display` | `string` | `id` | Specifies which property of the referenced entity to display. Options: `title`, `titleOrName`, or a custom property path |
| `columnGroup` | `string` | None | Assigns the column to a visual [column group](/powersheet/reference/sheet-config/column-groups) |
| `visible` | `boolean` | `true` | Controls whether the column is shown by default |
| `formatter` | `string` | None | References a formatter name from the [formatters](/powersheet/reference/sheet-config/formatters) section |
| `isReadOnly` | `boolean` | `false` | Prevents user editing of this column (deprecated in favor of `formatter=readOnly`) |
## Binding Path Syntax
Multi-item columns use dot-separated binding paths that follow the relationship chain defined in the [data model](/powersheet/reference/data-model/relationships). The path alternates between the collection navigation property and the entity type:
```
......
```
For a full reference on binding path construction, see [Binding Syntax](/powersheet/reference/sheet-config/binding-syntax).
## Configuration Example
The following example adds an external references multi-item column to a design requirement:
```yaml theme={null}
columns:
# Parent entity columns
title:
title: User Need
width: 300
hasFocus: true
# Multi-item column for external references linked to design requirements
systemRequirements.systemRequirement.designRequirements.designRequirement.externalReferences.externalReference:
title: External References
width: 200
multiItem: true
header: *blue
display: titleOrName
```
## Sources Configuration
Multi-item columns require their expansion paths to be declared in the `sources` section. The `expand` array must include the full chain of relationships:
```yaml theme={null}
sources:
- name: requirement
model: rtm
query:
from: UserNeed
where: "type = 'UserNeed'"
expand:
- name: systemRequirements
expand:
- name: designRequirements
expand:
- name: externalReferences
```
Every multi-item column binding path must have a corresponding expansion path in the `sources` configuration. If the expansion is missing, the column will not load related entities.
For source configuration details, see [Sources](/powersheet/reference/sheet-config/sources).
## Data Model Requirements
The entity types and relationships referenced by multi-item columns must exist in the [data model](/powersheet/reference/data-model/index):
```yaml theme={null}
domainModelTypes:
ExternalReference:
# entity type configuration
relationships:
- from: ExternalReference
to: DesignRequirement
linkRole: relatesTo
```
Ensure the Polarion link role is configured to allow links between the relevant work item types. See [Link Roles](/powersheet/reference/data-model/link-roles) and [Relationships](/powersheet/reference/data-model/relationships).
## Export Behavior
When exporting to Excel, multi-item cells render each item on a separate line within the same cell. Comma-separated values in the sheet are converted to newline-separated lists in the exported XLSX file.
## Complete YAML Example
```yaml theme={null}
header: &blue
style:
background: blue
color: white
columnGroups:
DesignReq:
groupName: Design Requirements
groupStyle: blue
headerStyle: blueHeader
columns:
title:
title: User Need
width: 300
hasFocus: true
sort: asc
systemRequirements.systemRequirement.title:
title: System Requirement
width: 250
systemRequirements.systemRequirement.designRequirements.designRequirement.title:
title: Design Requirement
width: 250
columnGroup: DesignReq
systemRequirements.systemRequirement.designRequirements.designRequirement.externalReferences.externalReference:
title: External References
width: 200
multiItem: true
header: *blue
display: titleOrName
columnGroup: DesignReq
systemRequirements.systemRequirement.verificationTestCases.verificationTestCase:
title: Verification Tests
width: 200
multiItem: true
header: *blue
sources:
- name: requirement
model: rtm
query:
from: UserNeed
where: "type = 'UserNeed'"
expand:
- name: systemRequirements
expand:
- name: designRequirements
expand:
- name: externalReferences
- name: verificationTestCases
```
## Related Pages
* [Columns](/powersheet/reference/sheet-config/columns) -- base column configuration reference
* [Binding Syntax](/powersheet/reference/sheet-config/binding-syntax) -- dot-separated path construction rules
* [Sources](/powersheet/reference/sheet-config/sources) -- data source and expansion path configuration
* [Relationships](/powersheet/reference/data-model/relationships) -- data model relationship definitions
* [Columns](/powersheet/reference/sheet-config/columns) -- full list of column-level properties
***
# Render Property
Source: https://learn.nextedy.com/powersheet/reference/sheet-config/render-property
The `render` property in a Nextedy POWERSHEET column configuration provides custom HTML rendering for cell content.
## Property Definition
| Property | Type | Default | Description |
| ---------------------- | ------ | ------- | ------------------------------------------------------------------------------------------------------------------------ |
| `columns..render` | string | None | JavaScript arrow function string returning HTML, or a predefined renderer name. Evaluated at render time in the browser. |
## Render Types
| Type | Syntax | Description |
| ------------------- | --------------------------------------- | --------------------------------------------------------- |
| Inline function | `render: > () => ...` | JavaScript arrow function returning HTML template literal |
| YAML anchor | `render: *displayItemAsIconIDTitleLink` | Reference to a reusable YAML anchor |
| Predefined renderer | `render: myCustomRenderer` | Reference to a renderer name defined in configuration |
## Render Resolution Flow
## Context Object
The JavaScript function has access to a `context` object for building dynamic HTML:
| Variable | Description |
| ------------------------------------------- | -------------------------------------------------------------------------------------------- |
| `context.value` | The current cell value |
| `context.entity` | The entity at the column's level, with properties such as `projectId`, `id` and `entityType` |
| `context.entity.entityType.custom.iconPath` | Icon path from entity type metadata |
| `context.entity.projectId` | Polarion project ID of the current item |
| `context.entity.id` | Work item ID of the current item |
| `context.polarionModel.polarionBaseUrl` | Base URL of the Polarion server |
## Inline Function Render
```yaml theme={null}
columns:
title:
title: Title
render: >
() => `${context.value} `
```
## Render with Icon and Link
Using a YAML anchor for reuse across columns:
```yaml theme={null}
snippets:
displayItemAsIconIDTitleLink: &displayItemAsIconIDTitleLink >
() =>
`${context.value} `
columns:
systemRequirements.systemRequirement:
title: System Requirement
render: *displayItemAsIconIDTitleLink
```
## Predefined Renderer Reference
Renderers can be defined in the configuration and referenced by name:
```yaml theme={null}
renderers:
myCustomRenderer: "() => `${context.value} `"
columns:
status:
render: myCustomRenderer
```
**Verify in application**
The exact `renderers` section configuration and available predefined renderer names may vary. Verify the supported renderer names in your Powersheet version.
## Render vs Display
| Aspect | `display` | `render` |
| ------------------- | ---------------------------------------------------- | ------------------------------------- |
| Primary purpose | Select which property of a referenced entity to show | Full custom HTML rendering |
| Property name input | `title`, `id`, `titleOrName` | Not supported (function or name only) |
| JS function input | Supported | Supported |
| Predefined names | Not supported | Supported via `renderers` section |
| Typical use | Navigation columns needing property selection | Any column needing custom HTML |
**When to Use render**
Use `render` when you need full control over cell HTML. Use `display` when you simply need to select which property of a navigation target to show. When both are needed on the same column, `display` handles property selection while `render` handles visual formatting.
## Complete YAML Example
```yaml theme={null}
snippets:
displayItemAsIconLink: &displayItemAsIconLink >
() =>
`${context.value} `
columns:
outlineNumber:
title: "#"
width: 80
formatter: readonly
title:
title: User Need
width: 200
hasFocus: true
render: *displayItemAsIconLink
systemRequirements.systemRequirement.title:
title: System Requirement
width: 180
render: *displayItemAsIconLink
columnGroup: sysReq
systemRequirements.systemRequirement.severity:
title: Severity
width: 100
columnGroup: sysReq
columnGroups:
sysReq:
groupName: System Requirements
groupStyle: darkblue
headerStyle: blue
collapseTo: systemRequirements.systemRequirement.title
formatters:
readonly:
- expression: 'true'
style: readOnlyStyle
styles:
readOnlyStyle:
backgroundColor: 'grey100'
sources:
- id: main
model: rtm
query:
from: UserNeed
where: "type = 'UserNeed'"
expand:
- name: systemRequirements
title: System Requirements
```
## Related Pages
* [Display Property](/powersheet/reference/sheet-config/display-property) -- property selection for navigation columns
* [Columns](/powersheet/reference/sheet-config/columns) -- full column property reference
* [Binding Syntax](/powersheet/reference/sheet-config/binding-syntax) -- column binding path patterns
* [Server Rendering](/powersheet/reference/server-rendering/index) -- server-side rendering reference
***
# Sheet Header
Source: https://learn.nextedy.com/powersheet/reference/sheet-config/sheet-header
Reference for the Nextedy POWERSHEET sheet header -- the title, subtitle, and icon that state which slice of Siemens Polarion ALM data is on screen, each a static value or a dynamic expression over document, project, and URL-parameter context.
The header sits at the top of a sheet, next to the toolbar, and states **which slice of data you are looking at** -- a `title`, a `subtitle`, and an `icon`. Because each can be computed from the current document, project, and URL parameters, one configuration used across many variants or projects tells you at a glance that you are on the right one, without going back to Polarion to check.
Each of the three is either a static value or a single [dynamic value expression](/powersheet/reference/sheet-config/dynamic-expressions) (`() => …`). They are top-level keys in the sheet configuration, alongside `sources`, `columns`, and `views`:
```yaml theme={null}
title: "Requirements"
subtitle: "() => context.project.name"
icon: "Table"
```
## The three fields
| Key | Type | What it shows |
| ---------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `title` | `string` \| `() => …` | The primary heading. Falls back to the document name when it resolves to nothing (see [Fallback and suppression](#fallback-and-suppression)). |
| `subtitle` | `string` \| `() => …` \| `false` | A secondary line above the title. Defaults to the document name when a `title` is set; `false` (or an expression resolving falsy) hides it. |
| `icon` | `string` \| `() => …` \| `false` | A glyph or image shown beside the title. Defaults to the `table` glyph; `false` (or an expression resolving falsy) is the only way to show none. |
## Evaluation context
A `() => …` header expression receives the same `context` object as other dynamic values, so the header can be driven by the sheet's surroundings. The fields most relevant here:
| Expression | Resolves to |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `context.name` | The current document (configuration) name -- the same value the header falls back to. |
| `context.project.name` | The Polarion project's display name. Optional: a project may expose only its id, in which case this is absent. |
| `context.project.id` | The Polarion project id. |
| `context.parameters.` | Any value present on the sheet's [URL query string](/powersheet/concepts/url-parameters), by the name it was given. |
For the complete object see [Context Expressions](/powersheet/reference/data-model/context-expressions). Reading a value from the URL is covered under [URL Parameters](/powersheet/concepts/url-parameters).
Build any surrounding text **inside** the expression -- the whole value must be a single `() => …` for it to be evaluated. Concatenate or use a template literal (`` () => `Type: ${context.parameters.subtype}` ``) rather than mixing literal text with an expression.
## Icon values: glyph or image
The `icon` value is classified automatically by what it contains:
* A name made up only of letters and digits -- for example `Table`, `AspectRatio`, `World` -- is a **[Fluent (MDL2) glyph](https://developer.microsoft.com/en-us/fluentui#/styles/web/icons#available-icons)**, rendered by name.
* Any value containing a `/`, `:`, or `.` is treated as an **image source** and rendered as an ` `. That covers every practical image form:
| Value | Interpreted as |
| --------------------------------------------- | ----------------------------------------------------- |
| `AspectRatio` | Fluent glyph, by name |
| `/polarion/icons/avatar/admin/avatar.png` | Image -- a root-relative Polarion (or app) asset path |
| `https://cdn.example.com/icons/worksheet.png` | Image -- an absolute URL |
| `data:image/svg+xml;base64,PHN2Zy8+` | Image -- an inline data URI |
The rule is purely the presence of a `/`, `:`, or `.`, so even a bare filename with an extension (`worksheet.png`) is taken as an image rather than a glyph. If an image source fails to load, the icon is simply omitted rather than showing a broken-image placeholder.
## Fallback and suppression
Each field decides independently what to show when it is omitted or resolves to nothing. An expression that resolves to a falsy value (`false`, `null`, `""`, `undefined`) **suppresses** the field -- it never prints the literal text `false`.
| Field | Omitted | Resolves falsy | Explicit `false` |
| ---------- | -------------------------------------------------------- | ------------------------------------- | ------------------------------------------ |
| `title` | Document name | Document name (never a blank heading) | -- not supported; `title` takes no `false` |
| `subtitle` | Document name **if a `title` is set**, otherwise nothing | Hidden | Hidden |
| `icon` | The `table` glyph | Hidden | Hidden |
Two consequences worth noting:
* Because `icon` defaults to the `table` glyph, `icon: false` is the **only** way to render a sheet with no icon.
* A `title` that evaluates to empty behaves exactly like an omitted `title`: the document name becomes the heading, and (unless you set a `subtitle`) it is not also repeated as the subtitle.
## Worked example
This RTM configuration varies all three fields by a `subtype` URL parameter, so `…&subtype=electrical` and `…&subtype=mechanical` open the same sheet under distinct, self-describing headers -- while a plain link with no `subtype` falls back to the document's own name and the default icon:
```yaml theme={null}
icon: >
() => {
switch (context.parameters.subtype) {
case 'electrical': return 'AspectRatio'; // Fluent glyph
case 'mechanical': return 'World'; // Fluent glyph
case 'absolute': return 'https://cdn.example.com/icons/worksheet.png'; // absolute URL -> image
case 'relative': return '/polarion/icons/avatar/admin/avatar.png'; // Polarion asset -> image
default: return 'table'; // fallback glyph
}
}
subtitle: "() => context.parameters.subtype ? context.project.name + ': ' + context.name : false"
title: "() => context.parameters.subtype ? `Type: ${context.parameters.subtype}` : context.name"
```
With `…&subtype=electrical` the header reads **Type: electrical** over a project-and-document subtitle, beside the `AspectRatio` glyph. Open the same sheet with no `subtype` and the subtitle's expression resolves `false` (so it is hidden), the title falls back to the document name, and the icon defaults to `table`.
## Related
The `() => …` syntax used by all three header fields.
How `context.parameters.` values reach the header from the sheet's URL.
The full `context` object a header expression can read.
A task that reflects a URL parameter in the header.
# Sort By
Source: https://learn.nextedy.com/powersheet/reference/sheet-config/sortby
The `sortBy` section of a Nextedy POWERSHEET sheet configuration defines the default client-side sort order for rows when the sheet loads. It supports multiple columns and custom sort directions.
## sortBy Properties
| Property | Type | Default | Description |
| -------------------- | ------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `sortBy` | array | `[]` | Array of sort definitions applied in order. The first entry is the primary sort; subsequent entries break ties. |
| `sortBy[].columnId` | string | None | **(required)** Dot-separated binding path to the column that should be sorted. Must match a column key defined in the `columns` section. |
| `sortBy[].direction` | string | `"asc"` | **(optional)** Sort direction. Supported values: `"asc"` (ascending), `"desc"` (descending). |
## Sort Behavior
| Behavior | Description |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------ |
| Client-side | Sorting is applied in the browser after data is loaded |
| Multi-column | Multiple sort entries are supported; order in the array determines priority |
| Default direction | If `direction` is omitted, `"asc"` is used |
| Interactive override | Users can click column headers to change sort direction at runtime |
| Default sort persistence | The configured `sortBy` is always re-applied as a secondary sort after user-initiated sorts to maintain hierarchical stability |
## Sort Flow
## Basic Sort
Sort by a single column in ascending order:
```yaml theme={null}
sortBy:
- columnId: outlineNumber
direction: asc
```
## Multi-Column Sort
Sort by primary column, then by secondary column for rows with equal primary values:
```yaml theme={null}
sortBy:
- columnId: outlineNumber
direction: asc
- columnId: title
direction: asc
```
## Descending Sort
```yaml theme={null}
sortBy:
- columnId: severity
direction: desc
```
## Column-Level Sort
Individual columns can also specify a default sort direction via the `sort` column property. This is applied in addition to the global `sortBy` configuration.
| Property | Type | Default | Description |
| ---------------- | ------ | ------- | --------------------------------------------------------------------------- |
| `columns.*.sort` | string | None | Default sort direction for this specific column. Values: `"asc"`, `"desc"`. |
```yaml theme={null}
columns:
outlineNumber:
title: "#"
width: 80
sort: asc
```
**sortBy vs Column sort**
Use the top-level `sortBy` for the primary sheet sort order. Use the column-level `sort` property when a specific column should always maintain a particular direction as a secondary sort criterion.
## Interactive Sort
Users can sort interactively in the sheet:
| Action | Result |
| ----------------------------- | ------------------------------------------------------ |
| Click column header sort icon | Sort by that column (toggles ascending/descending) |
| `Ctrl+Click` column header | Add column to existing multi-column sort |
| Reset sort (toolbar) | Remove user-applied sorts and restore `sortBy` default |
Sort state indicators appear in column headers showing the current sort direction. Multi-column sort shows small numbers indicating sort priority.
## Sort Type Behavior
| Column Type | Sort Behavior |
| ------------- | ----------------------------------------------- |
| Text (string) | Alphabetical sort |
| Enum | Sort by enum value sequence, not alphabetically |
| Reference | Sort by display value of the referenced entity |
| Workflow | Sort by transition display text |
| Custom render | Sort by the rendered display value |
## Complete YAML Example
```yaml theme={null}
sortBy:
- columnId: outlineNumber
direction: asc
columns:
outlineNumber:
title: "#"
width: 80
sort: asc
title:
title: User Need
width: 200
hasFocus: true
systemRequirements.systemRequirement.title:
title: System Requirement
width: 180
columnGroup: sysReq
systemRequirements.systemRequirement.severity:
title: Severity
width: 100
columnGroup: sysReq
columnGroups:
sysReq:
groupName: System Requirements
groupStyle: darkblue
headerStyle: blue
collapseTo: systemRequirements.systemRequirement.title
sources:
- id: main
title: RTM
model: rtm
query:
from: UserNeed
where: "type = 'UserNeed'"
expand:
- name: systemRequirements
title: System Requirements
```
## Related Pages
* [Columns](/powersheet/reference/sheet-config/columns) -- the `sort` column-level property
* [Columns](/powersheet/reference/sheet-config/columns) -- column definitions and binding paths
***
# Sources
Source: https://learn.nextedy.com/powersheet/reference/sheet-config/sources
The `sources` section of a Nextedy POWERSHEET sheet configuration defines an array of data source objects that specify which entities to load from Polarion and how to traverse relationships via expansion paths.
Sources are the bridge between the data model (which defines entity types and relationships) and the sheet columns (which define how data is displayed). The data model declares what entities and relationships exist; sources declare which of those entities to load and which relationships to expand; columns declare how to render the resulting data.
**Configuration Layers**
Understanding how sources connect to the data model and columns is essential. See [Cardinality](/powersheet/reference/data-model/cardinality) for the full relationship between these three configuration layers.
## Source Data Flow
## Top-Level Source Properties
The `sources` key is a top-level array in the sheet configuration YAML, alongside `columns`, `views`, `formatters`, and other sections.
| Property | Type | Required | Default | Description |
| --------------- | ------ | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id` | string | **Yes** | None | Unique identifier for this data source. Referenced by tool settings to bind a source to a sheet. |
| `title` | string | No | None | Human-readable label displayed in the Powersheet UI for this data source. |
| `model` | string | **Yes** | None | Reference to the data model that defines entity types and relationships. |
| `query` | object | **Yes** | None | Query definition specifying which root entities to load. See [Query Properties](#query-properties). |
| `expand` | array | No | `[]` | Expansion paths for loading related entities through data model [relationships](/powersheet/reference/data-model/relationships). See [Expand Properties](#expand-properties). |
| `entityFactory` | object | No | None | Default property values applied when creating new entities from this source. See [Entity Factory](#entity-factory). |
The first source in the array (`sources[0]`) is the primary data source for the sheet. Additional sources can define secondary entity types for multi-type configurations.
## Query Properties
The `query` object within each source defines how to retrieve root-level entities from Polarion.
| Property | Type | Required | Default | Description |
| --------------- | ------ | -------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `query.from` | string | **Yes** | None | Root entity type to query. Must match an entity type defined in the data model's `domainModelTypes`. |
| `query.where` | object | No | None | Filter predicate restricting which entities are loaded. Supports [dynamic value expressions](/powersheet/reference/sheet-config/dynamic-expressions) with `() =>` syntax. |
| `query.take` | number | No | None | Maximum number of root entities to return. Limits the result set size. |
| `query.orderBy` | array | No | None | Array of sort specifications applied server-side to order results before they reach the sheet. Each entry specifies a property name and direction. |
### Dynamic Where Clauses
The `where` property supports [dynamic value expressions](/powersheet/reference/sheet-config/dynamic-expressions) using the `() =>` syntax. The predicate value is evaluated at runtime, allowing queries that depend on document parameters, the current date, or other context values.
The resulting value must match the expected type for the property being filtered. For example, date comparisons require ISO 8601 format strings.
**Static filter example:**
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
where:
severity:
"!=": null
```
**Dynamic filtering with document parameters:**
```yaml theme={null}
sources:
- id: filtered_items
query:
from: UserNeed
where:
Client:
"==": "() => `${context.parameters.client} ${context.parameters.status}`"
```
**Date-based filtering example:**
```yaml theme={null}
sources:
- id: future_items
query:
from: UserNeed
where:
dueDate:
">": "() => new Date().toISOString()"
```
**Dynamic Expression Format**
Dynamic expressions must be valid JavaScript arrow functions starting with `() =>`. The resulting value must be in the correct format for the property type. For dates, always use `.toISOString()` in the expression to produce a properly formatted string.
## Expand Properties
The `expand` array defines which related entities to load by traversing navigation properties declared in the data model [relationships](/powersheet/reference/data-model/relationships). Expansion paths determine the hierarchical depth of the sheet and directly control which columns can be bound to the loaded data.
| Property | Type | Required | Default | Description |
| ------------------------ | ------ | -------- | ------- | ----------------------------------------------------------------------------------------------------------- |
| `expand[].name` | string | **Yes** | None | Navigation property name to expand. Must match a `direct` or `back` name from the data model relationships. |
| `expand[].expand` | array | No | None | Nested expansion for loading multi-level relationships. Same structure as the parent `expand`. |
| `expand[].entityFactory` | object | No | None | Default values for new entities created at this expansion level. See [Entity Factory](#entity-factory). |
### Single-Level Expansion
For one-to-many (1:N) or many-to-one (N:1) relationships, a single expansion level is sufficient.
**N:1 example** (each `UserNeed` belongs to one `Chapter`):
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: chapter
```
Here `chapter` is a `direct` navigation property from the data model, loading the single parent `Chapter` entity for each `UserNeed`.
**1:N example** (each `Chapter` has many child `UserNeed` entities):
```yaml theme={null}
sources:
- id: chapters
query:
from: Chapter
expand:
- name: userNeeds
```
Here `userNeeds` is a `back` navigation property. The expansion creates child rows in the sheet for each related `UserNeed`.
### Nested Expansion (Multi-Level)
For many-to-many (M:N) relationships, or when building deep hierarchies, use nested `expand` entries. M:N relationships use an association entity, so the expansion path traverses two levels: the association collection and then the target entity.
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: systemRequirement
expand:
- name: designRequirements
expand:
- name: designRequirement
```
This creates a four-level hierarchy: `UserNeed` > `SystemRequirement` (via M:N association) > `DesignRequirement` (via M:N association). Each M:N hop requires two expand levels: one for the association collection (`systemRequirements`) and one for the target entity (`systemRequirement`).
**Expansion Depth**
There is no hard limit on nesting depth, but deeper hierarchies increase data load and rendering time. A typical RTM configuration uses 3-5 expansion levels.
### Cardinality and Expand Patterns
The relationship cardinality in the data model determines the correct expand pattern:
| Cardinality | Model Direction | Source Expand | Column Binding | UI Behavior |
| ----------- | ---------------------------------------- | ------------------------------------------------------------- | -------------------------------------- | ----------------------------- |
| **N:1** | `direct` name (e.g., `chapter`) | `- name: chapter` | `chapter`, `chapter.title` | Single-value reference picker |
| **1:N** | `back` name (e.g., `userNeeds`) | `- name: userNeeds` | `userNeeds` | Child rows (new sheet level) |
| **M:N** | `back` name (e.g., `systemRequirements`) | `- name: systemRequirements` then `- name: systemRequirement` | `systemRequirements.systemRequirement` | Multi-item reference picker |
For comprehensive examples of each cardinality pattern with matching data model, source, and column configurations, see [Cardinality](/powersheet/reference/data-model/cardinality).
## Entity Factory
The `entityFactory` object defines default property values that are automatically applied when a user creates a new entity from the sheet. This can be specified at the source level (for root entities) or within an expand entry (for child entities at that expansion level).
| Property | Type | Required | Default | Description |
| --------------- | ------ | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `entityFactory` | object | No | None | Key-value pairs where each key is a property name and each value is the default. Values can be strings, numbers, booleans, or null. |
```yaml theme={null}
sources:
- id: user_needs
query:
from: UserNeed
entityFactory:
severity: "medium"
status: "draft"
expand:
- name: systemRequirements
entityFactory:
status: "proposed"
expand:
- name: systemRequirement
```
In this example, new `UserNeed` entities default to `severity: "medium"` and `status: "draft"`, while new association entities at the `systemRequirements` level default to `status: "proposed"`.
### Dynamic Entity Factory Values
Entity factory values support [dynamic value expressions](/powersheet/reference/sheet-config/dynamic-expressions) using the `() =>` syntax, allowing defaults that reference document parameters or computed values:
```yaml theme={null}
entityFactory:
Client: "() => context.parameters.client"
CreatedDate: "() => new Date().toISOString()"
```
## Complete YAML Example
A full RTM (Requirements Traceability Matrix) source configuration demonstrating multi-level expansion, query filtering, and entity factories:
```yaml theme={null}
sources:
- id: user_needs
title: User Needs
model: rtm
query:
from: UserNeed
where:
severity:
"!=": null
entityFactory:
severity: "medium"
expand:
- name: systemRequirements
expand:
- name: systemRequirement
expand:
- name: designRequirements
expand:
- name: designRequirement
```
This configuration:
1. Queries all `UserNeed` entities where `severity` is not null
2. Expands through the M:N relationship to `SystemRequirement` via the `systemRequirements` association
3. Further expands through the M:N relationship to `DesignRequirement` via the `designRequirements` association
4. Sets a default `severity` of `"medium"` for newly created `UserNeed` entities
### Alternative: Hazard-Based Source
A risk management source starting from `Hazard` entities:
```yaml theme={null}
sources:
- id: hazards
title: Hazards
query:
from: Hazard
expand:
- name: riskControls
expand:
- name: riskControl
```
## Configuration Scoping
Sheet configurations (including sources) can be defined at two scopes:
| Scope | Location | Behavior |
| ----------- | ------------------------------ | ------------------------------------------------------------------------------------------ |
| **Project** | Project SVN repository | Available only to the specific project. Listed without suffix in the configuration picker. |
| **Global** | Global configuration directory | Available to all projects. Listed with a `(Global)` suffix in the configuration picker. |
Both global and project-specific configurations are discovered automatically and presented in the **Administration > Nextedy Powersheet** configuration interface. No default configuration is predefined; administrators must explicitly select a configuration for each document.
## Interaction with Other Configuration Sections
Sources do not exist in isolation. They connect to several other sheet configuration sections:
* **[Columns](/powersheet/reference/sheet-config/columns):** Column binding paths (the key of each column entry) must align with the navigation properties defined in the source expansion paths. A column key like `systemRequirements.systemRequirement.title` requires that the source expands through `systemRequirements` and then `systemRequirement`.
* **[Views](/powersheet/reference/sheet-config/views):** Views override column visibility but do not change source definitions. The same sources feed all views.
* **[Formatters](/powersheet/reference/sheet-config/formatters):** Formatters apply conditional styling to cells. The `context.entity` available in formatter expressions refers to entities loaded by the sources.
* **[Sort By](/powersheet/reference/sheet-config/sortby):** Client-side sorting is applied after source data is loaded. The `columnId` in `sortBy` entries must reference columns that are bound to source data.
* **[Binding Syntax](/powersheet/reference/sheet-config/binding-syntax):** The dot-notation paths used in column keys directly mirror the navigation property names from source expansion paths.
* **[Constraints](/powersheet/reference/data-model/constraints):** A source's `query`/`where` filters which root entities load at the sheet level. Restricting which items can be picked, linked, or created (or scoping a load to the current document) is defined separately as data-model `constraints` (`load`/`pick`/`create`), not in `sources`. The two are independent layers that combine with AND; they are not alternative formats.
## Best Practices
**Start Simple**
Begin with a minimal single-source configuration and extend incrementally. Jumping directly to complex multi-source, multi-level configurations leads to hard-to-diagnose errors. Validate each expansion level before adding the next.
* **Match expand to columns:** Every column binding path that traverses a navigation property requires a corresponding expand entry in the source. A missing expand results in empty columns.
* **Use entity factories for required fields:** If the target Polarion work item type has required custom fields, set defaults in `entityFactory` to avoid save validation errors.
* **Limit query scope with `where`:** Use filter predicates to reduce the number of root entities loaded, improving sheet load performance.
* **Name sources descriptively:** Use meaningful `id` values (e.g., `user_needs`, `hazards`) rather than generic names. The `title` property provides the human-readable label in the UI.
***
**Related pages:**
[Sheet Configuration Reference](/powersheet/reference/sheet-config/index) |
[Columns](/powersheet/reference/sheet-config/columns) |
[Relationships](/powersheet/reference/data-model/relationships) |
[Cardinality](/powersheet/reference/data-model/cardinality) |
[Dynamic Value Expressions](/powersheet/reference/sheet-config/dynamic-expressions) |
[Binding Syntax](/powersheet/reference/sheet-config/binding-syntax)
# Styles
Source: https://learn.nextedy.com/powersheet/reference/sheet-config/styles
The `styles` section of a Nextedy POWERSHEET sheet configuration defines named style definitions that control the visual appearance of cells and headers.
## Style Definition
| Property | Type | Default | Description |
| ------------------------------- | ------------- | ------- | ------------------------------------------------------------------------------------------------------------------- |
| `styles` | object | `{}` | Top-level section containing named style definitions. Each key is a style name referenced by formatters or headers. |
| `styles..backgroundColor` | string | None | Background color using a color token name (e.g., `grey100`, `red200`) or a predefined style name |
| `styles..color` | string | None | Text color using a color token name (e.g., `grey700`, `purple700`) |
| `styles..fontWeight` | number/string | None | Font weight value (e.g., `600` for semi-bold) |
| `styles..textDecoration` | string | None | Text decoration (e.g., `line-through`) |
## Predefined Styles
Powersheet includes 20 built-in styles available without any custom definition. Custom styles defined in the `styles` section are merged on top of these defaults.
### Status Styles
| Style Name | Text Color | Background Color | Other |
| ------------- | ---------- | ---------------- | ------------------------------ |
| `none` | none | none | |
| `boldTitle` | | | `fontWeight: 600` |
| `unsupported` | `grey800` | `grey200` | `textDecoration: line-through` |
| `readOnly` | | | Read-only cell indicator |
### Neutral Styles
| Style Name | Text Color | Background Color |
| ---------- | ---------- | ---------------- |
| `darkgrey` | `grey700` | `grey200` |
| `grey` | `grey700` | `grey100` |
### Color Styles
| Style Name | Text Color | Background Color |
| ------------- | ----------- | ---------------- |
| `darkred` | `red700` | `red200` |
| `red` | `red700` | `red100` |
| `darkorange` | `orange700` | `orange200` |
| `orange` | `orange700` | `orange100` |
| `darkgreen` | `green700` | `green200` |
| `green` | `green700` | `green100` |
| `lightgreen` | `green700` | `primaryalt100` |
| `darkblue` | `blue700` | `blue200` |
| `blue` | `blue700` | `blue100` |
| `lightblue` | `blue700` | `teal100` |
| `darkteal` | `teal700` | `teal200` |
| `teal` | `teal700` | `teal100` |
| `darkpurple` | `purple700` | `purple200` |
| `purple` | `purple700` | `purple100` |
| `lightpurple` | `purple700` | `primary100` |
## Style Resolution Flow
## Defining Custom Styles
```yaml theme={null}
styles:
readOnlyStyle:
backgroundColor: 'grey100'
warningHeader:
backgroundColor: 'orange200'
color: 'orange700'
criticalCell:
backgroundColor: 'red100'
color: 'red700'
fontWeight: 600
```
## Using Styles with Formatters
Styles are applied to cells via the `formatters` section. A formatter references a style name and applies it when an expression evaluates to `true`.
```yaml theme={null}
formatters:
readonly:
- expression: 'true'
style: readOnlyStyle
styles:
readOnlyStyle:
backgroundColor: 'grey100'
columns:
outlineNumber:
title: "#"
width: 80
formatter: readonly
isReadOnly: true
```
## Using Styles with Headers
Styles are applied to column headers via the `header.style` property on a column, or to column group headers via `groupStyle` and `headerStyle` on a column group.
```yaml theme={null}
columns:
description:
title: Foreseeable Sequence of Events
width: 140
header:
style: lightpurple
columnGroups:
epic:
groupName: Epics
groupStyle: darkgreen
headerStyle: green
collapseTo: title
```
See [Column Groups](/powersheet/reference/sheet-config/column-groups) for full group styling reference.
## Color Token Reference
Styles use **color tokens** as shorthand for hex color values. Each color family has variants from `100` (lightest) to `700` (darkest).
### Purple
| Token | Value |
| ----------- | --------- |
| `purple100` | `#eae6ff` |
| `purple200` | `#c0b6f2` |
| `purple300` | `#998dd9` |
| `purple400` | `#8777d9` |
| `purple500` | `#6554c0` |
| `purple600` | `#5243aa` |
| `purple700` | `#403294` |
### Blue
| Token | Value |
| --------- | --------- |
| `blue100` | `#deebff` |
| `blue200` | `#b3d4ff` |
| `blue300` | `#4c9aff` |
| `blue400` | `#2684ff` |
| `blue500` | `#0065ff` |
| `blue600` | `#0052cc` |
| `blue700` | `#064198` |
### Teal
| Token | Value |
| --------- | --------- |
| `teal100` | `#e6fcff` |
| `teal200` | `#c1f7ff` |
| `teal300` | `#79e2f2` |
| `teal400` | `#00c7e6` |
| `teal500` | `#00b8d9` |
| `teal600` | `#00a3bf` |
| `teal700` | `#006686` |
### Green
| Token | Value |
| ---------- | --------- |
| `green100` | `#edfae1` |
| `green200` | `#c9eea4` |
| `green300` | `#abe86f` |
| `green400` | `#8dce4c` |
| `green500` | `#6aa82b` |
| `green600` | `#3d7900` |
| `green700` | `#2e5b00` |
### Orange
| Token | Value |
| ----------- | --------- |
| `orange100` | `#fffae6` |
| `orange200` | `#ffeeb4` |
| `orange300` | `#ffe380` |
| `orange400` | `#ffc400` |
| `orange500` | `#ffab00` |
| `orange600` | `#ff991f` |
| `orange700` | `#a94700` |
### Red
| Token | Value |
| -------- | --------- |
| `red100` | `#ffebe6` |
| `red200` | `#ffbdad` |
| `red300` | `#ff8f73` |
| `red400` | `#ff7452` |
| `red500` | `#ff5630` |
| `red600` | `#de350b` |
| `red700` | `#970900` |
### Grey
| Token | Value |
| --------- | --------- |
| `grey100` | `#f9f9f9` |
| `grey150` | `#f1f1f1` |
| `grey200` | `#e8e8e8` |
| `grey300` | `#e0e0e0` |
| `grey400` | `#ccd0db` |
| `grey500` | `#838dad` |
| `grey600` | `#666e89` |
| `grey650` | `#666e89` |
| `grey700` | `#162858` |
**Style Naming Convention**
Use descriptive style names that reflect purpose rather than appearance: `readOnlyStyle`, `criticalCell`, `warningHeader` rather than `greyBackground` or `redText`. This makes configurations easier to maintain when color schemes change.
## Complete YAML Example
```yaml theme={null}
columns:
outlineNumber:
title: "#"
width: 80
formatter: readonly
isReadOnly: true
title:
title: Title
width: 200
hasFocus: true
columnGroup: requirements
description:
title: Description
width: 140
header:
style: lightpurple
columnGroups:
requirements:
groupName: Requirements
groupStyle: darkblue
headerStyle: blue
collapseTo: title
formatters:
readonly:
- expression: 'true'
style: readOnlyStyle
criticalHighlight:
- expression: 'true'
style: criticalCell
styles:
readOnlyStyle:
backgroundColor: 'grey100'
criticalCell:
backgroundColor: 'red100'
color: 'red700'
fontWeight: 600
```
## Applying Styles to Headers
Header styles are applied through the `header.style` property on individual columns and the `groupStyle` / `headerStyle` properties on [column groups](/powersheet/reference/sheet-config/column-groups).
### Column Header Style
| Property | Type | Default | Description |
| ---------------------------- | ------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `columns..header` | object | None | Header styling configuration for the column |
| `columns..header.style` | string | None | Name of a predefined or custom style to apply to the column header. Must reference a style name from the `styles` section or a predefined style. |
```yaml theme={null}
columns:
description:
title: Foreseeable Sequence of Events
width: 140
header:
style: lightpurple
```
### Reusing Header Styles with YAML Anchors
YAML anchors reduce repetition when multiple columns share the same header style:
```yaml theme={null}
columns:
systemRequirements.systemRequirement.title:
title: System Requirement
header: &blueHeader
style: blue
systemRequirements.systemRequirement.severity:
title: Severity
header: *blueHeader
```
### Column Group Header Style
Column groups apply styles to the group header bar and optionally to all column headers within the group.
| Property | Type | Default | Description |
| ------------------------------- | ------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `columnGroups..groupStyle` | string | None | Style applied to the column group header background. References a predefined or custom style name. If not specified, white is used. |
| `columnGroups..headerStyle` | string | None | Style applied to all column headers within the group. Can be overridden by `header.style` on individual columns. If not specified, white is used. |
```yaml theme={null}
columnGroups:
epic:
groupName: Epics
groupStyle: darkgreen
headerStyle: green
collapseTo: title
```
### Header Style Resolution
**Priority order:**
1. `columns..header.style` -- applied if defined (highest priority)
2. `columnGroups..headerStyle` -- applied if column belongs to a group and no `header.style` is set
3. Default white -- applied if neither is defined
### Custom Header Styles
Define custom styles in the `styles` section and reference them from header configurations:
```yaml theme={null}
styles:
warningHeader:
backgroundColor: 'orange200'
color: 'orange700'
columns:
outlineNumber:
title: "#"
width: 80
header:
style: warningHeader
```
## Related Pages
* [Formatters](/powersheet/reference/sheet-config/formatters) -- conditional styling rules that reference styles
* [Column Groups](/powersheet/reference/sheet-config/column-groups) -- `groupStyle` and `headerStyle` properties
* [Columns](/powersheet/reference/sheet-config/columns) -- `formatter` and `header` column settings
***
# URL Parameters
Source: https://learn.nextedy.com/powersheet/reference/sheet-config/url-parameters
Reference for URL-driven parameters in Nextedy POWERSHEET: the parameters block schema, reserved system names, and every configuration surface where a URL value applies against Siemens Polarion ALM.
URL query parameters are surfaced to the sheet configuration as `context.parameters.` and read through [dynamic value expressions](/powersheet/reference/sheet-config/dynamic-expressions) (`() => …`). Fed into a query `where`, they scope the query on the server at render time. For the parameter mechanism see [URL Parameters](/powersheet/concepts/url-parameters); for how a `where` filters on the server see [Server-Side Filtering](/powersheet/concepts/server-side-filtering); for the task see [Open a Scoped Sheet with URL Parameters](/powersheet/guides/sheet-configuration/parametrize-sheet-url).
## Reading a Parameter
```yaml theme={null}
where:
severity: "() => context.parameters.domain"
```
For a URL ending in `…&domain=HW`, `context.parameters.domain` resolves to the string `HW`. Any parameter present on the URL is readable this way; declaring it in the `parameters` block (below) is only required for defaults and the required gate.
## Configuration Surface
The same `() => context.parameters.` expression applies across the source configuration:
| Location | Applies to |
| ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `sources[].query.where` | The root query for the sheet. |
| `sources[].expand[].query.where` | An expanded level's [subquery](/powersheet/reference/query-api/expand-clause), filtered independently of the current document. |
| `sources[].constraints.applyCurrentDocumentTo` | The entity type scoped to the current document (see [Document Filtering](/powersheet/reference/query-api/document-filtering)). |
| `sources[].entityFactory` | Default values applied to newly created items. |
| `title`, `subtitle`, `icon` | The [sheet header](/powersheet/reference/sheet-config/sheet-header), evaluated against the context including `context.parameters`. |
### Server-Rendered Properties
Starting with Powersheet 26.7.2, URL parameters also reach [server-rendered properties](/powersheet/reference/server-rendering/context-variables) defined in the data model. Inside a `serverRender` Velocity template the values are read through `$context.parameters.` -- the server-side counterpart of the client-side `() => context.parameters.` form:
```velocity theme={null}
$!context.parameters.domain
```
Read the parameter with Velocity's quiet reference (`$!context.parameters.`, with the `!` immediately after the `$`) so a missing parameter renders blank instead of the literal reference text. A `serverRender` template driven by a URL parameter remains read-only -- it can read Polarion data but not modify it. See [Context Variables](/powersheet/reference/server-rendering/context-variables) for the full behavior and a worked example.
## The `parameters` Block
A top-level `parameters` object declares named parameters, keyed by parameter name (mirroring how `columns` and `views` are keyed). It drives defaults and the required gate:
```yaml theme={null}
parameters:
domain:
required: true
ifMissing:
message: "Choose a domain to open this view."
button:
label: "Open selection page"
url: "/polarion/…/select-domain"
status:
default: "open"
```
| Property | Type | Description |
| ------------------------ | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| `required` | `boolean` | When `true` and the parameter has neither a URL value nor a `default`, the sheet does not load; the missing-parameter message is shown instead. |
| `default` | `string` | Value used when the URL omits the parameter. A `default` also satisfies a `required` parameter. |
| `ifMissing.message` | `string` | Message shown when this required parameter is missing. Accepts a `() => …` dynamic value. |
| `ifMissing.button.label` | `string` | Label for the link shown in the missing-parameter dialog. Accepts a `() => …` dynamic value; when omitted, a generic label is used. |
| `ifMissing.button.url` | `string` | Target of the link, opened in the same tab. Accepts a `() => …` dynamic value. The button appears only when `button.url` is set. |
### Required and Optional Parameters
* **Optional (the default).** A referenced parameter with no value drops its `where` condition, so the query runs without it and the broader set loads.
* **Required.** A `required` parameter with no URL value and no `default` blocks the sheet. The dialog shows the first missing parameter's `ifMissing` message and button; when several are missing, the message lists them all. Administrators additionally get an **Open Configuration** action.
**A broken expression fails loudly**
A parameter that has no value degrades gracefully (the condition is dropped). This is distinct from a malformed `() => …` expression, which raises an error during query construction rather than silently producing a filterless query.
## Reserved System Parameters
Powersheet carries its own navigation state in URL parameters. Starting with Powersheet 26.7.2, these **system parameters** are prefixed with an underscore (`_`) so they cannot collide with your own parameter names. They also populate the corresponding typed context fields (see the note below).
| Parameter | Legacy name | Purpose |
| ----------- | --------------- | --------------------------------------------------------------------------------------------------------------------------------- |
| `_project` | -- | Current Polarion project. |
| `_document` | `document` | Current document. |
| `_revision` | `revision` | Historical revision to load (see [baseline and revision queries](/powersheet/reference/query-api/baseline-and-revision-queries)). |
| `_title` | `documentTitle` | Document title carried from the Polarion link. |
| `_view` | -- | Saved view to apply on load, by view id. |
| `_version` | -- | Internal build cache-buster written by Powersheet. Do not set it yourself. |
**Reserve the leading underscore for Powersheet:** do not give your own parameters names beginning with `_`.
**Legacy names still open existing links**
Before 26.7.2 the navigation parameters had no underscore. The legacy bare names listed above (`document`, `revision`, `documentTitle`) are still honored so links saved in Polarion documents, wikis, and bookmarks keep working unchanged. When both the underscored and the legacy name are present on a URL, **the underscored one wins**. Writes only ever emit the underscored form, so a rewritten URL never carries two disagreeing copies. `_project`, `_view`, and `_version` are internal and never appeared in saved links, so they have no legacy alias.
**Context fields are unchanged -- no config edits needed**
The rename applies to the **URL** only. The typed context fields a configuration reads -- `context.project`, `context.document`, `context.revision`, `context.documentTitle` -- keep their unprefixed names and behavior, so existing sheet configurations need no changes. And because the URL system names are now underscore-prefixed, a user-defined parameter named `document` (or any former reserved name) arrives verbatim in `context.parameters.document` and no longer affects navigation.
### The `_view` Parameter
`?_view=` opens the sheet in a saved [view](/powersheet/reference/sheet-config/views) identified by its id. When `_view` is absent, the configured default view (if any) is applied instead. The value is part of the URL, so the selected perspective is shareable.
## See Also
* [URL Parameters](/powersheet/concepts/url-parameters) -- the parameter mechanism concept
* [Server-Side Filtering](/powersheet/concepts/server-side-filtering) -- filtering a sheet on the server, at the root and on expand levels
* [Open a Scoped Sheet with URL Parameters](/powersheet/guides/sheet-configuration/parametrize-sheet-url)
* [Dynamic Expressions Reference](/powersheet/reference/sheet-config/dynamic-expressions)
* [Context Expressions](/powersheet/reference/data-model/context-expressions) -- the full context object
* [Sheet Header](/powersheet/reference/sheet-config/sheet-header) -- title, subtitle, and icon driven by the same context
* [Expand Clause](/powersheet/reference/query-api/expand-clause) -- expand subquery `where`
# Views
Source: https://learn.nextedy.com/powersheet/reference/sheet-config/views
Views in Nextedy POWERSHEET are named column visibility presets that let users switch between different column layouts for the same data source.
See also: [Columns](/powersheet/reference/sheet-config/columns) | [Column Groups](/powersheet/reference/sheet-config/column-groups) | [Styles](/powersheet/reference/sheet-config/styles)
## Views Structure
The base view is defined by the `columns` section. Each entry in `views` extends the base view by overriding column visibility. The views selector UI presents all configured views to the user.
## View Properties
Each view is defined as a keyed entry under the `views` map. The key becomes the display name shown in the views selector.
**YAML key naming**
In the property table below, `` is a placeholder for the actual YAML map key you define, such as `Without V&V`, `Compact`, or `Requirements Only`. This key is the user-visible label in the views selector dropdown.
| Name | Type | Default | Description |
| -------------------------------------- | --------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `` | `object` | -- | Top-level key in the `views` map. The key string is the display name shown to users in the views selector. |
| `.name` | `string` | Key name | Human-readable label for the view. Visible in the views selector list. If omitted, the YAML key is used as the name. |
| `.default` | `boolean` | `false` | When set to `true`, this view is applied automatically when the document loads. Only one view should have `default: true`. When a default view is configured, the base view option may be hidden from the menu. |
| `.columns` | `object` | -- | **Required.** Column visibility overrides for this view. Keys must be binding paths that match column definitions in the top-level `columns` section. |
| `.columns.` | `object` | -- | Override object for a specific column identified by its binding path. |
| `.columns..visible` | `boolean` | `true` | Set to `false` to hide this column in the view. Columns not listed in the view inherit their `visible` setting from the base `columns` section. |
## Defining Views
Views are defined in the top-level `views` section of the sheet configuration. Each key in the `views` map becomes a selectable view in the UI:
```yaml theme={null}
views:
Without V&V:
columns:
validationTestCases.validationTestCase:
visible: false
systemRequirements.systemRequirement.verificationTestCases.verificationTestCase:
visible: false
systemRequirements.systemRequirement.designRequirements.designRequirement.verificationTestCases.verificationTestCase:
visible: false
```
In this example, the "Without V\&V" view hides validation and verification test case columns while keeping all other columns at their default visibility.
**Selective overrides**
Views only need to list columns that differ from the base state. Columns not mentioned in a view retain their `visible` setting from the `columns` section. This means most views are short -- you only specify what you want to hide (or show, if hidden by default).
## Base View
The **base view** is the column layout defined by the top-level `columns` section in the sheet configuration. It represents the complete set of columns at their configured `visible` state. The base view serves as the foundation that all named views extend.
| Scenario | Behavior |
| ------------------------------------- | ------------------------------------------------------------------------------------------ |
| No `views` section defined | Only the base view is available. No views selector appears. |
| `views` defined but no `default` view | Base view is active on document load. Labelled "Default view" in the selector. |
| `views` defined with a `default` view | The default view is active on document load. Base view option may be hidden from the menu. |
| Invalid view requested | Falls back to the base view column configuration. |
| View cleared by user | Returns to the base view. |
The base view can be given a custom name by defining an empty view entry:
```yaml theme={null}
views:
Full RTM:
columns: {}
Without V&V:
columns:
validationTestCases.validationTestCase:
visible: false
```
In this example, the base view is labelled "Full RTM" in the selector, with an empty `columns` override meaning no visibility changes from the base.
## Default View
One view can be designated as the default view by setting `default: true`. When configured, this view is applied automatically when the document loads, instead of the base view:
```yaml theme={null}
views:
Compact:
default: true
columns:
systemRequirements.systemRequirement.designRequirements.designRequirement:
visible: false
validationTestCases.validationTestCase:
visible: false
```
| Property | Value | Effect |
| --------- | -------------------- | --------------------------------------------------------- |
| `default` | `true` | This view loads automatically on document initialization. |
| `default` | `false` (or omitted) | Base view loads on document initialization. |
**Single default only**
Only one view should have `default: true`. If multiple views set `default: true`, the behavior is undefined and may vary. When a default view is set, the base view option may be hidden from the views menu.
## View Selection Methods
Users can switch between views at runtime through two mechanisms:
| Method | Description |
| --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Menu** | Access via the alternative views menu item in the sheet toolbar. Shows all configured views with a "Selected" indicator next to the active view. |
| **Dropdown selector** | Quick-access dropdown list showing view names. Selecting a view immediately applies its column visibility overrides. |
Both methods present the same list of available views. The currently active view is visually indicated in both the menu and the dropdown.
## View-Specific Column Visibility
Each view independently controls which columns are visible. Views can hide entire entity-level columns (hiding all related child data) or selectively hide individual property columns:
```yaml theme={null}
views:
Requirements Only:
columns:
systemRequirements.systemRequirement.designRequirements.designRequirement:
visible: false
validationTestCases.validationTestCase:
visible: false
systemRequirements.systemRequirement.verificationTestCases.verificationTestCase:
visible: false
Design Focus:
columns:
severity:
visible: false
validationTestCases.validationTestCase:
visible: false
```
**How column binding paths work in views:**
The `columns` keys in a view must match the binding paths defined in the top-level `columns` section. A binding path follows the `navigationProperty.childProperty.propertyName` pattern from the data model. For details on binding path syntax, see [Binding Syntax](/powersheet/reference/sheet-config/binding-syntax).
| Binding Path Example | What It Hides |
| ---------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------- |
| `severity` | Root-level severity column |
| `validationTestCases.validationTestCase` | Entire validation test case entity column |
| `systemRequirements.systemRequirement.verificationTestCases.verificationTestCase` | Verification tests nested under system requirements |
| `systemRequirements.systemRequirement.designRequirements.designRequirement.verificationTestCases.verificationTestCase` | Deep-nested verification tests under design requirements |
## Cross-Document View Linking
Views can reference alternative documents with the same name, enabling switching between different tool representations of related data. When configured, the views selector dropdown shows both view names and linked document names, allowing users to navigate between different perspectives.
**Verify in application**
Cross-document view linking depends on the `alternativeViewDocument` property on the document configuration. The views selector displays both in-document views and alternative document links in the same dropdown.
## Error Handling
Views handle configuration errors gracefully:
| Error Condition | Behavior |
| ----------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| Non-existent binding path in view `columns` | View still loads; unrecognized paths are silently ignored. Base view columns remain unchanged for those paths. |
| Invalid view definition (missing `columns`) | Falls back to the base view. |
| View references column not in `columns` section | No effect; the column override is skipped. |
**Incremental configuration**
Start with a minimal view configuration and extend gradually. A view with a single column override is valid and useful for quickly creating focused perspectives.
## Runtime Behavior
The following details describe how views behave at runtime:
* **View switching is instant.** Changing views only toggles column visibility; it does not re-fetch data from the server.
* **Data remains loaded.** Hidden columns still have their data loaded in memory. Showing them again via a different view is instantaneous.
* **Views do not affect sorting or filtering.** Column sort state and filter state are independent of the active view. Sorting by a hidden column still applies.
* **Views persist during the session.** The selected view remains active until the user switches to another view or reloads the document.
* **Configuration is read-only at runtime.** Users cannot create or edit views from the UI; views must be defined in the YAML configuration by an administrator.
## Complete YAML Example
The following example demonstrates a full sheet configuration with multiple views for an RTM (Requirements Traceability Matrix) use case using the standard entity hierarchy (`UserNeed` -> `SystemRequirement` -> `DesignRequirement` -> `Hazard` -> `RiskControl`):
```yaml theme={null}
columns:
outlineNumber:
title: "#"
width: 80
isReadOnly: true
frozen: true
title:
title: User Need
width: 200
hasFocus: true
severity:
title: Severity
width: 100
systemRequirements.systemRequirement.title:
title: Sys Req Title
width: 200
columnGroup: sysReq
systemRequirements.systemRequirement.severity:
title: Sys Req Severity
width: 100
columnGroup: sysReq
systemRequirements.systemRequirement.designRequirements.designRequirement:
title: Design Outputs
width: 180
multiItem: true
display: title
validationTestCases.validationTestCase:
title: Validation Tests
width: 180
multiItem: true
display: title
systemRequirements.systemRequirement.verificationTestCases.verificationTestCase:
title: Verification Tests
width: 180
multiItem: true
display: title
columnGroups:
sysReq:
groupName: System Requirements
groupStyle: darkblue
headerStyle: blue
collapseTo: systemRequirements.systemRequirement.title
views:
Without V&V:
columns:
validationTestCases.validationTestCase:
visible: false
systemRequirements.systemRequirement.verificationTestCases.verificationTestCase:
visible: false
Requirements Only:
columns:
systemRequirements.systemRequirement.designRequirements.designRequirement:
visible: false
validationTestCases.validationTestCase:
visible: false
systemRequirements.systemRequirement.verificationTestCases.verificationTestCase:
visible: false
Compact:
default: true
columns:
systemRequirements.systemRequirement.severity:
visible: false
systemRequirements.systemRequirement.designRequirements.designRequirement:
visible: false
validationTestCases.validationTestCase:
visible: false
systemRequirements.systemRequirement.verificationTestCases.verificationTestCase:
visible: false
sources:
- id: rtm
query:
from: UserNeed
expand:
- name: systemRequirements
expand:
- name: designRequirements
- name: verificationTestCases
- name: validationTestCases
```
In this configuration:
* The **base view** shows all eight columns including system requirements, design outputs, and both test types.
* **Without V\&V** hides both test columns, focusing on requirements and design.
* **Requirements Only** hides design outputs and both test types, showing only user needs and system requirements.
* **Compact** is the default view (`default: true`), loading automatically. It shows only user need columns and system requirement titles, hiding severity details, design outputs, and all tests.
## Configuration Tips
**Naming conventions**
Use descriptive view names that communicate the analysis perspective: "Without V\&V", "Requirements Only", "Risk Analysis", "Compliance Review". The view name appears directly in the dropdown selector.
**Column groups and views**
Views work with [column groups](/powersheet/reference/sheet-config/column-groups). Hiding all columns in a group effectively hides the entire group header. Consider defining views that align with your column group boundaries for clean visual results.
**Binding path accuracy**
View column keys must exactly match the binding paths in the `columns` section. A typo in the binding path (e.g., `systemRequirement.title` instead of `systemRequirements.systemRequirement.title`) will be silently ignored, and the column will remain visible.
***
**Related pages:** [Columns](/powersheet/reference/sheet-config/columns) | [Column Groups](/powersheet/reference/sheet-config/column-groups) | [Binding Syntax](/powersheet/reference/sheet-config/binding-syntax) | [Styles](/powersheet/reference/sheet-config/styles)
# Admin AI Assistant
Source: https://learn.nextedy.com/risksheet/concepts/admin-ai-assistant
How the Admin AI Assistant works in Nextedy RISKSHEET: a documentation-grounded chat in the configuration editor, scoped to the Risksheet documentation, and designed so the editor keeps working even when the assistant does not.
The **Admin AI Assistant** is a documentation-grounded chat in the Risksheet configuration editor. It is not included with Risksheet: it arrives with the separately installed **Nextedy AI** package. It opens from the sparkle button in the editor toolbar, and its window is titled **✦ Risksheet AI**. While an administrator is editing a Risksheet configuration, they can ask natural-language questions about Risksheet configuration and get answers drawn from the Risksheet documentation, with links to the relevant pages.
This page explains what the assistant is, why it works the way it does, how its answers stay grounded in the documentation, and what determines whether it is available. For the task of opening and using it, see [Use the Admin AI Assistant](/risksheet/guides/configuration/use-admin-ai-assistant).
**One assistant, shared across products**
The assistant is not part of Risksheet itself. It arrives with the separately installed **Nextedy AI** package, which plugs into the configuration editor that Nextedy products share. The Risksheet build tells the assistant which product it is serving, so the panel is titled **✦ Risksheet AI** and answers are drawn from the Risksheet documentation rather than another product's. **Add data model**, offered in the Powersheet editor, is not available here — Risksheet has no separate data-model file to attach.
## Why it exists
Switching context to a separate documentation site or a support channel breaks the configuration workflow and slows down problem solving. The assistant puts the answer one click away from where the question arises — inside the editor, while the configuration is still on screen — so administrators spend less time hunting through documentation and more time configuring.
The questions it is built for are the ones that come up mid-task: how to configure a particular behavior, which property controls it, what an existing block of configuration does, why something is not working, the difference between two concepts, or simply where something is documented.
## A guide, not an operator
The assistant answers questions and points to the right documentation. It does **not** change, save, or apply configuration on your behalf. The administrator stays in control of the configuration file and makes every edit themselves in the editor. There is no code path from the chat to your saved configuration.
**Two assistants, both labeled AI Assistant**
Nextedy AI adds two assistants to Risksheet, and the interface labels both of them **AI Assistant**. This page describes the **Admin AI Assistant** — the one in the configuration editor, which only reads documentation and answers questions about configuring the product. Its panel is titled **✦ Risksheet AI**, and it never changes anything.
The other is the **Risksheet AI Assistant**, opened from a sparkle button in the Risksheet grid toolbar, which works on the risk content itself.
Both reach your installation through the same Nextedy AI package, but they take it from there differently — the Admin AI Assistant asks the package only for the proof it needs to reach the Nextedy AI documentation service, while the Risksheet AI Assistant runs its actions against the Polarion server.
## Grounded in the documentation
The assistant runs in a documentation-search mode rather than as an open-ended chatbot: its answers are grounded in documentation content, not generated freely. Several design choices keep the answers relevant:
| Aspect | How it works |
| --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Product scoping** | Every request identifies the product as Risksheet, so the service answers for Risksheet rather than for another Nextedy product. |
| **Streaming responses** | Answers stream in incrementally as they are generated. A typing indicator is shown between sending the question and the first content arriving. |
| **Conversation continuity** | The conversation is held on the Nextedy AI service, so a short follow-up is understood against the earlier turns, and the conversation is restored when you reopen the panel. |
| **Starter questions** | When the panel is empty it offers suggested starter questions, fetched from the AI service for the current product. If the service returns none, no chips are shown. |
Conversations do not live forever. The editor keeps only the conversation's identifier in the browser; the turns themselves are held by the AI service, and once it has dropped a conversation the panel simply starts a fresh one.
Because answers come from a language model reading documentation, the assistant shows a standing reminder that *"AI can make mistakes. Verify important information."* Treat its answers as guidance and confirm property names and behavior against the linked documentation before relying on them in production.
## What the assistant sees
By default the assistant answers from the documentation alone — it does **not** receive your configuration. When a question is specifically about the file being edited, the administrator can explicitly attach it with **Add configuration**, and only then is that content sent alongside the question. The attachment appears as a **Configuration** chip and can be removed at any time.
**Privacy by default**
Sending no configuration content unless it is explicitly attached is deliberate: attaching your configuration is a decision you make per conversation, not something the assistant does for you. On the default path your configuration stays out of the request entirely, and the assistant reads only what it needs to search the documentation.
## Availability
The editor resolves an availability status before enabling the assistant, and reflects it on the toolbar button. The signal is deliberately **not** a product health check — it is the result of the token flow described below actually succeeding.
| State | What it means | In the editor |
| ------------------------- | ----------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------- |
| **Available** | The Nextedy AI package answered and a session token was issued. | The **AI Assistant** button is enabled; its tooltip reads *"AI Assistant"*. |
| **Package not installed** | The Nextedy AI package is absent from the server. | The button is disabled; its tooltip reads *"Install the Nextedy AI plugin, or contact Nextedy, to enable the AI Assistant"*. |
| **Unavailable** | The package is installed but could not be reached, or the proof could not be exchanged for a session token. | The button is disabled; its tooltip reads *"AI Assistant is currently unavailable"*. |
### How the browser authenticates
Authentication runs in two hops, both made by the **browser** — the Polarion server itself never makes an outbound call:
The editor calls the Nextedy AI plugin on your own Polarion server at `/polarion/nx_ai/api/ai-token`. Polarion returns a signed license proof for the signed-in user. This request stays inside your network.
The browser posts that proof to the Nextedy token service, which validates it and returns a short-lived session token.
Every question is sent to the Nextedy AI service with that token attached. The token is cached in the browser and refreshed automatically shortly before it expires.
Because the proof travels through the browser, the assistant works even when your Polarion server has no outbound internet access.
**No licence is needed, and the button never claims otherwise**
The Admin AI Assistant requires **no** valid Nextedy AI license. Installing the Nextedy AI package on the server is enough, together with a signed-in Polarion user — which is why none of the three tooltips above mentions a licence.
**This applies to the editor assistant only.** The Risksheet AI Assistant in the sheet does require a valid license: on the grid toolbar an invalid one disables the button with its own, differently worded tooltip. See [Nextedy AI](/overview/resources/nextedy-ai) for what the license covers.
**The button appears even without the package — and can be turned off**
When the Nextedy AI package is not installed, the **AI Assistant** button still appears in the editor toolbar, disabled, rather than being hidden, and its tooltip reads *"Install the Nextedy AI plugin, or contact Nextedy, to enable the AI Assistant"*. This is deliberate: it advertises the capability and says how to obtain it. An administrator who does not want it advertised can turn it off through context properties, independently for the editor assistant and for the one in the sheet.
### Graceful degradation
Availability of the assistant is an independent signal from the rest of the editor. If the Nextedy AI plugin or service cannot be reached, only the **AI Assistant** button is disabled — the configuration editor, and the rest of Risksheet, continue to work normally. The assistant is an addition to the editor, never a dependency of it.
## Related Pages
Step by step: open the assistant in the editor, ask questions, and attach the configuration you are editing.
Open the editor the assistant lives in, and save configuration changes.
The package the assistant arrives with, where it appears in each product, and what its license covers.
How templates and document configurations inherit and override each other.
The property reference the assistant's answers draw on.
# AI Assistant
Source: https://learn.nextedy.com/risksheet/concepts/ai-assistant
How the AI Assistant works in Nextedy RISKSHEET — the Select, Discover, Apply model behind its actions, what context it sends, how a suggestion is verified before you see it, and what has to be in place for it to appear.
The **AI Assistant** is an AI capability you can add to Powersheet and Risksheet. It is not included with either product: it arrives with the separately installed **Nextedy AI** package and is licensed on its own.
In Risksheet the assistant works on the row you are standing on. You pick one of the **actions** your administrator has configured — one that finds candidate harms on a HARA row, say, or existing control measures on an FMEA row — and it looks through your own Polarion project for work items that fit, explains why each one fits, and offers to link them into the sheet for you.
This page explains the model behind that: what an action actually does, what the assistant is told about your row, why you can trust the items it comes back with, where it is weak, and what has to be true for it to be available at all.
**The AI Assistant proposes, you decide.** Every result is a recommendation for you to review, adjust, or reject. The assistant does not change work items, sheet data, or configuration on your behalf — a link is only created when you click **Apply**.
## Select, Discover, Apply
Every action follows the same three-beat shape, and it is worth holding onto because it explains both the strengths and the limits of the feature.
| Beat | What happens | Who is in control |
| ------------ | --------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| **Select** | You put the cursor on a risk row and choose an action, either from the cell's right-click menu or from the list in the assistant panel. | You choose the row and the action. |
| **Discover** | The assistant searches your own Polarion project for work items that fit the row, and offers the ones that fit best. | The administrator's action configuration decides what the assistant looks for. |
| **Apply** | You read the suggestions and click **Apply** on the ones you want. Risksheet writes the link into the sheet. | You decide, one recommendation at a time. |
The assistant never skips a beat. It cannot go looking on its own, and it cannot apply anything you have not clicked.
## What an action does
An action reads the context configured for your row, finds work items in your own Polarion project that fit it, and comes back with a short, ordered list of proposals — each one an existing work item with a one-sentence rationale for why it fits. The panel reports progress while it works.
Two properties of that are worth holding onto:
* **It only proposes what belongs in the target column.** An action is scoped to the work-item types that can legitimately go into the column it fills, so a HARA harm action cannot propose a test case.
* **It only sees what you can see.** The assistant reads your project with your own Polarion permissions, so it can never surface an item you would not be allowed to open yourself.
What it proposes is drawn from your project, never from the model's general knowledge of the domain.
## What the assistant is told about your row
The assistant does not read your sheet. It receives a small set of labelled values, assembled fresh each time you run an action:
* **Which row you are on** — its ID and its title.
* **The fields your administrator chose.** An action's configuration maps sheet fields onto labels, and those labels are what the model reads. A HARA action typically passes the use step, the hazardous situation, and the hazard; an FMEA action passes the failure mode and its cause.
* **How many items to return, and how to sort them**, when the action sets them.
* **Anything a project script adds.** A document's top panel can contribute extra context — a device name, an intended use, a governing standard — so an action can be told things that live outside the grid.
Nothing else about the document or the project is sent, and nothing is sent until you run an action.
Because the labels are what the model reads, they are worded as prose rather than as field ids. That is a configuration choice, and it is the main lever an administrator has over how well an action performs.
## Why you can trust what comes back
A language model asked for work items will happily invent plausible ones. The assistant is built so that invented items cannot reach you.
**Every recommendation is a work item that really exists in your project.** Each proposal is confirmed against your project data before it is shown to you, and anything that cannot be confirmed is discarded. The assistant never presents an item it has not verified, and it never invents a work-item ID.
**Titles come from Polarion, not from the model.** Every recommendation is shown with the title Polarion currently holds for that work item, so even for an ID that does exist you are never shown a title the model made up.
If nothing survives that check, the panel tells you so rather than quietly showing less:
* **`No matching items found in the project.`** — nothing in your project matched the row.
* **`No verified matches found. The AI suggested items that don't exist in the search results.`** — there were proposals, but none of them could be confirmed against your project.
Each recommendation carries a one-sentence rationale, written by the model, and the list is ordered with the closest fit first. Treat the rationale as the model's reasoning about relevance rather than as a measurement; the panel's standing reminder that *"AI can make mistakes. Verify suggestions before applying."* applies to it too.
## Where it is weak
The assistant is built to offer a generous set of candidates rather than risk missing the right item. Three things follow from that:
* **Matching is loose, and it is only as selective as the least distinctive word in your wording.** Phrases are not matched as phrases: a row whose fields say "tissue damage" will also draw in items that speak only of damage. Distinctive, domain-specific wording in the configured fields produces sharper results than generic wording.
* **Very short abbreviations and common words do not help.** One- and two-character terms such as "UV" or "CO", and everyday English words, will not narrow anything down. Spell the term out where the sheet allows it.
* **There is a ceiling on how many items a single run considers.** Raising an action's requested result count past about thirty makes no difference to what comes back.
This is also why an action pointed at a very large, weakly-typed column tends to produce vaguer results than one pointed at a narrow, well-typed one — and why the wording of the fields an action passes is the main lever an administrator has on quality.
The assistant also has no memory of your earlier rows: each run starts from the row you are on.
## What has to be in place
The assistant is deliberately layered, and each layer fails visibly rather than silently. Five things must all be true before an action appears on a row:
Without it, Risksheet works exactly as it always did. The toolbar may still show a disabled sparkle button as a promotion, whose tooltip explains what the package would add.
The in-sheet assistant sends its requests from your Polarion server, so the server needs an endpoint to send them to. Until that is set, the assistant reports itself unavailable and cannot be opened.
The in-sheet assistant is license-gated. With an invalid license the toolbar button is shown but disabled, its tooltip naming the license as the problem — and no AI entries appear in the cell menu at all.
A Polarion project property turns the in-sheet assistant on or off per project, so a project that should stay AI-free can opt out even on a licensed server.
Actions are not built in. Until an administrator defines them, the panel has nothing to offer.
**An invalid license denies the in-sheet assistant outright.** This differs from the behaviour you may know from other Nextedy products, where an invalid license degrades a feature rather than blocking it. Here the entry point stays visible and refuses to run, so the state is obvious to the user and actionable by the administrator. The exact tooltip for each state is listed in [Toolbar and Risksheet Menu](/risksheet/reference/toolbar).
The rest of Risksheet is unaffected by all of this. If the AI is unreachable, only the AI entry points go away — the grid, saving, exports, and reviews carry on.
## See Also
Run an action on a risk row and apply a suggestion into the sheet.
Turn the assistant on for a project and write your first action.
Every field of the action configuration file, with defaults.
The package, its license, and where the assistant appears across products.
* [Traceability and Linking](/risksheet/concepts/traceability) — the link model an applied recommendation writes into
* [Configure HARA Workflows](/risksheet/guides/risk-management/hara-configuration) — the sheet an action typically runs against
* [Understanding Licenses](/risksheet/guides/licensing/understanding-licenses) — how Nextedy licensing works in Risksheet
# Architecture
Source: https://learn.nextedy.com/risksheet/concepts/architecture
Nextedy RISKSHEET is an app for Siemens Polarion ALM. It does not run as a standalone application, it does not own a database, and it does not introduce an alternate identity or access-control layer.
This page builds a mental model of how Risksheet fits into Siemens Polarion ALM, how data flows between the grid and the platform, and where the boundaries of the product lie. If you understand this picture, the rest of the documentation — configuration, traceability, review workflows, export — will fit together naturally.
## The Core Idea: A View Onto Polarion
A useful analogy: think of Risksheet the way you would think of a spreadsheet view over a relational database. The spreadsheet is a workspace for analysis — sorting, filtering, formulas, conditional formatting — but the rows are records in the database. Closing the spreadsheet does not delete the records, and opening a different spreadsheet over the same table shows the same data, possibly arranged differently.
In our case, the "database" is Polarion's work-item store, and the "spreadsheet" is the risksheet grid embedded in a Polarion LiveDoc.
Risksheet adds three things on top of Polarion:
1. **A grid renderer** that turns work items into rows and fields into columns, with cell merging, calculated values, conditional formatting, and saved views.
2. **A sheet configuration** that declares the structure of that grid — which columns to show, how to group rows visually, how to calculate values, how to style cells.
3. **A small server-side component** that loads the configuration, mediates communication between the browser grid and Polarion's work-item APIs, and handles export.
That is the entire product surface. There is no Risksheet database, no Risksheet user directory, no Risksheet permission system.
**Common misconception**
Risksheet is sometimes described as if it had its own data store. It does not. A risksheet is a view; deleting the grid would not delete a single work item. Conversely, edits made directly in Polarion (in tables, in the work-item editor, via imports, via APIs) are immediately visible in any open risksheet, because both surfaces read the same underlying records.
## The Two Halves: Browser Grid and Server Extension
Risksheet has two cooperating parts:
* **Client-side grid** — JavaScript code that runs in the user's browser inside the Polarion LiveDoc page. It renders rows, evaluates JavaScript formulas, applies cell decorators, handles editing, and drives the review UI.
* **Server-side extension** — a Polarion plugin that exposes endpoints for the grid to load configurations, fetch work-item data, save edits in batches, and generate PDF and Excel exports.
This split has practical consequences:
* **Formulas and conditional formatting are JavaScript that runs in the browser.** They can react instantly to user input without a server round-trip, but they can only see data Polarion has already loaded into the page.
* **Edits are saved through the server extension, which writes work items via Polarion's own APIs.** Risksheet does not bypass workflow, signatures, or field-level permissions — if Polarion would have rejected a write, Risksheet's save will fail in exactly the same way.
* **The grid behaves the same regardless of how the user reached it** (LiveDoc page, direct link, embedded view). The configuration is attached to the document, not to a session.
## What a Risksheet Actually Contains
When you open a risksheet, three layered ingredients combine:
| Layer | Where it lives | What it provides |
| --------------------------------- | --------------------------------------- | ------------------------------------------------------------------------------------------- |
| **Work items** | Polarion's work-item store | The actual data: risk items and any linked tasks, requirements, hazards, controls |
| **Sheet configuration** | Document attachment on the LiveDoc | The structure of the grid: columns, levels, types, formulas, styles, views |
| **Custom logic and presentation** | Top panel template, PDF export template | Optional Velocity templates for the information panel above the grid and for PDF formatting |
Risksheet keeps these three concerns separate on purpose. The work items are the audited record. The sheet configuration is a declarative description of how to show those records. Custom logic — risk matrices, complex conditional rendering, branded PDF layouts — lives in separate Velocity templates so that changes to it do not perturb the declarative configuration. This separation matters in regulated industries (ISO 26262, ISO 14971, IEC 61508, ISO/SAE 21434), where the scope of validation is smaller when configuration and custom code change independently.
For details about how the configuration is loaded and inherited, see [Configuration Hierarchy](/risksheet/concepts/configuration-hierarchy).
## The Risk Item as Aggregation Point
Looking at a risksheet from a methodology angle (FMEA — Failure Mode and Effects Analysis, HARA — Hazard Analysis and Risk Assessment, TARA — Threat Analysis and Risk Assessment, STRIDE, CVSS — Common Vulnerability Scoring System), the central object is the **risk item** — a single Polarion work item that ties together everything an analyst needs to assess one failure mode, hazard, threat, or vulnerability.
The risk item is best understood as a mapping table:
A single row in the grid maps:
* **Context** — the function, system item, hazard, or scenario the risk applies to (typically a linked upstream work item)
* through **risk attributes** — the failure mode, cause, effect, or threat description
* to a **classification** — numeric or categorical scoring (severity, occurrence, detection, ASIL — Automotive Safety Integrity Level, RPN — Risk Priority Number, CVSS score)
* with **mitigations** — linked downstream tasks, safety requirements, or controls
* to a **residual risk** — the reassessed scoring after mitigations are applied.
All of these are fields or link roles on the same Polarion work item, surfaced as columns in the grid. Reading the row left to right traces the analytical chain from "what could go wrong" through "what we did about it" to "what risk remains". This shape is the same whether the methodology is FMEA, HARA, TARA, STRIDE, or CVSS — only the column names, scales, and standards change. Risksheet is a generic tool that supports any of these methodologies; Nextedy provides solution templates for typical methodologies across industries.
For the underlying work-item structure and the two-entity data model (risk items plus linked task items), see [Data Model and Work Items](/risksheet/concepts/data-model).
## Data Flow at a Glance
In one sentence: the server loads the configuration and the work items, the browser renders the grid and evaluates formulas, and edits travel back through the server, where Polarion enforces its normal rules before persisting them.
A few properties follow directly from this flow:
* **No separate cache or shadow store.** What you see in the grid is the result of a fresh query against Polarion's work-item store, scoped to the document and the current view.
* **All edits go through Polarion.** Workflow transitions, field validations, custom-field constraints, permissions, signatures, and history are all applied by Polarion on save. Risksheet does not have a back door.
## Security: Polarion Is the Source of Truth
Every row in a risksheet is a Polarion work item, so Polarion — not Risksheet — decides who may read or change it. Risksheet adds no identity system, no parallel permission store, and no external network exposure: it runs inside Polarion's web container and is reachable only through an authenticated Polarion session. Security is a **shared responsibility** between the platform and the product.
**Handled by Polarion** — user authentication and authorization (roles, permissions, project access), session management, HTTPS/TLS, Content Security Policy, CSRF protection on state-changing operations, network and OS/JVM/database hardening, central logging, secure secrets storage through the User Account Vault, and the SQL/Lucene query restrictions that are on by default since Polarion 2410. Risksheet relies on these and never bypasses or replaces them.
**Handled by Risksheet** — correct use of the Polarion APIs under the authenticated user's context, safe rendering of user-controlled data, conservative default limits on how much data a sheet processes and renders, and keeping day-to-day grid work clearly separated from privileged configuration.
For the data and permission concerns, that split lands entirely on the platform side:
| Concern | Where it is enforced |
| ------------------------------ | ----------------------------------------- |
| Authentication | Polarion login |
| Project membership | Polarion project roles |
| Work-item type permissions | Polarion permissions (per type, per role) |
| Field-level read and write | Polarion field permissions |
| Workflow transitions | Polarion workflow |
| History, audit, signatures | Polarion history and e-signature features |
| Document access | Polarion document permissions |
| Enumerations and rating scales | Polarion enumeration administration |
Risksheet does not add a parallel permission system. If a user cannot edit a particular field in Polarion's own form view, they cannot edit it in the risksheet either — the server rejects the save the same way. If a user cannot read a work item, that work item does not appear in their grid. Administrative actions (changing the sheet configuration, managing licensing, registering documents as risksheets) are gated on Polarion administrative roles.
### Configuration Is Privileged
Sheet configuration is not user data. It can define formulas, custom cell renderers, and server-rendered templates, so it is treated as privileged — closer to administrative code than to a preference.
* **Storage** — configuration lives as a document attachment on the LiveDoc (see [What a Risksheet Actually Contains](#what-a-risksheet-actually-contains)), which means it is governed by Polarion's standard document and attachment permissions rather than by a separate Risksheet access layer.
* **Management** — the configuration editor is restricted to users with at least **Project Administrator** privileges.
* **Templates** — configuration is normally defined once on a **template document** that many instance documents reference through their `templateDoc` field.
Because configuration is stored as document data, permissions on template documents and their attachments are part of your security posture. If regular users can edit a template document or its configuration attachment through ordinary Polarion mechanisms, they can change how every risksheet that follows that template behaves — without ever opening the configuration editor.
### Safe Rendering
Administrator-configured rendering — custom cell renderers, row-header decorators, server-rendered columns, and top-panel templates — controls how work item data is displayed, and its safety depends on which Polarion API the configuration uses:
* **Rendering API** (for example `$item.fields().description().render()`) applies Polarion's built-in HTML sanitization and is the right choice for anything administrator-configurable.
* **Open API / raw access** — the field value without `.render()` — returns unsanitized content. Where a template uses it, the administrator is responsible for escaping the output before it reaches the page.
Template scripting is restricted to trusted roles and is **not sandboxed** beyond that role restriction.
### Query and Processing Limits
Risksheet applies configurable limits to how much data a single sheet loads and renders, with deliberately conservative defaults (the link suggester's `nextedy.risksheet.suggester.resultLimit`, for example, defaults to 20). Raising a limit can affect Polarion's performance noticeably, so evaluate the change outside production first.
For day-to-day expectations about who can do what, see [User Roles and Permissions](/risksheet/concepts/user-roles) and [Data Model and Work Items](/risksheet/concepts/data-model) (which covers work item visibility and levels). For the cross-product picture — the full shared responsibility model, secure development practices, and the administrator checklist — see [Product Security](/overview/security-and-privacy/product-security).
**What this means in practice**
Hardening a Risksheet deployment means hardening Polarion. There is no separate Risksheet admin console to lock down. If sensitive risk records must be restricted, restrict them at the Polarion level (project membership, work-item type permissions, document permissions) — the grid will follow.
The one part that is genuinely yours to get right is configuration access: keep template documents and their configuration attachments administrator-only.
## Traceability Without Replication
Risk analysis only matters if it connects to the rest of the engineering record: requirements, hazards, and design elements upstream; mitigations, controls, and tests downstream. Because Risksheet's rows are real work items, traceability is implemented with Polarion's own link roles — not by copying data into the grid or maintaining a parallel reference table.
* **Upstream context** (functions, hazards, requirements) is loaded through link roles defined in the sheet configuration. The values shown in upstream columns are read from the linked items in real time.
* **Downstream mitigations** (safety requirements, controls, tests) are also linked work items, optionally created inline from the grid. Their fields can be edited through the same grid if the configuration allows.
* **Cross-project links** are supported wherever Polarion supports them, so shared libraries (a harms catalog, a function catalog, a requirements library) can be referenced from many risksheets without duplication.
This means an existing change-impact analysis in Polarion still works: if you trace a requirement, the risksheets that reference it appear naturally as linked work items. See [Traceability and Linking](/risksheet/concepts/traceability) for the link patterns and the configuration options that drive them.
## Misconceptions Worth Naming
**Verify in application**
Risksheet versions evolve quickly. Where this page describes general behavior, individual capabilities may depend on the Risksheet and Polarion versions installed in your environment.
* **"Risksheet has its own database."** It does not. The grid is a presentation of Polarion work items.
* **"Risksheet is only for FMEA."** Risksheet is a generic risk-analysis grid that supports FMEA, HARA, TARA, STRIDE, CVSS, and other methodologies. Nextedy provides solution templates for typical methodologies across industries; the engine itself is methodology-agnostic.
* **"Configuration changes affect all risksheets."** The sheet configuration is attached per document, with inheritance from templates. See [Configuration Hierarchy](/risksheet/concepts/configuration-hierarchy) for the resolution order.
* **"Approval reviews lock a document."** Risksheet's approval review records approval-tagged comments — it does not by itself drive Polarion's formal document workflow states (draft to reviewed to approved). When formal state transitions are required, they remain a Polarion document-workflow action. See [Review Workflows](/risksheet/concepts/review-workflows) for the three review styles and their boundaries.
## Where to Go Next
* For a higher-level positioning of the product, read [What is Risksheet?](/risksheet/concepts/what-is-risksheet).
* For the data shape behind the grid, read [Data Model and Work Items](/risksheet/concepts/data-model).
* To put the model to work, see the [How-To Guides](/risksheet/guides/index), in particular [Risk Management](/risksheet/guides/risk-management/index) and [Configuration Management](/risksheet/guides/configuration/index).
# Configuration Hierarchy
Source: https://learn.nextedy.com/risksheet/concepts/configuration-hierarchy
A risk programme is rarely a single document. A typical safety project produces dozens of risk analyses — one per system, one per subsystem, one per software component, one per interface.
Nextedy RISKSHEET (Risksheet) solves this with a clear separation between **configuration templates** and **risksheet instances**. A single template defines how the analysis looks and behaves; many instances inherit that template and each binds the resulting grid to its own scope — its own system, subsystem, or component. This page explains the mental model behind that separation, where templates live, how instances pick up the right one, and what to expect when configuration changes over time.
## The Mental Model: One Template, Many Instances
The clearest analogy is a product specification template. A safety department defines a single FMEA template that prescribes the column layout, severity and occurrence scales, RPN calculation, and styling. Every engineering team then creates **their own FMEA document** — one for the braking system, one for the steering ECU, one for the diagnostic interface. The document is the unit of work; the template is the unit of governance.
In Risksheet terms:
* A **risksheet instance** is a single Polarion LiveDoc with risk items inside it. It is what users open, edit, and review. Each instance is bound to a specific **context** — a system, subsystem, or component — through the document title, location, and the work items it contains.
* A **configuration template** is a shared definition of how those instances look and behave. It lives as sheet configuration (`risksheet.json`) on a designated template document. Many instance documents reference the same template and inherit its settings.
The arrows in the diagram are the **inheritance relationship**: each instance reads its grid structure from the template. The instances themselves are independent — they hold different risk items, link to different requirements, and follow different lifecycles. The template is the contract; the instance is the work.
**Why this matters**
Without this separation, every new risk document would either be a hand-edited copy of an older one (configuration drift) or every methodology change would require updating dozens of identical files. The template-instance model gives you a single place to evolve the methodology and many places to apply it.
## What Lives in the Template vs. the Instance
The line between "template content" and "instance content" is sharp and worth internalising. A common misconception is that everything in the sheet configuration is shared — in reality, only the sheet configuration itself is. The risk data is always per-instance.
| Belongs to the template | Belongs to the instance |
| ---------------------------------------------------------------------------- | ----------------------------------------- |
| Column definitions (`columns`, including `bindings` and `type`) | The risk items (work items) themselves |
| Visual hierarchy (`levels`) | Values entered into cells |
| Calculated columns (`formulas`) | Links to upstream requirements |
| Conditional formatting (`cellDecorators` and `styles`) | Links to downstream mitigations and tasks |
| Work item types in use (`dataTypes`) | Review comments and approval state |
| Saved views (`views`) | The document title, location, and history |
| Default sort (`sortBy`), header layout (`headers`), review setup (`reviews`) | Attachments and revisions |
The template answers *what the grid looks like*. The instance answers *what we are analysing*.
**All data lives in Polarion**
Risksheet does not have its own data store. Every risk item is a standard Polarion work item, subject to Polarion authorization and traceable through Polarion's audit infrastructure. The configuration controls how that data is displayed and edited — it does not duplicate or cache the data elsewhere.
## Template Scoping: Project vs. Global
Templates can be defined at two scopes, and the choice has real consequences for how a programme is governed.
### Project-Scoped Templates
A project-scoped template is a LiveDoc inside the same Polarion project as the instance documents. The project's administrators control it, and only documents within that project can reference it. This is the default scope and the simplest to reason about: one project, one set of templates, one team.
Use project scoping when:
* The methodology is project-specific (for example, a customer-tailored FMEA for one programme).
* The team running the project also owns the methodology.
* Cross-project sharing is not required.
The project-level setting that defines where templates live is the **Risksheet Template Path** (default: `Risks/Risk Specification`). Administrators can configure multiple comma-separated paths to support several methodologies inside one project — for example, a path for FMEA templates and another for HARA templates.
### Global-Scoped Templates
A global-scoped template lives in a dedicated **library project** — a shared, organization-wide repository (often called `GlobalLibrary` or similar). Instance documents in *any* project can reference templates from that library, which makes the library project the single source of truth for company-wide methodology.
The reference uses the `PROJECTID:TEMPLATE_PATH` format, for example `GlobalLibrary:Risks/Risk Specification`. The colon separates the library project ID from the document path inside that project.
Use global scoping when:
* A single safety or quality team owns the methodology for many engineering projects.
* Compliance with ISO 26262, ISO 14971, or similar standards requires a controlled, central methodology.
* You want to audit every change to the FMEA methodology in one place rather than across N project repositories.
A project can mix both scopes. An engineering project might inherit its main methodology from a global library template, while keeping a small project-local template for an experimental analysis type. The two coexist without conflict — each instance picks exactly one template to follow.
## Template Linking: How an Instance Finds Its Template
The link between an instance and its template is explicit, not magical. Each instance document carries a Polarion custom field — typically `templateDoc` — that records which template document it follows. The field is of type `enum:@document` (an enum bound to Polarion's built-in document list), which means a user selects an existing template document rather than typing a free-form path. This eliminates broken references and lets Polarion's referential integrity guard against template documents being moved or deleted without notice.
When a user opens a risksheet instance:
1. Risksheet reads the instance document's `templateDoc` field.
2. It loads the sheet configuration from the referenced template.
3. The grid renders using the template's columns, levels, formulas, and styles.
4. The instance's own work items populate the rows.
If the instance has no `templateDoc` reference, Risksheet falls back to the project's configured template path. If neither is set, the instance must carry its own sheet configuration directly.
**Avoid Polarion's Reuse function for templates**
Polarion has a generic "Reuse" feature for duplicating documents and their content. It is tempting to use it to "clone" a template into each new instance, but doing so creates an independent copy of the configuration attachment on every instance. The link to the template is lost, and future template changes will not propagate. Instead, create instances normally and set the `templateDoc` reference — that is the supported inheritance mechanism.
### What Happens When the Template Changes
Because the instance reads the template's configuration on open, **changes to the template are picked up the next time each instance is opened**. There is no manual push, no rebuild step, and no per-instance migration. Add a new column to the template, fix a formula, adjust a rating threshold — every instance that links to that template will reflect the change on its next session.
This is powerful, but it is also why the template-instance separation needs disciplined ownership. Editing a template is a methodology change, not a per-document tweak. In regulated environments, template edits should pass through the same review gate as any other methodology artefact.
**Per-instance overrides are possible but discouraged**
An instance can carry its own sheet configuration that overrides the template's. This is occasionally useful — for example, to disable a column for one specific analysis — but every override is a piece of configuration that escapes central governance. Prefer extending the template (with views, for example) over per-instance overrides.
## Saved Views: Lightweight, Per-Document Adaptation
Often, what looks like a need for per-instance configuration is actually a need for a different *view* of the same configuration. The template's `views` section lets you define multiple saved column subsets that users can switch between — without changing the underlying template.
For example, a single DFMEA template can offer views like *Identify Failure Modes*, *Initial Risk Ranking*, *Mitigations*, and *Final Risk Assessment*. Each view shows the columns relevant to one stage of the analysis. The data is identical across views; only the visible columns change.
Views support an `@all` shorthand to include every column, and a `-columnId` prefix to exclude individual columns from that set:
```yaml theme={null}
views:
- name: Full Analysis
defaultView: true
columnIds:
- "@all"
- name: Initial Ranking
columnIds:
- failureMode
- severity
- occurrence
- detection
- rpn
- name: Without Upstream Links
columnIds:
- "@all"
- "-upstreamRequirements"
```
This pattern often eliminates the need for per-instance overrides entirely. Instead of forking the template, add a view to it. See [Configuration Management](/risksheet/guides/configuration/index) for practical configuration steps.
## Versioning: A Practical Reality, Not Yet a Polished Workflow
A natural question follows from everything above: *if instances pick up the template's current configuration whenever they open, what about audits, baselines, and historical fidelity?* Risksheet's answer here is honest and worth stating plainly: **versioning of the configuration template is supported through Polarion's general document revision and baseline mechanisms, but it is not yet a fully mature, purpose-built feature**.
What is true today:
* Each template document is a standard Polarion LiveDoc, so it has revisions, baselines, and audit history like any other Polarion document.
* When a risksheet instance is viewed at a specific revision (for example, through a Polarion baseline), the grid renders in read-only mode and reflects the state of that point in time.
* Changes to the template are visible in Polarion's history view, and Polarion's role-based permissions can restrict who is allowed to edit it.
What is still evolving:
* There is no built-in mechanism to pin an instance to a specific *template revision*. Instances always follow the template's current state.
* The configuration editor offers history-style features for the sheet configuration, but cross-instance impact analysis ("which instances would be affected by this template change?") is not yet provided out of the box.
* Migration tooling for breaking template changes (renamed columns, restructured levels) is a manual exercise — the template author needs to coordinate with instance owners.
**Verify in application**
Risksheet's configuration editor introduced YAML editing support with syntax highlighting and history-style features in v25.5.0. Specific versioning capabilities continue to evolve — confirm exact behaviour against your installed version.
### Practical Guidance Today
In practice, teams handle template versioning by combining product features with process discipline:
| Practice | Why it works |
| ------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
| Treat the template as a controlled methodology artefact, with its own review gate. | Stops accidental edits from rippling across every analysis overnight. |
| Use Polarion baselines on the template document at release milestones. | Creates a recoverable, audit-visible snapshot of the methodology in use. |
| Communicate template changes to instance owners before they are applied. | Avoids surprise when a column disappears or a formula's behaviour shifts. |
| Use saved views for stage-based or role-based adaptations rather than forking the template. | Keeps the template canonical; reduces the need for per-instance overrides. |
| For breaking changes, plan a coordinated rollout window across affected instances. | Acknowledges that instances cannot independently pin an older template. |
| Capture the template's revision in the instance's review records. | Documents which methodology revision was in force when an analysis was approved. |
This combination is enough for most regulated programmes today, but expect the product to keep adding more first-class versioning support over time.
## Common Misconceptions
**"Each risksheet document needs its own configuration file."** Only if you choose to override the template. The intended model is that many instances share one template, and most instances carry no configuration of their own — they inherit it through their `templateDoc` reference.
**"Copying a template document with Polarion's Reuse feature is how you create a new instance."** No. Reuse duplicates the configuration attachment, breaking the link to the original template. Create instances through the normal Risksheet document creation flow, then set the `templateDoc` reference.
**"Changing the template will retroactively change every historical analysis."** When a user views an instance at a historical revision (a baseline), Polarion renders the document as it was at that point in time, and Risksheet honours that read-only mode. The methodology shown in the historical view is whatever the template was at the time of the snapshot, as far as Polarion's revision tracking allows.
**"The template defines the data; the instance defines the look."** It is the opposite. The template defines the *look and behaviour*; the instance defines the *data*. Confusing this is the most common cause of unnecessary per-instance configuration overrides.
## Where to Go Next
* [Data Model and Work Items](/risksheet/concepts/data-model) — how risk items and task items are stored as Polarion work items.
* [Architecture](/risksheet/concepts/architecture) — how Risksheet runs inside Polarion and where each piece of configuration is loaded.
* [Configuration Management](/risksheet/guides/configuration/index) — practical guides for setting up template paths, linking documents, and managing views.
* [Administration](/risksheet/guides/administration/index) — administrator-facing tasks for project-level Risksheet settings.
* [Templates Reference](/risksheet/reference/templates/index) — reference detail for template documents and their configuration.
# Data Model and Work Items
Source: https://learn.nextedy.com/risksheet/concepts/data-model
Nextedy RISKSHEET does not maintain its own data store. Every row in the grid, every cell value, and every link between items maps directly to standard Polarion work items in Siemens Polarion ALM.
This page builds the mental model you need before touching configuration. It explains the two-entity data model, the distinction between the actual Polarion entities and the visual hierarchy you see in the grid, and the role of the risk item as the central aggregation point that ties context, classification, and mitigations together.
## All Data Lives in Polarion
The first and most important idea: there is no Risksheet database. When you save a cell, the value is written to a Polarion work item field. When you create a row, a new Polarion work item is created. When you link a risk to a mitigation, a Polarion link is created using a configured link role. When you open a baseline, you are reading Polarion's revision history.
This has practical consequences:
* **Authorization** is enforced by Polarion. If a user cannot edit a field in the Polarion tracker, they cannot edit it in Risksheet either.
* **Audit and history** come from Polarion. Every change to a work item is captured in Polarion's revision history; Risksheet does not maintain a parallel log.
* **Search and reporting** use Polarion's search index. Risk items found through Risksheet are the same items found through Polarion queries, LiveReports, or third-party tools.
* **Mandatory fields** are intentionally NOT enforced inside Risksheet. By design, you can leave required fields blank during analysis and have Polarion's workflow validation catch them when the document moves to a later status. To make required columns visible during entry, use a cell decorator to color them — see [Styling and Formatting](/risksheet/guides/styling/index).
**Mental Model**
Think of Risksheet as a spreadsheet view onto Polarion. The spreadsheet has no value of its own without the underlying work items, and editing the spreadsheet is identical to editing the work items directly.
## The Two-Entity Data Model
Risksheet's data model has exactly two entity types, regardless of methodology or industry. Every Risksheet you will ever see is built from these two types of Polarion work items:
1. **Risk items** — the main rows of the grid. Configured under `dataTypes.risk`. Typical work item types: failure modes (Failure Mode and Effects Analysis, FMEA), hazards (Hazard Analysis and Risk Assessment, HARA), threats (Threat Analysis and Risk Assessment, TARA, or STRIDE), risk records, or — in non-risk use cases — requirements.
2. **Task items** — downstream linked work items, one or more per risk item. Configured under `dataTypes.task`. Typical work item types: mitigations, safety requirements, controls, countermeasures, or test cases.
The names "risk" and "task" are naming conventions inside the configuration. They are NOT constraints on what kind of work items you can use. A Risksheet configured with `dataTypes.risk.type: requirement` and `dataTypes.task.type: testcase` becomes a requirements traceability matrix. The grid does not care — it simply renders one type of work item as the main row and another as the downstream relationship.
Every configuration property under `dataTypes.risk` and `dataTypes.task` defines a small contract with Polarion: which work item type to use, which link role connects them, which work item types are eligible as upstream references, and so on. See [Configuration Reference](/risksheet/reference/configuration/index) for the full list.
## The Risk Item as Central Aggregation Point
The risk item is the keystone of Risksheet's data model. It is the row that ties together everything you want to express about a single failure, hazard, threat, or other risk concept. Read each risk item from left to right and it tells a complete story:
1. **Context** — where this risk lives. Upstream link columns (`itemLink`, `multiItemLink`) point back to the function, system, component, or requirement that the risk applies to. Context columns answer "what is this risk a risk of?"
2. **Risk attributes** — the description of the failure itself. Editable Polarion fields on the risk work item: failure mode title, cause, effect of failure, hazard description.
3. **Classification** — how the risk is rated before mitigation. Severity, occurrence, and detection are scored using rating scales backed by Polarion enumerations. A formula then computes an initial classification — for example, an initial Risk Priority Number (RPN), an Automotive Safety Integrity Level (ASIL) grade, or a 2D risk matrix cell.
4. **Mitigations** — what is being done about it. Task items link from the risk row, each typically representing a mitigation, control, safety requirement, or countermeasure. The task item itself is a separate Polarion work item with its own owner, status, and traceability.
5. **Residual risk** — how the risk is rated AFTER mitigation. New severity, new occurrence, new detection — same columns conceptually, but stored in different fields and producing a "new RPN" or "final classification".
The risk item is, in effect, a mapping table: it joins upstream context to downstream mitigations and records the before/after classification of the risk along the way. This is why almost every Risksheet column ultimately attaches to the risk item or to one of its task children — the grid is a flattened, navigable view of that mapping.
| Region of the row | Typical columns | Backed by |
| ---------------------- | ---------------------------------------------------- | ---------------------------------------- |
| Context | Item, function, system reference | Upstream links (itemLink, multiItemLink) |
| Risk attributes | Failure mode, cause, effect | Polarion fields on the risk work item |
| Initial classification | severity, occurrence, detection, RPN | rating fields + a formula |
| Mitigations | Mitigation actions, controls, owners | Task items (downstream links) |
| Residual risk | new severity, new occurrence, new detection, new RPN | rating fields + a formula |
## Two Senses of "Level": Data Model vs Visual
The word "level" appears twice in the Risksheet vocabulary, with two very different meanings. Confusing them is the single most common source of misunderstanding when a new configuration does not behave as expected.
### Data model levels (always exactly two)
In the data model, there are only two levels: risk items and task items. Both are real Polarion work items. Both are governed by Polarion permissions, workflows, and history. You cannot add a third data model level — the engine does not support it.
### Visual levels (one, two, three, or more — configured by you)
The grid you see can present a hierarchy that looks much deeper than two levels. A typical Design FMEA shows Item → Failure mode → Cause → Effect, which feels like four levels. A Functional Hazard Assessment shows Function → Failure condition → Detail, which feels like three. None of these are extra entities in Polarion. They are produced by **cell merging**.
The mechanism is the `levels` array in the sheet configuration. Each entry defines one visual level, and each column declares which level it belongs to through its `level` property. When consecutive rows have the same value in a level's control column, the cells in that column are merged vertically, producing the visual appearance of a parent row spanning multiple child rows.
```yaml theme={null}
levels:
- name: Item
controlColumn: item
zoomColumn: item
- name: Failure mode
controlColumn: failureMode
zoomColumn: failureMode
- name: Cause
controlColumn: systemItemId
zoomColumn: causes
```
Every level entry must have three properties:
| Property | Type | Purpose |
| --------------- | ------ | ---------------------------------------------------------------------------------------------- |
| `name` | string | Display name in the navigation and zoom menu (for example, "Item", "Failure mode", "Detail") |
| `controlColumn` | string | Column ID whose value drives cell merging — rows with the same value get merged for this level |
| `zoomColumn` | string | Column ID used as the target when a user uses zoom or drill-down navigation |
### How columns connect to levels
The column `level` property is a one-based integer that points into the `levels` array:
* `level: 1` corresponds to the first entry in `levels` (the outermost grouping)
* `level: 2` corresponds to the second entry
* `level: 3` corresponds to the third entry
Columns that share the same `level` number get **identical** cell merging behavior — that is the practical meaning of "same level". They merge wherever the control column of that level has the same value across rows. Task columns (those bound to `task.*` fields) have no level assigned; they merge by parent risk item plus task ID, which is built-in.
**Why columns at the same level merge together**
Because they share a control column. A level says: "merge cells in any column at this level wherever this control column's value is identical in consecutive rows." If you put both "Item" and "Item description" at level 1 with `controlColumn: item`, they will both merge into the same blocks. This is intentional — it produces the appearance of a parent-row whose attributes span all child rows beneath it.
### Common misconceptions
**Common misconceptions about levels**
* **"Adding a level adds a new work item type."** No. Levels are display configuration. The data still has two entity types (risk and task) regardless of how many visual levels you define.
* **"Risksheet aggregates items from multiple documents."** No. A Risksheet is a visualization of a single LiveDoc. It cannot pull work items from other documents based on naming patterns or document hierarchy. If you need cross-document analysis, use a Polarion query, a LiveReport, or branching.
## Visibility and Levels
Defining visual levels is only half of how a row appears in the grid. The other half is visibility: which Polarion work items actually flow into the level at all. Risksheet applies a layered set of filters before any cell merging happens, and understanding that pipeline prevents the most common "why is this item missing?" or "why can't I edit this?" questions.
### What determines whether an item appears
When you open a Risksheet, it loads the risk- and task-type work items that already exist in its LiveDoc — an existing document opens pre-populated with its items, not as a blank grid. From that set, not every work item is necessarily rendered: visibility is the combined result of type filtering, status filtering, permission checks, and level membership.
**Type filtering.** The `dataTypes` configuration defines which work item types are allowed at each tier:
* `dataTypes.risk.type` — work item types displayed as risk items (the main grid rows). Multiple types can be specified as comma-separated values.
* `dataTypes.task.type` — work item types displayed as task/mitigation items (the downstream linked rows). Multiple types can also be specified as comma-separated values.
Work items whose type does not match either `risk.type` or `task.type` are excluded from the grid entirely. This is the most fundamental visibility filter.
**Rejected status filtering.** Work items with a status matching the configured `rejectedStatus` (default: `rejected`) are automatically hidden from the grid. The system applies separate rejected-status rules for risk items and task items. This enables a soft-delete pattern: instead of permanently deleting a risk item, change its workflow status to the rejected one and it disappears from the grid while remaining available for audit and traceability in Polarion.
**Soft delete via rejected status**
Rather than permanently deleting risk items, configure `rejectedStatus` and move unwanted items into that status. They remain in Polarion for history and traceability but no longer clutter the active risk analysis view.
**Permission-based filtering.** Risksheet respects Polarion's security model. Work items the current user lacks read permission for are silently excluded from results — the user simply does not see items they cannot access. This is especially important in regulated environments where role-based access to risk data is mandated.
**Unresolvable item filtering.** Work items that are corrupted, deleted at the repository level, or otherwise unresolvable are automatically excluded to prevent grid errors. This is a defensive mechanism that handles data quality issues silently.
### Upstream, downstream, and indirectly linked items
Levels are fundamentally about relationships between work items, and the terminology used in Risksheet maps directly to the direction of traceability links:
* **Upstream items** are work items the current row links TO (for example, a failure mode links to a system requirement). They appear in upstream traceability columns, typically configured as `itemLink` or `multiItemLink` column types.
* **Downstream items** are work items that link FROM the current row (for example, mitigation tasks linked to a failure mode via the task role). They appear in task-level columns at the bottom of the hierarchy.
A common source of confusion is the difference between items that are directly linked to a risk item and items that are linked through an intermediary. If a failure mode (Level 2) links to a requirement (Level 1), and that requirement links to a system function, the system function is an indirect link — it is not directly connected to the failure mode.
Standard Risksheet columns can only display directly linked work items. To show items connected through upstream relationships, there are two options:
1. **Server render columns** — Use Velocity scripts to traverse indirect links and render the results as read-only HTML. See [Server Render Columns](/risksheet/reference/columns/server-render-columns) for the Velocity patterns.
2. **`upstreamChains`** — A configuration property (format: `fromType-linkRole-toType`) that automatically builds transitive link chains. This creates actual Polarion links, making the indirect relationships editable. Note that `upstreamChains` only creates links; it never deletes them.
**Multi-level display is not transitive**
Users frequently expect that configuring a Level 2 column will automatically show items linked through Level 1 items. This is not how levels work. Each level displays items that are *directly* linked to the current row's work item. Indirect links require explicit configuration via server render or `upstreamChains`.
### Cross-project item visibility
Risksheet supports displaying work items from other Polarion projects. This is configured via the `project` parameter in the `typeProperties` section of a column or data type definition. When a project ID is specified, Risksheet loads items from that project instead of (or in addition to) the current one.
Cross-project visibility has well-defined limits:
* It works for **directly linked items only**. Indirect links through intermediary work items in other projects require additional configuration, typically server render columns with cross-project Velocity queries.
* The user must have read permissions in the target project. Items the user cannot access are filtered out.
* Workflow status dropdowns correctly load actions for the source project using the `project!workItemId` format, enabling status editing for cross-project items.
### The read-only boundary
Not every visible item is editable. Several factors can make work items or individual columns read-only:
| Condition | Effect |
| ------------------------------------------------------------------ | --------------------------------------------------------------------- |
| `readonly: true` in root configuration | Entire grid is read-only |
| `downstreamReadonly: true` | Downstream linked items (tasks) from other documents cannot be edited |
| `reviewer: true` | Reviewer mode restricts editing and shows review-specific controls |
| Historical revision viewing | Viewing a non-current revision forces read-only mode automatically |
| Column has `serverRender` | Column is always read-only |
| Column has `formula` | Column is read-only by default |
| System fields (`id`, `status`, `type`, `project`, `outlineNumber`) | Always read-only regardless of configuration |
| Permission restrictions | Columns where the user lacks write permission are read-only |
**`readonly` vs `readOnly` — casing is intentional**
The casing differs by level and both are correct. The **root-level** grid flag is lowercase `readonly` (`readonly: true` makes the whole grid read-only). The **column-level** property is camelCase `readOnly` (set on an individual column definition). They are deliberately different keys at their respective levels — neither should be "corrected" to match the other.
**New items and workflow**
Newly created work items (identified by IDs starting with `*`) have limited functionality until saved. Status dropdowns are disabled for new items because workflow actions only apply to items that exist in Polarion. Save the item first; workflow transitions become available afterwards.
### Cell merging revisited
When multiple Level 2 items share the same Level 1 parent, the Level 1 columns merge vertically to span all child rows. This produces the characteristic FMEA layout where a single failure mode description spans multiple cause/effect pairs. The `controlColumn` property on each level determines which column drives the merge grouping: rows with the same value in the control column at a given level are merged.
The visual result is a grid where:
* Level 1 columns span multiple rows, showing the parent item data once.
* Level 2 columns show one row per child item.
* Task-level columns show one row per downstream linked item within each Level 2 group.
### Context menu and item creation
The context menu (right-click on a grid cell) provides options for creating new items at different levels. The menu dynamically generates options from the `levels` array where `showInMenu` is `true`. Only levels configured for menu visibility appear as creation options.
The context menu also provides:
* **Open Row Item** — navigates to the current row's work item in Polarion's item editor.
* **Open \[Column] Item** — opens the linked work item for that column; the menu label embeds the column name (for example **Open Item/Func Item**).
* **Open Task Item** — opens a task work item; the menu label uses the task type name from `dataTypes.task.name` if configured.
* **Remove Row Item** — removes the selected row (only in editable grids).
* **New Level Items** — creates new work items at the selected level (only in editable grids).
### A practical mental model for levels
Think of levels as a telescope with adjustable zoom:
* **Level 1** is the widest view — top-tier items (system functions, hazards, or failure modes depending on your structure).
* **Level 2** zooms in to the children of each Level 1 item — causes, effects, or sub-failure modes.
* **Task level** zooms to the finest detail — mitigation tasks, verification activities, or design changes linked to specific Level 2 items.
Each column in the grid is assigned to exactly one zoom level. When you look at a row, the Level 1 columns show data from the Level 1 parent, the Level 2 columns show data from the Level 2 item, and the task columns show data from the downstream linked task. All three coexist in the same visual row, but they represent data from different work items connected by links.
The `levels` configuration in `risksheet.json` tells Risksheet how many zoom levels exist and which column drives the grouping at each level. The `dataTypes` configuration tells Risksheet which work item types belong to which tier and which link roles connect them.
## Where Data Lives: Fields, Links, and Configuration
When the grid renders, three different sources of data flow into the cells you see:
| Cell source | What it is | Where it lives |
| ------------------ | ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------- |
| Field value | A column whose `bindings` matches a Polarion field reads that field's value | Polarion work item field |
| Linked field value | A column with `bindings: linkedItem.fieldId` reads from an upstream or downstream linked item | Different Polarion work item, reached via link role |
| Formula result | A column with a `formula` runs JavaScript to compute the value from other cells in the same row | Computed at display time, optionally stored back to a field |
Columns declare these mappings using the `bindings` property (note: plural — `bindings`, not `binding`). Examples:
```yaml theme={null}
columns:
- id: title
header: Failure mode
bindings: title
type: string
level: 2
- id: sev
header: Severity
bindings: severityRating
type: rating:severityEnum
level: 2
- id: hazard
header: Hazard
bindings: hazard.title
type: string
level: 1
- id: rpn
header: RPN
formula: commonRpn
type: int
readOnly: true
level: 2
```
Three binding patterns are possible:
* `bindings: title` — a direct field on the risk work item.
* `bindings: hazard.title` — a field on a linked item. Read-only by default because the value belongs to a different work item.
* `bindings: task.$item` — the entire task work item, used by server-rendered columns that need full Velocity access.
For an enum or rating column, you also declare the enum identifier in the column `type`:
```yaml theme={null}
- id: severity
header: Severity
bindings: severityRating
type: rating:severityEnum
- id: detectionMethod
header: Detection methods
bindings: detectionMethods
type: multiEnum:detectionMethodsEnum
```
The enum identifier (`severityEnum`, `detectionMethodsEnum`) points to a Polarion enumeration defined in **Administration → Enumerations**, not to something inside the sheet configuration. Risksheet asks the server to load the enumeration values at runtime; this is why custom rating scales are configured in Polarion administration first, then referenced from the column.
**Verify in application**
The exact set of column types that can appear in your project depends on the field types defined for the configured work item types. Risksheet auto-detects the column type from the Polarion field type when `type` is omitted, but explicit declaration is recommended for clarity and to override defaults.
## Linking: Upstream Context and Downstream Mitigations
The two main link directions create the "left side" and "right side" of the risk item story.
**Upstream links** (left side) attach a risk to its context. They are configured on individual columns through `typeProperties`:
```yaml theme={null}
- id: hazard
header: Hazard
bindings: hazard
type: itemLink
typeProperties:
linkRole: relates_to
linkTypes: hazard
document: 02 - Risk Management File/Harms Library
level: 1
```
The configuration above tells Risksheet that the "Hazard" column links to existing work items of type `hazard` from a shared library document. New entries created inline (if `canCreate` allows) go to that document.
**Downstream links** (right side) attach a risk to its mitigations. They are configured under `dataTypes.task`:
```yaml theme={null}
dataTypes:
task:
type: mitigation
role: mitigates
name: Mitigation
zoomColumn: mitigationTitle
```
A single risk row can have many task rows beneath it; the grid renders each task as a "child" row visually grouped with its parent risk. The link itself is a normal Polarion link with the configured role.
For deeper explanations of these mechanics, see [Traceability and Linking](/risksheet/concepts/traceability). For the configuration reference, see [Configuration Reference](/risksheet/reference/configuration/index).
## What About Required Fields, Branching, and Cross-Document References?
A few behaviors that surprise new users — all consequences of "data lives in Polarion":
* **Required Polarion fields are not enforced during entry.** This is by design. Risksheet keeps the entry surface fast and forgiving; required-field validation belongs to a later workflow status, or to a visual highlight applied through a cell decorator.
* **Read-only branches.** When a document is branched, the branched copy shows the original risk items as read-only references by default. If `editableReferencedWorkItems` is enabled at the project level, those referenced items become editable in the branch. There is currently no way to reference individual risks across non-branched documents — branching is the supported mechanism for shared risk content.
* **One document per Risksheet.** Risksheet is the visualization of a single LiveDoc. It does not aggregate items across multiple documents based on filename suffixes, document hierarchy, or query results. If a workflow needs cross-document analysis, the answer is either to combine the source documents, use Polarion queries, or open multiple Risksheets side-by-side.
## How This Shapes Your Configuration Decisions
If you keep the two-entity / two-sense-of-level model in mind, several configuration decisions become clearer:
1. **Choose the risk work item type carefully.** Whatever you put under `dataTypes.risk.type` becomes the row, the search target, the access control unit, and the audit subject. Switching types later is expensive.
2. **Pick task work item types intentionally.** Each task type carries its own custom fields, workflow, and link roles. Multiple downstream types are supported (comma-separated in `dataTypes.task.type` since recent versions), but each adds complexity.
3. **Use levels for visual structure, not data structure.** If you find yourself wishing for a "third data model level", you are probably looking for either a deeper visual hierarchy (add to `levels`) or an upstream library (add an `itemLink` column with `typeProperties.document`).
4. **Use views, not extra documents, for different perspectives.** Saved views let the same underlying data appear with different column subsets for identify-failures vs initial-ranking vs final-assessment stages.
For practical guidance on putting this model to work, see [Column Configuration](/risksheet/guides/columns/index), [Risk Management](/risksheet/guides/risk-management/index), and [Configuration Hierarchy](/risksheet/concepts/configuration-hierarchy).
# Data Synchronization
Source: https://learn.nextedy.com/risksheet/concepts/data-synchronization
Nextedy RISKSHEET is a live editing surface over Polarion data. The grid you see in your browser is not a separate database — it is a structured view of Polarion work items, fields, and links.
This page explains the two mental models you need to work confidently with Risksheet over time: how calculated values are kept in sync between client-side formulas and server-stored fields, and how Risksheet's comparison mode lets you diff a risk assessment against an earlier revision.
**All data lives in Polarion**
Risksheet does not maintain its own data store. Risk items, task items, links, and field values all live in Polarion work items, subject to Polarion authorization and Polarion's full audit history. Risksheet visualizes and edits that data — it does not duplicate it.
## Calculated Values Are Polarion Data
The grid is dense with calculated values: a Risk Priority Number (RPN) built from severity, occurrence, and detection; an Automotive Safety Integrity Level (ASIL) derived from severity, exposure, and controllability; a recommended action category derived from a risk matrix. In a spreadsheet, these would be ephemeral cell formulas. In Risksheet, they have a second life: they are persisted as real values on real Polarion work items.
That dual nature — calculated in the browser, stored on the server — is what makes Risksheet auditable. A regulator or quality auditor browsing the Polarion work item one year from now will see the same RPN that the engineer saw on the day the risk was assessed, even if formula coefficients or rating scales have since been adjusted.
### The "live" vs "stored" pair
A useful mental model is to think of every calculated cell as having two values living together:
* A **live value** — what the formula evaluates to right now, given the current inputs in the row and the formula function in the current sheet configuration.
* A **stored value** — what was persisted to the Polarion work item field the last time the row was saved.
When you open a document for editing, both values normally agree. The live value is recomputed from current inputs and the stored value is read from Polarion. If you change a severity rating, the live RPN recomputes immediately while the stored RPN still reflects the pre-edit number. The save then writes the new live value into the stored field.
### Why the stored value matters
If Risksheet only computed RPNs at view time, three things would break in regulated contexts:
1. **Audit immutability.** Reviewers need to see exactly what the original assessor saw. If the formula changes later, recomputing on-the-fly would silently rewrite history.
2. **External tools.** Other Polarion artifacts — LiveReports, Velocity templates, dashboards, exports, and the reporting layer — read directly from Polarion fields. They cannot run Risksheet's JavaScript formulas. They need a number in the field.
3. **Filtering and querying.** Polarion's Lucene queries operate on stored field values. To filter "all hazards with RPN > 250" you need 250 to be persisted, not recalculated per request.
Formulas in the sheet configuration are therefore best understood as **rules for keeping stored values up to date**, not as a replacement for stored values.
## When Live and Stored Values Diverge
Most of the time live and stored values match. Several scenarios cause them to drift apart:
* **Edits outside Risksheet.** A user opens the underlying work item in Polarion's normal LiveDoc editor or work item form and changes severity. The Risksheet formula has not been re-run on that row.
* **Formula changes.** A configuration administrator updates the RPN formula — for example to change a weighting coefficient or add a new factor. Existing stored values reflect the old formula; new edits will use the new one.
* **Rating scale changes.** Severity used to range 1–5; the project decides to switch to 1–10. Old stored numbers are now on a different scale than the live formula expects.
* **Bulk imports.** Rows are created or updated through a script, an import, or the server API. The formulas have not executed for those rows.
* **`readOnly: false` on a formula column.** Formula columns can be configured as editable. When they are, a user can type a value directly into the calculated cell, intentionally overriding the formula.
**`readOnly: false` on formula columns**
A column with a `formula` reference and `readOnly: false` lets users override the calculated value with a typed one. This is occasionally useful — for example, in early FMEA workshops where a moderator wants to record a value before the formula inputs exist — but it is the most common source of drift between live and stored values. Treat it as the exception, not the default.
### Reconciling drift — Check stored formulas
For exactly these situations, Risksheet provides a reconciliation action: **Menu > Rows > Check stored formulas**. This walks the rows currently visible in the grid, re-evaluates every formula column, and writes the live result back into the stored Polarion field where it differs.
This is the only routine bulk-recalculation flow you need to know about. It is safe to run after a formula change, after a bulk import, or any time you suspect a column may have stale values. Because it operates row-by-row through normal save transactions, it produces normal Polarion revisions on the affected work items — the change is fully auditable.
**When to run Check stored formulas**
Run it after any change to formulas, rating scales, or scoring rubrics. Run it after bulk imports. Run it whenever a colleague reports "the RPN in the report doesn't match the RPN in the grid." It is idempotent — running it when everything is already in sync does nothing.
For the step-by-step procedure, see Run formula recalculation and the broader Manage formula columns guide.
### Save behavior and scroll position
When you save a Risksheet, the grid by default refreshes to show the persisted state. On large sheets this can scroll the view back to the top, which is disorienting if you have just added a row near the bottom. The `global.refreshOnSave` property controls this:
* `refreshOnSave: true` (default) — the grid reloads the saved state. Safer for collaborative editing but causes scroll-to-top.
* `refreshOnSave: false` — keeps focus on the last edited cell after save. Recommended for large risk analyses where you make many edits per save cycle.
This is a configuration choice, not a runtime mode — see Optimize large grid performance for the trade-offs.
## Comparison Mode — Diffing Assessment Versions
A risk analysis evolves. Severity ratings are re-estimated as new evidence arrives, mitigations are added, classifications change. Auditors and reviewers regularly need to answer the question: *what changed since the last review?*
Risksheet's comparison mode answers this by diffing the current sheet against a specific past revision of the underlying LiveDoc document.
### How comparison works
Risksheet versioning rides on top of the underlying LiveDoc document. Every save of the risksheet produces a Polarion document revision in the normal way. Comparison mode loads two snapshots — the current state and a chosen historical revision — and overlays them in a single view, highlighting cells that differ.
A subtle but important detail: comparison waits for data to fully load on **both** sides before computing the diff. This is what guarantees you are not seeing a partial picture — a half-loaded snapshot would produce spurious "changes". The comparison command checks the loading state, waits if necessary, and only then runs the diff logic. From a user's perspective this just means the diff appears when everything is ready; you do not need to manually wait for loading.
### What you see in comparison mode
When comparison is active, the grid switches into a read-only diff view with the following definite behaviors:
* **Mandatory sorting.** The grid is sorted by Item ID and then by Revision. This is not optional and not user-configurable while comparison is active. The diff alignment depends on this sort order — disabling it would make pair-matching ambiguous.
* **Disabled custom renderers.** Columns that normally use a custom `cellRenderer` (server-rendered Velocity, custom HTML decorators, attachment renderers) fall back to plain value display in comparison mode. The diff highlighter operates on field values, not on rendered output.
* **Disabled task column sorting.** Task columns cannot be re-sorted while comparison is active. They follow the parent risk item's order so that linked tasks stay grouped with their parent.
* **Cells flagged as changed.** Cells whose value differs between the two revisions are visually distinguished. New rows (present in current but not in the historical revision) and removed rows (present in the historical revision but not in current) are marked as well.
**Comparison mode is read-only**
You cannot edit cells while comparison is active. Exit comparison to return to normal editing. This protects the diff — editing while diffing would create a moving target and confuse the alignment.
### Baselining
Comparison works against any revision in the document's history, but in practice teams use it most against **baselines**: named milestones in the LiveDoc revision graph corresponding to formal review gates, releases, or audit dates. Because risksheet versioning is the underlying LiveDoc's versioning, the same baselines you create for the document (Polarion Baselines view) are available as comparison targets in Risksheet.
This is the architectural reason "Risksheet versioning" feels so seamless: there is no separate Risksheet revision counter. Saving the document saves the risksheet. Baselining the document baselines the risksheet. Comparing against a baseline compares the risksheet inside that baseline.
For practical workflows see Compare risksheet revisions and Manage risksheet baselines.
## Common Misconceptions
**"I changed the formula, so the existing RPNs are now wrong."**
The existing stored RPNs are unchanged. The live recalculation only happens on rows you re-touch. Run **Menu > Rows > Check stored formulas** to bring stored values in line with the new formula.
**"Risksheet has its own database that gets out of sync with Polarion."**
There is no separate database. The "drift" you sometimes see is between *client-side recalculation* and *server-stored fields* — both inside Polarion, just at different layers. See [Risksheet architecture](/risksheet/concepts/architecture) for the layering picture.
**"Comparison mode is comparing my unsaved edits against the server."**
No. Comparison loads two committed revisions of the LiveDoc — typically the current saved state and a chosen historical revision. Unsaved local edits are not what the diff is showing.
**"I can't find a row in my comparison view that I know I edited."**
Comparison forces sort by Item ID and Revision. Your edit is there, just in its sorted position — not where it sat in your usual saved view.
**"The image I exported looks different from the grid."**
Some renderings — custom cell renderers, server-rendered Velocity, embedded images — are not preserved identically in Excel and PDF exports. This is unrelated to data sync; the underlying field values are correct.
## Where to Go Next
* For the layered architecture (browser app, server communication, Polarion API) see [Risksheet architecture](/risksheet/concepts/architecture).
* For the work item model that all this data lives on, see [Data model and work items](/risksheet/concepts/data-model).
* For how cross-project links work, including unlinking and traceability across project boundaries, see [Traceability and linking](/risksheet/concepts/traceability).
* For practical recalculation procedures, see the [Risk management guides](/risksheet/guides/risk-management/index).
* For configuration of formulas and styles, see the [Formulas reference](/risksheet/reference/formulas/index) and [Cell decorators](/risksheet/reference/styling/index).
# Documentation Framework
Source: https://learn.nextedy.com/risksheet/concepts/diataxis-framework
Nextedy RISKSHEET documentation is organized around the **Diátaxis framework** — a systematic approach to technical writing that recognises a simple truth: people read documentation for different reasons.
Understanding this framework helps you reach the right answer faster. It also explains why a page about exporting to PDF will not teach you what an FMEA is, and why the page that explains Risk Priority Number (RPN) does not walk you through configuring a severity column step-by-step. Those are deliberately separated concerns.
## The Four Modes of Documentation
Diátaxis identifies four distinct documentation needs, each best served by a different style of writing. Think of them as four corners of a square, defined by two axes: whether the reader is **studying** or **working**, and whether the content focuses on the **product** or on the reader's **goal**.
Each quadrant answers a different question:
| Quadrant | Question it answers | Risksheet section |
| ---------------- | -------------------------------------------------------- | -------------------------------------------------------------------------------------- |
| **Tutorial** | "I am new — show me a safe path." | [Getting Started](/risksheet/getting-started/index) |
| **How-To Guide** | "I have a real task — how do I do it?" | [Guides](/risksheet/guides/index), [Troubleshooting](/risksheet/troubleshooting/index) |
| **Concept** | "Why does it work this way?" | Concepts (you are here) |
| **Reference** | "What does this property do? What are the valid values?" | [Reference](/risksheet/reference/index), [FAQ](/risksheet/faq/index) |
The framework is older than Risksheet itself — it was distilled by Daniele Procida from years of observing real readers. The Risksheet documentation site adopts it because risk analysis spans both regulated-industry theory and very practical, fiddly day-to-day configuration. A page that mixes the two leaves both audiences frustrated.
## Why Mixing Modes Hurts Documentation
The most common documentation failure is the page that tries to do everything at once: a few paragraphs of background theory, then a step-by-step procedure, then a half-finished reference table, and finally an unrelated troubleshooting tip. Readers experience this as noise.
Consider three different people opening the documentation on a Wednesday afternoon:
* A **safety engineer new to Polarion** wants to produce her first HARA. She needs a tutorial that holds her hand and lets her succeed. She does not yet need to know about cell decorators.
* A **quality manager** has been running FMEAs for years. He needs to look up the exact name of the property that controls cell merging on the failure-mode column. He needs a reference page, fast.
* A **risk methodology lead** is evaluating whether Risksheet can support a new ISO/SAE 21434 TARA process. She needs to understand how the configuration model is built, so she can map her methodology onto it. She needs a concept page.
A single combined page would frustrate all three. By separating modes, each reader can land where they need to be and ignore the rest.
**Quick test**
If a page makes you feel like you are reading the wrong thing, you probably are — the right page exists in a different quadrant. Use the sidebar groups (Getting Started / Concepts / Guides / Reference) to jump.
## How the Risksheet Site Is Organised
The site mirrors the four quadrants in its top-level navigation. The names are deliberately consistent and never substituted — "Concepts" is never called "Overview" or "Core Concepts", and "Guides" is never called "Tutorials" or "How-To".
### Getting Started — Tutorials
The tutorial section is short, narrow, and prescriptive. Its job is not to explain everything but to **build confidence** by producing a working result quickly. A tutorial may use a feature without explaining its full configuration surface — that is a feature, not a bug.
For example, the recommended path is **always to start from a Nextedy solution template** rather than from a blank configuration. Templates are pre-built sheet configurations for typical risk methodologies (FMEA, HARA, TARA). Starting from a template means the new user lands on a working risksheet within minutes, then adapts it. Starting from scratch means hours of YAML editing before anything works.
See [Getting Started](/risksheet/getting-started/index) for the safe, guided introduction.
### Concepts — Understanding
The Concepts section answers **why** Risksheet is shaped the way it is. It builds the mental model you will reuse every time you configure, troubleshoot, or extend the tool.
Examples of concept-level questions:
* Why does Risksheet have three separate configuration files instead of one?
* What does it really mean to say Risksheet has "two data entities and N visual levels"?
* How does a saved view differ from a column's visibility setting?
These pages contain very few step-by-step instructions. When they do reference a procedure, they link out to the relevant how-to guide — for example, the [Configuration Hierarchy](/risksheet/concepts/configuration-hierarchy) page explains the inheritance model and links to the [Configuration Management guides](/risksheet/guides/configuration/index) for the procedural side.
### How-To Guides — Recipes
A how-to guide assumes you already understand the basic vocabulary and now have a real problem to solve. The guide tells you the shortest reliable path from problem to result.
Risksheet how-to guides are grouped by feature area:
* [Column Configuration](/risksheet/guides/columns/index) — adding, editing, hiding, and styling columns
* [Risk Management](/risksheet/guides/risk-management/index) — calculating RPNs, applying classification matrices, building mitigation chains
* [Review Management](/risksheet/guides/reviews/index) — comment-based, work-item-based, and approval reviews
* [Export](/risksheet/guides/export/index) — PDF export, Excel export, customising export templates
* [Integration](/risksheet/guides/integration/index) — linking Risksheet to upstream requirements and downstream tasks
* [Administration](/risksheet/guides/administration/index) — installation, template setup, configuration properties
* [Advanced Configuration](/risksheet/guides/advanced/index) — query factories, custom Velocity panels, multi-project setups
[Troubleshooting](/risksheet/troubleshooting/index) lives under Guides too, because "fix this broken thing" is a goal-oriented task — not a concept and not a property lookup.
### Reference — Lookup
Reference pages are dry, complete, and structured like a dictionary. They list every property of a column type, every valid value of an enumeration, every Velocity variable available in a template. A good reference page is **boring** — and it should be, because nobody reads it cover-to-cover.
The reference section is split by configuration domain:
* [Configuration](/risksheet/reference/configuration/index) — top-level sections of the sheet configuration
* [Column Types](/risksheet/reference/columns/index) — every column type and its properties
* [Fields](/risksheet/reference/fields/index) — Polarion field bindings
* [Formulas](/risksheet/reference/formulas/index) — formula functions, parameters, and the `info` object
* [Styling](/risksheet/reference/styling/index) — cell decorators, CSS styles, and conditional formatting
* [API](/risksheet/reference/api/index) — server-side and client-side APIs
* [Templates](/risksheet/reference/templates/index) — top panel and PDF export Velocity templates
* [Configuration Examples](/risksheet/reference/examples/index) — complete working snippets for common scenarios
* [Compatibility](/risksheet/reference/compatibility/index) — version requirements
The [FAQ](/risksheet/faq/index) is, structurally, also reference content — short, focused answers to single questions.
## A Worked Example: One Topic, Four Pages
To see how the framework plays out in practice, consider the topic **"calculating RPN with severity, occurrence, and detection ratings"**. The same topic appears in all four quadrants — but each page does a different job:
| Reader need | Reader's question | Where to look |
| -------------------- | ------------------------------------------------------------------------------------------------ | -------------------------------------- |
| Build a first FMEA | "I have never used Risksheet — get me to a working risk score." | Getting Started tutorial |
| Adjust thresholds | "Our process uses 100/200 as RPN thresholds, not the template's 150/250 — how do I change them?" | How-to guide on conditional formatting |
| Understand the model | "Why is the formula in one file and the visualization rule in another?" | Concepts (this section) |
| Find a property | "What is the exact name of the property that styles a cell red?" | Reference for cell decorators |
## Common Misconceptions
The Diátaxis split is not about how long a page is, or how technical it is, or how much code it contains. It is about the **reader's task**. Three misconceptions trip people up:
**Misconception 1: "Concepts pages must be theoretical."**
Concept pages explain *why* and *how the system is shaped* — not necessarily abstract theory. A concept page can include code-level examples (such as the YAML snippet of a `levels` array), as long as the goal is to illuminate the underlying model rather than to walk the reader through a task.
**Misconception 2: "If a page contains numbered steps, it is a tutorial."**
Tutorials and how-to guides both contain steps. The difference is *purpose*:
* A **tutorial** says: "Follow these exact steps and you will succeed. We chose this path because it is safe and predictable, not because it is the most efficient."
* A **how-to** says: "You have a real problem. Here is the minimum-friction path to solve it. We assume you already know the basics."
**Misconception 3: "Reference pages need an introduction."**
Reference pages should not warm up. A reader looking up `cellDecorators` does not want to read three paragraphs about risk theory first — they want the property table. Reference pages start with a short description and dive straight into the structured content.
**Concept pages link out, reference pages stand alone**
A useful rule of thumb when you write or edit Risksheet documentation: concept pages should link generously to how-to guides and reference pages. Reference pages should be self-contained — they are the destination, not the starting point.
## What This Means for You as a Reader
When you arrive at the Risksheet documentation site, the sidebar gives you four entry points. Picking the right one saves time:
1. **First contact with the product?** Open [Getting Started](/risksheet/getting-started/index). Do not browse — the tutorial assumes you go in order.
2. **Trying to do something specific?** Go to [Guides](/risksheet/guides/index) and find the matching feature area.
3. **Something is broken or unexpected?** Open [Troubleshooting](/risksheet/troubleshooting/index) — it is the how-to mode for the error case.
4. **Looking up a precise detail?** Jump to [Reference](/risksheet/reference/index) and use the in-page search.
5. **Have a one-line question?** Try the [FAQ](/risksheet/faq/index) first.
## What This Means for the Product
The Diátaxis split is not just an editorial choice — it reflects something true about Risksheet itself. The product is built on a separation of concerns:
* A **declarative sheet configuration** (the YAML/JSON file with `columns`, `levels`, `dataTypes`, `formulas`, `styles`, `cellDecorators`) describes what the grid looks like.
* A **scripting layer** (the top panel Velocity template) describes how complex risk-matrix logic is calculated.
* A **presentation layer** (the PDF export Velocity template) describes how the result is printed.
This three-file architecture exists because regulated industries (medical devices under ISO 14971, automotive under ISO 26262, industrial under IEC 61508, cybersecurity under ISO/SAE 21434) need to validate each layer separately. The documentation mirrors that structure — concepts explain the separation, guides show how to work within each layer, and the reference catalogues every property in each layer.
In other words: the Risksheet documentation is shaped like Risksheet. Once you internalise the four-quadrant model, both the product and the documentation become easier to navigate.
**Where to go next**
If this is your first concept page, read [What is Risksheet?](/risksheet/concepts/what-is-risksheet) next, followed by [Architecture](/risksheet/concepts/architecture) and [Configuration Hierarchy](/risksheet/concepts/configuration-hierarchy). Together they give you the full mental model in under thirty minutes of reading.
# Concepts
Source: https://learn.nextedy.com/risksheet/concepts/index
Nextedy RISKSHEET builds on Polarion ALM to deliver structured risk analysis with full traceability.
## Core Concepts
[**What is Risksheet?**](/risksheet/concepts/what-is-risksheet) -- Overview of Risksheet as a risk analysis tool within Polarion ALM, its relationship to Powersheet, and the one-document-per-risksheet design model.
[**Architecture**](/risksheet/concepts/architecture) -- How the server plugin, client-side grid, and Polarion data layer work together to render interactive risk tables.
[**Data Model and Work Items**](/risksheet/concepts/data-model) -- How risk items, tasks, and upstream requirements map to Polarion work items with configurable types, fields, and link relationships. All data lives in Polarion work items; Risksheet does not maintain a separate data store. Includes how visual levels (defined by the `levels` array) create hierarchy through cell merging on top of the underlying work item types.
## Configuration
[**Configuration Hierarchy**](/risksheet/concepts/configuration-hierarchy) -- How global templates, project templates, and document-level sheet configurations inherit and override each other, and how the sheet configuration structure (columns, levels, dataTypes, formulas, styles, views) shapes the grid.
[**Admin AI Assistant**](/risksheet/concepts/admin-ai-assistant) -- The documentation-grounded chat in the Risksheet configuration editor: how it stays grounded in the Risksheet documentation, what it needs to be available, and the browser-based authentication flow behind it.
## Access and Visibility
[**User Roles and Permissions**](/risksheet/concepts/user-roles) -- Administrator, editor, and reviewer roles, and how permissions control what users can see and modify.
## Traceability and Workflow
[**Traceability and Linking**](/risksheet/concepts/traceability) -- Upstream links to requirements and downstream links to mitigation tasks, including role-based filtering and cross-project linking.
[**Review Workflows**](/risksheet/concepts/review-workflows) -- Comment-based, work-item-based, and approval-based review processes. Note that approval review creates approval-tagged comments but does not drive Polarion's formal approval state transitions.
[**AI Assistant**](/risksheet/concepts/ai-assistant) -- How the AI Assistant proposes existing Polarion work items for a risk row and links the ones you accept, what context an action sends, and how each suggestion is verified against the project before it reaches you. Arrives with the separately installed Nextedy AI package.
## System Behavior
[**Working Sessions**](/risksheet/concepts/working-sessions) -- How Risksheet maintains browser sessions, handles save and refresh against Polarion data, and manages unsaved changes and concurrent editing.
[**Data Synchronization**](/risksheet/concepts/data-synchronization) -- How calculated values stay in sync between client-side formulas and Polarion-stored fields, and how comparison mode diffs a risk assessment against an earlier revision.
**Where to Start**
If you are new to Risksheet, begin with [What is Risksheet?](/risksheet/concepts/what-is-risksheet) for the product overview, then read [Architecture](/risksheet/concepts/architecture) and [Data Model and Work Items](/risksheet/concepts/data-model) to build a mental model of how the system works.
# Live Data Views
Source: https://learn.nextedy.com/risksheet/concepts/live-data-views
Nextedy RISKSHEET supports staged risk assessment by exposing different subsets of columns through saved **views**.
A view in Risksheet is a saved column visibility preset. It does not store its own copy of data and it does not change the underlying work items. All rows in the grid remain bound to the same Polarion work items at all times — the view only changes which columns are visible. Switching from one view to another is therefore a zero-cost UI operation that filters the grid down to the columns a given role needs to see during a given stage of the analysis.
This page explains how the five typical stages of a risk assessment map onto views, how views are declared in the sheet configuration, and which configuration properties drive the behavior.
## Stages of a Staged Risk Assessment
A typical FMEA, HARA, or TARA proceeds through five stages. Each stage has a distinct intent and a distinct set of columns. The diagram below shows the progression.
### Stage 1 — Context and Risk Identification
The analyst captures the system context and lists the failure modes, hazards, or threats. Visible columns are the upstream context (function, item, system reference) and the initial description fields (failure mode, hazard, threat scenario). Classification and mitigation columns are hidden so the analyst is not tempted to fill them in before the identification work is complete.
### Stage 2 — Risk Classification
The risk team rates each identified risk. Visible columns are the classification parameters such as severity, occurrence, detection, ASIL, or CVSS metric vectors. Mitigation and residual columns remain hidden. This view is typically used in a workshop where multiple stakeholders agree on the initial ratings.
### Stage 3 — Mitigation Planning
Mitigation owners propose actions. The view exposes the task (downstream) columns — the linked mitigation item, owner, target date, and status — alongside the classification result so the planner can prioritize. Residual-risk fields are still hidden.
### Stage 4 — Residual Risk Assessment
After mitigations are agreed, analysts rate the residual risk. The view shows the residual severity, residual occurrence, residual detection, and the calculated residual RPN or risk index. The initial classification columns may also be visible side-by-side so the change is visible at a glance.
### Stage 5 — Final Review
The reviewer needs the complete picture. This view exposes every column, typically using the `@all` shorthand, so nothing is hidden during sign-off.
## How Views Are Configured
Views are declared in the `views` section of the sheet configuration. Each entry has a `name` and a list of `columnIds` to include. One view can be marked as the default with `defaultView: true` so it loads automatically when the sheet opens.
```yaml theme={null}
views:
- name: 1. Context & Risk Identification
columnIds:
- function
- item
- failureMode
- hazard
- name: 2. Risk Classification
columnIds:
- failureMode
- severity
- occurrence
- detection
- initialRpn
- name: 3. Mitigation Planning
columnIds:
- failureMode
- initialRpn
- task
- owner
- dueDate
- status
- name: 4. Residual Risk Assessment
columnIds:
- failureMode
- initialRpn
- resSeverity
- resOccurrence
- resDetection
- residualRpn
- name: 5. Final Review
defaultView: true
columnIds:
- "@all"
```
Two special tokens are available inside `columnIds`:
| Token | Effect |
| ------------- | ----------------------------------------------------------------------- |
| `"@all"` | Includes every column defined in the configuration. |
| `"-columnId"` | Excludes a single column from the set (typically combined with `@all`). |
A "show everything except the downstream task block" view can therefore be expressed concisely:
```yaml theme={null}
- name: Risks Only
columnIds:
- "@all"
- "-task"
- "-owner"
- "-dueDate"
- "-status"
```
**Use views as a process gate**
Naming views with a leading number ("1. Context...", "2. Classification...") makes the intended order visible in the view switcher and turns the dropdown itself into a lightweight workflow guide.
**The column property name is `columnIds`, not `columns`**
The `views[].columnIds` array names the columns to show. Earlier drafts of community documentation used `columns`, but the engine only honors `columnIds`. Using the wrong name produces an empty view (no columns rendered).
## Views Versus Filters
Views are about **which columns** are visible. They do not filter rows. Row-level scoping is handled by other mechanisms:
| Mechanism | Scope | Configured in |
| ---------------------------------------------- | ------------------------------------------------- | ------------------- |
| `views` | Hides/shows columns | Sheet configuration |
| `queryFactories` | Filters autocomplete options inside link columns | Sheet configuration |
| `dataTypes.task.document` | Restricts downstream tasks to a specific document | Sheet configuration |
| URL parameters (`sort`, `filter`, `collapsed`) | Per-session row filtering and sorting | URL query string |
The same sheet can therefore be opened multiple times with the same view but different URL filters — for example, one tab showing only the highest-severity rows for a triage meeting, another tab showing all rows for a complete review.
**Verify in application**
The exact column IDs to put inside each `columnIds` list depend on your specific sheet configuration. Open the configuration editor and copy the `id` value of each column you want to expose; the IDs are case-sensitive.
## What Users See
When views are configured, the grid toolbar shows a view switcher. Selecting a view immediately re-renders the grid with the new column set — no work items are reloaded, no data is lost, and any unsaved edits remain in place. Switching back exposes the previously hidden columns again.
You should now see five entries in the view switcher of the configured sheet, the "5. Final Review" view selected by default, and only the columns appropriate to the current stage visible after picking any other entry.
## See also
* [Configuration Hierarchy](/risksheet/concepts/configuration-hierarchy)
* [Data Model and Work Items](/risksheet/concepts/data-model)
* [Review Workflows](/risksheet/concepts/review-workflows)
* [Configuration management guides](/risksheet/guides/configuration/index)
# Review Workflows
Source: https://learn.nextedy.com/risksheet/concepts/review-workflows
Risk analyses in regulated industries are not finished when the last severity rating is entered.
This page explains why review workflows exist as a first-class concept in Nextedy RISKSHEET, the three review strategies the product supports, where each strategy stores its evidence, and the limits you should know about before choosing one. It is conceptual; for the practical steps of turning a strategy on, see the [Review Management guides](/risksheet/guides/reviews/index).
## Why Reviews Live in the Grid
In sectors governed by ISO 26262, ISO 14971, IEC 61508, and ISO/SAE 21434, risk analyses are formal records. A failure mode without evidence of independent review is, for an auditor, an unreviewed claim. Without an integrated mechanism, teams typically fall back on three patterns, all of which create gaps:
* Exporting the risk table to a spreadsheet, circulating it for review, and manually reconciling redlines back into Polarion.
* Opening each risk item individually in Polarion to add a comment or approval, losing the grid context that explains *why* the row matters.
* Running a parallel document-level review that has no link to the row-by-row evidence inside the analysis.
Risksheet closes that gap by treating reviews as data on the same work items the grid already shows. Reviewers see a row in its hierarchical context, with its severity and occurrence values, its upstream requirement, and its downstream mitigation, and capture their judgement in place. The evidence is then queryable, filterable, and exportable using the same Polarion infrastructure as the risks themselves.
**All review evidence stays in Polarion**
Risksheet does not maintain a separate review database. Every review — whether a comment, a linked work item, or an approval comment — is stored inside Polarion, subject to Polarion authorization, and tracked by Polarion's audit infrastructure. Risksheet visualizes and edits this data; it does not duplicate it.
## The Three Review Strategies
Risksheet supports three mutually exclusive review strategies, configured per document through the `reviews.reviewManager` property in the sheet configuration. The system inspects this value and routes all review operations — listing existing reviews, creating new ones, deciding whether the review columns appear at all — to the matching implementation. You pick one strategy per document; you do not mix two.
The three strategies differ in *where* the review evidence is persisted and *what shape* it takes:
When `reviews.reviewManager` is configured, Risksheet enables two grid columns: one that lists existing reviews on each row, and one that lets reviewers add a new review with a title and text. Toggling these columns visible or hidden is a single user action; when toggled, Risksheet auto-sizes the affected rows so longer review entries do not clip. If no review manager is configured, neither column appears — the feature is invisible.
### Comment-Based Review
A comment-based review is the lightweight option. Each review is stored as a Polarion comment attached to the reviewed work item. The reviewer types a title and a body in the grid; Risksheet creates a comment on the underlying work item; the comment then shows up everywhere Polarion shows comments — in the work item pane, in notifications, in mention queries, and back in the Risksheet grid.
The mental model: think of comment-based review as a sticky note attached to the risk row. It is easy to start, easy to read, and easy to ignore. There is no separate object to track and no extra workflow state to maintain. The trade-off is that comments have a relatively flat lifecycle. They can be marked resolved or unresolvable, but they do not pass through review stages, do not carry their own custom fields, and cannot be queried in the rich ways work items can.
Comment-based review fits early-phase analyses, peer-review notes during authoring, and processes where the formal sign-off happens at the document level rather than per row.
### Work-Item-Based Review
A work-item-based review elevates each review to a full Polarion work item linked back to the reviewed risk. Choosing this strategy means every review carries the full weight of Polarion's work item infrastructure: its own type, its own workflow, its own custom fields, and its own audit trail. Reviews can be queried, reported on, and assigned to specific reviewers the same way any other work item is.
The mental model: think of work-item-based review as filing a review *report*, not pinning a sticky note. The report is itself an object — it has an ID, a status, an assignee — and it points back at the risk it reviewed via a bidirectional link.
Configuration lives under `reviews.typeProperties` and supports the following properties:
* **`itemTypes`** — the Polarion work item type used for each review (for example, `review`). Mandatory.
* **`linkRole`** — the Polarion link role connecting each review to the risk it reviews (typically `review`). Mandatory.
* **`query`** — an optional Lucene expression that further filters which linked work items count as reviews; useful when the same link role is reused for non-review purposes.
* **`document`** — an optional target document, in `SPACE/DOCUMENT` form, where new reviews are created. When set, Risksheet creates reviews as positioned items inside that document, placing each new review after the last existing review item of the same type.
* **`project`** — an optional target project ID, allowing reviews to live in a different project from the risk. Project resolution supports expression evaluation, so values like the current project can be referenced dynamically.
* **`itemTemplate`** — an optional Velocity template for rendering each review in the grid. When omitted, Risksheet falls back to a default format that shows the review work item ID as a clickable link, the author's full name (or user ID), the creation timestamp, the title if it differs from the description, and the HTML-rendered description.
Because the rendered output is wrapped in the `risk_reviews` CSS class, teams can style review entries to match their visual conventions.
Work-item-based review fits formal validation workflows, sign-off processes that need their own reviewer assignment and status, and any context where review activity itself must be auditable as an artifact. It is the strategy of choice when an auditor will ask: "show me every review on this risk, who did it, when, and what state is it in".
**Required configuration**
The work-item-based strategy requires both `itemTypes` and `linkRole` to be present. Missing either causes Risksheet to refuse review creation at runtime. The standard value for `linkRole` is `review`, and when `document` is configured it must be supplied in `SPACE/DOCUMENT` form (for example, `Risks/HARA-2024`). Always verify both required properties — and the format of `document` if you use it — before rolling out a configuration.
### Approval-Based Review
Approval-based review uses Polarion's native approval comment system. Each review is created as a Polarion comment tagged with the fixed title *Approval comment*, marking it as a sign-off rather than ordinary discussion. The grid lists existing approval comments — preferring the reviewer's full name over their user ID, formatting the timestamp consistently, and hiding comments that have been resolved or are unresolvable so the active sign-off picture is always clear.
The mental model: think of approval-based review as a stamp on the risk row. The stamp carries a name, a date, and a note. It is heavier than a freeform comment because it uses Polarion's distinguished approval channel, and it sits naturally beside other approval evidence on the same work item.
**Approval review does not trigger Polarion's formal approval workflow**
Risksheet's approval review creates approval-tagged comments but does **not** trigger Polarion's formal approval state transitions (draft -> reviewed -> approved). Use this strategy when you want sign-off evidence captured next to other Polarion approvals, but do not assume that adding an approval review through Risksheet will move the work item through Polarion's approval lifecycle. If the formal lifecycle matters, drive state transitions in Polarion separately.
This limitation is the most common misunderstanding in practice. Approval-based review is the right choice when your governance model treats *the existence of approval comments* as the evidence, not when it depends on the work item's status field flipping to an approved state.
## Selection Precedence
When multiple review manager values are technically configurable, Risksheet evaluates them in a fixed priority order: comment-based first, work-item-based second, approval-based third. In practice you should configure exactly one strategy per document; the precedence rule only matters in unusual situations where conflicting values exist. Treating `reviews.reviewManager` as a single-value property is the safe approach.
| Strategy | `reviewManager` value | Storage | Best for |
| --------------- | --------------------- | ----------------------------- | ----------------------------------------- |
| Comment-based | `CommentBased` | Polarion comments on the risk | Peer review, lightweight notes |
| Work-item-based | `WorkItemBased` | Separate linked work items | Formal validation with their own workflow |
| Approval-based | `ApprovalBased` | Approval-tagged comments | Sign-off evidence beside other approvals |
## How Reviews Appear in the Grid
When a review manager is configured, two dedicated columns become available: one that lists the current reviews on each row, and one that lets a reviewer add a new review through a title-and-text input. Toggling these columns is a single command that hides or shows both at once and then automatically resizes affected rows to accommodate the typically taller content of review entries. If the configuration changes — for example, the review manager is removed — the columns disappear cleanly.
The format the grid uses to display reviews depends on the strategy:
* **Comment-based** shows each comment as it exists in Polarion.
* **Work-item-based** shows either the default template (clickable ID, author, timestamp, title if distinct, HTML description) or whatever the configured `itemTemplate` produces.
* **Approval-based** shows each approval comment with the reviewer's name, timestamp, and comment body, filtered to active approval comments only.
In all three cases, the output is wrapped in a `risk_reviews` CSS class, so visual styling can be customized through the styles section of the sheet configuration.
## What Risksheet Reviews Are Not
Several capabilities sit just outside Risksheet's review feature today. Understanding the boundary prevents disappointment and helps you choose the right tool for the right step.
* **Risksheet review is not Polarion's full work item approval workflow.** Approval actions that move a work item through Polarion's approval lifecycle — the formal draft -> reviewed -> approved transitions, with role-based approver lists, escalation, and notifications — are not exposed in the Risksheet grid today. This capability is planned but not yet available. Until it ships, teams that need full approval lifecycle integration drive those actions from the Polarion work item view or document view; Risksheet captures the discussion that informs the decision.
* **The Polarion `resolution` field is not editable from Risksheet.** That field is typically mandatory during status transitions, and Polarion's APIs do not allow third-party tools to drive transitions when mandatory fields are required. Use the Polarion work item view to change resolution or status.
* **Administrators can still see some fields as editable that Polarion otherwise treats as read-only.** Polarion does not expose a complete read-only field contract to third-party products. When users with administrator permissions edit through Risksheet, the underlying Polarion check that would normally block the edit may not fire. Plan permission models accordingly; do not rely on Risksheet to enforce read-only state for administrators.
These constraints are real today. Treat them as design boundaries, not bugs.
## Choosing a Strategy: A Decision Sketch
| If you need... | Consider... | Because... |
| ---------------------------------------------- | ----------------------- | --------------------------------------------------------------- |
| Quick peer-review notes during authoring | Comment-based | Lowest setup cost; lives next to other Polarion comments |
| Per-review assignee, status, and custom fields | Work-item-based | Reviews are full work items with their own workflow and queries |
| Sign-off evidence alongside other approvals | Approval-based | Uses Polarion's native approval comment channel |
| Formal state transitions on the risk itself | None of the above (yet) | Status transitions are not exposed via Risksheet today |
The decision is not which strategy is *best* in the abstract, but which one matches the artifact your process requires. If you cannot describe the artifact your auditor will ask for, that is a sign to step back and design the artifact before configuring the strategy.
## Where to Go Next
For practical steps and configuration recipes, see the [Review Management guides](/risksheet/guides/reviews/index). For the underlying configuration property reference and the shape of `reviews.typeProperties`, see [Configuration](/risksheet/reference/configuration/index). To understand how reviews participate in Polarion authorization and visibility, see [User Roles and Permissions](/risksheet/concepts/user-roles) and [Data Model and Work Items](/risksheet/concepts/data-model) (covers work item visibility and levels). For how reviews fit into the broader traceability picture between requirements, risks, and mitigations, see [Traceability and Linking](/risksheet/concepts/traceability).
# Traceability and Linking
Source: https://learn.nextedy.com/risksheet/concepts/traceability
In regulated industries — automotive (ISO 26262), medical devices (ISO 14971), industrial safety (IEC 61508), and cybersecurity (ISO/SAE 21434) — risk analysis is not a standalone artifact.
Nextedy RISKSHEET (Risksheet for short) is designed around this expectation. Rather than inventing a proprietary linking layer, Risksheet uses Siemens Polarion ALM's native work item links to express every relationship in a risk analysis. The grid you see in a LiveDoc is, at its core, a structured editor for those links — a mapping table that aggregates context from elsewhere in Polarion into a single auditable row.
This page explains the mental model: how a risk item acts as a mapping table, how traceability is built directly on Polarion's link infrastructure, and how Risksheet integrates end-to-end with requirements, design, and test data already in your project.
## A Risk Item Is a Mapping Table
The most useful way to think about Risksheet is not as a "risk database" but as a **mapping engine**. Each row in the grid is one risk item — typically a Polarion work item of type `failureMode`, `hazard`, `riskRecord`, or whatever your methodology calls it — and the columns of that row aggregate four kinds of information into one auditable record.
A single Risksheet row therefore performs five jobs at once:
1. **Aggregate upstream context** — pulls in the requirement, function, hazard, or use step that this risk derives from.
2. **Hold the risk attributes** — captures severity, occurrence, detection, exposure, or whatever parameters your methodology uses.
3. **Compute or store the classification** — produces an RPN, an ASIL level, a CVSS score, or a custom risk class.
4. **Reference the mitigations** — lists the downstream tasks, controls, or safety requirements that reduce the risk.
5. **Track the residual risk** — captures the post-mitigation rating and the verification status.
Because every one of those columns is either a field on the risk work item or a link to another work item, the entire row is a structured projection of data that already lives in Polarion. This is why Risksheet can serve methodologies as diverse as FMEA, HARA, TARA, STRIDE, and CVSS scoring with the same underlying engine: the columns change, but the mapping-table pattern does not.
**Beyond risk: requirements traceability matrices**
The same mapping pattern works for requirements traceability. By configuring the main row type as `requirement` and the downstream type as `testcase`, a sheet becomes a V\&V matrix showing which test cases verify which requirements. "Risk" and "task" are naming conventions inherited from the most common use case — the engine itself is methodology-agnostic and supports any two work item types you wish to relate.
## Built on Polarion Traceability
A defining design choice of Risksheet is that **every link is a native Polarion work item link**. There is no separate risk database, no shadow link table, no proprietary identifier scheme. When you connect a risk row to an upstream requirement or a downstream mitigation task, Risksheet creates a standard Polarion link with a configured link role — exactly the same kind of link that the Polarion tracker, traceability reports, suspect-link logic, and impact analysis already understand.
This has practical consequences that matter for compliance and for day-to-day work:
* **One source of truth.** A link created in the Risksheet grid appears in the Polarion work item's "Linked Work Items" section, in Polarion document views, and in any custom Lucene query you run against the project.
* **Standard audit trail.** Every link creation, change, and deletion is captured in Polarion's history. Risksheet does not bypass or duplicate this.
* **Standard authorization.** Whatever the user is permitted to see and edit in Polarion, that is what they see and edit in Risksheet. There is no separate permission model.
* **Bidirectional navigation.** Because links are real, you can jump from the risk into the upstream requirement, then back out from the requirement into every risk that references it — using normal Polarion navigation.
* **Suspect link propagation.** When an upstream requirement changes, Polarion's suspect-link mechanism marks the related risk as suspect, prompting reassessment. This is automatic.
**All data lives in Polarion**
Risksheet does not maintain its own data store. The grid is a view onto Polarion work items — it visualizes and edits them, but it does not store them separately. Closing the Risksheet does not "save" anything special; the work items and their links are already there.
### Two Link Directions
Risksheet distinguishes two directions of linking, and they are configured in different places.
**Upstream links** point from the risk to a *cause* or *source*: the requirement that introduced the hazard, the function being analyzed, the hazardous situation. These are configured as **item link columns** on the row, using `type: itemLink` or `type: multiItemLink`, with a `typeProperties` block that specifies the link role, the allowed work item types, and the search scope.
**Downstream links** point from the risk to a *consequence* or *response*: the mitigation task, safety control, verification activity, or test case. These are configured globally for the sheet using the `dataTypes.task` section, which declares the work item type, the link role, and how new tasks are created.
```yaml theme={null}
dataTypes:
risk:
type: failureMode
task:
type: safetyRequirement
role: mitigates
name: Safety Requirement
zoomColumn: taskTitle
document: Risks/FHA-SYS-001
```
The `type` and `role` properties tell Risksheet which work item type to create and which link role to apply. The `name` property is the label shown in the toolbar and menus when creating tasks. The `zoomColumn` property tells Risksheet which column to focus on after a new task is created. The `document` property restricts the scope of tasks to a specific LiveDoc path — only tasks inside that document are loaded as downstream items. For configuration syntax details, see the [Reference](/risksheet/reference/index) section.
### Chained Upstream Links
Sometimes two upstream items both link to the same risk but do not link to each other. Consider a medical device risk where the same risk record references both a Use Step (from the Instructions for Use) and a Procedure Step (from the clinical procedure). The two upstream items have no direct relationship, but for impact analysis you may want a link between them.
Risksheet can build these "horizontal" relationships automatically. A project property defines patterns of the form `fromType-linkRole-toType` and, whenever a risk row connects two upstream items that match the pattern, Risksheet creates the missing link between them. The mechanism only **adds** links — it never removes existing ones, so it is safe to apply retroactively. For the exact property syntax, see [Configuration properties](/risksheet/reference/configuration/index).
## End-to-End Integration
Because all linking goes through Polarion, Risksheet does not exist in a documentation silo. A risk analysis sits in the same project as the requirements, the design specification, and the test management content, and the links between them are visible from every direction.
In a typical regulated workflow the chain looks like this:
* A **system requirement** describes a function the product must perform.
* A **design element** or **function block** implements that requirement.
* A **risk analysis** identifies failure modes of that function, classifies them, and proposes mitigations.
* A **mitigation** is itself a work item — often a safety requirement or design constraint — that addresses one or more failure modes.
* A **test case** verifies that the mitigation works as intended.
Risksheet makes the middle of this chain a structured editor. Auditors and engineers can trace forward from any requirement to the risks it produces and the mitigations that close them, or backward from any test result to the risks it covers and the requirements those risks were derived from. Because the chain runs through Polarion's link graph, the same data feeds Polarion's traceability reports, Live Reports, and Lucene queries.
### Historical and Revision Traceability
Compliance does not stop at the current state. Auditors regularly need to see what the linking structure looked like at a previous milestone — for example, the set of mitigations linked to a hazard at the moment a release was approved. Risksheet supports this by loading downstream items from a specific document or work item revision when you view a historical baseline. The grid then shows the relationships as they existed at that point in time, with the same row structure and the same column logic, but with the linked work items frozen to the revision you selected.
This time-aware traceability is essential for change impact analysis. When a requirement changes, the team can compare the current risk mapping with a previous baseline and identify which risks must be re-evaluated.
### Task Resolution and Filtering
The downstream side of the chain is rarely a flat list. In real projects, the set of tasks linked to a given risk is filtered by status, type, ownership, or document location. Risksheet supports this in four independent ways:
| Mechanism | What it filters by | Where configured |
| -------------- | ------------------------------------------------------------------------------- | ------------------------- |
| Task type | The Polarion work item type, e.g. `safetyRequirement`, `task`, `testCase` | `dataTypes.task.type` |
| Link role | The role connecting risk to task, e.g. `mitigates`, `verifies` | `dataTypes.task.role` |
| Custom query | An additional Lucene query, e.g. only tasks with status `open` or assignee `me` | `dataTypes.task.query` |
| Document scope | A specific LiveDoc path containing the tasks | `dataTypes.task.document` |
These filters compose: the tasks shown are those that match the configured type **and** the configured link role **and** the optional query **and** (if set) the document scope. The result is a focused view — for example, "all open mitigation tasks for this hazard, drawn from the master mitigation document."
**Verify in application**
The exact application of custom queries is governed by a project property that toggles query filtering on tasks. If you have configured a query but do not see it applied, check the project administration settings for the related option.
### Subsheet Navigation
For complex analyses, a single sheet may not be enough. A master HARA, for example, can list all top-level hazards while each hazard has its own detailed risk analysis in a separate Risksheet document. Risksheet supports this master-detail pattern by making the task link column a clickable hyperlink that opens the child risksheet document directly.
```yaml theme={null}
dataTypes:
risk:
type: hazard
task:
type: riskRecord
role: relatesTo
name: Detailed Analysis
zoomColumn: taskTitle
linkToRisksheet: true
document: Risks/Detailed Hazard Analyses
```
When `linkToRisksheet` is enabled, clicking the task identifier opens the linked downstream document in a new risksheet view, allowing the user to drill from a top-level hazard into its detailed analysis without leaving Polarion.
## Common Misconceptions
> "Risksheet keeps its own link database."
It does not. Every Risksheet link is a Polarion work item link with a standard link role. If you delete Risksheet tomorrow, the links remain in Polarion and are usable by any other tool.
> "Risksheet only works for FMEA."
The engine is methodology-agnostic. The same configuration mechanism supports FMEA, HARA, TARA, STRIDE, CVSS scoring, and even non-risk patterns like requirements-to-test-case traceability matrices. Nextedy ships solution templates for the most common methodologies, but the underlying tool does not enforce any one of them.
> "If I link a requirement in Risksheet, only Risksheet knows about it."
The link is created in Polarion and is fully visible in the Polarion tracker, in document views, and in queries. A second team member working on the same requirement will see it linked to the risk record without ever opening Risksheet.
> "Upstream and downstream are symmetric — they work the same way."
They are configured very differently. Upstream links are defined per-column using `type: itemLink` and a `typeProperties` block, so different upstream columns can reach different kinds of work items. Downstream links are defined once globally in `dataTypes.task`, so the entire sheet shares a single downstream type and role. This asymmetry reflects the practical pattern: a risk usually has many *kinds* of upstream context (requirement, function, hazard) but a uniform *kind* of downstream response (mitigation tasks).
## Putting It Together
The mental model to carry forward is this:
* A risk row is a mapping table — it pulls upstream context in, holds the risk attributes and classification, and points to downstream mitigations and verifications.
* Every link is a Polarion link, which means everything you build in Risksheet is visible, auditable, and queryable through Polarion's standard infrastructure.
* The same engine handles many methodologies because the linking pattern is generic — only the column definitions, work item types, and link roles change between an FMEA, a HARA, and a requirements traceability matrix.
* Time-aware loading and document-scoped task filtering make the model robust against the real complexities of regulated change control.
For practical configuration of these traceability features, see the [Risk Management guides](/risksheet/guides/risk-management/index), the [Configuration Management guides](/risksheet/guides/configuration/index), and the [Integration guides](/risksheet/guides/integration/index). For complete property syntax, see the [Configuration reference](/risksheet/reference/configuration/index) and [Column Types reference](/risksheet/reference/columns/index).
# User Roles and Permissions
Source: https://learn.nextedy.com/risksheet/concepts/user-roles
Nextedy RISKSHEET runs inside Siemens Polarion ALM and never stores data of its own — every risk item, mitigation task, comment, and review record lives as a Polarion work item under Polarion's authorization model.
This page explains the conceptual model behind these layers, why they exist, and the common misconceptions teams hit when granting access for FMEA, HARA, TARA, STRIDE, or compliance traceability work.
## The Three Usage Tiers
In any risksheet — whether it is a Failure Mode and Effects Analysis (FMEA), a Hazard Analysis and Risk Assessment (HARA), a Threat Analysis and Risk Assessment (TARA), or a generic compliance traceability matrix — people interact with the grid in one of three ways. These tiers describe **what a person does**, not what role Polarion has assigned to them. The Polarion role and the active licenses then determine whether that activity is actually permitted.
### Tier 1: Viewer / Reviewer
The Viewer/Reviewer tier treats a risksheet as an **interactive report**. People at this tier open the document, scroll through risk items, switch between saved views (for example, "Classification Summary" versus "Final Risk Assessment"), filter and sort the grid, drill into linked requirements or test cases, and export the result to Excel or PDF. They can also participate in review workflows — leaving comments, voting on approval-tagged items, or marking review work items — without changing the underlying risk data.
This tier is the right fit for stakeholders who consume risk analysis as evidence rather than producing it: auditors checking ISO 26262 work products, project managers tracking Risk Priority Numbers (RPNs) before a milestone, customers reviewing a HARA, or compliance officers verifying ISO 14971 risk control coverage.
### Tier 2: Author
The Author tier is for the people who **build the risk analysis itself**. Authors create new risk items, edit field values (severity, occurrence, detection, hazard classification, treatment, residual risk), attach mitigation tasks through link columns, recalculate formulas, and toggle between saved views to focus on a particular phase of the analysis. Authors typically include safety engineers running an FMEA, hazard analysts producing a HARA, cybersecurity analysts building a TARA or STRIDE table, and quality engineers driving a Common Vulnerability Scoring System (CVSS) workflow.
An Author still operates within the structure that an Administrator has defined. They do not change which columns exist, which work item types are used for risk items versus mitigation tasks, or which formulas calculate the risk score — they fill in the analysis under that structure.
### Tier 3: Administrator
The Administrator tier configures the **structure that Authors work inside**. Administrators choose the work item types backing risk items and mitigation tasks (`dataTypes.risk.type`, `dataTypes.task.type`), define the visual hierarchy through the `levels` array, decide which columns appear and what they map to with the `bindings` property, attach formulas and cell decorators, edit the top panel template that hosts risk matrices and dashboards, and publish templates that other projects inherit.
Administrators also set Risksheet's project properties (template paths, suggester behavior, permission flags), control which user views see the Risksheet topic in Polarion navigation, and decide which projects use which licenses.
**Tiers describe activity, not Polarion roles**
A single person can move between tiers depending on the document. A safety engineer might be an Author on the system FMEA they own, a Reviewer on a peer's HARA, and only a Viewer on a TARA owned by the security team. The combination of Polarion permissions and license assignment determines whether each activity is actually allowed.
## The License Model
Risksheet's license model maps onto the three usage tiers. There are two license types, and the way they combine is what creates the practical distinction between "can change risk data" and "can read risk data".
| License | Scope | Grants | Typical Tier |
| ------------------- | --------------- | ---------------------------------------------------------------------------------- | --------------------- |
| **Author license** | Named, per user | Create, edit, and delete risk items, mitigation tasks, formulas, and saved views | Author, Administrator |
| **Connect license** | Server-wide | Open and view risksheets, run saved views, export, comment, participate in reviews | Viewer / Reviewer |
The Connect license is server-wide: once it is active on the Polarion server, anyone with a Polarion seat and the necessary project access can open a risksheet in read-only mode. This is what lets large organizations expose risk analyses to stakeholders, auditors, and reviewers without buying a per-user Risksheet seat for every observer.
The Author license is named and per-user — assigned to specific people who actually build and maintain the risk analysis. Authors and Administrators both need it. Without it, even a Polarion Project Administrator sees the risksheet as read-only.
**Polarion permissions always apply on top**
Licenses control whether a Risksheet feature is available at all. Polarion's project permissions control whether a specific user is allowed to use it on a specific document. A user with an Author license still cannot edit a risksheet in a project where Polarion grants them only read access. Risksheet never bypasses the underlying authorization model — it inherits it.
The misconception that "Risksheet has its own permissions" sometimes appears in tickets where a user expects an in-app role assignment to unlock editing. There is no such assignment. The unlock happens when (a) the Polarion role grants edit on the project, and (b) the Author license is active for the user, and (c) the relevant Risksheet project properties are configured to allow it (see [Project Properties](#project-properties-that-shape-permissions) below).
## How Polarion Permissions Layer In
Because every risksheet cell is a Polarion work item field, Polarion's permission system applies to every read and every save. This is intentional: it means a risk analysis enjoys the same audit trail, access control, and traceability infrastructure as the requirements, test cases, and design items it links to.
Polarion permission concepts that directly affect a risksheet user:
| Polarion concept | What it controls in Risksheet |
| ---------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| **Project role** assignment | Whether the user can open documents in this project and edit work items at all |
| **Work item permissions** (per type, per role) | Whether specific fields on the underlying risk or task work items can be edited |
| **Workflow state** | A risk item in an approved state may be locked by its workflow even if the user has the Author license |
| **Document workflow** | A LiveDoc in a frozen state prevents structural changes through the risksheet |
| **User group / hat** | Which navigation topics — and therefore which risksheets — are even visible to the user |
A common surprise: a user might have an Author license and a Project User role, but still see a particular column as read-only. The cause is almost always at the Polarion layer — a workflow has moved the item to a state where the field is locked, or the field is restricted to a different role by Polarion's permission management.
**Read-only Fields is a Polarion UI property without an API**
Polarion's "Read-only Fields" project property is a UI-only setting that has no programmatic interface. Risksheet cannot read it directly, so this property alone does not enforce field-level restrictions in the grid. To enforce read-only behavior based on work item status, use Risksheet's Permissions Management with the `nextedy.risksheet.checkInstanceFieldPermissions=true` project property. Risksheet then evaluates the same workflow-state field permissions that Polarion uses elsewhere.
## Project Properties That Shape Permissions
A handful of project administration properties (set under **Administration > Nextedy Risksheet > Setup**) directly affect what a user can do. These are not user roles themselves — they are switches that an Administrator flips to extend or restrict how Risksheet interprets Polarion permissions. The defaults are listed where verified in the product knowledge base.
| Property | Default | Effect on permissions |
| ------------------------------------------------- | -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `nextedy.risksheet.checkInstanceFieldPermissions` | `false` | When `true`, Risksheet honors per-state field permissions defined by Polarion's permission management — so a field becomes read-only in the grid when the work item's current workflow state restricts it |
| `nextedy.risksheet.checkPrototypePermissions` | `true` | Enforces work item type prototype permissions before allowing edits |
| `nextedy.risksheet.upstreamSubColumnsReadonly` | `true` | Treats columns that display fields of linked upstream items (for example, a column with `bindings: harm.title`) as read-only |
| `nextedy.risksheet.editableReferencedWorkItems` | `false` (v23.3.3+) | Project administration property allowing limited editing of referenced upstream work items directly from the grid |
| `nextedy.risksheet.moduleOnlyPermissions` | `false` (v24.8.5+) | Constrains permission evaluation to document-scope only |
| `nextedy.risksheet.checkLinkRoleCompliance` | `false` (v24.2.2+) | Validates link role compatibility before allowing relationship edits |
| `nextedy.risksheet.risksheetTemplatePath` | `Risks/Risk Specification` | Restricts where Authors can create new risk documents from templates — multiple paths can be comma-separated |
The interaction matters: switching on `checkInstanceFieldPermissions` is the recommended way to make a risksheet honor workflow-state field locks. Without it, a user with the Author license who otherwise has edit rights on the work item may be able to change a field that the workflow intends to freeze.
## Visibility: The Topic Gate Before Permissions
A subtle but frequent source of "I cannot access Risksheet" tickets is not permissions at all — it is **navigation visibility**. Risksheet appears in the Polarion sidebar through a Risksheet topic that is mapped to user views (also called "hats"). If the topic is missing from the active view, the user does not see Risksheet in the sidebar at all and is redirected to the project home page or the space home page when they try to navigate to it.
Visibility is gated before permissions are even evaluated. Several support tickets that initially looked like browser compatibility issues or installation failures turned out to be a missing topic in the user's current view after an upgrade. The symptom is consistent: the user is silently redirected away from the Risksheet URL, sometimes with an unrelated error such as an XML parsing error on a stylesheet.
The correct fix is in **Administration > Topics**: ensure that every view used by people who need access to risksheets includes the Risksheet topic. This is an administration task, not a permission change.
**Diagnosing 'Risksheet stopped working' after an upgrade**
Before suspecting browser compatibility, certificates, or licensing, check that the user's current view still includes the Risksheet topic. Custom views built for niche roles often omit topics added by later releases.
## Reviewer Mode and Downstream Read-Only
Beyond the three core tiers, Risksheet supports two server-injected runtime modes that further constrain what a session can do — they are decided by Risksheet at load time, not chosen by the user:
* **Reviewer mode** is enabled automatically when the user is participating in a review of the risksheet. The grid switches into a review-specific UI with annotation controls. The user can read every column, leave comments, and approve or reject — but cannot freely edit risk data outside the review workflow.
* **Downstream read-only** treats linked items from other documents as non-editable, even if the user has the Author license. This prevents accidental cross-document edits when an author opens a risksheet that includes upstream references to a shared harms library or requirements catalog.
These modes are part of why a user with the Author license still sees a "read-only" experience on a particular sheet. The cause is the document's review state or its linkage to upstream libraries, not a permission misconfiguration.
## A Shared Mental Model
A useful way to think about access to a risksheet is as a stack of filters that each user request passes through, in order:
| Layer | Decided by | Result |
| ----------------------------------- | ------------------------------------------------------ | --------------------------------------------------------------- |
| 1. Visibility (topic in view) | Administrator (Topics configuration) | Can the user see Risksheet at all? |
| 2. License (Connect or Author) | Server-wide license configuration | View only, or view + edit? |
| 3. Polarion project role | Polarion administration | Which projects and documents are accessible? |
| 4. Work item / workflow permissions | Polarion administration + Risksheet project properties | Which fields can change in which states? |
| 5. Risksheet runtime mode | Risksheet (review state, downstream linkage) | Reviewer mode, downstream read-only? |
| 6. Configuration intent | Administrator (sheet configuration) | Which columns are marked `readOnly: true` in the configuration? |
The Author capability is granted only when every layer above it permits the action. This is why the most common ticket category — "I have a license but cannot edit field X" — almost always resolves at a layer other than licensing: the workflow has locked the state, the column is configured `readOnly: true`, the field is upstream-bound, or the user is operating in a review.
## Common Misconceptions
The following beliefs come up repeatedly in support tickets and are worth dispelling before they shape an access-control strategy.
> "Risksheet has its own user database, so I just need to grant the user a Risksheet role."
Risksheet does not maintain user accounts or roles. Users are Polarion users; their effective Risksheet capabilities come from Polarion permissions plus license entitlement.
> "Polarion's Read-only Fields setting will lock fields in the grid."
The Read-only Fields project setting is a UI-only Polarion property without an API, so Risksheet cannot enforce it. To make a field read-only based on workflow state, enable `nextedy.risksheet.checkInstanceFieldPermissions=true` and use Polarion's Permissions Management, which Risksheet does evaluate.
> "If a Project Administrator opens a risksheet, they can edit everything."
A Project Administrator who lacks an Author license can still only view a risksheet. The Polarion role grants the administrative ability to change configuration if a license is present, but read-only is the default without one.
> "Risksheet stopped working in Firefox after the update — must be a browser issue."
Usually the topic for Risksheet is missing from the user's current view. The browser is fine; the navigation view simply does not surface Risksheet anymore, and the user is redirected.
> "I can change the sheet configuration since I am an editor on the document."
Editing the sheet configuration requires a Polarion Admin role on the project. Document edit rights are not sufficient. Non-admin users who need configuration changes must coordinate with their project administrator.
**Verify in application**
Exact license names, project property defaults, and topic configuration paths may evolve between Risksheet releases. When in doubt, verify in your installed version under **Administration > Nextedy Risksheet > Setup** and **Administration > Topics**.
## How This Connects to Other Concepts
User access is just one cross-cutting concern in a risksheet. To follow the related concepts:
* For how risksheet data is structured and persisted as Polarion work items, see [Data Model and Work Items](/risksheet/concepts/data-model).
* For the review workflows that drive Reviewer mode, see [Review Workflows](/risksheet/concepts/review-workflows).
For the practical tasks behind these concepts, the following how-to guides cover the steps that an Administrator or Author actually performs:
* [Licensing](/risksheet/guides/licensing/index) walks through assigning and renewing Author and Connect licenses.
* [Administration](/risksheet/guides/administration/index) covers Risksheet project setup, including topic configuration and project properties.
* [Configuration Management](/risksheet/guides/configuration/index) and [Advanced Configuration](/risksheet/guides/advanced/index) show how Administrators publish and inherit templates.
* [Review Management](/risksheet/guides/reviews/index) explains how to run comment-based, work-item-based, and approval reviews.
* [Troubleshooting](/risksheet/troubleshooting/index) lists fixes for the visibility, license, and permission symptoms described here.
Across all of these, the central principle remains the same: Risksheet visualizes and edits Polarion data — it does not store data separately, and it does not introduce a separate authorization layer. The right access for each user comes from choosing the appropriate usage tier, granting the right license, and letting Polarion's project permissions do the work they were designed for.
# What is Risksheet?
Source: https://learn.nextedy.com/risksheet/concepts/what-is-risksheet
Nextedy RISKSHEET is a generic spreadsheet-like interface for managing structured work item collections inside Siemens Polarion ALM.
The simplest mental model: **think of what you used to do in Excel, but inside Polarion**. Same familiar tabular editing experience — rows, columns, cell merging, formulas, conditional formatting — but every cell is backed by a real Polarion work item field, with full traceability, versioning, permissions, and audit history built in.
**One-sentence summary**
Risksheet turns a Polarion LiveDoc into an interactive, methodology-aware grid where each row is a work item, each column is a field or computed value, and the whole structure is driven by a sheet configuration.
## The Problem Risksheet Solves
Risk analysis, traceability matrices, and compliance assessments share a structural pattern: a table where each row represents a structured record (a failure mode, a hazard, a requirement, a threat), each column captures a specific property (severity, occurrence, mitigation, parent function), and certain columns are computed from others (RPN = severity × occurrence × detection).
Historically, organizations have solved this in two ways:
1. **Spreadsheets** (Excel, Google Sheets) — familiar and flexible, but disconnected from the rest of the engineering lifecycle. No traceability to requirements, no link to design or test artifacts, no formal review history, no enforced workflow, and frequent versioning chaos.
2. **Generic ALM tables** — traceable and versioned, but row-oriented editing is slow, formulas are weak or non-existent, conditional formatting is limited, and hierarchical analyses (failure mode → cause → effect) become awkward.
Risksheet is designed to give you the **Excel-like editing experience** for tabular analysis **without leaving Polarion**. The data lives in Polarion work items — subject to Polarion authorization, fully traceable, fully versioned — while the user interacts with a fast, formula-aware, hierarchical grid.
Risksheet is **not a separate database**. There is no parallel store, no syncing layer, no risk of the grid drifting from the system of record. Every value the user types lands directly on a Polarion work item field, governed by Polarion's permissions and captured in Polarion's revision history.
## A Methodology-Agnostic Tool
A common misconception — reinforced by demos and marketing — is that Risksheet is "for FMEA" or "for HARA". It is not. Risksheet is a generic tool supporting any risk management methodology, including FMEA, HARA, TARA, STRIDE, and CVSS. The methodology comes from the **sheet configuration**: the columns you define, the formulas you write, the levels you organize, and the styling rules you apply.
Because Risksheet does not constrain methodology, Nextedy ships **solution templates** for typical methodologies across industries:
| Industry | Typical methodology | What the template provides |
| ----------------------------- | -------------------------- | ---------------------------------------------------------------------------------- |
| Automotive (ISO 26262) | DFMEA, HARA, ASIL | Severity / occurrence / detection scales, ASIL classification, mitigation tracking |
| Medical devices (ISO 14971) | Risk management file | Hazard / harm structure, risk control measures, residual risk assessment |
| Industrial safety (IEC 61508) | Functional safety analysis | SIL determination, safety function decomposition |
| Aerospace | FHA, PSSA, SSA | Function / failure condition / detail levels, classification |
| Cybersecurity (ISO/SAE 21434) | TARA, STRIDE, CVSS | Threat, vulnerability, attack tree, CVSS scoring |
You start from a solution template that matches your industry and methodology, then adapt the columns, formulas, and scales to your organization's process. You do not start from a blank configuration.
**Generic traceability matrix**
The two underlying entity slots — internally called "risk" and "task" — are abstract. They can hold any two Polarion work item types. A "risk" can be a requirement; a "task" can be a test case. With this configuration Risksheet becomes a requirements traceability matrix or a V\&V matrix. The name "Risksheet" reflects the most common use case, not the limit of the tool.
## What Is Risk Management, Briefly?
Risk management — as practiced under ISO 14971, ISO 26262, IEC 61508, ISO/SAE 21434, and similar standards — is a structured process of identifying things that could go wrong, evaluating how bad and how likely they are, deciding what to do about them, and proving that the residual exposure is acceptable.
The process is broadly the same across standards, even when the terminology differs:
1. **Identify** items, functions, hazards, threats, or failure modes that could harm safety, security, mission, or business.
2. **Analyze** each one by assigning ratings — typically severity, occurrence/likelihood, and detectability — drawn from a defined scale.
3. **Score** the combined risk (an RPN, ASIL, SIL, CVSS value, or qualitative classification).
4. **Mitigate** unacceptable risks by adding controls, design changes, requirements, or tests.
5. **Reassess** after mitigations to confirm residual risk is acceptable.
6. **Trace** every risk to its source (function, requirement, hazard) and every mitigation to its evidence (task, test, design).
7. **Review and approve** the analysis as a controlled, audited artifact.
Risksheet does not enforce any particular vocabulary or scoring formula. It provides the **grid, the formulas, the levels, the styling, and the traceability** that all of these methodologies happen to need. The specific columns ("ASIL", "Severity\_S2", "Hazard", "CVSS\_Vector") and the specific formulas (`RPN = S × O × D`, ASIL lookup tables, CVSS calculators) live in the sheet configuration.
## How Risksheet Works — The Mental Model
There are five core ideas that make Risksheet feel coherent once you see them together.
### 1. The Grid Is a View Over Polarion Work Items
Each row in a risksheet is a Polarion work item. The work item's type, fields, links, and permissions are defined in Polarion. The grid simply **renders** these as cells and lets the user edit them. When you change a cell value, Risksheet updates the work item field. When you save, Polarion writes a new revision. There is no separate store.
This is the most important architectural fact: Risksheet visualizes and edits Polarion data — it does not store data separately.
### 2. Columns Are Defined Per-Document
Each LiveDoc that uses Risksheet has its own **sheet configuration** describing which columns appear, what they bind to, how they are styled, and how they compute. The configuration covers:
* Which Polarion field each column reads (`bindings`)
* The column type (enum, rating, text, number, item link, formula)
* Headers, widths, header groups
* Default sort order and saved column visibility presets (called **views**)
* Named formulas that calculate derived values like RPN
* Named cell decorators that apply conditional CSS styling
A typical risksheet has many columns — input fields the user fills in, computed columns showing derived values, and link columns pointing to upstream requirements or downstream mitigation tasks. See [Architecture](/risksheet/concepts/architecture) for how this configuration is delivered and merged across documents and templates.
### 3. Visual Levels Group Rows by Cell Merging
In an FMEA, an "Item" can have many "Failure Modes", and each Failure Mode can have many "Causes". A naive grid would repeat the Item text on every row — visually noisy and error-prone. Risksheet uses **levels** (a configuration concept) to merge cells: when consecutive rows share the same Item value, the Item cell is merged into one tall block; when they share the same Failure Mode, that cell is merged at the next level down.
A crucial subtlety: **visual levels and data model levels are different**. The data model has exactly two slots — main row items and downstream linked items. Visual levels (1, 2, 3, …) are presentation concepts achieved through cell merging. Every row in the FMEA above can be the same Polarion work item type; the visual hierarchy comes from which column values happen to repeat. See [Data Model and Work Items](/risksheet/concepts/data-model) for the full mechanics of work item visibility and levels.
### 4. Formulas Compute Derived Values
Most risk methodologies involve computed values. A classic example is the Risk Priority Number:
> RPN = Severity × Occurrence × Detection
In Risksheet, this is a named formula in the sheet configuration. A column references the formula and Risksheet recomputes the value when any input changes. Formulas are written in JavaScript and receive the row data; they can express anything from simple multiplication to ASIL lookup tables, CVSS calculators, or qualitative classification logic.
Computed values are typically **paired with cell decorators**: small functions that apply CSS classes based on the value. Low RPN gets a green background; high RPN gets red. This produces the familiar "traffic light" risk view without manual cell coloring.
**Complex logic belongs in the top panel**
For regulated environments, the recommended pattern is to keep the sheet configuration declarative (column structure, references to named formulas) and externalize complex calculations — risk matrices, multi-field classifiers, conditional formatting helpers — into the **top panel configuration** (a Velocity template displayed above the grid). The sheet configuration then contains thin wrappers like `function(info){ return getInitialRE(info); }`. This separates auditable structure from custom logic and shrinks the validation scope when matrices change.
### 5. Traceability Is Built In
Every Risksheet row is a Polarion work item, so every Polarion link is available. Risksheet exposes this in two directions:
* **Upstream** — a column can show a linked requirement, function, hazard library entry, or any other reference work item. Typically these columns are read-only displays of properties from the linked item.
* **Downstream** — separate "task" rows below a risk represent mitigations, safety requirements, controls, or test cases. They are real Polarion work items linked via a configured link role.
The combination of declarative columns plus configured task links means each risk analysis is **automatically a traceability artifact**. There is no separate "trace matrix" step.
See [Traceability and Linking](/risksheet/concepts/traceability) for the link role configuration and the upstream library pattern.
## Common Misconceptions
Several patterns of confusion appear consistently in support discussions. Clearing them up early prevents structural mistakes.
**One document, one risksheet**
A risksheet is **the visual representation of a single Polarion LiveDoc**. It cannot aggregate work items from multiple documents or route items between documents based on naming conventions. If you need a combined view across several analyses, that is a Polarion-level concern (a wiki page, a saved query, or a separate "summary" document). It is not something Risksheet does.
**Risksheet vs Powersheet**
Risksheet and Nextedy POWERSHEET are different products with different goals. Risksheet is the **risk analysis grid** with levels, formulas, ratings, and the risk/task two-entity model. Powersheet is a more general-purpose work item table tool. If a customer needs FMEA, HARA, TARA, or any structured risk methodology with hierarchical levels and traceability to mitigations, Risksheet is the right product. New users often confuse the two.
**Approval review does not advance Polarion workflow state**
Risksheet supports three review modes — comment-based, work-item-based, and approval review. The approval review creates approval-tagged comments but does NOT trigger Polarion's formal approval state transitions (draft → reviewed → approved). If you need formal document workflow signoff, configure the Polarion document workflow separately. The approval review captures reviewer intent; the workflow state must be advanced through Polarion's document workflow.
**No ratings, enums, or relations top-level config sections**
Some older guides describe top-level `ratings`, `enums`, or `relations` sections in the sheet configuration. These do not exist. Rating scales and enumerations are defined in Polarion (Administration → Enumerations) and referenced from columns via `type: rating:`, `type: enum:`, or `type: multiEnum:`. Dependent enumerations are a column-level feature, not a separate section. If you see those sections in a config, they are ignored by the engine.
## How Configuration Reaches a Document
Each LiveDoc loads a sheet configuration. The configuration can come directly from the document, or it can be inherited from a global template attached to the document. Template inheritance is what makes solution templates effective: an administrator maintains the canonical FMEA template centrally, and every new FMEA document picks up its columns, levels, formulas, and styles automatically.
For deeper detail on where configuration files live, how template inheritance works, and how the three configuration files relate to each other (sheet configuration, top panel, PDF export), see:
* [Architecture](/risksheet/concepts/architecture)
* [Configuration Hierarchy](/risksheet/concepts/configuration-hierarchy)
## Where Risksheet Fits in the Polarion Picture
| You can use Polarion for… | Risksheet adds… |
| ---------------------------------------------- | ----------------------------------------------------------------------------- |
| Storing requirements, tests, design work items | A grid-shaped editing surface for structured analyses |
| Linking work items across artifacts | Configured upstream and downstream link columns within the grid |
| Workflow on documents | Risksheet-internal review modes plus standard document workflow |
| Exporting LiveDoc documents to PDF | Custom PDF export configuration tuned to risk-table layouts |
| Querying work items with Lucene | Saved views (column visibility presets) and queryFactory-backed autocompletes |
Risksheet does not replace any of Polarion's core capabilities — it gives risk-analysis-style work the editing surface that pure work item editing lacks, while keeping the data inside Polarion.
## Choosing the Right Risksheet Workflow
| If your goal is… | Start here |
| -------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| Build a working FMEA / HARA / TARA from a template | [Risk Management Guides](/risksheet/guides/risk-management/index) |
| Understand columns, levels, and formulas before editing config | [Configuration Hierarchy](/risksheet/concepts/configuration-hierarchy) and [Data Model and Work Items](/risksheet/concepts/data-model) |
| Configure upstream and downstream traceability | [Traceability and Linking](/risksheet/concepts/traceability) |
| Set up review and approval | [Review Workflows](/risksheet/concepts/review-workflows) |
| Look up exact column properties and formula syntax | [Reference](/risksheet/reference/index) |
| Find the JSON shape of a specific feature | [Configuration Reference](/risksheet/reference/configuration/index) and [Configuration Examples](/risksheet/reference/examples/index) |
| Export to PDF or Excel | [Export Guides](/risksheet/guides/export/index) |
| Diagnose a problem with your risksheet | [Troubleshooting](/risksheet/troubleshooting/index) |
## Summary
Risksheet is best understood as **the spreadsheet experience for Polarion-tracked structured analyses** — methodology-agnostic, configuration-driven, traceability-native, and grounded in real Polarion work items. Methodology (FMEA, HARA, TARA, STRIDE, CVSS, requirements traceability, V\&V matrices) is a function of configuration, not a property of the tool. Solution templates ship the typical configurations so you can start from a known-good baseline and tailor it to your process rather than starting from scratch.
What is constant across every Risksheet deployment is the foundation:
* **One LiveDoc, one risksheet, one configuration**
* **All data lives in Polarion work items** with full permissions, history, and audit
* **The grid is a view**, not a separate database
* **Columns, formulas, levels, and decorators are declarative** in the sheet configuration
* **Traceability is intrinsic** — upstream and downstream links are columns, not afterthoughts
* **Methodology is configurable** — the same engine produces FMEA, HARA, TARA, CVSS, or a generic traceability matrix depending on how it is set up
To go deeper into how the pieces fit together architecturally, continue to [Architecture](/risksheet/concepts/architecture). To start using Risksheet on a real document, see [Getting Started](/risksheet/getting-started/index).
# Working Sessions
Source: https://learn.nextedy.com/risksheet/concepts/working-sessions
A working session is the period between opening a Nextedy RISKSHEET grid in your browser and the next save or reload.
This page explains how Risksheet handles long-running analysis work, how save and refresh interact with the underlying Polarion data, why concurrent editing requires explicit coordination, and how project-level configuration is separated from each user's personal preferences.
## Sessions vs. Polarion Data
Risksheet is a grid that visualizes and edits data living in Siemens Polarion ALM. There is no separate Risksheet database — every risk item, severity rating, mitigation link, and Risk Priority Number (RPN) value is stored as a standard Polarion work item with custom fields. A working session is simply the browser's view of those work items at a point in time, plus any unsaved edits you have made since the grid was loaded.
## Staged Work Across Multiple Days
Failure Mode and Effects Analysis (FMEA), Hazard Analysis and Risk Assessment (HARA), and Threat Analysis and Risk Assessment (TARA) analyses rarely complete in one sitting. A typical risk specification document evolves over weeks: identifying failure modes one day, classifying severity and occurrence in a workshop later, then revisiting mitigations after a design review. Each return to the document is a **new working session** — the grid loads the current state of every risk item from Polarion, including changes made by other team members in between.
A few properties of this model matter in practice:
* Closing the browser tab or navigating away discards any unsaved edits. Sessions are not preserved across browser restarts.
* Reopening the document later starts fresh against the latest Polarion data — your previous session's saved changes are visible, and so are changes made by others since.
* Long-running analyses naturally split into many short sessions, each ending with a **Save**. There is no "session resume" feature beyond Polarion's normal versioning of work items.
**Save before you step away**
Treat **Save** as a checkpoint. If a meeting interrupts you, save first — even partially completed edits — rather than leaving the tab open with unsaved work for hours. This protects you from accidental tab closures and frees the work for review by colleagues.
## Save and Refresh — No Live Propagation
Edits you make to cells (severity ratings, mitigation text, link selections) accumulate in your browser. They are not pushed to Polarion until you press **Save**. Likewise, edits another user saves to the same document are not pushed to your browser — you only see them when the grid reloads.
This means two different but related things happen at save time:
| Action | What it does |
| ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Save** | Sends your accumulated edits to Polarion as a batch. After a successful save, your browser displays values consistent with what was just written. |
| **Refresh on save** | Optionally re-fetches the document from Polarion immediately after saving so your view also reflects changes made by other users since you opened the grid. Controlled by the `refreshOnSave` setting in the `global` section of the sheet configuration. |
| **Manual reload** | Pressing your browser's reload (or navigating back to the document) discards unsaved edits and shows the current server state. Use this when you want to see other users' latest saved changes. |
The key point: there is no real-time channel between Risksheet sessions. Risksheet does not push updates to your grid while you are working. You only see other users' work after a save-with-refresh or a manual reload.
**Stale views are easy to miss**
If you keep a Risksheet tab open for hours and another analyst saves changes during that time, your grid will still show the data from when you first opened it. Saving from a stale view can overwrite recent work. When in doubt, reload before making significant edits.
### Refresh on Save and Scroll Position
By default, Risksheet refreshes the grid after each save operation. For large risk tables with hundreds of rows, this refresh scrolls the view back to the top, making it difficult to locate the row you were editing.
The `refreshOnSave` configuration property controls this behavior. When set to `false`, the grid preserves your scroll position and focus after saving, keeping you on the last edited cell. The trade-off is that your view will no longer automatically pick up changes saved by other users — you must trigger a manual reload to see them.
**Large Sheets**
For risk tables with more than 50-100 rows, setting `refreshOnSave` to `false` significantly improves the editing experience by eliminating the scroll-to-top behavior after each save.
## Concurrent Editing — Per-Session Isolation
Polarion's optimistic concurrency model applies to Risksheet edits, but Risksheet itself does not coordinate sessions in real time:
While two analysts have the same document open, each sees only what was on the server when they loaded the grid plus their own local edits. Risksheet does not show that someone else is editing, and it does not lock rows. The first save is committed normally; a second save against the same work items succeeds as long as the underlying Polarion fields have not been changed by the first save in conflicting ways. If they have, Polarion may reject the save and you must reload to see the current state and re-apply your changes.
**Avoid editing the same rows simultaneously**
Because there is no real-time conflict indicator, two analysts editing the same risk item at the same time can silently overwrite each other on save. Coordinate by row range (for example, by failure-mode chapter) or by Risksheet view, and reload before saving if you suspect someone else has been active.
## Project Configuration vs. Personal Preferences
A working session draws on two independent layers of configuration. They have very different scopes and lifecycles:
| Layer | Scope | Examples | Where stored |
| ------------------------ | ----------------------------------------- | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| **Sheet configuration** | The document (shared by all users) | Columns, levels, formulas, cell decorators, styles, saved views, review setup | Sheet configuration attached to the Polarion document (editable through the YAML editor since v25.5.0) |
| **Personal preferences** | Your user account on this machine/browser | Currently selected saved view, column widths you have adjusted, expanded/collapsed groups, sort order | Per user, per browser — kept across sessions for the same user |
The sheet configuration is administered by document owners or template authors. Changing it affects every analyst working on the document. Personal preferences are yours alone — choosing a different saved view (for example, switching from **Initial Risk Ranking** to **Final Risk Assessment**) does not change what your colleagues see.
Because saved views are part of the shared sheet configuration but the *current selection* is personal, several users can work on the same document at the same time, each looking through a different view that highlights the columns relevant to their stage of the analysis.
**Verify in application**
The exact set of personal preferences persisted between sessions depends on your Risksheet version and Polarion configuration. If a preference you expect to remember (such as a custom column width) is reset between sessions, confirm with your administrator that user-preference persistence is enabled in your deployment.
## Practical Recommendations
A few habits make working across many sessions reliable:
1. **Save before context switches.** Save before lunch, before joining a meeting, and before leaving for the day. Treat saves as commit points in your analysis.
2. **Reload before bulk edits.** If you have had the tab open for more than an hour, reload before changing many cells. This pulls in any work your colleagues saved in the meantime.
3. **Coordinate by chapter or level.** For multi-analyst sessions (for example, a HARA workshop), agree in advance who edits which Level 1 group. This avoids silent overwrites.
4. **Use saved views to focus.** Switch to a stage-specific saved view (such as **Identify Failure Modes** or **Mitigations**) to reduce visible columns and minimize accidental edits to columns owned by other reviewers.
5. **Use the configuration editor for shared changes.** Modifying the sheet configuration changes the document for everyone — do not edit it during another analyst's active session unless you have agreed on the change.
6. **Treat the document, not the session, as the unit of work.** Long analyses are a sequence of many short, saved sessions against the same Polarion document, not one long interactive session.
## Verification
You should now see:
* Each time you open a Risksheet document, a new session begins with a fresh load from Polarion.
* Edits stay in your browser until you press **Save**; other users only see them after they reload.
* Long analyses naturally span many sessions across days or weeks; the document is the unit of continuity, not the session.
* Saved views and the sheet configuration are shared by everyone working on the document; your selected view, column widths, and expand/collapse state are personal to your user.
## See also
* [Data Synchronization](/risksheet/concepts/data-synchronization)
* [Review Workflows](/risksheet/concepts/review-workflows)
* [Configuration Hierarchy](/risksheet/concepts/configuration-hierarchy)
* [User Roles and Permissions](/risksheet/concepts/user-roles)
# Frequently Asked Questions
Source: https://learn.nextedy.com/risksheet/faq/index
Find answers to common questions about Nextedy RISKSHEET. This section organizes questions by topic so you can quickly locate information about product capabilities, configuration, licensing, and troubleshooting.
Risksheet is a risk analysis app for Siemens Polarion ALM that provides an interactive Excel-like grid for structured risk assessment. It supports FMEA, HARA, TARA, STRIDE, and CVSS risk analysis workflows directly within Polarion LiveDoc documents, with full traceability to requirements and design elements.
Risksheet supports multiple risk analysis frameworks: FMEA (Failure Mode and Effects Analysis), HARA (Hazard Analysis and Risk Assessment), TARA (Threat Analysis and Risk Assessment), STRIDE (cybersecurity threat analysis), and CVSS scoring (v3.1/v4.0). You configure the tool to match any of these methodologies through the sheet configuration.
Risksheet supports workflows aligned with the following standards:
| Standard | Domain |
| ------------------------ | --------------------- |
| ISO 26262 | Automotive safety |
| ISO 14971 | Medical devices |
| IEC 61508 | Industrial safety |
| ISO/SAE 21434 | Cybersecurity |
| IEC 62443 | Industrial security |
| AIAG & VDA FMEA Handbook | Automotive FMEA |
| CVSS v3.1/v4.0 | Vulnerability scoring |
All risk data is stored as standard Polarion work items with custom fields. This means your risk data benefits from Polarion's built-in version control, baseline management, and traceability features. Configuration is stored in a sheet configuration file attached to each LiveDoc document, with optional template inheritance for consistency across projects.
Yes. Risksheet does not require specific work item types or mandatory fields. You configure the risk and task types through the `dataTypes` section of sheet configuration, specifying your custom work item type IDs. See [Configuration Questions](/risksheet/faq/configuration) for more details.
No. Risksheet is deployed as a Polarion server plugin. It uses Polarion's existing data storage and runs within the Polarion server environment. The client-side grid renders within LiveDoc pages in the browser, requiring no additional infrastructure.
Yes. You can create multiple Risksheet documents within a single Polarion project, each with its own sheet configuration. This allows different risk analysis types (for example, FMEA and HARA) to coexist in the same project with independent column layouts, severity scales, and review workflows.
Risksheet supports export to Excel (.xlsx) and PDF formats with formatted risk tables. You can use saved views to control which columns appear in exports. See [Feature Questions](/risksheet/faq/features) for details on export capabilities.
**Verify in application**
This page provides general orientation based on the product brief. For specific configuration details and property references, refer to the [Reference](/risksheet/reference/index) section.
## See Also
* [Feature Questions](/risksheet/faq/features) -- specific capability details
* [Configuration Questions](/risksheet/faq/configuration) -- setup and customization
* [Getting Started](/risksheet/getting-started/index) -- initial setup tutorials
**Feature Status**
This page documents both currently supported features and known limitations. Feature availability may change with new releases. Check your installed version's release notes for the latest status.
***
## Column and Data Entry
Dependent enums — where the available options in one dropdown column are filtered based on the selection in a parent column — are supported as a column-level feature in recent releases (v25.3.1+). They are configured directly on the dependent enum column (typically through a `queryFactory` or column-level dependency declaration), not as a top-level configuration section. The available options in the child column are filtered at runtime based on the value selected in the parent enum column.
Note that severity, occurrence, and detection scales use integer IDs (for example, 1 through 10 for an FMEA severity scale), unlike regular Polarion enumerations which use string IDs. This distinction is important when configuring risk parameter columns: define the scale as a Polarion enumeration with integer IDs and bind a custom field on the work item type to it, then reference it from the column with `type: rating:` and `bindings: `.
**Verify in application**
Cascading dropdown behaviour depends on the installed Risksheet version. Check your current release notes for the exact column-level syntax supported in your build.
No. Drag and drop is not supported for inserting existing work items into the Risksheet grid. To link existing Polarion work items, use the item link column editor which provides autocomplete-based search. Type at least 3 characters to trigger a search that matches work items by ID and type. The editor also prevents duplicate selections — if you attempt to link an item that is already present, you receive a notification.
For multi-item link columns, the same autocomplete behavior applies, with additional support for selecting multiple items in a single cell.
No. Risksheet intentionally does not enforce Polarion mandatory fields during item creation. This is a deliberate design decision to simplify data entry — the assumption is that mandatory fields are enforced at later workflow statuses via Polarion's built-in workflow validation rules, not at the point of initial data entry.
To visually indicate which fields are required, use `cellDecorators` and `styles` in the sheet configuration to highlight mandatory column backgrounds with conditional formatting:
```yaml theme={null}
cellDecorators:
requiredHighlight: |
function(info){
if(!info.value){
$(info.cell).addClass('required-empty');
}
}
styles:
.required-empty: "background-color: #fff3e0 !important; border-left: 3px solid #e65100 !important;"
```
**Visual Highlighting for Required Fields**
Use conditional formatting via `cellDecorators` to apply a colored background or left border to mandatory columns when they are empty. This gives users a visual cue about required data without blocking their data entry workflow. See [Apply Conditional Formatting](/risksheet/guides/styling/conditional-formatting) for detailed setup instructions.
No. The first "Item Id" column in the Risksheet grid cannot be renamed. This is a known limitation of the column configuration system. The `systemItemId` binding is a reserved system column that always displays as "Item Id" in the grid header.
***
## Risk Analysis Workflows
Yes. Risksheet is a generic risk analysis tool and can be configured for Safety FMEA (SFMEA), Design FMEA (DFMEA), Process FMEA (PFMEA), and other FMEA variants. The column layout, risk parameters, and hierarchy levels are fully configurable through the sheet configuration. Each FMEA type uses the same underlying structure but with different column `bindings`, severity/occurrence/detection scales, and formula definitions appropriate to the analysis type.
You can maintain multiple Risksheet configurations within a single Polarion project — each LiveDoc document can have its own sheet configuration with an independent column layout and risk parameter setup. Rather than starting from a blank configuration, pick the closest Nextedy solution template for your industry and methodology and modify it to match your process. See [Configure FMEA Workflows](/risksheet/guides/risk-management/fmea-configuration) for setup details.
Yes. Risksheet is methodology-agnostic and supports any risk analysis approach, including Failure Mode and Effects Analysis (FMEA), Hazard Analysis and Risk Assessment (HARA), Threat Analysis and Risk Assessment (TARA), STRIDE, and Common Vulnerability Scoring System (CVSS). Because Risksheet has no mandatory fields or hard-coded work item types, you can configure custom column layouts, threat categories, and severity scales that align with the STRIDE methodology (Spoofing, Tampering, Repudiation, Information Disclosure, Denial of Service, Elevation of Privilege). Start from the closest solution template and adapt the columns and scales to STRIDE. See [Implement STRIDE Analysis](/risksheet/guides/risk-management/stride-analysis) for configuration guidance.
Yes. Multiple Risksheet configurations per project are fully supported. Each Polarion LiveDoc document that contains a Risksheet has its own sheet configuration attached as a document attachment. This means you can have separate FMEA, HARA, and TARA analyses in the same project, each with completely independent column layouts, risk parameters, and styling.
Additionally, you can use template-based configuration inheritance where a global template provides shared settings and each document overrides only the properties that differ. See [Set Up Global Templates](/risksheet/guides/configuration/global-templates) for details.
***
## Document and Integration Scope
Yes. Risksheet is designed as a visual representation of a single Polarion LiveDoc document. It cannot aggregate or route work items from multiple documents based on naming patterns or other criteria. Each Risksheet instance corresponds to one document. All risk items are stored as standard Polarion work items belonging to that document — Risksheet visualises and edits Polarion data, it does not maintain a separate data store.
However, you can create multiple Risksheet documents per project with independent configurations, and use cross-project linking to reference items across documents and projects. The `createInCurrentDocument` parameter controls whether newly created items are stored in the current document.
Collection awareness — filtering work items by collection membership and displaying correct revisions — is not currently available in Risksheet. This is a recognized feature request from enterprise customers who use Polarion collections for release management. The feature is under consideration and may appear in a future release.
**Verify in application**
Collection support is being prioritized. Check the latest release notes for current status. As a workaround, use document-level filtering to restrict the scope of displayed work items.
Electronic signatures are not supported directly in Risksheet because the Polarion API does not expose electronic signature capabilities for programmatic access. If your regulatory process requires signatures when rejecting items, the recommended workaround is to split the action into two steps:
1. **In Risksheet**: Execute the rejection workflow action (without signature)
2. **In Polarion**: Execute a separate workflow action that requires the electronic signature
This separation ensures the signature requirement is met through Polarion's native signature mechanism while allowing the initial rejection to be performed efficiently within the Risksheet grid.
***
## Approval and Review Workflows
Review columns are available for three review modes via the `reviews` section of the sheet configuration: comment-based reviews, work-item-based reviews, and approval reviews. You can set `reviews.reviewManager` to `"CommentBased"` for comment-based reviews, or configure the approval review variant to capture approver decisions inline in the grid.
**Approval review limitation**
Risksheet approval review creates approval-tagged comments on the reviewed work items but does **not** trigger Polarion's formal approval workflow (draft → reviewed → approved). Status transitions still have to be performed through Polarion's own workflow actions. For full approval workflows that require status transitions, navigate to the individual work item or use the Polarion document view. Workflow approval actions executed from within the Risksheet grid are planned for a future release.
See [Set Up Review Process](/risksheet/guides/reviews/setup-review-process) for current review capabilities and configuration details.
Risksheet supports **freeze columns** (keeping left-side columns visible during horizontal scrolling) but does not currently support **freeze rows** (pinning specific rows at the top during vertical scrolling). Column freezing is available through the right-click context menu or sheet configuration. Freeze rows is a recognized feature request and may be implemented in a future release.
For freeze column configuration, see [Configure Freeze Panes](/risksheet/guides/visualization/freeze-panes).
***
## Feature Availability Summary
| Feature | Status | Notes |
| ----------------------------------------- | -------------------------- | ------------------------------------------------------------------------- |
| Dependent enums (cascading dropdowns) | ✅ Supported (column-level) | Configured per column in recent versions; not a top-level config section |
| Drag and drop | ❌ Not supported | Use autocomplete link editor instead |
| Mandatory field enforcement | ❌ Not enforced (by design) | Use `cellDecorators` for visual highlighting |
| Item Id column rename | ❌ Not supported | `systemItemId` is a reserved system column |
| Electronic signatures | ❌ Not supported | Polarion API limitation; use split workflow |
| Multi-document aggregation | ❌ Not supported | One document per Risksheet instance |
| Collection awareness | Planned | High-priority feature request |
| Full Polarion approval workflow from grid | Planned | Approval review tags comments only; status transitions happen in Polarion |
| Freeze rows | Planned | Freeze columns currently supported |
| Freeze columns | ✅ Supported | Via context menu or configuration |
| Review columns | ✅ Supported | Comment-based, work-item-based, and approval-based |
| SFMEA/DFMEA/PFMEA | ✅ Supported | Fully configurable per FMEA type |
| STRIDE, HARA, TARA, CVSS | ✅ Supported | Risksheet is methodology-agnostic |
| Multiple configs per project | ✅ Supported | Each document has its own sheet configuration |
| `createInCurrentDocument` | ✅ Supported | Controls where new items are stored |
## See Also
* [Configuration Questions](/risksheet/faq/configuration) -- setting up columns and properties
* [General Questions](/risksheet/faq/general) -- product overview and methodology support
* [Licensing Model](/risksheet/faq/licensing-model) -- license types and entitlements
Risksheet includes two default project templates that can be installed via **Administration > Nextedy Risksheet > Setup**: a standard `risksheet_template` for general FMEA risk analysis and a `risksheet_templateHara` for HARA workflows. These templates provide starting configurations with pre-built columns, formulas, and risk scales. However, most organizations customize the configuration to match their specific work item types, custom fields, and risk methodologies. Risksheet does not require specific work item types or mandatory Polarion fields -- it adapts to your existing Polarion setup through the sheet configuration.
The configuration is stored in a file named `risksheet.json` attached to each Polarion LiveDoc document. If a document does not have its own sheet configuration, it inherits the configuration from its Polarion document template hierarchy. You can also define global templates that multiple documents inherit from. The sheet configuration file contains the complete configuration including `columns`, `dataTypes`, `levels`, `formulas`, `styles`, `cellDecorators`, `views`, `global`, `reviews`, and `sortBy`. Rating and enumerated values are not stored as top-level sections in the file -- they are defined as Polarion enumerations and referenced from columns (for example via `type: rating:`). You can edit it using the built-in configuration editor (accessible to users with `canAdmin` privileges) or by modifying the JSON attachment directly.
For more details, see [Configuration Questions](/risksheet/faq/configuration) and the [Getting Started](/risksheet/getting-started/basic-configuration) tutorial.
Risksheet supports multiple configurations per project. Each Risksheet document has its own sheet configuration, so you can create separate documents for each risk analysis type (e.g., one for FMEA, one for HARA, and one for STRIDE) and configure each independently. The `dataTypes` section determines which Polarion work item types appear as risk items and mitigation tasks:
```yaml theme={null}
dataTypes:
risk:
type: fmea_risk
role: has_cause
task:
type: mitigation_action
role: mitigates
showInMenu: true
```
The template path configuration supports multiple paths separated by commas (default: `Risks/Risk Specification`), allowing you to organize different risk document types in different folders within your project.
No. Risksheet does not mandate specific Polarion work item types or custom fields. You configure which work item types to use through the `dataTypes.risk.type` and `dataTypes.task.type` properties in sheet configuration. Columns are bound to any Polarion field using the `bindings` property. The system supports all standard Polarion field types: text, integer, float, date, datetime, time, boolean, enum, multiEnum, duration, currency, rating, and user references. Custom fields are accessed the same way as built-in fields.
**Custom work item types are fully supported**
You can use any custom work item type as your risk or task type. Configure color coding via `cellDecorators`, merged cells via `levels` configuration, and risk scales via Polarion enumerations referenced from columns with `type: rating:` -- all without requiring predefined Polarion fields.
Use project-level properties in Polarion administration to rebrand Risksheet for your organization:
| Property | Default | Description |
| ------------------------ | --------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| Tool name | `Risksheet` | Display name in the Polarion navigation UI. Change to match your methodology (e.g., "FMEA Tool", "Risk Matrix", "Safety Analysis"). |
| Document name (singular) | `Risk Analysis` | Singular form used in document creation dialogs and labels |
| Document name (plural) | `Risk Analyses` | Plural form used in document list headers and navigation |
These properties are set at the project level and affect all Risksheet documents within that project.
The item suggester provides autocomplete when linking work items in item link and multi-item link columns. Several project-level properties control its behavior:
| Setting | Default | Purpose |
| ----------------- | ------- | --------------------------------------------------------------------------------------------------------- |
| Fuzzy search | `true` | Allows approximate matches to help find items with slight spelling variations or typos |
| Wildcard search | `true` | Supports `*` and `?` wildcard patterns in search queries |
| Keyword mandatory | `false` | When `true`, requires keyword input before searching; when `false`, all matching items are shown |
| Result limit | `20` | Maximum number of suggestions displayed. Higher values may impact performance. |
| All-field search | `false` | When `true`, searches all fields of linked items rather than just primary fields. May impact performance. |
You must type at least **3 characters** to trigger the autocomplete search. Shorter input produces no results by design. Duplicate items cannot be selected -- the system prevents adding an item that is already linked and shows a notification if you attempt to add a duplicate. You can further customize suggestions using `queryFactory` functions on individual columns or data types.
Use the `createInCurrentDocument` parameter to store newly created upstream items within the same LiveDoc document rather than in a separate location. This is configured in the `dataTypes` section of sheet configuration and reduces context switching when building traceability chains.
**Verify in application**
The exact parameter name and behavior should be verified against your Risksheet version's configuration reference, as this feature may have additional options or constraints.
Yes. Risksheet supports Polarion branched documents. Enable branching support by setting the project property:
```
nextedy.risksheet.branchingSupport = true
```
**Case-sensitive property name**
The property name uses a **lowercase** `n` in `nextedy`. This is case-sensitive -- using an uppercase `N` (e.g., `Nextedy.risksheet.branchingSupport`) will not enable branching support. Double-check the exact casing in your project properties configuration.
Yes. By default, changes made through Risksheet trigger Polarion's automatic suspect link marking on traceability relationships. To disable this behavior, set the auto-suspect disabling property to `true` in project administration. When enabled, edits made in Risksheet will not flag upstream or downstream linked items as suspect. This may be desirable in workflows where Risksheet edits are considered routine updates that should not require re-verification of linked items.
Yes. Item protection for approved or verified work items is supported through a combination of Polarion permission management and Risksheet configuration properties. Certain system fields (`id`, `status`, `type`, `project`, `outlineNumber`, `author`, `resolution`, `created`, `updated`) are always read-only in Risksheet. Additionally, any column can be marked as `readOnly` in the column configuration, and the entire grid can be set to read-only using the top-level `readonly` property.
**Verify in application**
The specific configuration for protecting items based on workflow status (e.g., approved, verified) should be verified against your Risksheet version's permission management documentation.
Catalogs used with Risksheet must be work item collections, not plain text in documents. Risksheet operates on Polarion work items, so any catalog data must be stored as work items that can be queried and linked through the standard Polarion data model.
## See Also
* [General Questions](/risksheet/faq/general) -- overview and general product questions
* [Feature Questions](/risksheet/faq/features) -- capability details and limitations
* [Licensing Model](/risksheet/faq/licensing-model) -- license types and user management
* [Getting Started](/risksheet/getting-started/basic-configuration) -- initial configuration tutorial
* [Performance Troubleshooting](/risksheet/troubleshooting/performance-slow-loading) -- optimization and performance
**Key principle**
Risksheet does not have its own data store. Every cell you see in the grid is a Polarion work item field. All integration points use Polarion's own infrastructure, which means authorization, audit, and traceability are inherited automatically.
Risksheet is a Polarion server app that renders an interactive grid inside Polarion LiveDoc documents. Each row in a risksheet is a standard Polarion work item, and each column maps to a field on that work item via the `bindings` property. Because the data lives in Polarion, you can mix risksheet pages with normal LiveDoc content in the same document and reuse Polarion features such as workflows, baselines, and reports.
See [Concepts](/risksheet/concepts/index) for the architectural overview and [Reference](/risksheet/reference/index) for the configuration details.
Risksheet uses Polarion's standard link roles to connect risk items to upstream requirements and downstream mitigation tasks. You configure upstream traceability in the sheet configuration so that linked requirements appear as columns in the grid, and the same mechanism feeds downstream traceability for tasks and verification items. Because links are normal Polarion links, they are visible in Polarion's traceability matrices and impact analysis views.
See [Integration](/risksheet/guides/integration/index) for step-by-step configuration and [Configuration Examples](/risksheet/reference/examples/index) for upstream and downstream snippets.
Yes. Risksheet supports export of the grid to Excel and PDF using the export configuration, and the exported tables preserve formatting such as severity colors and merged cells where applicable. There is no direct round-trip import — Polarion remains the system of record — but you can use Polarion's standard Excel round-trip on the underlying work items if your process requires it. See [Export](/risksheet/guides/export/index) for the supported export options.
Severity, occurrence, detection, ASIL levels, and similar pick-lists are defined as standard Polarion enumerations under **Administration > Enumerations**. A custom field on the relevant work item type binds to the enum, and the column in the risksheet uses `type: rating:` or `type: enum:` with `bindings: ` to reference it. The server loads enum values automatically, so the grid stays in sync with whatever the Polarion administrator configures.
**Where to define scales**
The severity/occurrence/detection scales are not defined inside the sheet configuration. Define them as Polarion enumerations and reference them by id from the column — that way the same scales are reusable across documents and reports.
Yes, through Polarion's standard configuration inheritance and template documents. A LiveDoc template can carry a sheet configuration, and documents created from that template inherit and can extend it. For cross-project sharing, place the template in a shared project or use Polarion's global configuration mechanisms. See [Templates](/risksheet/reference/templates/index) and [Configuration Management](/risksheet/guides/configuration/index) for the recommended patterns.
Risksheet provides a server-side API surface that can be used from Velocity scripts and Polarion's existing extension points to render content, compute values, or assemble reports. For most automation needs — bulk updates, reporting, or integrations with external systems — the recommended approach is to use Polarion's REST or SOAP APIs against the underlying work items, since that is where the data actually lives. See [API](/risksheet/reference/api/index) for the available Velocity context entries.
Because every risk item is a Polarion work item, you can build Polarion LiveReport widgets and queries against the same data the grid displays. Typical patterns include displaying top-RPN risks, counting open mitigation tasks, or charting risk distribution by severity. There is no special Risksheet widget — use the standard LiveReport widgets with Lucene queries against the work item type used for risk items.
Yes. Risksheet supports cross-project linking through Polarion's normal cross-project link roles, which makes it possible to share generic failure modes, threat libraries, or component-level risks across multiple project risksheets. The column definition simply needs to allow the appropriate work item types and projects through its picker configuration. See the [Integration](/risksheet/guides/integration/index) guide for examples.
Risksheet provides three review styles: comment-based review, work-item-based review, and approval review. The approval review records approval-tagged comments on the relevant work items, which is useful for audit evidence and ISO 26262 / ISO 14971 review records.
**Approval review limitation**
Risksheet's approval review does NOT trigger Polarion's formal approval state transitions (draft → reviewed → approved). If your process requires a state transition, drive it from a Polarion workflow action on the work item or document rather than from the risksheet approval review alone.
See [Review Management](/risksheet/guides/reviews/index) for the recommended setup.
Risksheet is a generic tool that supports any risk management methodology, including FMEA, HARA, TARA, STRIDE, and CVSS. Nextedy provides solution templates for typical methodologies across automotive (ISO 26262), medical devices (ISO 14971), industrial (IEC 61508), and cybersecurity (ISO/SAE 21434, IEC 62443) industries. Pick the closest solution template for your industry, understand its configuration, then modify it to match your process — never start from a blank configuration.
| Methodology | Typical scales | Common standards |
| ----------- | ------------------------------------------ | --------------------- |
| FMEA | severity, occurrence, detection (RPN) | AIAG & VDA, ISO 14971 |
| HARA | severity, exposure, controllability (ASIL) | ISO 26262 |
| TARA | impact, attack feasibility | ISO/SAE 21434 |
| CVSS | base, temporal, environmental | CVSS v3.1 / v4.0 |
| STRIDE | threat category, impact | Microsoft SDL |
Start with the [Integration](/risksheet/guides/integration/index) guide for end-to-end setup, then consult [Configuration Examples](/risksheet/reference/examples/index) for ready-to-adapt sheet configurations. For questions about feature scope see [Feature Questions](/risksheet/faq/features), and for environment/version questions see [Compatibility](/risksheet/reference/compatibility/index). If something behaves unexpectedly, check [Common Troubleshooting](/risksheet/faq/troubleshooting-faq) first.
**Quick rule of thumb**
Load time is driven far more by the **number of linked-item columns** (especially `multiItemLink`) than by the number of rows. If a sheet feels slow, look at column count and broken cross-project links **before** worrying about row count.
## Performance Profile at a Glance
The diagram below shows the main factors that drive risksheet load time, in rough order of impact. Use it to decide where to focus when investigating a slow sheet.
## Load Time and Sizing
Multi-minute load times are almost always caused by one of two issues: **unresolvable linked work items** (broken cross-project references) or **too many item-link columns** in a single sheet. Both make the server do disproportionate work for every row when building the grid. Check the Polarion server log first for stack traces around the time of a slow load; if you see exceptions related to resolving linked items, that is your root cause. See [Common Troubleshooting](/risksheet/faq/troubleshooting-faq) for diagnostic steps.
Column count, specifically item-link and `multiItemLink` columns, has a much larger impact than row count. A sheet with 250 rows and 17 linked-item columns (7 of them `multiItemLink`) can be noticeably slower than a sheet with several times more rows and fewer link columns. Each linked-item column triggers additional work item lookups per row, and that cost compounds.
There is no hard limit, but performance scales much better when you keep sheets focused. Sheets in the low hundreds of rows generally load quickly when columns are well chosen. If you find yourself well above that and the sheet is also column-heavy, splitting by methodology or scope is usually a bigger win than trying to optimize row count.
## Sheet Design for Performance
It can be. Combining multiple Failure Mode and Effects Analysis (FMEA) variants — for example usability FMEA and design FMEA — in a single sheet tends to push the column count high, because each variant adds its own columns and links. The recommended optimization is to **split one large sheet into dedicated sheets per FMEA type**. Each sheet ends up smaller, faster, and easier to review. See [Risk Management](/risksheet/guides/risk-management/index) for guidance on structuring methodology-specific sheets.
There is no fixed threshold, but if a sheet has many item-link columns and several `multiItemLink` columns, expect load time to grow noticeably. Treat each `multiItemLink` column as a significant cost, and ask whether the relationship truly needs to be visible in this sheet or whether it can live on an upstream document. See [Column Configuration](/risksheet/guides/columns/index) for column-design patterns.
Sometimes, yes. A saved view limits which columns are displayed for a given workflow stage, which can reduce client-side rendering work. However, saved views do not reduce the underlying data the server must assemble — if the slowness comes from resolving links, switching views will not help. Use views for workflow staging; use sheet splitting for true performance relief. See [Reference: Configuration Examples](/risksheet/reference/examples/index).
## Concurrency and Multi-User Use
A risksheet is editable by multiple users at the same time, but each open instance pulls its own data from Polarion. With heavy sheets (high column count, many linked items), concurrent users compound the load on the Polarion server. If you see slowdowns only when several users are active, the bottleneck is more likely on the Polarion server side than in Risksheet itself.
**All data lives in Polarion**
Risksheet does not maintain a separate data store. Every read and write is against Polarion work items, subject to Polarion authorization. That means Polarion server health, indexing state, and authorization checks all directly affect risksheet load time.
## Diagnosing Slowness
Start with the Polarion server log. If you see exceptions related to unresolvable work item references occurring during grid load, the cause is broken cross-project links rather than the sheet itself. If you see general Polarion slowness — database reindexing in progress, long-running queries on unrelated documents, high CPU — then Risksheet is downstream of a server issue and tuning the sheet will not help. See [Common Troubleshooting](/risksheet/faq/troubleshooting-faq).
Yes. Historical database reindexing and similar Polarion server maintenance operations can make every work item read slower, which Risksheet feels acutely because it reads many work items per page load. In documented cases, what looked like a Risksheet performance problem turned out to be a Polarion server misconfiguration. Always check whether scheduled maintenance is running before drilling into sheet configuration.
Find them and fix them. Unresolvable linked work items — items that no longer exist or are inaccessible to the current user — cause expensive exceptions every time the grid tries to assemble that row, and the cost can dominate page load. Review item-link columns for stale references, clean up links to removed work items, and verify cross-project access for users who report slowness.
**Broken links are a silent multiplier**
A single unresolvable reference may not be noticeable, but dozens across many rows can turn a sub-second page load into a multi-minute wait. Sweep stale links periodically, especially after project moves or work item deletions.
## Optimization Checklist
| Action | When to apply | Expected benefit |
| ----------------------------------------- | ------------------------------------------------------- | ---------------------------------- |
| Split combined FMEA sheets by methodology | Sheet mixes multiple analysis types | High — fewer columns per sheet |
| Reduce `multiItemLink` columns | Several multi-link columns in one sheet | High — fewer per-row lookups |
| Clean up broken cross-project links | Server log shows resolve errors | High — removes per-row exceptions |
| Use saved views for staged workflows | Different users need different columns | Medium — less client rendering |
| Check Polarion server maintenance state | Slowness coincides with admin tasks | Diagnostic — rule out server cause |
| Reduce row count | Sheet is very large and column count is already minimal | Low — usually not the bottleneck |
**Verify in application**
The optimal split point between sheets, the right number of `multiItemLink` columns, and acceptable load times all depend on your Polarion deployment, hardware, and user load. Treat the guidance above as starting points and measure in your own environment.
**Start from a template, not from scratch**
Whether you are adopting Risksheet for the first time or moving an existing analysis to a new version, begin from one of the Nextedy solution templates that matches your methodology (FMEA, HARA, TARA, STRIDE, CVSS). Templates carry verified `columns`, `levels`, `dataTypes`, `formulas`, `cellDecorators`, and `styles` sections. Modify a template to match your process rather than authoring a sheet configuration from a blank file. See [Configuration Examples](/risksheet/reference/examples/index) and the [Templates](/risksheet/reference/templates/index) reference.
A Risksheet upgrade replaces the server-side Polarion plugin and the client-side grid renderer. Your existing sheet configurations, top panel templates, PDF export templates, and Polarion work items are not modified by the upgrade. New configuration properties become *available* to use, but documents continue to function with their existing configuration until you opt in.
In most cases no. Risksheet upgrades aim to be backwards-compatible — existing `columns`, `levels`, `dataTypes`, `formulas`, `cellDecorators`, and `styles` continue to work. Migration is typically needed only when you want to adopt a new property (for example `createInDocument` or `linkToRisksheet`) or fix a property name that was previously misspelled. See [Configuration Management](/risksheet/guides/configuration/index) for the recommended workflow.
From version 25.5.0 onward, the configuration editor supports YAML editing with syntax highlighting, error detection, and history. Open the document menu and choose **Menu > Configuration > Edit Risksheet Configuration**. The underlying file remains the sheet configuration (`risksheet.json`) — the editor presents it as YAML so the file is easier to read and review.
Newer properties can be added incrementally to an existing sheet configuration once the server has been upgraded to the required version. Examples include `createInDocument` for choosing where new tasks are created, `linkToRisksheet` on `dataTypes.task` for subsheet navigation, and dependent enums at the column level. Add only the properties you need and leave the rest of the configuration unchanged.
**Verify in application**
After adding a new property, open the document in Polarion and confirm the grid behaves as expected before rolling the change out to templates and child documents.
By far the most common is the column property `bindings` (plural). Some older or hand-edited configurations contain `binding` (singular), which silently fails because the column never resolves a Polarion field. When you migrate, search every `columns` entry and confirm the property is `bindings: `. The reference for column properties is in [Column Types](/risksheet/reference/columns/index) and [Fields](/risksheet/reference/fields/index).
Remove them. Those three top-level sections do not exist in the real Risksheet engine — the engine ignores them entirely. Rating scales and enumerated values are defined as Polarion enumerations in **Administration > Nextedy Risksheet > Setup** and referenced from columns via `type: rating:`, `type: enum:`, or `type: multiEnum:`. Dependent enums are a column-level feature available from v25.3.1, not a top-level configuration section.
| Section in old config | What to do | Replacement mechanism |
| --------------------- | ---------- | --------------------------------------------------------------------------------------------------------- |
| `ratings: {}` | Delete | Define ratings as Polarion enumerations; reference with `type: rating:` |
| `enums: {}` | Delete | Define enums as Polarion enumerations; reference with `type: enum:` or `type: multiEnum:` |
| `relations: []` | Delete | Configure dependent enums at the column level (v25.3.1+) |
A document inherits configuration from its template at the point of creation and on subsequent **Refresh from Template** actions. After an upgrade, you can update a template first, validate it on a sandbox document, and then propagate the change to existing documents at your own pace. Because all data lives in Polarion work items and not in a Risksheet-private store, refreshing a configuration never moves or rewrites your risk items. See [Templates](/risksheet/reference/templates/index) and [Configuration Management](/risksheet/guides/configuration/index).
The licensing tier affects what users can do, not how Risksheet is configured. Three tiers are supported: ALM, Requirements, and QA licenses provide full create-and-modify access; the PRO license can modify existing Risksheet rows but cannot create new ones; the REVIEWER license is read-only. See [Licensing](/risksheet/guides/licensing/index) and the [Licensing Model](/risksheet/faq/licensing-model) FAQ for details.
Older generated documentation sometimes used the property name `columns` for saved views — the real property name is `columnIds`. When migrating a `views` entry, rename the array to `columnIds` and check whether you want to use the `@all` shorthand or the `-columnId` exclude prefix:
```yaml theme={null}
views:
- name: Full Analysis
defaultView: true
columnIds:
- "@all"
- name: Initial Risk Ranking
columnIds:
- failureMode
- severity
- occurrence
- name: No Up/Down Risks
columnIds:
- "@all"
- "-upstreamRisks"
```
The `defaultView` property (v24.1.0+) marks which view loads first when the document opens. See [Saved Views](/risksheet/guides/columns/index) under column configuration guides.
Yes — `formulas` and `cellDecorators` are evaluated client-side and are not transformed by upgrades. The recommended pattern, especially in regulated industries, is to keep `formulas` thin and define the heavy logic (risk matrices, multi-field conditional formatting) in the top panel configuration (`risksheetTopPanel.vm`). This separation keeps the sheet configuration auditable while custom logic stays under code review. See [Formulas](/risksheet/reference/formulas/index) and [Styling](/risksheet/reference/styling/index).
The configuration reference for each property notes the minimum version where applicable. Examples include `editableReferencedWorkItems` (v23.3.3+), `checkLinkRoleCompliance` (v24.2.2+), `createInDocument` (v24.8.1+), `moduleOnlyPermissions` (v24.8.5+), the dependent enum column feature (v25.3.1+), and YAML editing in the configuration editor (v25.5.0+). Before adopting a property, confirm your server is at least at the listed version. See [Compatibility](/risksheet/reference/compatibility/index) and [Configuration](/risksheet/reference/configuration/index).
**Coordinate Polarion and Risksheet upgrades**
Risksheet runs inside Polarion ALM. Always verify the Polarion version your environment runs and the Risksheet version are compatible before upgrading either component. Your Polarion administrator should perform the upgrade and run a sandbox validation before changing production templates.
## Related pages
* [Configuration Questions](/risksheet/faq/configuration) — general configuration questions
* [Licensing Questions](/risksheet/faq/licensing) — license tiers and entitlement
* [Common Troubleshooting](/risksheet/faq/troubleshooting-faq) — issues seen during and after upgrades
* [Configuration Management](/risksheet/guides/configuration/index) — how to roll configuration changes safely
* [Compatibility](/risksheet/reference/compatibility/index) — version requirements per property
***
Risksheet distinguishes between two categories of users. **Server users** are all registered users on the Siemens Polarion ALM server, regardless of whether they hold a Polarion license or use Risksheet. **Active users** are users explicitly assigned to Risksheet through a special user group, and they can create, edit, and manage risk items. All other server users receive **read-only access** through the Connect license, allowing them to view risk analysis data without editing.
**Common Licensing Pitfall**
Risksheet counts **all registered users on the Polarion server** as server users -- not just users who hold Polarion licenses. If your Polarion server has 203 registered users but only 50 Polarion license holders, the Risksheet server user count is 203. This distinction frequently causes confusion during initial licensing.
Active users are managed by adding user email addresses to a special user group in Polarion Administration. When you assign users to this group, they gain full editing capabilities in Risksheet including creating risk items, editing cell values, and saving changes. Users not in the group retain read-only viewing access. The specific group name depends on your product configuration:
* **Risksheet only**: Assign users to the `nextedy_risksheet_users` group
* **Risksheet + Powersheet**: Assign users to the `nextedy_powersheet_users` group (see the migration question below)
**Active License Required**
You must have an active Risksheet license before you can assign active users to the group. The user group assignment feature is only available with a valid production license.
Risksheet is available in tiered licensing based on the number of active users:
| Tier | Active Users | Server Users | Notes |
| ----------- | ---------------------- | -------------------------- | --------------------------------------- |
| Small team | 20 active users | Unlimited (read-only view) | Suitable for departmental risk teams |
| Medium team | 50 active users | Unlimited (read-only view) | Cross-functional deployment |
| Unlimited | Unlimited active users | Unlimited | Cost-effective above 60-70 active users |
| Active Users Needed | Recommended Tier | Notes |
| ------------------- | ---------------------- | ------------------------------------ |
| \< 20 | Small team (20 users) | Suitable for departmental risk teams |
| 20 -- 50 | Medium team (50 users) | Cross-functional deployment |
| 50 -- 70 | Compare tier pricing | Unlimited may be more cost-effective |
| > 70 | Unlimited | Best value above 60-70 active users |
The unlimited licensing tier becomes cost-effective when your organization has more than 60-70 active users who need editing capabilities. If you anticipate growth beyond 50 active users, evaluate the unlimited tier during your initial purchase. For current pricing details, see the [Risksheet pricing FAQ](https://www.nextedy.com/product/nextedy-risksheet/#faq).
The Connect license provides **read-only access** to Risksheet for all Polarion server users who are not assigned as active users. With the Connect license, non-active users can view risk analysis data, browse risk tables, and see all column values, but they cannot create new risk items, edit cell values, or save changes. This ensures that stakeholders, auditors, and reviewers can access risk data without consuming active user slots.
The SMB (small and medium business) discount is a reduced pricing tier available to organizations that stay within 50 server users on the Polarion server. Since server users count all registered accounts regardless of license type, exceeding the 50 server user threshold disqualifies the SMB pricing. Regularly audit your Polarion server for inactive or deprovisioned user accounts to maintain eligibility.
**Verify in application**
Contact Nextedy sales for current SMB pricing details and eligibility requirements -- see the [Risksheet pricing FAQ](https://www.nextedy.com/product/nextedy-risksheet/#faq) for the latest information. The 50 server user threshold is based on all registered accounts on the Polarion server.
Risksheet counts **all registered server users** on the Polarion server, not Polarion license holders. This is a critical distinction. For example, if you have 7 named Risksheet licenses and 203 registered accounts on the server, the system counts 203 server users. To stay within license limits, you can either clean up inactive server accounts or upgrade your Risksheet license tier. Common sources of unexpected server user counts include:
* Service accounts used by integrations
* Deactivated users who were never removed from the server
* Test accounts from previous deployments
* Integration accounts for CI/CD systems
When both Risksheet and Powersheet are installed with valid production licenses, Risksheet automatically detects the Powersheet installation and switches to an enhanced configuration that unlocks additional features. This integration is transparent -- no manual configuration is required. However, the **user group assignment changes**:
* Risksheet reads active user assignments from the `nextedy_powersheet_users` group instead of `nextedy_risksheet_users`
* This change is automatic when Powersheet has a valid production license
* Evaluation or trial Powersheet licenses do not trigger this switch
* The dual license system tracks user counts for both products independently
**Upgrade Migration**
When updating Risksheet across major versions where Powersheet is also installed, verify that your active users are assigned to the correct group (`nextedy_powersheet_users`). The automatic switch from `nextedy_risksheet_users` to `nextedy_powersheet_users` can cause access issues if users are only configured in the old group. Review user group membership before and after the upgrade.
Yes. Evaluation licenses allow you to trial Risksheet with full functionality before purchasing a production license. During evaluation, all Risksheet features are available for assessment. Note that evaluation Powersheet licenses do **not** enable the enhanced Risksheet features that require a production Powersheet license -- the automatic feature unlocking only occurs with a valid production Powersheet license. Evaluation licenses are time-limited and designed for proof-of-concept and capability assessment.
See [Evaluate Risksheet](/risksheet/getting-started/evaluation) for details on starting an evaluation.
Risksheet supports dynamic license revalidation that automatically checks both Risksheet and Powersheet license status. When a license status changes -- for example, when a Powersheet license is activated, expires, or is upgraded from evaluation to production -- Risksheet adjusts available features accordingly without requiring a server restart. The system maintains separate license managers for Risksheet and Powersheet, each tracking server users, configured named users, and configured concurrent users. License changes are detected automatically and the configuration adapts in real time.
If you have a valid Risksheet license but cannot save changes, the most common causes are:
1. **Server user count exceeded**: Your Polarion server has more registered users than your license allows. Risksheet counts all registered server accounts, not just Polarion license holders. Clean up inactive server accounts or upgrade your license tier.
2. **Not assigned as active user**: Your user account is not in the active user group (`nextedy_risksheet_users` or `nextedy_powersheet_users`). Ask your administrator to add your email to the appropriate group.
3. **Read-only Connect access**: You are accessing Risksheet through the Connect license (read-only mode). Contact your administrator to be assigned as an active user.
4. **License group mismatch**: If both Risksheet and Powersheet are installed, ensure you are in the `nextedy_powersheet_users` group rather than the `nextedy_risksheet_users` group.
5. **Polarion ALM license restriction**: Risksheet honors your underlying Polarion ALM license capability (see the next question). If your Polarion license is PRO, you can modify existing risk items but cannot create new lines; if it is REVIEWER, you have read-only access.
6. **Document-level permissions**: The Polarion document itself may have restricted write access. Verify your project role and document permissions.
Risksheet honors the capability of your underlying Polarion ALM license. Three Polarion license tiers map to Risksheet behavior as follows:
| Polarion License | Risksheet Capability |
| --------------------------- | ------------------------------------------------------------- |
| **ALM / Requirements / QA** | Full access -- create new risk items and modify existing ones |
| **PRO** | Modify existing risk items only -- cannot create new lines |
| **REVIEWER** | Read-only access |
This is independent of the Risksheet active-user assignment: a user must be both (a) in the active user group (or accessing read-only via the Connect license) and (b) holding a Polarion license that permits the action they want to perform. For example, an active user with a PRO Polarion license can edit existing failure modes but cannot add a new row to the risk table. To create new risk items, the user must hold an ALM, Requirements, or QA license.
For pricing details on each tier, see the [Risksheet pricing FAQ](https://www.nextedy.com/product/nextedy-risksheet/#faq).
Yes. You can upgrade your licensing tier at any time to increase the number of active users. When you upgrade, the license revalidation mechanism detects the change and adjusts the available active user slots without requiring a server restart. To downgrade, contact Nextedy support to discuss your options. Active user changes take effect immediately once the new license is applied.
The server user count is the total number of registered user accounts on your Polarion server. You can check this through Polarion Administration under user management. Remember that this count includes all accounts -- active users, inactive users, service accounts, and integration accounts. Compare this number against your Risksheet license tier to ensure compliance.
***
**Contact Nextedy Sales**
For current pricing, custom licensing arrangements, or questions about your specific deployment, see the [Risksheet pricing FAQ](https://www.nextedy.com/product/nextedy-risksheet/#faq) or contact Nextedy sales directly. Pricing tiers, SMB discount eligibility, and unlimited license breakpoints may vary based on your organization's needs.
## Related Pages
* [Evaluate Risksheet](/risksheet/getting-started/evaluation) -- starting a Risksheet evaluation
* [Understanding Licenses](/risksheet/guides/licensing/understanding-licenses) -- in-depth licensing guide
* [General Questions](/risksheet/faq/general) -- general product questions
* [Installation](/risksheet/getting-started/installation) -- installing Risksheet on your Polarion server
**Pricing vs. licensing**
This page explains how the **licensing model** works (Active Users, Server Users, Connect, PRO, REVIEWER). For pricing tiers and quote-related questions, see [Pricing Questions](/risksheet/faq/pricing).
## How the Licensing Model Fits Together
The diagram below summarizes the three categories of users that can interact with a risksheet, and what each can do.
## Active Users and Server Users
An **Active User** can create and edit risk items, change the sheet configuration, and run formulas inside a risksheet. A **Server User** is any Polarion user on the server who can open and read risksheets but cannot modify risk data; this read-only access is granted through the **Connect** license that ships with Risksheet. Active Users count against your purchased tier (for example, 20, 50, or unlimited); Server Users are unlimited. See [Licensing Model](/risksheet/faq/licensing-model) for the full breakdown.
Active Users are **explicitly assigned by a Polarion administrator** through a Polarion user group — they are not calculated automatically based on activity. The administrator creates a group, assigns the Active User role to specific users, and adds those users to the group by their account. This is distinct from the default Polarion user role: every Polarion user can open a risksheet read-only, but only members of the Active User group can edit. For the exact administrator workflow, see [Licensing](/risksheet/guides/licensing/index).
**Active User assignment is not automatic**
A user does not become an Active User simply by opening or editing a risksheet. Until an administrator adds them to the Active User group, they fall back to the Connect (read-only) access level — regardless of their Polarion ALM license.
Risksheet tracks user counts for both server users and configured named users against your purchased tier. The administrator can review the assignment by opening the user group used for Active Users and counting its members. If you need help auditing the assignment or comparing it to your purchased seats, contact Nextedy support.
As a rule of thumb, **unlimited Active User licensing becomes more cost-effective above roughly 60 to 70 Active Users**. Below that threshold, named tiers (typically 20 or 50 Active Users) are usually a better fit. The crossover point depends on your specific quote — see [Pricing Questions](/risksheet/faq/pricing) for how to request a quote that compares tiers side by side.
## Relationship to Polarion ALM Licenses
Yes. Risksheet builds on top of Polarion ALM, and Polarion's license tier determines what a given user can do **inside the risksheet grid**, in addition to the Risksheet Active User assignment.
| Polarion license | What the user can do in a risksheet |
| ------------------------------------ | ------------------------------------------------------------- |
| ALM / Requirements / QA (full named) | Full access: create new risk items, modify existing ones |
| PRO | **Modify existing risk items only** — cannot create new lines |
| REVIEWER | Read-only with comment and approval rights |
**PRO license cannot create new risk items**
A common misconception is that Risksheet operates independently of Polarion ALM licensing. It does not. PRO-licensed users see the grid and can edit cells in existing rows, but **the action to add a new row is disabled**. If your team needs to create risk items, the user must hold an ALM/Requirements/QA-class Polarion license **and** be an Active User in Risksheet.
No. REVIEWER users get read-only access through the Connect license that comes with Risksheet, so they do not consume Active User seats. They can read the grid, leave comments, and participate in approval-based reviews (see [Review Management](/risksheet/guides/reviews/index)).
**Verify in application**
The exact set of UI actions available to a REVIEWER inside the grid depends on the configured review workflow. Verify your specific scenario against your installed version before final sign-off.
## Risksheet and Powersheet Together
When a valid Powersheet **production** license is present alongside Risksheet, Risksheet automatically switches to an enhanced configuration that unlocks additional features. This switch is **transparent and automatic** — there is no manual setting to toggle. If the Powersheet license is removed or expires, Risksheet reverts to its standard feature set on the next license revalidation.
No. Only a valid **production** Powersheet license activates the enhanced Risksheet configuration. Evaluation or trial Powersheet licenses do not trigger the feature unlock. If you are testing Powersheet alongside Risksheet, expect Risksheet to behave as if Powersheet were not installed until a production license is applied.
No. Risksheet supports dynamic license revalidation and checks both the Risksheet and Powersheet licenses periodically. When the Powersheet status changes — activated, expired, or upgraded from evaluation to production — Risksheet adjusts the available features automatically without a restart.
Yes. Each product has its own license manager and its own user counts (server users, named users, concurrent users where applicable). You can license Risksheet on its own, Powersheet on its own, or both together; the products do not require each other to function.
## Configurations, Documents, and Reuse
The Risksheet license is **server-wide** — it covers all projects on the Polarion server, not just one. A single Risksheet license entitles you to run any number of risksheet documents across any number of projects, subject only to the Active User count tied to your tier.
Yes. A project can contain multiple risksheets, each with its own sheet configuration (the file commonly referred to as `risksheet.json`). This means a single project can run an FMEA, a HARA, and a TARA in parallel, each driven by its own sheet configuration. See [Configuration Management](/risksheet/guides/configuration/index) for how to manage multiple configurations in one project.
Yes. Risk analyses can be reused across product variants through standard Polarion mechanisms — there is no separate per-variant license. The Active User count is what is licensed, not the number of variants or analyses.
**Reuse mechanics**
The specific reuse mechanism depends on your Polarion setup (branching, document templates, or copy workflows). The Risksheet license does not restrict any of these patterns.
## Trial, Evaluation, and Support
Nextedy provides evaluation builds of Risksheet that include a time-limited license. During evaluation you have access to the same features as a production install, except that any Powersheet-dependent enhancements require a **production** Powersheet license (an evaluation Powersheet license does not unlock them). For a quote, see [Pricing Questions](/risksheet/faq/pricing).
Risksheet ships with starter templates for typical risk analysis methodologies (FMEA, HARA, TARA, STRIDE). The recommended way to evaluate the tool is to pick the closest solution template for your industry, run through its sheet configuration, and adjust it to your process. See [Templates](/risksheet/reference/templates/index) for the available starting points and [Getting Started](/risksheet/getting-started/index) for the end-to-end walkthrough.
Licensing questions, quotes (including comparisons between 20, 50, and unlimited Active User tiers), and quote-for-resale requests are handled by Nextedy sales. Reach out through your reseller or the Nextedy contact channels on the support portal. For technical questions about applying or revalidating an already-issued license, contact Nextedy support and reference your server installation.
**Quick rule of thumb**
If you expect **fewer than \~60 people to actively edit risk items**, a tiered license (20 or 50 Active Users) is usually the most cost-effective choice. Above 60–70 Active Users, the **unlimited** tier typically becomes cheaper than buying additional tier expansions. All other Polarion users can still read risksheets at no extra Risksheet cost through the Connect license.
Risksheet is sold in tiers based on the number of **Active Users** — people who create, edit, or manage risk items in the grid. Standard quote tiers are **20 Active Users**, **50 Active Users**, and **Unlimited Active Users**. All other Siemens Polarion ALM users on the same server get read-only access through the bundled **Connect** license, at no additional Risksheet cost. See [Licensing Model](/risksheet/faq/licensing-model) for the full breakdown of user types.
Choose the tier by counting people who **interactively work in the grid** — entering failure modes, scoring severity/occurrence/detection, assigning mitigation tasks, or running review workflows. Read-only viewers do not consume Active User seats. The diagram below shows the typical decision flow.
A common pattern: pilot with the 20-user tier during evaluation, then move up to 50 or Unlimited when the program rolls out across multiple teams.
Based on customer purchasing patterns, **Unlimited becomes the cheaper option once you exceed roughly 60–70 Active Users**. Below that, the 20- or 50-user tiers are usually less expensive than adding incremental seats up to unlimited. Above that, the math reverses — adding seats one tier at a time costs more than going straight to Unlimited. Request quotes for the tiers near your expected user count to confirm for your specific situation.
Polarion server users who do **not** create or edit risk items are **not** counted against your Active User quota. They access risksheet content read-only through the Connect license that is bundled with Risksheet. There is no per-seat charge for these read-only users — they can be **unlimited** in number, regardless of which tier you buy. This is why customers with large Polarion installations can keep Risksheet cost predictable even when hundreds of stakeholders need to view risk analyses.
| User type | What they can do | Counts toward tier? |
| ---------------------------------- | ---------------------------------------------------- | ------------------- |
| Active User | Create, edit, score, link, run reviews on risk items | Yes |
| Polarion server user (via Connect) | View risksheets, open risk items read-only | No — unlimited |
| Polarion reviewer-only user | Read-only access to documents and risk items | No — unlimited |
Contact your Nextedy partner or Nextedy directly with: (1) approximate number of Active Users, (2) Polarion deployment size, (3) target start date, and (4) any partner/reseller channel involved. Quotes are typically provided for the standard tiers (20, 50, unlimited) so you can compare. For procurement planning, budgeting in the **fiscal year before deployment** is common — many customers plan Risksheet purchases as part of next year's Polarion budget cycle.
Yes. Risksheet is available through Nextedy partners and resellers, including Polarion solution partners. Partners can request quotes on behalf of end customers and bundle Risksheet with Polarion ALM licenses, integration services, or solution templates. The license model and tiers are the same regardless of channel.
Yes. If your Active User count grows beyond the tier you originally purchased, you can upgrade to a higher tier (for example, from 20 to 50, or from 50 to Unlimited). Contact Nextedy or your reseller to arrange the upgrade. There is no need to reinstall the app — only the license entitlement changes. For activation and license file handling, see [Licensing Questions](/risksheet/faq/licensing).
Active User assignment is performed by a Polarion administrator after the license is activated on your server. Until then, the assignment screen is not available. The administrator selects specific Polarion users as Active Users, up to the tier limit. Unassigned users automatically fall back to read-only access via Connect. For step-by-step instructions, see the [Licensing](/risksheet/guides/licensing/index) guide.
**Verify in application**
Exact menu paths and screens for Active User assignment may vary by Risksheet version. Confirm the current procedure in your Polarion **Administration > Nextedy Risksheet > Setup** area after activating the license.
Yes. Risksheet is a generic tool that supports any risk management methodology — FMEA, HARA, TARA, STRIDE, CVSS, and others — within a single license. There is no separate purchase for each methodology. Nextedy provides solution templates for typical industry workflows (automotive ISO 26262, medical ISO 14971, industrial IEC 61508, cybersecurity ISO/SAE 21434), and all of them run on the same Risksheet license. See [Concepts](/risksheet/concepts/index) for an overview of methodology support.
Pricing for renewals and tier upgrades may change over time. When planning a multi-year procurement, ask Nextedy or your reseller for written quotes that specify validity periods, and confirm whether maintenance/support renewals are tied to original tier pricing or current list pricing. Budgeting one fiscal year ahead and locking in quotes during that planning cycle is the most common approach customers use to manage this.
* [Licensing Model](/risksheet/faq/licensing-model) — Active Users, Server Users, Connect license, and how seats are counted.
* [Licensing Questions](/risksheet/faq/licensing) — activation, license files, renewals, and support entitlement.
* [Licensing Guide](/risksheet/guides/licensing/index) — step-by-step administrator tasks for assigning Active Users.
* [General Questions](/risksheet/faq/general) — high-level questions about what Risksheet is and who uses it.
**How to use this page**
Locate the symptom that matches what you see in your Risksheet document, read the short answer, then jump to the linked detailed page if you need configuration examples or root-cause explanations.
## Diagnostic Decision Path
## Configuration Issues
The most common cause is a mismatch between `dataTypes.risk.type` in the sheet configuration and the actual Polarion work item type used in your LiveDoc. Confirm the work item type ID matches exactly (case-sensitive), and verify that the document contains items of that type. See [Configuration Management](/risksheet/guides/configuration/index) for verification steps.
The sheet configuration is attached to the document, but the page may still be showing a cached version. Reload the LiveDoc (full browser refresh, not just navigation) and confirm you edited the right configuration — the document configuration takes priority over the template configuration. See [Configuration Hierarchy](/risksheet/guides/configuration/index) for the inheritance rules.
Formula errors most often come from referencing a property that does not exist on the row object. Use `info.item['columnId']` syntax with the exact column `id`, not the column header. Also confirm the column you are reading from has `bindings` set (plural — `bindings`, not `binding`) so values are actually loaded. See the [Formulas reference](/risksheet/reference/formulas/index) for parameter conventions and the `info` object structure.
## Column and Data Issues
This is almost always caused by an incorrect `bindings` value. The property is `bindings` (plural) and must contain the exact Polarion field ID — not the field label. Field IDs are case-sensitive. For linked-item bindings such as `task.title` or `harm.title`, the prefix must match the configured `dataTypes` key. See [Column Configuration](/risksheet/guides/columns/index).
**Common mistake**
Writing `binding: severityRating` (singular) instead of `bindings: severityRating` (plural) silently produces empty columns — no error is thrown, the column just renders blank.
Visual cell merging is controlled by the `levels` configuration. Each level must declare three properties: `name`, `controlColumn`, and `zoomColumn`. Columns merge when consecutive rows share the same value in the level's `controlColumn`. Also remember that the column `level` property is **1-indexed** — `level: 1` corresponds to `levels[0]`. See [Risk Management Guides](/risksheet/guides/risk-management/index).
Calculated columns rely on the formula being re-evaluated when source cells change. Confirm your formula returns a value (not undefined), reads from the right `info.item[...]` properties, and that the source columns have `bindings` configured. If the formula calls a function from the top panel template, also verify the top panel configuration loads correctly. See the [Formulas reference](/risksheet/reference/formulas/index).
## Styling and Conditional Formatting
A cellDecorator MUST use `toggleClass` to apply visual styling, because grid cells are reused across rows. The canonical form is jQuery `$(info.cell).toggleClass(...)`, as used in the product's reference templates (`wijmo.toggleClass(...)` is a non-canonical equivalent). Setting inline styles directly produces inconsistent results as cells scroll. Also confirm the CSS class name you toggle exists in the `styles` section, and that the style value is wrapped in `{}` braces, for example `'.rpn3': '{background-color: #e53935 !important;}'`. See [Styling and Formatting](/risksheet/guides/styling/index).
**Style value format**
Risksheet style values are CSS rules wrapped in braces. Forgetting the braces or omitting `!important` is a common reason styles silently fail to apply.
## Saving, Editing, and Permissions
This usually indicates a PRO license. The Risksheet PRO license tier allows modifying existing rows but does not allow creating new rows — only the ALM, Requirements, or QA license tiers grant full create-and-modify access. The REVIEWER license is read-only. Verify the current user's assigned Polarion license. See [Licensing Questions](/risksheet/faq/licensing) and [Licensing Model](/risksheet/faq/licensing-model).
This is typically intentional behavior driven by a cellDecorator. Risksheet supports per-row read-only logic by appending to `info.item.systemReadOnlyFields` inside a decorator function (a pipe-delimited string like `'|asilSeverity|asilExposure|'`). When a row is, for example, classified as "QM" in a HARA analysis, ASIL-specific fields become locked for that row only. Check your `cellDecorators` section for logic touching `systemReadOnlyFields`. See [Styling and Formatting](/risksheet/guides/styling/index).
If `dataTypes.task.canCreate: false` is set, task creation is globally disabled — users can only link to existing items. Similarly, individual itemLink columns can disable creation with `canCreate: false`. If creation is enabled but new items are not visible, confirm `dataTypes.task.createInCurrentDocument` or `dataTypes.task.createInDocument` (v24.8.1+) targets a document you have access to. See [Risk Management](/risksheet/guides/risk-management/index).
## Saved Views
The view's `columnIds` array must use exact column `id` values (the property is `columnIds`, plural, not `columns`). You can use the special `@all` token to include all columns and the `-columnId` prefix to exclude one, for example `["@all", "-task"]`. To make a view load by default, set `defaultView: true` on the view object (v24.1.0+). See [Saved Views guide](/risksheet/guides/columns/index).
## Reviews and Approvals
Risksheet's approval review creates approval-tagged comments but does NOT trigger Polarion's formal approval state transitions (draft → reviewed → approved). It is a review-tracking mechanism inside the grid. If you need full Polarion approval workflow integration, use Polarion's native document workflow alongside Risksheet's review feature. See [Review Management](/risksheet/guides/reviews/index).
**Three review types**
Risksheet supports comment-based, work-item-based, and approval-based reviews. Each has a different scope and traceability footprint.
## Reference Quick Table
| Symptom | Most likely cause | Where to look |
| -------------------------------------- | ----------------------------------------------------------- | ----------------------------------------------------------------- |
| Empty grid | Wrong `dataTypes.risk.type` | [Configuration Management](/risksheet/guides/configuration/index) |
| Empty column | `binding` (singular) instead of `bindings` | [Column Configuration](/risksheet/guides/columns/index) |
| Stale formula | Source column missing `bindings` | [Formulas reference](/risksheet/reference/formulas/index) |
| Wrong cell merging | `level` property is 1-indexed; check `controlColumn` | [Risk Management Guides](/risksheet/guides/risk-management/index) |
| No cell coloring | Decorator not using `toggleClass`, or missing `{}` in style | [Styling and Formatting](/risksheet/guides/styling/index) |
| Cannot create rows | PRO or REVIEWER license tier | [Licensing Model](/risksheet/faq/licensing-model) |
| Locked cells per row | `systemReadOnlyFields` in a cellDecorator | [Styling and Formatting](/risksheet/guides/styling/index) |
| Missing columns in view | `columnIds` typo or wrong column id | [Saved Views guide](/risksheet/guides/columns/index) |
| Approval review has no workflow effect | By design — review-only, not workflow | [Review Management](/risksheet/guides/reviews/index) |
## When to Escalate
**Before contacting support**
Capture the sheet configuration, the document ID, the Polarion version, the Risksheet version, and a short description of the expected vs. actual behavior. Most configuration issues can be resolved by comparing your sheet configuration against the closest [solution template](/risksheet/reference/templates/index).
If a problem persists after checking the above, see the full [Troubleshooting](/risksheet/troubleshooting/index) section for deeper diagnostics, log locations, and recovery procedures. For configuration-related issues, the [Configuration Examples](/risksheet/reference/examples/index) page shows verified working snippets from production solution templates.
**Cannot find your answer?**
If your question is not covered in the FAQ topics above, check the [Guides](/risksheet/guides/index) section for step-by-step instructions, the [Reference](/risksheet/reference/index) section for detailed property documentation, or the [Troubleshooting](/risksheet/troubleshooting/index) section for error resolution procedures.
# Basic Configuration
Source: https://learn.nextedy.com/risksheet/getting-started/basic-configuration
By the end of this tutorial you will understand how Nextedy RISKSHEET is configured, recognise the three configuration files involved, locate the sheet configuration on a Polarion LiveDoc, and make a small, safe change using the built-in YAML configuration editor. You will leave with a mental model of what belongs in each file and where to go next for deeper customization.
## What you will achieve
By the end of this tutorial you will understand how Risksheet is configured, recognise the three configuration files involved, locate the sheet configuration on a Polarion LiveDoc, and make a small, safe change using the built-in YAML configuration editor. You will leave with a mental model of what belongs in each file and where to go next for deeper customization.
## Prerequisites
* Risksheet is installed on your Siemens Polarion ALM instance (see [Installation](/risksheet/getting-started/installation))
* You are familiar with the grid and toolbar (see [Understanding the Interface](/risksheet/getting-started/understanding-interface))
* You have administrator permissions on the Polarion project
**Start from a template, never from scratch**
Risksheet is a flexible tool. It supports any risk-management methodology, including Failure Mode and Effects Analysis (FMEA), Hazard Analysis and Risk Assessment (HARA), Threat Analysis and Risk Assessment (TARA), STRIDE, and Common Vulnerability Scoring System (CVSS). Nextedy ships solution templates for typical methodologies across automotive, medical, aerospace, and cybersecurity. Always pick the closest template and adapt it -- do not build a configuration from an empty file.
## The three configuration files
A risksheet is shaped by three distinct configuration files. Each lives as an attachment on the Polarion LiveDoc (or on a template document) and each addresses a different concern.
| File | Purpose | Format |
| -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------ |
| Sheet configuration (`risksheet.json`) | Declarative grid definition: columns, hierarchical levels, data types, formulas, styles, cell decorators, views, reviews | JSON, edited as YAML in the configuration editor |
| Top panel configuration (`risksheetTopPanel.vm`) | Velocity template for the information panel above the grid; hosts custom UI controls and shared JavaScript helpers | Velocity |
| PDF export configuration (`risksheetPdfExport.vm`) | Velocity template that controls the layout and styling of PDF exports | Velocity |
This separation matters for regulated industries (ISO 26262 automotive, ISO 14971 medical, IEC 61508 industrial, ISO/SAE 21434 cybersecurity). The sheet configuration is a declarative, auditable artifact that describes both WHAT the grid shows and HOW its values are calculated and styled: formulas, conditional formatting (cell decorators), and styles all live in the sheet configuration. The top panel template covers only the content of the information panel above the grid, and export presentation lives in its own template. Each layer can be reviewed, validated, and changed independently.
## Where the configuration lives -- Polarion vs. Risksheet
A common point of confusion is what is configured in Polarion itself and what is configured in the sheet configuration. The boundary is simple:
| In Polarion administration | In the sheet configuration |
| ------------------------------------------------------------------------------ | -------------------------------------------------------------- |
| Work item types (for example a "Failure Mode" or "Hazard" type) | Which work item type the grid uses for risk items and tasks |
| Custom fields on those work item types | Which fields the columns are bound to |
| Enumerations (severity scales, occurrence scales, classification, ASIL levels) | How those enumerations are displayed and styled |
| Link roles between work items | Which link role connects a risk item to its related work items |
| Document type (so a LiveDoc behaves as a risksheet) | The grid layout that the document presents |
Severity, occurrence, detection scales and any other rating dropdown live in **Administration > Enumerations** in Polarion. A custom field on the work item is bound to one of these enumerations. The sheet configuration then references the field through a column entry, and the server loads the enum values automatically.
**No separate data store**
Risksheet does not have its own database. Every value you enter in the grid is a Polarion work item field. Permissions, versioning, audit history, and traceability are all provided by Polarion. Risksheet is the visual surface that organises and edits this data.
1. Open your risksheet document in Polarion.
2. From the toolbar, choose **Menu > Configuration > Edit Risksheet Configuration**.
3. The configuration editor opens in a new browser tab.
You should see the YAML editor on the left and a preview/validation pane on the right. The editor (available since v25.5.0) offers syntax highlighting, inline error detection, and edit history.
**YAML, not raw JSON**
The underlying attachment is JSON, but you should always edit it as YAML through this editor. YAML is easier to read, easier to diff, and harder to break. Treat raw JSON edits as a last-resort fallback.
Scroll through the YAML. A real, working sheet configuration is made up of these top-level sections:
| Section | What it controls |
| ---------------- | ------------------------------------------------------------------------------------ |
| `global` | Culture/locale, toolbar settings, refresh behaviour |
| `columns` | Every column shown in the grid -- the core of the configuration |
| `levels` | The visual hierarchy created by cell merging (for example item, failure mode, cause) |
| `dataTypes` | Which Polarion work item types are used for risk items and tasks |
| `formulas` | Named JavaScript functions that calculate values such as Risk Priority Number (RPN) |
| `styles` | Named CSS classes used by cell decorators |
| `cellDecorators` | Logic that applies styles to cells based on their value |
| `headers` | Row and column header sizing |
| `reviews` | Review workflow integration |
| `sortBy` | Default sort order |
| `views` | Saved column-visibility presets (optional) |
| `queryFactories` | Advanced autocomplete filtering (rare) |
A section the engine does not recognise is simply ignored. (Beyond the core sections above, a few optional root-level keys also exist -- such as a root `readonly` flag -- and the server injects read-only runtime fields, described in [What to leave alone](#what-to-leave-alone) below.) If you came across older guides mentioning a top-level `ratings`, `enums`, or `relations` block, treat them as outdated: rating scales and enumerations live in Polarion, not in the sheet configuration.
The `dataTypes` section names the two Polarion work item types the risksheet operates on. Locate it and confirm both entries look broadly like this:
```yaml theme={null}
dataTypes:
risk:
type: failureMode
task:
name: Task
type: mitigationAction
role: mitigates
zoomColumn: taskId
```
The `risk` entry is the main row work item; the `task` entry is the downstream linked item (mitigations, safety requirements, controls). The `name` shown in the toolbar, the link `role`, and the `zoomColumn` used for navigation should all reflect your project's vocabulary.
**Naming is by convention**
`risk` and `task` are just keys. The underlying work item types can be anything in your project -- requirements and test cases, hazards and controls, threats and countermeasures. Risksheet works as a generic two-entity traceability grid.
A good first edit is renaming a column header. Find a column in the `columns` list and change only its `header` text:
```yaml theme={null}
columns:
- id: severity
bindings: severityField
header: Severity (S)
type: rating:severityEnum
level: 2
```
Save. The configuration editor validates the YAML. If validation passes, return to the risksheet document and use the Refresh button in the risksheet toolbar (or reload the document) -- the new header appears in the grid.
**Use `bindings`, not `binding`**
The column property that maps to a Polarion field is `bindings` (plural). A singular `binding` is silently ignored, leaving the column blank.
Highlighting RPN cells in green, amber, or red is a three-part collaboration inside the sheet configuration:
1. A **formula** computes a value (for example RPN = severity x occurrence x detection).
2. A **cell decorator** inspects the value and toggles a CSS class on the cell.
3. A **style** defines what that CSS class looks like.
A minimal example:
```yaml theme={null}
formulas:
rpn: (info) => { return info.item.severity * info.item.occurrence * info.item.detection; }
cellDecorators:
rpn: |
(info) => {
var v = info.value;
$(info.cell).toggleClass('rpn1', v <= 150);
$(info.cell).toggleClass('rpn2', v > 150 && v <= 250);
$(info.cell).toggleClass('rpn3', v > 250);
}
styles:
.rpn1: '{background-color: #eaf5e9 !important; color: #1d5f20 !important;}'
.rpn2: '{background-color: #fff8e1 !important; color: #8a6d00 !important;}'
.rpn3: '{background-color: #fdecea !important; color: #b71c1c !important;}'
```
| RPN range | Style class | Meaning |
| ------------- | ----------- | ----------------------------------- |
| 0 -- 150 | `rpn1` | Acceptable risk |
| 151 -- 250 | `rpn2` | Reduce as reasonably practicable |
| 251 and above | `rpn3` | Unacceptable -- mitigation required |
These thresholds are deployment-specific. Adjust them to match the risk acceptance criteria of your project or standard.
**Wrap style values in braces**
Style values must be wrapped in `{ ... }` braces, as shown above. Without the braces the engine cannot parse them and the cell remains unstyled.
## What to leave alone
A few properties you may see in real configurations are managed by the server at runtime. Do not set them by hand -- they are informational only:
* `canAdmin` -- whether the current user has admin rights
* `reviewer` -- whether the current user is in reviewer mode
* `source` -- path to the configuration source (document or template)
* `templateName` -- name of the template the configuration was loaded from
## Next steps
* Tour each section of the sheet configuration in [Configuration Reference](/risksheet/reference/configuration/index)
* Learn about column types and calculations in [Column Types](/risksheet/reference/columns/index) and [Formulas](/risksheet/reference/formulas/index)
* Apply visual hierarchy through cell merging in [Risk Management Guides](/risksheet/guides/risk-management/index)
* Customise styling for risk levels in [Styling and Formatting](/risksheet/guides/styling/index)
* Build saved column presets for staged workflows in [Configuration Management](/risksheet/guides/configuration/index)
* Manage templates and inheritance in [Templates](/risksheet/reference/templates/index)
* See full working examples in [Configuration Examples](/risksheet/reference/examples/index)
# Evaluate Risksheet
Source: https://learn.nextedy.com/risksheet/getting-started/evaluation
This tutorial walks you through evaluating Nextedy RISKSHEET on Siemens Polarion ALM.
## What you will achieve
By the end of this tutorial, you will have:
* Chosen one of two evaluation paths (hosted by Nextedy, or self-hosted on your own Polarion server).
* Instantiated a working risksheet from a Nextedy solution template — starting from the **functional safety template**, the simplest entry point.
* Opened the risksheet, explored the grid, edited a risk item, observed Risk Priority Number (RPN) calculation and conditional formatting, and used the review workflow.
* Identified whether Risksheet covers your team's Failure Mode and Effects Analysis (FMEA), Hazard Analysis and Risk Assessment (HARA), Threat Analysis and Risk Assessment (TARA), or other risk methodology needs.
**Key message**
Always **start from a solution template** and modify it to match your process. Never build a risksheet configuration from a blank file. Templates encode methodology expertise — column structures, levels, formulas, cell decorators, and review workflows — that you should adapt, not recreate.
## Prerequisites
* A modern web browser (Chrome, Firefox, or Edge).
* For the **hosted** path: an email address to request demo access.
* For the **self-hosted** path: a Polarion server running version **19.1 or later**, with administrator access for plugin deployment.
## Evaluation paths
Choose **one** path below. Both converge on the same common flow (Steps 4 through 8).
***
## Part 1 — Hosted evaluation (Nextedy demo server)
Use this path when you want to evaluate quickly without installing anything on your own infrastructure.
### Step 1: Request hosted trial access
Contact Nextedy to request demo server credentials. Provide your email address and the methodology you want to evaluate. The Nextedy team responds with a URL, username, and password for a pre-configured Polarion instance that already has Risksheet installed.
You should receive credentials for a Polarion instance that exposes one or more **solution template projects** — at minimum a functional safety FMEA example, often accompanied by HARA and other variants.
**Which template to ask for**
Ask for access to the **functional safety template** first. It is the simplest configuration and is the recommended entry point for evaluation. HARA and other templates demonstrate advanced features such as catalog reuse and dependent enums, which can distract from a first-pass evaluation.
### Step 2: Log in and locate the template projects
Open the demo URL in your browser and log in with the provided credentials. In the Polarion project navigator, you should see one or more template projects (for example, a project named for functional safety FMEA).
You should land on the Polarion home page with the demo projects listed. Skip ahead to **Part 3 — Common evaluation flow**.
***
## Part 2 — Self-hosted evaluation
Use this path when your security policy requires on-premises evaluation, or when you want to test Risksheet against your own Polarion configuration, user accounts, and link roles.
### Step 1: Verify Polarion version
Confirm your Polarion server is running version **19.1 or later**. Risksheet does not support earlier Polarion releases.
You should see the Polarion version on the **About Polarion** dialog (Help menu) or in the server admin panel.
### Step 2: Download Risksheet
Download the Risksheet plugin distribution from:
```text theme={null}
https://go.nextedy.com/risksheet-download-page
```
You should receive a plugin archive suitable for deployment into your Polarion installation directory.
### Step 3: Deploy Risksheet
Stop the Polarion server, copy the Risksheet plugin into your Polarion extensions directory (`[POLARION_INSTALL]/polarion/extensions/`) as instructed by the download page README, then prepare to restart.
**Required reset step**
Before restarting Polarion, **delete the workspace config cache**:
```text theme={null}
[POLARION_INSTALL]/data/workspace/.config
```
Skipping this step causes the Polarion OSGi runtime to use stale plugin metadata and Risksheet menus will not appear. The `.config` directory is regenerated automatically on the next start.
Restart Polarion. You should see Risksheet entries appear under **Administration > Nextedy Risksheet > Setup** after the server finishes initializing.
### Create a sandbox project from a solution template
In **Administration > Nextedy Risksheet > Setup**, use **Create New Project**. On the template-selection page, choose the template **Nextedy Risksheet FMEA Demo** (or **Nextedy Risksheet HARA Demo**), then click **Finish**.
Open the new project and select **Risksheet** in the left navigator (below **Work Items** and **Documents & Pages**). You should see a pre-configured risk specification with a working grid of example risk items, ready for exploration.
For full installation details, see [Installation](/risksheet/getting-started/installation). Then continue with **Part 3 — Common evaluation flow** below.
***
## Part 3 — Common evaluation flow
Both paths converge here. Whether you are using the hosted demo or a freshly provisioned local template, the next steps are identical.
### Step 4: Open the risksheet
Open the template LiveDoc (for example, *Risks/Risk Specification* in the functional safety project). The Risksheet grid renders inside the LiveDoc page.
You should see an Excel-like grid with:
* **Risk items** as rows (failure modes, hazards, or your methodology's equivalent).
* **Hierarchical levels** with cells visually merged where consecutive rows share the same parent value.
* **Column groups** organizing related columns (for example, initial assessment versus revised assessment).
* **Color-coded cells** for RPN and similar derived values.
* A **top panel** above the grid showing summary information.
### Step 5: Explore RPN calculation and conditional formatting
Click an RPN cell to inspect how it is derived. The template defines a `formulas` section in the sheet configuration that multiplies severity, occurrence, and detection ratings:
```yaml theme={null}
formulas:
commonRpn: |
function(info) {
var value = info.item['occ'] * info.item['det'] * info.item['sev'];
return value ? value : null;
}
commonRpnNew: |
function(info) {
var value = info.item['occNew'] * info.item['detNew'] * info.item['sevNew'];
return value ? value : null;
}
```
The grid also defines a `cellDecorators` section that applies CSS classes to RPN cells based on configurable thresholds. The functional safety template uses a three-band scheme:
| RPN range | Visual class | Meaning |
| --------- | --------------- | ----------- |
| 1 — 150 | `rpn1` (low) | Low risk |
| 151 — 250 | `rpn2` (medium) | Medium risk |
| > 250 | `rpn3` (high) | High risk |
**Thresholds are template-specific**
RPN thresholds are not product defaults — they are defined inside the template's `cellDecorators`. Different templates use different thresholds. When you adapt a template, adjust the thresholds in the sheet configuration to match your organization's risk policy.
Edit a severity, occurrence, or detection value in a row. The RPN cell should recalculate immediately, and its background color should update to match the new band.
### Step 6: Explore traceability — upstream and downstream
Risksheet does not store risk data separately — every row is a Polarion work item, so all data participates in Polarion authorization and traceability.
* **Upstream**: locate a column bound to a requirement or hazard link (for example, an `itemLink` column). The cell displays a linked work item ID; click it to open the source requirement in Polarion's editor.
* **Downstream**: locate the task column (typically labeled *Mitigation*, *Safety Goal*, or similar). Right-click a row and choose the option to open the linked task. The task opens in the Polarion item editor and shows a link back to the parent risk item.
You should observe that tasks are normal Polarion work items connected through a configured link role — they appear in standard Polarion reports and queries, not in a separate Risksheet-only database.
### Step 7: Try the review workflow
Risksheet supports three review strategies: comment-based, work-item-based, and approval review. The functional safety template typically ships with **comment-based review**, where each review is stored as a standard Polarion comment on the underlying work item.
Add a review on any row using the Risksheet review action. You should see the review captured as a comment on the risk item, with your author name, timestamp, and the text you entered. The review remains visible in Polarion's standard comment view.
**Approval review limitation**
If you switch the demo to approval review, be aware that Risksheet approval review creates approval-tagged comments but **does not trigger Polarion's formal approval state transitions** (draft -> reviewed -> approved). It is a lightweight comment-based mechanism, not a wrapper over the Polarion approval workflow.
### Step 8: Try export
Use the export action to export the current grid to Excel and then to PDF. You should receive a formatted spreadsheet and a paginated PDF that reproduce the column groups, conditional formatting, and merged cell hierarchy you see on screen.
You have now exercised the core workflow: open, edit, recalculate, link, review, export. This is enough to judge fit against your process.
## Evaluation checklist
Use this checklist to decide whether to proceed beyond evaluation:
| Capability | What to confirm |
| ---------------------- | --------------------------------------------------------------------------- |
| Grid layout | Columns, headers, and levels match how your team organizes risk analysis |
| Calculation | Formulas (RPN or your equivalent) reflect your scoring model |
| Conditional formatting | Risk bands and thresholds align with your acceptability criteria |
| Upstream traceability | Links to requirements/hazards work with your link roles and document layout |
| Downstream tasks | Mitigation tasks integrate with your existing Polarion task tracking |
| Reviews | Comment-based or work-item-based review fits your audit needs |
| Export | Excel and PDF output meet your reporting and archival requirements |
| Polarion permissions | All data is governed by standard Polarion authorization |
## What's next — building your own risksheet
Once evaluation confirms the fit, move on to building a real risksheet for your project. The single most important rule: **start from a solution template, never from a blank `risksheet.json`**. Templates encode methodology expertise — column structures, hierarchical levels, RPN formulas, cell decorators, review workflows, and risk-band styles — that took years of practice to refine. Copy the template that most closely matches your methodology (functional safety FMEA, HARA, TARA, or another variant) and adapt only what you need to change: rating scales, threshold bands, link roles, or column labels. Building from scratch almost always reproduces a worse version of what the templates already provide.
In practice this means: provision a new LiveDoc from a template (default folder path is `Risks/Risk Specification`), let the template's `risksheet.json` configuration flow in automatically, and only attach a custom `risksheet.json` to the document when you need to override specific fields. If you do attach one, the filename must be exactly `risksheet.json` — anything else is ignored and the template configuration is used instead.
* Adapt a template to your process: [Basic Configuration](/risksheet/getting-started/basic-configuration).
* Learn the grid layout, toolbar, and navigation: [Understanding the Interface](/risksheet/getting-started/understanding-interface).
* Browse pre-built configurations for other methodologies: [Configuration Examples](/risksheet/reference/examples/index).
## Next steps
* Install Risksheet in your own Polarion environment: [Installation](/risksheet/getting-started/installation).
* Learn the grid layout, toolbar, and navigation: [Understanding the Interface](/risksheet/getting-started/understanding-interface).
* Modify a template's columns, formulas, and decorators: [Basic Configuration](/risksheet/getting-started/basic-configuration).
* Browse pre-built configurations for other methodologies: [Configuration Examples](/risksheet/reference/examples/index).
* Adapt a template to your process: [Configuration Management](/risksheet/guides/configuration/index).
# Getting Started
Source: https://learn.nextedy.com/risksheet/getting-started/index
Nextedy RISKSHEET is a grid-based analysis app for Siemens Polarion ALM that visualizes and edits Polarion work items as a structured, traceable matrix.
## Learning Path
Follow these pages in order. Each step builds on the previous one.
Deploy Risksheet to your Polarion server and verify the installation.
Activate an evaluation license and pick a solution template that matches your industry.
Learn the grid layout, top panel, toolbar, and review controls.
Adapt a solution template to your process by modifying its sheet configuration.
**Start from a solution template**
Risksheet ships with solution templates covering common methodologies such as FMEA, HARA, TARA, STRIDE, and CVSS. Pick the closest template for your industry or methodology, understand its sheet configuration, then modify it to match your process. For evaluation, start with the functional safety template — it is the simplest. HARA and other advanced templates showcase features like catalogs, subsheets, and cross-project reuse.
**Risksheet is a generic traceability tool**
Although Risksheet is most often used for risk analysis, the data model has two abstract slots — risk items and task items — that can be bound to **any** two Polarion work item types. The same engine supports requirements traceability matrices, V\&V matrices, and other compliance matrices, not just FMEA or HARA. All data lives in Polarion work items; Risksheet visualizes and edits it, but does not store data separately.
## Where to Next
After completing the learning path:
* [**Concepts**](/risksheet/concepts/index) — understand the data model, levels, and configuration hierarchy.
* [**How-To Guides**](/risksheet/guides/index) — task-oriented recipes for column configuration, risk management, export, reviews, and administration.
* [**Reference**](/risksheet/reference/index) — full reference for columns, fields, formulas, styling, templates, and the configuration format.
* [**Troubleshooting**](/risksheet/troubleshooting/index) — resolve common issues.
* [**FAQ**](/risksheet/faq/index) — answers to frequently asked questions.
# Installation
Source: https://learn.nextedy.com/risksheet/getting-started/installation
By the end of this tutorial, you will have Nextedy RISKSHEET installed in your Siemens Polarion ALM environment with the administration pages accessible and the Risksheet topic available for your project.
## What You Will Achieve
By the end of this tutorial, you will have Risksheet installed in your Siemens Polarion ALM environment with the administration pages accessible and the Risksheet topic available for your projects. You will be ready to enable Risksheet in a project and create your first risk analysis document.
## Prerequisites
Before you begin, confirm the following:
* [Supported Polarion ALM](/overview/resources/polarion-version-support) version installed and running
* You have **administrator access** to the Polarion server (file system access and Polarion admin role)
* You have the Risksheet installation package (`.zip` or `.jar` file) provided by Nextedy
* You have a valid Risksheet license file (or plan to use the evaluation period)
* Server restart capability (you will need to restart Polarion during the process)
**Existing Projects vs. New Projects**
If you are adding Risksheet to a Polarion instance that already has projects, you will need to enable Risksheet in each project individually after the server-level installation. This tutorial covers the server-level installation. See [Add Risksheet to Existing Project](/risksheet/guides/administration/project-setup) for project-level setup.
## Installation Steps
### Step 1: Deploy the Plugin Files
Copy the Risksheet plugin files to your Polarion extensions directory:
```text theme={null}
[POLARION_INSTALL]/polarion/extensions/
```
Place the Risksheet `.jar` files and any accompanying resources into this directory. If you received a `.zip` archive, extract its contents into the extensions folder.
You should see the Risksheet plugin files listed in the extensions directory alongside any other Polarion extensions you have installed.
### Step 2: Delete the Configuration Cache
This step is critical. Remove the cached Polarion configuration directory to ensure Polarion detects the new plugin:
```text theme={null}
[POLARION_INSTALL]/data/workspace/.config
```
Delete the entire `.config` directory (not just its contents). Polarion will regenerate this directory on the next startup.
**Do Not Skip This Step**
Failing to delete `[POLARION_INSTALL]/data/workspace/.config` is the most common cause of installation problems. If you skip this step, the Risksheet **Setup** and **License** pages in Polarion administration will appear empty with no content. This step is required both for fresh installations and for updates to newer versions.
### Step 3: Restart Polarion
Restart the Polarion server to load the new plugin:
Depending on your environment, use the appropriate service command:
* **Linux**: `systemctl restart polarion` or the Polarion-provided startup script
* **Windows**: Restart the Polarion service through the Services management console
Wait for Polarion to fully start. The startup process may take several minutes depending on your server configuration and the number of installed extensions.
### Step 4: Verify the Setup Page Loads
After Polarion restarts, log in as an administrator and navigate to:
**Administration > Nextedy Risksheet > Setup**
You should see the Risksheet Setup page render with content (controls, status indicators, and template management options). This confirms that Risksheet loaded successfully and the configuration cache was rebuilt during startup.
**Empty Setup Page = Cache Issue**
If the Setup page loads but shows no content, the `.config` directory was not fully removed in Step 2. Stop Polarion, delete the `.config` directory again, and restart.
Provisioning solution templates (functional safety, FMEA, HARA, TARA, STRIDE, and similar starting points) is covered separately in [Evaluate Risksheet](/risksheet/getting-started/evaluation), where you can install a ready-to-use sample project and explore solution templates. Risksheet documentation always recommends starting from a solution template that matches your industry or methodology, then modifying its sheet configuration to fit your process — never start from a blank sheet configuration.
### Step 5: Verify the License Page
Navigate to **Administration > Nextedy Risksheet > License** to verify your license status.
You should see:
* Your license type (Standard or Evaluation)
* The number of server users detected
* The expiration date (if applicable)
* The license status showing as **Active**
If the License page appears empty with no content, return to Step 2 and confirm the `.config` directory was fully deleted, then restart Polarion again.
**Polarion License Tiers Affect Risksheet Use**
Risksheet respects Polarion ALM licensing. Risksheet license affects only the Risksheet editor itself. Users with an active (named/concurrent) license can actively edit data on the Risksheet. The rest of the server users get a Reviewer license. Reviewer licenses are read-only.
### Step 6: Add the Risksheet Topic to Your Project Views
To make Risksheet accessible inside a project, navigate to that project and open **Administration > Topics**. Add the Risksheet topic entry to your project's navigation views (hats):
```xml theme={null}
```
This entry must be present in every Polarion view (hat) where users need to access Risksheet. Without it, users assigned to that view will be redirected to the space home page when they attempt to open a Risksheet document.
**Topic Required for Each View**
If your Polarion instance uses multiple views (hats) for different roles, add the ` ` entry to **each view** that should have Risksheet access. Missing the topic in a specific view is the most common reason users report that Risksheet is not working for them while it works for others.
You should see "Risksheet" (or your configured tool name) appear in the project navigation sidebar after saving the Topics configuration.
### Step 7: Verify the Installation
Open a project where you added the Risksheet topic and click the **Risksheet** entry in the navigation sidebar. You should see the Risksheet home page showing:
* Available folders for creating new risk documents
* Template selection options
* Any existing risk analysis documents in the project
If you are redirected to the space home page instead, verify the topic configuration in Step 6 for the view your user account is assigned to.
## Post-Installation Checklist
| Item | How to Verify |
| ------------------------------------------- | ---------------------------------------------------------------- |
| Plugin files deployed to `extensions/` | Files visible in `[POLARION_INSTALL]/polarion/extensions/` |
| `.config` directory deleted and regenerated | Folder reappears after restart |
| Polarion restarted successfully | Polarion logs show clean startup |
| Setup page loads with content | **Administration > Nextedy Risksheet > Setup** renders controls |
| License page shows active license | **Administration > Nextedy Risksheet > License** loads with data |
| Risksheet topic added to project views | Risksheet visible in project sidebar |
| Risksheet home page accessible | No redirect to space home |
## Next Steps
With Risksheet installed and the administration pages accessible, proceed to:
* [Evaluate Risksheet](/risksheet/getting-started/evaluation) -- install the sample project and explore solution templates
* [Basic Configuration](/risksheet/getting-started/basic-configuration) -- customize column layouts and risk parameters in the sheet configuration
* [Understanding the Interface](/risksheet/getting-started/understanding-interface) -- learn the grid navigation and editing controls
# Understanding the Interface
Source: https://learn.nextedy.com/risksheet/getting-started/understanding-interface
## What you will achieve
By the end of this tutorial, you will be familiar with every major area of the Nextedy RISKSHEET interface: the toolbar, column headers, column group headers, the data grid, row headers, hierarchical row levels, context menus, cell editors, filtering controls, and saved views. You will know how to navigate a risk analysis table, identify different column types by their visual cues, understand the hierarchical row structure used for Failure Mode and Effects Analysis (FMEA) and Hazard Analysis and Risk Assessment (HARA) workflows, and perform basic interactions such as editing, sorting, and filtering.
Risksheet is a generic tool that supports any risk management methodology, including FMEA, HARA, Threat Analysis and Risk Assessment (TARA), STRIDE, and Common Vulnerability Scoring System (CVSS) analysis. The examples on this page use FMEA terminology, but the interface concepts apply identically to every methodology.
## Prerequisites
* Risksheet is installed on your Siemens Polarion ALM instance (see [Installation](/risksheet/getting-started/installation))
* You have access to a Polarion project with at least one risksheet document
* You are logged into Polarion with a valid license (see [Evaluate Risksheet](/risksheet/getting-started/evaluation))
**Sample Project**
If you do not have an existing risksheet document, follow [Evaluate Risksheet](/risksheet/getting-started/evaluation) to set one up before continuing with this tutorial. The recommended approach is to pick the closest Nextedy solution template for your industry and methodology, then adapt it — never start from a blank configuration.
Navigate to your Polarion project and open a LiveDoc document that contains a risksheet. The grid loads within the document page, replacing the standard Polarion table view with an interactive, Excel-like sheet.
You should see the full grid occupying the document area, with a toolbar row above and the data grid below.
The layout divides into four zones stacked top to bottom: the top panel area, the Risksheet toolbar, the header area (group headers and column headers), and the data grid containing all risk item rows. The Polarion navigation bar is shown on the left. All data shown in the grid lives in Polarion as standard work items — Risksheet does not maintain its own data store. Every change you make is saved as an edit to a Polarion work item, subject to Polarion's authorization rules and traceable through Polarion's audit infrastructure.
The toolbar row sits at the top of the grid. From left to right, it provides buttons for the most common operations:
| Button | Action | Notes |
| ------------------ | ---------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Menu** | Open the Risksheet menu | Hosts configuration, override, and other commands. Configuration is opened via **Menu > Configuration > Edit Risksheet Configuration** (only available to users with administrator permissions) |
| **Save** | Save all pending changes to the server | Batches multiple edits into one save operation |
| **Undo** | Undo the last edit | Client-side undo, works before save |
| **Redo** | Redo an undone edit | Cleared when you make a new edit |
| **+ Item** | Add a new top-level risk item | Adds a row at the highest hierarchy level |
| **+ Failure mode** | Add a new failure mode under the current item | Labels reflect the configured `levels` |
| **+ Cause** | Add a new cause under the current failure mode | Labels reflect the configured `levels` |
| **Delete** | Remove the selected item | Trash icon; clears or deletes the row depending on context |
| **+ Task** | Add a downstream task (mitigation, control) | Label reflects `dataTypes.task.name` |
| **Unlink Task** | Unlink the selected task from the risk | |
| **Refresh** | Reload the grid data from the server | Circular-arrow icon; pulls the latest work item values |
| **Views** | Switch between saved column visibility presets | Only visible if views are configured |
| **Fullscreen** | Expand the grid to fill the browser window | |
| **Search** | Search for any specific data on the Risksheet | |
| **Find & Replace** | Open a sidebar to find and replace the text | |
At the top-right of the toolbar, **Export to XLSX** downloads the current view as an Excel file (respecting column visibility settings) and **Export to PDF** generates a formatted PDF export (configurable through the PDF export configuration).
Hover over each button to see its tooltip description. The toolbar buttons are context-aware: some are disabled when there are no pending changes (Save, Undo, Redo) or when you lack the necessary permissions (configuration access).
**Keyboard Shortcuts**
Use `Ctrl+S` (or `Cmd+S` on macOS) to save, `Ctrl+Z` to undo, and `Ctrl+Y` to redo. Copy cells with `Ctrl+C` and paste with `Ctrl+V`. These shortcuts work whenever the grid has focus.
Risksheet supports two header rows above the data cells:
1. **Column group headers** — the top row that spans multiple columns under a shared label (for example, "Initial Risk Assessment" or "Revised Assessment"). These groups are configured via the `headerGroup` property on individual column definitions. The height of this row is set by `headers.columnGroupHeader.height` (default: `32` pixels). Groups can be collapsed to hide their member columns; columns marked with `collapseTo: true` remain visible as a summary when the group collapses.
2. **Column headers** — the row directly above the data cells showing individual column names (for example, "Severity", "Occurrence", "Detection", "RPN"). The height is set by `headers.columnHeader.height` (default: `32` pixels). Each header displays the value from the column's `header` property.
Click a column header to sort the grid by that column. Click again to reverse the sort direction. A third click removes the sort. Sorting is performed entirely client-side, so results appear instantly with no server round-trip.
**Collapsible Groups**
Click the collapse icon on a column group header to hide grouped columns. The column whose definition includes `collapseTo: true` stays visible as a summary; click the icon again to expand and show all columns.
Risksheet creates a visual hierarchy through cell merging, configured by the `levels` array in the sheet configuration. The underlying data model itself has exactly two entity types — risk items and downstream task items — both stored as ordinary Polarion work items. The grid can show three, four, or more visual levels by merging cells that share the same value in a designated control column.
Each entry in the `levels` array requires three properties:
| Property | Type | Purpose |
| --------------- | ------ | ----------------------------------------------------------------------------------------- |
| `name` | string | Display name shown in the navigation and zoom menus (for example, "Item", "Failure mode") |
| `controlColumn` | string | Column ID whose value is used as the grouping key for cell merging |
| `zoomColumn` | string | Column ID used as the target for zoom or drill-down navigation |
A typical FMEA sheet configuration uses three visual levels on the risk side, plus a downstream task entity:
```yaml theme={null}
levels:
- name: Item
controlColumn: item
zoomColumn: item
- name: Failure mode
controlColumn: failureMode
zoomColumn: failureMode
- name: Cause
controlColumn: systemItemId
zoomColumn: causes
dataTypes:
risk:
type: failureMode
task:
type: mitigation
role: mitigates
name: Task
zoomColumn: taskTitle
```
In this example, all risk rows are the same Polarion work item type (`failureMode`). The three visual levels appear purely through cell merging — the "Item" column merges consecutive rows that share the same item, and the "Failure mode" column merges consecutive rows that share the same failure mode. Downstream mitigation tasks are separate Polarion work items configured under `dataTypes.task`.
The **row header** column appears on the left side of the grid. It displays the work item ID and can show conditional color coding based on risk values. For example, the `headers.rowHeader.renderer` property names a cell decorator function (defined in the `cellDecorators` section) that color-codes row headers based on the revised RPN value, giving you an at-a-glance risk summary.
Click any editable cell in the grid to enter edit mode. The cell editor that appears depends on the column `type` configured in the sheet configuration:
| Column Type | Editor | Behavior |
| -------------------------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------- |
| `text` | Multi-line text input | Free-form text |
| `enum:`, `rating:` | Dropdown selector | Shows values from the referenced Polarion enumeration; can show descriptions when `showEnumDescription: true` |
| `multiEnum:` | Multi-select checkbox dropdown | Shows up to 2 selections, then "+N more" |
| `boolean` | Checkbox toggle | Click to toggle true/false |
| `date` | Date picker | Stores as `YYYY-MM-DD` |
| `datetime` | Date-time picker | Stores as ISO datetime |
| `int`, `float`, `currency` | Numeric input | Validates numeric entry |
| `itemLink` | Link picker with search | Browse or create linked work items |
| `multiItemLink` | Multi-link picker | Link to multiple work items |
| `taskLink` | Task link picker | Link or create downstream task items |
Severity, occurrence, and detection scales are not defined inside the sheet configuration. They are Polarion enumerations defined once in **Administration > Enumerations** and referenced from a column via `type: rating:` plus `bindings: `. The server loads the available values automatically.
After editing, your change is held in memory until you click **Save** or press `Ctrl+S`. Risksheet batches multiple edits and sends them to the server together, so you can make several changes before saving. The toolbar Save button shows an indicator when there are unsaved changes.
**Read-Only Cells**
Some cells cannot be edited. Cells with a `formula` (calculated columns), a `serverRender` script, or that reference system fields such as `id`, `type`, `project`, `created`, `updated`, or `outlineNumber` are automatically read-only. Columns explicitly marked with `readOnly: true`, and any grid viewing a historical revision (not the current head), are also read-only. Read-only cells display a visual indicator when you attempt to click them.
Right-click any row to open the context menu. The menu provides row-level operations:
| Menu Item | Action | Availability |
| --------------------- | --------------------------------------------------------------- | ------------------------------------------------------------- |
| **Open Row Item** | Opens the work item in the standard Polarion editor | Always available |
| **Open Linked Item** | Opens a linked work item from an item link or task column | When the cell contains a valid item link |
| **New \[Level] Item** | Creates a new work item at the specified hierarchy level | When `levels[].showInMenu` is `true` and the grid is editable |
| **New Task** | Creates a downstream mitigation task linked to the selected row | When the `dataTypes.task` configuration allows task creation |
| **Remove Row Item** | Removes the selected item from the grid | In editable grids only |
| **Freeze Pane** | Freezes columns to the left for horizontal scrolling | Always available |
| **Unfreeze Pane** | Removes column freezing | When columns are currently frozen |
The available menu items depend on the row's hierarchical level, the `dataTypes` configuration, and your Polarion user permissions. Custom context menu actions can also be added through the configuration's extensibility points.
Risksheet supports column-level filtering for any column where `filterable` is set to `true` (the default). Click the filter icon in a column header to open the filter panel, then select or deselect values to narrow the displayed rows.
Filtering is performed client-side, so results appear instantly. You can apply filters to multiple columns simultaneously. Filtered rows are hidden from view but not removed from the data — clearing the filter restores all rows.
Filters persist within your browser session but are not saved across page reloads. Filters are applied on the client and do not affect other users viewing the same document.
If your sheet configuration includes saved views (defined in the `views` array), use the **Views** dropdown in the toolbar to switch between different column visibility presets. Each view shows a different subset of columns, allowing you to focus on specific aspects of the analysis without scrolling through all columns.
A view is defined by its `name` and a `columnIds` array listing the columns to show. The special value `@all` includes every column, and a `-` prefix excludes a specific column from the set. One view per configuration may be marked `defaultView: true` to load automatically when the document is opened.
```yaml theme={null}
views:
- name: Full FMEA
defaultView: true
columnIds:
- "@all"
- name: Risk Summary
columnIds:
- failureMode
- rpn
- status
- name: Mitigation Tracking
columnIds:
- "@all"
- "-initialAssessment"
```
Common view configurations include:
| View Name | Columns Shown | Use Case |
| ------------------- | ----------------------------------------------------------------- | ----------------------------- |
| Full FMEA | All columns visible | Comprehensive analysis review |
| Risk Summary | Failure mode, RPN, status | Management reporting |
| Mitigation Tracking | Mitigation actions, assignee, due date, status | Action item follow-up |
| Initial vs. Revised | Severity, occurrence, detection, RPN for both initial and revised | Before/after comparison |
You can also reset your personal column width and visibility customizations back to the configuration default using the reset columns command.
## Next Steps
Now that you understand the interface layout and basic interactions, continue with these tutorials:
* [Basic Configuration](/risksheet/getting-started/basic-configuration) — learn how to customize the sheet configuration
* [How-To Guides](/risksheet/guides/index) — task-oriented guides for specific workflows such as column configuration, export, and review management
* [Concepts](/risksheet/concepts/index) — deeper explanations of architecture, data model, and traceability
# Configure the AI Assistant
Source: https://learn.nextedy.com/risksheet/guides/administration/configure-the-ai-assistant
Enable the AI Assistant in Nextedy RISKSHEET — connect a language model, license and switch on the assistant per project, define your first action, and point a sheet at it.
The **AI Assistant** offers no actions until you define them. This guide takes a Risksheet project from nothing to a working action on a risk row, in the order the pieces have to be in place.
For the model behind actions, see [AI Assistant](/risksheet/concepts/ai-assistant). For every field of the action file, see [AI Action Configuration](/risksheet/reference/configuration/ai-action-configuration).
## Prerequisites
* Polarion administrator rights on the server and on the project.
* The **Nextedy AI** package installed, and a valid **Nextedy AI** license — see [Nextedy AI](/overview/resources/nextedy-ai) and [Installing a License](/overview/resources/installing-the-license).
* A Risksheet document whose configuration you can edit.
* Access to a language-model endpoint. The in-sheet assistant calls the model from your Polarion server, so the server needs an endpoint and a key it can use.
**The in-sheet assistant needs a model endpoint configured on the server.** This is separate from the license. Until a key resolves, the assistant reports itself unavailable and the toolbar button stays disabled — the most common reason a correctly licensed installation offers no AI at all.
## Connect a language model
Set these in Polarion's global context properties (`.polarion/context.properties`):
```properties theme={null}
nextedy.ai.baseUrl=https://api.openai.com/v1
nextedy.ai.model=gpt-4o-mini
```
| Property | Default | Description |
| -------------------- | --------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `nextedy.ai.baseUrl` | `https://api.openai.com/v1` | Base URL of the model API. Point it at your own compatible endpoint to keep traffic inside your infrastructure. |
| `nextedy.ai.model` | `gpt-4o-mini` | Model identifier sent with each request. |
The API key is resolved from the first of these that holds a value:
A credential stored under the key `nextedy-openai-apikey`. This is the option to prefer — the vault keeps the secret encrypted and access-controlled.
`nextedy-openai-apikey`, passed to the Polarion process.
`OPENAI_API_KEY` in the Polarion process environment.
If none of them resolves, the assistant is unavailable.
The endpoint, model, and key are re-read per request, so changing any of them takes effect on the next action — no Polarion restart needed.
These properties are read from the **global** context only. They cannot be varied per project.
## Switch the assistant on for a project
Three project properties control what a project offers. All default to on, so a licensed server with a configured endpoint offers the assistant everywhere unless you opt out.
| Property | Default | Description |
| ---------------------------------- | ------- | ----------------------------------------------------------------------------------------------- |
| `nextedy.risksheet.aiAssistant` | `true` | The in-sheet AI Assistant in Risksheet documents. Set to `false` to keep a project AI-free. |
| `nextedy.risksheet.adminAssistant` | `true` | The assistant inside the Risksheet configuration editor. |
| `nextedy.risksheet.promotions` | `true` | Whether the toolbar advertises the assistant on installations that are **not** licensed for it. |
### Hiding a feature versus hiding an advert
These are two different jobs, and it is worth being clear which one you want:
* **You do not have the assistant, and do not want it advertised.** On an unlicensed installation the toolbar still shows the sparkle button, disabled, whose tooltip explains what the Nextedy AI package would add and how to get it. That is deliberate promotion. Setting `nextedy.risksheet.promotions` to `false` removes it.
* **You have the assistant, but not in this project.** Setting `nextedy.risksheet.aiAssistant` to `false` removes the in-sheet assistant from that project's documents entirely — no button, no cell-menu entries — while other projects on the same server keep it.
`nextedy.risksheet.promotions` only takes effect while the instance is unlicensed; on a licensed server it changes nothing, because there is no advert to suppress.
## Write an action
Action files are YAML, and they live in the Polarion configuration folder `.polarion/nextedy/ai/` — either in the project, or globally so several projects can share them. You can edit them through **Administration → Nextedy AI → AI Assistant Actions**, which lists the files in that folder.
Start with one action. This one looks for existing harm work items to link onto a HARA row:
```yaml actions.yaml theme={null}
globals:
systemContext: "An infusion pump delivering medication intravenously in a clinical setting."
actions:
find-harms:
label: "Find Harms"
message: "Suggest potential harms for this hazardous situation"
scope:
columns:
- hazardousSituation
- hazard_title
contextSources:
row:
fields:
useStep: "Use step"
hazardousSituation: "Hazardous situation"
hazard_title: "Hazard"
discover:
keywordPrompt: >
${globals.systemContext}
Generate keywords naming the types of HARM a patient or operator could suffer
as a consequence of the hazardous situation described in the context.
rankPrompt: >
Select the harms that could plausibly result from this hazardous situation.
If none of the candidates applies, return none rather than the closest match.
search:
maxCandidates: 30
output:
limit: 5
sortBy: "relevance"
apply:
field: harm
```
What each part is doing:
* **`label`** is the text in the cell menu and the panel list. **`message`** is the prompt title the analyst sees above the results.
* **`scope.columns`** restricts the action to those columns in the cell menu. Omit it and the action is offered on every column.
* **`contextSources.row.fields`** maps sheet field ids to the labels the model reads. Write the labels as prose — they are the model's only description of the row.
* **`discover.keywordPrompt`** tells the assistant what kind of thing to look for; **`discover.rankPrompt`** tells it which of the items it finds are worth proposing.
* **`apply.field`** names the column a recommendation is written into — and it also determines which work-item types the assistant proposes, since those come from the column's own configuration.
* **`globals`** are reusable strings; a `${globals.}` placeholder is substituted into an action's prompts.
**A misspelled field name has no effect.** A dropped letter in `rankPrompt`, for instance, leaves the action behaving as if you had not set it at all. Check names against [AI Action Configuration](/risksheet/reference/configuration/ai-action-configuration) when an action ignores something you configured.
## Point the sheet at the file
In the Risksheet configuration, name the file in the `global` block:
```yaml theme={null}
global:
assistantConfig: actions
```
The `.yaml` extension is optional. To share one project's file with another, qualify it with the project id — `"OtherProject/actions"`.
Until `assistantConfig` is set, the sheet requests no actions and the assistant has nothing to offer even on a fully configured server.
## Verify
Actions are read once when the sheet loads, so a configuration change needs a reload — not just a refresh of the grid.
A sparkle **AI Assistant** button sits at the right-hand end of the toolbar. Hover it: an enabled button tooltipped *"AI Assistant"* means everything resolved. A disabled one names the problem — the promotional text when the package or endpoint is unreachable, the license when the license is invalid, or *"AI Assistant — configure AI actions for this risksheet to enable it."* when the actions have not loaded.
Right-click a cell in one of the columns named in `scope.columns`. Your action should appear in its own group, after the **Open … Item** entries and before the **New …** entries. If the toolbar button is greyed out, no cell-menu entries appear at all.
Pick a row whose descriptive fields are filled in. An empty row gives the assistant nothing to work with, and a thin result is easy to misread as a broken configuration.
## Tune the results
Most disappointing results are a prompt problem rather than a plumbing problem.
* **Put the direction in the right prompt.** `keywordPrompt` should describe the *kind of result* you want found; `rankPrompt` should describe what makes a suggestion acceptable. Judgements about plausibility belong in `rankPrompt`; keep `keywordPrompt` to a plain description of the subject matter.
* **State the system context once** in `globals` and reuse it, rather than repeating it per action.
* **Give the model permission to return nothing.** An explicit "return none rather than the closest match" measurably reduces weak suggestions being offered as real ones.
* **Write distinctive words, and expect loose matching.** Matching is deliberately broad, so precision comes from `rankPrompt` rather than from a cleverer choice of words. Very short abbreviations do not help — prefer whole, distinctive terms in the fields the action reads.
### Overriding the built-in prompts
Four global context properties replace the assistant's built-in prompt wording for every action. Leave them unset to keep the defaults.
| Property | Replaces |
| ---------------------------- | ----------------------------------------------------------------------------------- |
| `nextedy.ai.keywordPrompt` | The built-in wording behind an action's `keywordPrompt`. |
| `nextedy.ai.processorPrompt` | The default used when an action defines no `rankPrompt`. |
| `nextedy.ai.relevancePrompt` | The built-in instruction on how closely a suggestion must fit before it is offered. |
| `nextedy.ai.jsonPrompt` | The built-in instruction that fixes the format the assistant expects an answer in. |
`nextedy.ai.jsonPrompt` governs the format the assistant expects the model's answer in. Changing it can stop recommendations appearing at all. Override it only when you know the shape you are asking for.
## Troubleshoot
Turn on logging while diagnosing, then turn it off again:
| Property | Default | Description |
| ---------------------- | ------- | ------------------------------------------------------------------------------- |
| `nextedy.ai.telemetry` | `false` | Logs action requests and their results at INFO. Safe to leave on in production. |
Warnings and errors are always logged regardless.
| Symptom | Likely cause |
| ------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Button disabled, tooltip is the promotional text | No model key resolves, or the Nextedy AI package is not installed. |
| Button disabled, tooltip names the license | The Nextedy AI license is missing or invalid, or no Polarion user could be identified. |
| Button disabled, tooltip asks for AI actions | `assistantConfig` is unset, names a file that does not exist, or the file defines no `actions`. |
| No button at all | The assistant is switched off for the project, or promotion of AI features is switched off. |
| An action is missing from a cell menu but present in the panel list | The column is not in that action's `scope.columns`. |
| Every run says no matching items were found | No items of the target column's work-item types are found — check the column's configured types, and that the items exist and are visible to the user. |
## See Also
* [AI Assistant](/risksheet/concepts/ai-assistant) — the model behind actions and what has to be in place
* [Use the AI Assistant](/risksheet/guides/risk-management/use-the-ai-assistant) — the analyst's task
* [AI Action Configuration](/risksheet/reference/configuration/ai-action-configuration) — every field, with defaults
* [Nextedy AI](/overview/resources/nextedy-ai) — the package and its license
* [Configure Permissions](/risksheet/guides/administration/permissions) — how sheet permissions apply to what the assistant can see
* [Customize the Top Panel](/risksheet/guides/customization/top-panel) — where a script can add extra context to an action
# Administration
Source: https://learn.nextedy.com/risksheet/guides/administration/index
Manage Nextedy RISKSHEET installation, updates, permissions, and project configuration.
Upgrade Risksheet to a new version, including pre-update checks and post-update verification.
Set up field-level permissions, admin access control, and read-only enforcement for risk items.
Enable Risksheet in a Polarion project that was not created from a Nextedy template.
Connect a language model, switch the assistant on per project, and define the actions it offers on a risk row.
Resolve common administration problems including empty setup pages, log errors, and license issues.
**New to Risksheet Administration?**
If you are setting up Risksheet for the first time, start with the [Installation](/risksheet/getting-started/installation) tutorial, then return here for ongoing administration tasks.
# Configure Permissions
Source: https://learn.nextedy.com/risksheet/guides/administration/permissions
Control who can view, edit, and administer Nextedy RISKSHEET documents by configuring project roles, field-level permissions, topic visibility, and template project access.
## Permission Architecture Overview
Risksheet enforces permissions at multiple layers. Understanding how these layers interact prevents common issues where users see broken layouts, cannot save edits, or are redirected away from the Risksheet view entirely.
| Permission Level | What It Controls | Where Configured |
| --------------------------- | ----------------------------------------------------------- | ----------------------------------------------------------------- |
| **Project Admin role** | Configuration editing, template management, `canAdmin` flag | Polarion project roles |
| **Sheet-level `readonly`** | Entire Risksheet read-only for all users | `readonly` property in sheet configuration |
| **Downstream `readonly`** | Prevents edits to linked items from other documents | `downstreamReadonly` property in sheet configuration |
| **Field-level permissions** | Per-field read-only based on workflow state | Polarion Permissions Management + `checkInstanceFieldPermissions` |
| **Reviewer mode** | Restricts to review-specific UI controls | `reviewer` property in sheet configuration |
| **Topic visibility** | Whether Risksheet appears in project navigation | Polarion Administration > Topics |
| **Template project access** | Whether the sheet loads the correct configuration | Polarion project read permissions |
Risksheet automatically determines admin status from the user's Polarion project role. The `canAdmin` property is set at runtime based on the current user's permissions --- you do not set it manually in sheet configuration.
When `canAdmin` is `true`, the user can:
* Open the Risksheet configuration editor (accessible via **Menu > Configuration > Edit Risksheet Configuration**)
* Edit sheet configuration directly or through the configuration editor UI
* Manage global templates and template paths
* Access the configuration editor at the URL: `/risksheet/configuration/?project=&document=`
When `canAdmin` is `false`, the **Edit Risksheet Configuration** entry under **Menu > Configuration** is hidden and the user cannot modify the sheet structure.
To grant admin access to a user:
1. Navigate to **Administration** > **Users & Roles** in your Polarion project.
2. Assign the user the **Admin** role for the project.
3. The user will see `canAdmin = true` on their next Risksheet load.
**Admin Users Can Bypass Read-Only Fields**
Risksheet can modify Polarion fields that are marked read-only when the user has administrator permissions. This happens because Polarion's read-only field APIs are not available to third-party applications. Admin users should exercise caution when editing approved or verified risk items.
To make the entire Risksheet read-only for all users (regardless of their project role), set the `readonly` property in sheet configuration:
```yaml theme={null}
readonly: true
```
| Property | Type | Default | Description |
| -------------------- | ------- | ------- | ----------------------------------------------------------------------------------------------------------- |
| `readonly` | boolean | `false` | Makes the entire Risksheet read-only, preventing any user edits to grid cells or structure |
| `downstreamReadonly` | boolean | `false` | Makes downstream linked items (tasks, mitigations) read-only to prevent edits to items from other documents |
| `reviewer` | boolean | `false` | Enables reviewer mode which restricts editing and shows review-specific UI controls |
**Historical Revisions Are Always Read-Only**
When viewing a historical revision of a document (via the `revision` URL parameter), Risksheet automatically forces `readonly` to `true`, regardless of the configuration setting. This prevents accidental edits to historical snapshots.
Polarion's built-in "Read-only Fields" UI property has no API, so Risksheet cannot enforce it directly. Instead, use Polarion Permissions Management with the `checkInstanceFieldPermissions` configuration property to control which fields are editable based on the work item's current workflow state.
### Enable the Property
1. Navigate to **Administration** > **Configuration Properties** in Polarion.
2. Add the following property:
```
nextedy.risksheet.checkInstanceFieldPermissions=true
```
3. Save the configuration.
### Configure Field Permissions in Polarion
1. Navigate to **Administration** > **Permissions** in your Polarion project.
2. Define which fields can be edited in each workflow state. For example:
* **Draft** state: all fields editable
* **In Review** state: only review-related fields editable, risk parameters locked
* **Approved** state: all fields read-only
3. Risksheet reads these permission rules at runtime and marks individual cells as read-only based on each work item's current status.
**Polarion Read-Only Fields Are Not Supported**
Polarion's "Read-only Fields" property (configured in the work item type's workflow settings) has no API accessible to third-party apps. Risksheet cannot read or enforce this property. You **must** use Permissions Management with `checkInstanceFieldPermissions=true` to achieve field-level read-only behavior. Without this property enabled, Risksheet cannot determine which fields should be locked.
**Known Limitation: Child Document Items**
There is a known issue where items from child documents may display fields as editable in the grid but block the save operation when field permissions deny modification. This can cause confusing "save failed" errors. A fix is planned for a future Risksheet version. In the meantime, ensure child document items have consistent permission configurations.
### How Field Permissions Appear in the Grid
When `checkInstanceFieldPermissions` is enabled:
* Read-only cells receive a `readonly` CSS class, which provides a visual indicator (typically a subtle background change)
* Attempting to edit a read-only cell has no effect --- the cell editor does not activate
* The `readOnly` column property is automatically set to `true` for restricted fields, overriding the column-level configuration
* System fields (`author`, `resolution`, `created`, `updated`, `type`) are always read-only regardless of permission settings
When your Risksheet uses a configuration template from a different Polarion project (via `source` or `templateName` in sheet configuration), all users who open the Risksheet must have **read access** to the template project. Without this access, Risksheet fails to load the template configuration and falls back to a default or broken structure.
### Symptoms of Missing Template Access
* Users see a completely different Risksheet structure than other users in the same project
* The column layout does not match the expected FMEA/HARA configuration
* No explicit error message is displayed --- the sheet simply loads with wrong columns
### Resolution
1. Identify the template project by checking the `source` or `templateName` property in sheet configuration:
```yaml theme={null}
source: /ProjectTemplates/FMEA-Template/risksheet.json
templateName: FMEA Standard Template
```
2. Navigate to the template project's **Administration** > **Users & Roles**.
3. Grant **read access** to all users and groups that need to use the Risksheet in the consuming project.
**Silent Failure on Missing Template Permissions**
When a user lacks read access to the template project, Risksheet does **not** display an error message. Instead, it silently loads a different (likely broken) configuration. If a user reports seeing a different sheet structure than their colleagues, check their access to the template project first.
Risksheet must be registered as a topic in your Polarion project's navigation for users to access it from the sidebar menu. If the topic is not configured for a user's role or view, they are redirected to the space home page instead of the Risksheet view.
### Add Risksheet to Navigation
1. Navigate to **Administration** > **Topics** in your Polarion project.
2. Ensure the Risksheet topic is listed and enabled.
3. Verify that the topic is assigned to all relevant **views** and **roles**. Each view/role combination must include the Risksheet topic.
**Risksheet Redirects to Space Home Page**
If specific users are redirected to the space home page when navigating to Risksheet while other users can access it normally, the issue is almost certainly a missing topic assignment. Check **Administration** > **Topics** and verify the Risksheet topic is configured for that user's view/role combination.
Formula-generated fields can conflict with field-level permissions in ways that cause unexpected save failures. Understanding this interaction prevents frustrating errors for end users.
### The Problem
1. A formula column computes a value (e.g., a title or RPN) and stores it in the work item.
2. The work item's status changes to one where the field is read-only (e.g., "Approved").
3. On the next Risksheet load, the formula recalculates the value.
4. If the stored value differs from the formula output (due to data migration, truncation, or external edits), Risksheet marks the item as "edited."
5. When the user saves, Polarion rejects the write because the field is read-only in the current workflow state.
### Prevention Strategies
* **Run Check stored formulas before status transitions**: Before moving risk items from Draft to Review or Approved, ensure all formula values are synchronized. Navigate to **Menu** > **Rows** > **Check stored formulas** (requires v24.5.1+).
* **Keep formula columns visible during status changes**: Formula columns must be visible for reconciliation to work.
* **Avoid title truncation drift**: After Polarion migrations, check that stored title lengths match formula output lengths.
**Formula Fields and Save Failures**
Formula-generated fields may trigger save failures when permissions restrict editing. If stored values differ from formula output (for example, after title truncation during a Polarion migration), Risksheet tries to save the recalculated values, which are then blocked by field permissions. Use Check stored formulas in an editable workflow state to resolve the discrepancy before transitioning to a restricted state.
## Verification
After configuring permissions, you should now see:
1. ✅ Admin users can open the configuration editor via **Menu > Configuration > Edit Risksheet Configuration** and can modify sheet configuration
2. ✅ Non-admin users cannot access the configuration editor
3. ✅ When `checkInstanceFieldPermissions=true` is set, cells in approved work items display as read-only with visual indication
4. ✅ All users see the same Risksheet structure (confirming template project access is correct)
5. ✅ Risksheet appears in the project navigation sidebar for all intended roles
6. ✅ Connect/viewer users see the sheet in read-only mode without editing capability
## See Also
* [Assign Active Users](/risksheet/guides/licensing/assigning-active-users) --- control who gets named edit access versus viewer access
* [Understand License Types](/risksheet/guides/licensing/understanding-licenses) --- how licensing tiers affect edit permissions
* [Manage User Groups](/risksheet/guides/licensing/user-groups) --- organize users into permission groups
* [Work with Formulas and Hidden Columns](/risksheet/guides/advanced/formulas-hidden-columns) --- formula behavior and reconciliation
* [Set Up Global Templates](/risksheet/guides/configuration/global-templates) --- configure template inheritance across projects
* [Troubleshoot Administration Issues](/risksheet/guides/administration/troubleshooting) --- resolve common permission-related errors
# Add Risksheet to Existing Project
Source: https://learn.nextedy.com/risksheet/guides/administration/project-setup
Enable Nextedy RISKSHEET in a Siemens Polarion ALM project that was not created from a Nextedy template by configuring work item types, document types, and navigation topics.
## Prerequisites
* Polarion administrator access
* Risksheet installed on the server
* The Nextedy demo project installed via **Administration > Nextedy Risksheet > Setup**
**Install Demo Project First**
Before adding Risksheet to an existing project, you must install the Nextedy demo project from the Setup page. This makes the Risksheet topic and default templates available. Without this step, the `risksheet` topic will not be recognized.
**Do Not Use Polarion's Document Reuse Function**
Do **not** use Polarion's built-in document Reuse function to clone a Risksheet document into another project or location. Reuse creates unnecessary duplication of the sheet configuration attachments and breaks the link between a document and its template. To share configuration across projects or documents, use template inheritance through the `templateDoc` custom field instead (see Step 3).
1. Navigate to **Administration > Nextedy Risksheet > Setup**.
2. Click the install button to deploy the default Risksheet templates.
3. Verify the templates (`risksheet_template` and `risksheet_templateHara`) are listed.
The setup process installs two starter templates: one for a typical FMEA (Failure Mode and Effects Analysis) risk analysis and one for HARA (Hazard Analysis and Risk Assessment) workflows. Risksheet itself is a generic tool supporting any risk management methodology — including FMEA, HARA, TARA (Threat Analysis and Risk Assessment), STRIDE, and CVSS (Common Vulnerability Scoring System) — and Nextedy provides solution templates for typical methodologies across industries.
Ensure your project has a work item type for risk items. Risksheet does not require specific fields or work item types — it is fully configurable for any work item type.
1. Navigate to **Administration > Work Items > Types** in your project.
2. Verify you have a risk-related work item type (for example, `risk`, `failureMode`, or any custom type).
3. If needed, create a new work item type for risk items.
Risksheet does not introduce a separate data store. All risk items remain standard Polarion work items, subject to Polarion authorization and fully traceable via Polarion's audit infrastructure.
Set up a document type with the Risksheet property, and configure the `templateDoc` custom field that connects each document to its template:
1. Navigate to **Administration > Documents & Pages > Document Types** in your project.
2. Create or edit a document type (for example, `riskSpecification`).
3. Add the Polarion configuration property `nextedy.risksheet.riskDocumentType` and set its value to your document type.
4. Add a `templateDoc` custom field to the document type with field type **`enum:@document`** — Polarion's built-in document-reference enumeration. This field holds the connection between a Risksheet document and the template document it inherits its sheet configuration from.
**templateDoc Custom Field Type**
The `templateDoc` custom field on individual Risksheet documents must be defined with type **`enum:@document`** — the special `@document` built-in enum that produces a document-reference picker. In the field definition this looks like ` `. Do not use a plain string or text type, and do not use a custom document-type enum — the picker behavior depends on the built-in `@document` enumeration. (The analogous user-reference field type is `enum:@user`, as used by fields such as `owner`.)
**Multiple Document Types**
The `nextedy.risksheet.riskDocumentType` property supports multiple document types using parenthesized syntax if you need Risksheet to work with different document categories.
Set up where users can create new Risksheet documents:
1. Navigate to **Administration > Nextedy Risksheet** in your project.
2. Configure the template path. The default value of `nextedy.risksheet.risksheetTemplatePath` is `Risks/Risk Specification`. For a shared global template, use the form `GlobalLibrary:Risks/Risk Specification` to reference a template stored in another project.
3. Multiple paths can be specified as comma-separated values.
```text theme={null}
Project Setup Flow:
Install Demo Templates (Setup page)
|
v
Configure Work Item Type (risk items)
|
v
Configure Document Type + templateDoc field
|
v
Set Template Path (document location)
|
v
Add Risksheet Topic to Sidebar
|
v
Test: Create New Risksheet Document
```
Add the Risksheet topic to your project's sidebar navigation:
1. Navigate to **Administration > Topics** in your project.
2. Add ` ` to the sidebar configuration for the relevant views and roles.
3. Save the configuration.
**Risksheet Not Visible After Setup**
If Risksheet does not appear in the navigation after adding the topic, verify that the topic is configured for the specific view/role that the user is assigned to. Removing or omitting the Risksheet topic from a custom navigation view makes Risksheet invisible in that view.
Optionally customize how Risksheet appears in your project. The following properties are available in **Administration > Nextedy Risksheet**:
| Property | Default | Purpose |
| ------------------------ | --------------- | ------------------------------- |
| Tool Name | `Risksheet` | Display name in the UI |
| Document Names (plural) | `Risk Analyses` | Plural label for document lists |
| Document Name (singular) | `Risk Analysis` | Singular label in dialogs |
## Verification
1. Navigate to your project's sidebar and click the Risksheet entry.
2. You should now see the Risksheet home page with folder navigation and a document creation option.
3. Create a test risksheet document to verify the configuration. Pick the closest solution template for your industry or methodology rather than starting from a blank document — modify it to match your process from there.
4. Confirm the document loads with the correct template and column layout.
## See Also
* [Installation](/risksheet/getting-started/installation) — initial plugin installation
* [Configure Template Paths](/risksheet/guides/configuration/template-path-configuration) — advanced template path options
* [Set Up Global Templates](/risksheet/guides/configuration/global-templates) — share templates across projects
* [Basic Configuration](/risksheet/getting-started/basic-configuration) — customize your first risksheet
# Troubleshoot Administration Issues
Source: https://learn.nextedy.com/risksheet/guides/administration/troubleshooting
Resolve common Nextedy RISKSHEET administration problems including empty setup pages, server log errors, and configuration failures.
## Common Issues and Solutions
### Empty Setup or License Pages
**Symptom:** After installing or updating Risksheet, the Setup and License pages in Administration are empty or fail to load.
**Cause:** Plugin caches were not cleared after the update.
**Fix:**
1. Stop the Polarion server.
2. Delete the `[POLARION_INSTALL]/data/workspace/.config` directory.
3. Restart the Polarion server.
4. Navigate to **Administration** > **Nextedy Risksheet** > **Setup** to verify.
**Always Clear Caches After Updates**
This is the most common post-installation issue. Delete `[POLARION_INSTALL]/data/workspace/.config` after every Risksheet installation or update.
### Risksheet Menu Not Appearing
**Symptom:** The Risksheet entry does not appear in the project navigation after installation or update.
**Cause:** Either two plugin versions exist in the extensions folder, or the Risksheet topic is not configured for the user's view/role.
**Fix:**
1. Check `[POLARION_INSTALL]/polarion/extensions/` for duplicate Risksheet folders. Delete the old version.
2. Verify **Administration** > **Topics** includes the Risksheet topic for all relevant views and roles.
3. If the `.metadata` folder exists in the extensions directory, delete it.
### UnsupportedOperationException in Server Logs
**Symptom:** Server logs show `UnsupportedOperationException` related to document field rendering (for example, `renderingLayouts`) when opening a Risksheet.
**Cause:** A known document field rendering issue, particularly after upgrading to Polarion 2310.
**Fix:** This error has **no functional impact** on Risksheet. The system skips failed fields and continues normally. Update to Risksheet 24.7.0+ to suppress these log entries.
| Symptom | Cause | Resolution |
| --------------------------------- | -------------------------------------------- | --------------------------------------------------------------- |
| **Empty Admin Pages** | Corrupted workspace config | Delete `data/workspace/.config`, restart Polarion |
| **Menu Missing** | Duplicate extensions or missing topic config | Check `extensions/` for duplicates, verify Topics configuration |
| **UnsupportedOperationException** | Known document field rendering issue | Non-harmful -- update to Risksheet 24.7.0+ to suppress |
| **StringIndexOutOfBounds** | Misconfigured sheet configuration | Check sheet configuration syntax with JSON linter |
| **Query Parse Errors** | Invalid Polarion configuration | Check Polarion config settings |
| **License Shows 0 Users** | Missing user group | Create `nextedy_powersheet_users` group or restart Polarion |
### Velocity Template Errors
**Symptom:** `StringIndexOutOfBoundsException` appears in server logs, possibly related to `risksheetTopPanel.vm` or other Velocity templates.
**Cause:** Misconfigured sheet configuration or custom Velocity template files.
**Fix:**
1. Review your sheet configuration for syntax errors.
2. Check any custom `risksheetTopPanel.vm` template for malformed Velocity expressions.
3. Validate JSON syntax using a JSON linter.
### License Shows 0 Named Users
**Symptom:** The License page shows 0 named users despite users being in the `nextedy_risksheet_users` group.
**Cause:** Either the license needs to be refreshed, a service restart is required, or the user group name is wrong after a version upgrade.
**Fix:**
1. Reopen the **Administration** > **Nextedy Risksheet** > **License** page.
2. If still 0, restart the Polarion service.
3. If both Risksheet and Powersheet are installed (v25.11.0+), create a `nextedy_powersheet_users` group and add users to it.
**Custom Help URL**
If your team needs access to internal documentation, configure the `settings.global.help` property in your sheet configuration to point to your organization's documentation URL. The default points to the official Nextedy support portal.
## Verification
After resolving any of the above issues, you should now see the Risksheet administration pages loading correctly, the navigation menu appearing for all configured user roles, and the License page displaying the correct version and user counts.
## See Also
* [Update Risksheet](/risksheet/guides/administration/update) -- correct update procedures to avoid common issues
* [Configure Permissions](/risksheet/guides/administration/permissions) -- resolve permission-related access problems
* [Add Risksheet to Existing Project](/risksheet/guides/administration/project-setup) -- verify project setup is complete
# Update Risksheet
Source: https://learn.nextedy.com/risksheet/guides/administration/update
Upgrade Nextedy RISKSHEET to a newer version while preserving your existing configuration, Velocity templates, document data, and user assignments.
## Prerequisites
Before starting the update process, ensure you have:
* Polarion administrator access on the target server
* The new Risksheet version downloaded from the Nextedy website
* A complete backup of your current Polarion installation
* Access to a non-production test environment for validation
* Knowledge of your current Risksheet version (check **Administration** > **Nextedy Risksheet** > **License**)
1. Back up your Polarion server data directory including all project data
2. Export any custom sheet configurations you have modified at the document level
3. Back up custom Velocity templates (`risksheetTopPanel.vm`, `risksheetPdfExport.vm`) if you have customized them
4. Record your current Risksheet version from **Administration** > **Nextedy Risksheet** > **License**
5. Document the Polarion version running on the server (from **Administration** > **About Polarion**)
**Always test in a non-production environment first**
Risksheet releases can occasionally be pulled back due to discovered regressions. Always deploy updates to a staging or test environment and validate all critical workflows before applying the update to production. This includes testing document loading, PDF export, and any custom Velocity templates.
1. **Stop the Polarion server** completely
2. Navigate to the `[POLARION_INSTALL]/polarion/extensions/` directory
3. **Delete** the existing Risksheet plugin folder entirely (e.g., `com.nextedy.risksheet_24.7.0`)
4. Verify that no other Risksheet version folders remain in the `extensions/` directory
**Delete the old version -- do not copy over it**
A common and critical update mistake is copying the new plugin folder over the old one instead of deleting the old version first. This results in two plugin versions coexisting in the `extensions/` directory, which causes the Risksheet menu to disappear from the Polarion navigation for all users. **Only one version folder per Nextedy product is allowed in the extensions directory.**
1. Copy the new Risksheet plugin folder into `[POLARION_INSTALL]/polarion/extensions/`
2. Delete the `[POLARION_INSTALL]/data/workspace/.config` directory to clear all plugin caches
3. Optionally, delete the `[POLARION_INSTALL]/data/workspace/.metadata` directory if you experience persistent issues after the update
4. Start the Polarion server
**Clear plugin caches after every update**
After installing or updating Risksheet, you **must** delete the `[POLARION_INSTALL]/data/workspace/.config` directory to clear plugin caches. Failure to do so is a known cause of empty Setup and License pages in the Polarion administration interface. This step is required for every update, not just the initial installation.
After the Polarion server has started successfully:
1. Log in to Polarion as an administrator
2. Navigate to **Administration** > **Nextedy Risksheet** > **License**
3. Confirm the version number matches the newly installed release
4. Navigate to **Administration** > **Nextedy Risksheet** > **Setup**
5. Verify the setup page loads correctly and displays template installation options
6. Open an existing Risksheet document and confirm the grid renders with all columns and data
7. Test PDF export on at least one document to verify Velocity template compatibility
8. Check the Polarion server logs for any new exceptions or warnings
**Check server logs proactively**
After an update, review the Polarion server logs for the first 15 minutes of operation. Look for `UnsupportedOperationException` (harmless on versions prior to 24.7.0 running on Polarion 2310), query parsing errors, or template rendering failures. Address any new exceptions before rolling out to end users.
If you are updating to Risksheet version 25.11.0 or later and have both Risksheet and Powersheet installed with production licenses, a license group migration is required.
**Background:** Starting with v25.11.0, when both products are installed, Risksheet reads user assignments from the `nextedy_powersheet_users` group instead of the legacy `nextedy_risksheet_users` group. This is a license unification change that aligns user management across Nextedy products.
**Migration steps:**
1. In Polarion Administration, create a `nextedy_powersheet_users` global user group if it does not already exist
2. Add all members from the `nextedy_risksheet_users` group to the new `nextedy_powersheet_users` group
3. Navigate to **Administration** > **Nextedy Risksheet** > **License** and verify the named user count reflects the expected number of users
4. Keep the `nextedy_risksheet_users` group in place for backward compatibility until all projects have been verified
**License group migration is mandatory when Powersheet is installed**
When both Risksheet and Powersheet are installed with production licenses, upgrading to v25.11.0 or later without creating the `nextedy_powersheet_users` group causes the License page to show **0 named users configured** and all Risksheet licenses to appear inactive. Users will lose access to Risksheet until the group is created and populated.
| Scenario | User Group for Named Users | Notes |
| ------------------------------------ | -------------------------- | --------------------- |
| Risksheet only (any version) | `nextedy_risksheet_users` | No migration needed |
| Risksheet + Powersheet (pre-25.11.0) | `nextedy_risksheet_users` | Legacy behavior |
| Risksheet + Powersheet (25.11.0+) | `nextedy_powersheet_users` | Migration required |
| Risksheet + Powersheet (26.1.0) | `nextedy_powersheet_users` | Improved license flow |
After verifying the core installation, check the following configuration aspects:
1. **Custom Velocity templates** -- Open documents that use custom `risksheetTopPanel.vm` or `risksheetPdfExport.vm` templates. Verify the panels render correctly and PDF exports produce expected output.
2. **Project-level settings** -- Navigate to project administration and verify Risksheet project properties are intact:
* Template path configuration (default: `Risks/Risk Specification`)
* Tool name customization (default: `Risksheet`)
* Document name labels (default: `Risk Analysis` / `Risk Analyses`)
* Suggester settings (fuzzy search, wildcard search, result limit)
3. **Custom queries** -- If your sheet configuration files contain custom `query` properties in `dataTypes.risk` or `dataTypes.task`, verify these Lucene queries still parse correctly. Polarion version upgrades can change query processing behavior.
4. **Template installation** -- If the new Risksheet version includes updated project templates, consider re-installing them via **Administration** > **Nextedy Risksheet** > **Setup**. Note that template re-installation overwrites previous template versions.
## Troubleshooting Update Issues
| Symptom | Likely Cause | Resolution |
| ----------------------------------------------- | ----------------------------------------------- | -------------------------------------------------------------------------------- |
| Empty Setup and License pages | Plugin cache not cleared | Delete `[POLARION_INSTALL]/data/workspace/.config`, restart Polarion |
| Risksheet menu not appearing in navigation | Two plugin versions in extensions directory | Delete the old version folder; only one version per product is allowed |
| `UnsupportedOperationException` in server logs | Document field rendering issue on Polarion 2310 | Non-harmful log error; fixed in Risksheet 24.7.0+ |
| License page shows 0 named users | License group migration needed (v25.11.0+) | Create `nextedy_powersheet_users` group and add users |
| Unparseable query errors after update | Polarion Auto Assignment configuration conflict | Check Polarion Auto Assignment settings, not Risksheet config |
| Risksheet not activating in some projects | Post-maintenance configuration drift | Verify version compatibility and complete all update steps including Setup check |
| Grid renders but text formatting is incomplete | Partial update or cache issue | Clear browser cache, delete `.config` directory, restart server |
| `backLink` parameter errors when creating tasks | Known bug in versions prior to 24.11.0 | Update to Risksheet 24.11.0 or later |
**Persistent issues after update**
If the Risksheet menu does not appear after following all steps, try also deleting the `.metadata` folder at `[POLARION_INSTALL]/data/workspace/.metadata` and restarting the Polarion server. This forces a complete plugin re-initialization.
## Verification
You should now see:
* The new Risksheet version number displayed on the **License** page in Administration
* The **Setup** page loading correctly with template installation options
* All existing Risksheet documents rendering with their full column layout and data
* The Risksheet menu visible in the Polarion navigation panel for all configured projects
* PDF export producing formatted output using your Velocity templates
* The correct number of named users on the License page (after license group migration if applicable)
## See Also
* [Troubleshoot Administration Issues](/risksheet/guides/administration/troubleshooting) -- resolve common post-update problems
* [Manage User Groups](/risksheet/guides/licensing/user-groups) -- handle license group migration details
* [Assign Active Users](/risksheet/guides/licensing/assigning-active-users) -- configure named user assignments
* [Installation](/risksheet/getting-started/installation) -- first-time Risksheet setup instructions
* [Add Risksheet to Existing Project](/risksheet/guides/administration/project-setup) -- add Risksheet to projects after installation
# Perform Bulk Editing
Source: https://learn.nextedy.com/risksheet/guides/advanced/bulk-editing
Edit multiple risk items at once using keyboard shortcuts, multi-row selection, and cascading relationship propagation.
## Select Multiple Cells
To perform bulk operations, first select the target cells:
1. Click a cell to select it as the starting point
2. Hold **Ctrl** (or **Cmd** on macOS) and click additional cells to add them to the selection
3. Alternatively, click the first cell, then **Shift+Click** the last cell in a range to select a contiguous block
**Row Selection**
Click the row header to select an entire row. Hold **Ctrl** and click additional row headers to select multiple non-adjacent rows.
## Copy Values to Multiple Cells
The most efficient bulk editing technique is copy-paste across selected cells:
1. Select the source cell containing the value you want to replicate
2. Press **Ctrl+C** to copy the cell value
3. Select all target cells where you want to paste the value (using Ctrl+Click or Shift+Click)
4. Press **Ctrl+V** to paste the value into all selected cells
**Merged Cells**
Copy-paste works only on unmerged cells. If your selection includes merged cells (common in multi-level FMEA hierarchies), only the unmerged cells receive the pasted value. Merged cells accept paste operations only into the merge root cell.
## Bulk Edit with Cascading Updates
When you edit an enumeration field across multiple selected rows, Nextedy RISKSHEET automatically propagates dependent enumeration updates to all selected items. This keeps data consistent across bulk operations.
**Example:** Changing the `Risk Category` from "Mechanical" to "Electrical" on three selected rows simultaneously updates each row's `Risk Type` options according to configured relationship mappings.
### How It Works
1. Select multiple rows by clicking row headers while holding **Ctrl** or **Shift**
2. Edit a parent enumeration field (e.g., `severity`) on any of the selected rows
3. Risksheet applies the new value to all selected rows
4. Dependent child columns update automatically based on the configured dependent enum mapping
**Cascading Changes Are Fully Undoable**
All cascading relationship updates from a bulk edit are tracked as a single undo action. Press **Ctrl+Z** to revert the parent change and all automatically updated child fields across all affected rows at once.
## Keyboard Shortcuts for Bulk Operations
| Shortcut | Action |
| --------------- | ------------------------------------------------- |
| **Ctrl+C** | Copy selected cell value |
| **Ctrl+V** | Paste value into all selected cells |
| **Ctrl+Z** | Undo last operation (including cascading updates) |
| **Ctrl+Y** | Redo last undone operation |
| **Ctrl+Click** | Add cell to selection |
| **Shift+Click** | Select range of cells |
**Fill-down not available**
The **Ctrl+D** fill-down shortcut (similar to Excel) is not currently available in this version. Use the Ctrl+C / Ctrl+V workflow described above as an alternative for filling values down through a column.
## Autocomplete for Consistent Data Entry
When editing text or link columns across multiple rows, Risksheet provides autocomplete suggestions to speed up data entry and maintain consistency:
* **Text fields**: As you type, existing values from the same column are suggested for consistency across risk items
* **Link columns**: Type a work item ID or title to search, or click the dropdown arrow to browse available items
* **New item creation**: For link columns with `canCreate` enabled, type a new value and select **Add new \** to create and link a new work item inline
**Auto-Selection**
When autocomplete returns exactly one matching item for a non-task link column, Risksheet auto-selects it. This significantly speeds up bulk data entry when linking to items with unique identifiers.
Autocomplete includes unsaved local changes, so you can reference items created earlier in the same session before saving to the server.
## Verify Your Bulk Edit
After performing bulk edits:
1. Review the modified cells — changed values appear with a visual indicator until saved
2. Check that dependent enum columns updated correctly on all edited rows
3. Save the document to persist changes to Polarion
You should now see all bulk-edited values saved, with dependent fields correctly reflecting the cascading relationship rules.
## See Also
* [Configure Dependent Enums](/risksheet/guides/advanced/dependent-enums) — set up cascading relationships between columns
* [Configure Multi-Select Enums](/risksheet/guides/advanced/enum-multiselect) — enable multi-value selection on enum columns
* [Use Undo and Redo](/risksheet/guides/advanced/undo-redo) — revert bulk operations
* [Configure Calculated Columns](/risksheet/guides/columns/calculated-columns) — formulas that recalculate after bulk edits
# Configure Cross-Project Linking
Source: https://learn.nextedy.com/risksheet/guides/advanced/cross-project-linking
Display and link Siemens Polarion ALM work items from other projects in your Nextedy RISKSHEET by configuring `project` parameters in column type properties and data type definitions.
## Configure Upstream Cross-Project Columns
To display linked items from another Polarion project in an `itemLink` or `multiItemLink` column, add the `project` parameter to the column's `typeProperties`:
```yaml theme={null}
columns:
- header: System Requirement
bindings: sysReq
type: itemLink
typeProperties:
linkTypes: systemRequirement
linkRole: refines
project: RequirementsProject
```
For items from multiple projects, specify a space-separated list. The `$projectId` runtime variable resolves to the current project ID:
```yaml theme={null}
typeProperties:
linkTypes: systemRequirement
linkRole: refines
project: $projectId RequirementsProject EngineeringProject
```
### typeProperties Sub-Properties Reference
The `typeProperties` object on an `itemLink` or `multiItemLink` column accepts the following sub-properties. Use the correct names — `linkTypes` (plural, comma-separated string) and `linkRole` (not `type` or `role`):
| Sub-property | Type | Description |
| --------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `linkRole` | string | Link role ID that connects the risk item to the linked item (e.g., `refines`, `verifies`). Required. |
| `linkTypes` | string | Comma-separated work item type IDs allowed in this column (e.g., `systemRequirement` or `systemRequirement,softwareRequirement`). Required. |
| `linkDirection` | string | Set to `back` to traverse links in the reverse direction (link points from the target item to the risk item). |
| `backLink` | boolean | Enable back-link rendering for reverse-direction display. |
| `itemTemplate` | string | Velocity template for custom item display in the column cell. |
| `queryFactory` | string | Reference to a named function in the top-level `queryFactories` section that returns a Lucene query for filtering autocomplete suggestions. |
In addition to these six core sub-properties, cross-project columns commonly use `project` (cross-project loading) and `createInCurrentDocument` (control where new items are saved). The `document` sub-property restricts the autocomplete to a specific upstream library document.
## Configure Downstream Cross-Project Tasks
To display and create downstream tasks in another project, use `project` or `projects` in the `dataTypes.task` section:
**Single target project:**
```yaml theme={null}
dataTypes:
task:
type: mitigationAction
role: mitigates
project: TasksProject
```
**Multiple target projects** (requires v23.7.0+):
```yaml theme={null}
dataTypes:
task:
type: mitigationAction
role: mitigates
projects:
- TasksProject
- VerificationProject
```
**Use `project` for single and `projects` for multiple**
Use the `project` parameter for a single target project. Use `projects` (plural, array, v23.7.0+) when loading tasks from multiple projects. For `itemLink` and `multiItemLink` columns loading from multiple projects, the system saves new items to the first listed project by default.
## Save New Items in the Current Project
When a column loads items from multiple projects, new items created from that column are saved in the first listed project. To force new items into the current project, add `createInCurrentDocument`:
```yaml theme={null}
typeProperties:
project: $projectId ProjectA ProjectB
linkTypes: systemRequirement
linkRole: refines
createInCurrentDocument: true
```
**Control Target Project for New Items**
When `createInCurrentDocument` is not set, the system uses the first project listed in the `project` parameter for saving new items. Reorder the project list — or place `$projectId` first — to control the default save target.
## Dynamic Configuration via Configuration Properties
For portable configurations that work across different project environments, use Risksheet configuration properties to dynamically resolve project IDs, link roles, and types in the sheet configuration:
```yaml theme={null}
typeProperties:
linkRole: $config.getRisksheetProjectProperties().getProperty('taskLinkRole', 'mitigates')
linkTypes: $config.getRisksheetProjectProperties().getProperty('taskLinkTypes', 'mitigationAction')
project: $config.getRisksheetProjectProperties().getProperty('taskProject', 'DefaultProject')
```
This pattern reads values from the project's Risksheet configuration properties with fallback defaults, eliminating hardcoded project IDs. It makes the sheet configuration portable when deploying the same Risksheet template across multiple projects.
## Cross-Project Work Item Operations
Risksheet supports full CRUD operations on cross-project items. All data lives in Polarion work items — Risksheet does not store anything separately, so cross-project links resolve through Polarion's standard work item APIs:
| Operation | Behavior |
| ----------------- | ----------------------------------------------------------------------------------------------- |
| **Display** | Items from configured projects appear in columns with their project-qualified IDs |
| **Create** | New items saved to the first listed project or current project (with `createInCurrentDocument`) |
| **Update** | Editing cross-project items updates them in their home project |
| **Delete/Unlink** | Unlinking removes the relationship; deletion removes the item from its home project |
**Clustered Polarion Limitation**
Items from different Polarion server instances cannot be displayed in the same Risksheet. Cross-project linking requires all projects to reside on the same Polarion server.
## Limitations
| Limitation | Details |
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Direct links only** | Cross-project display works for directly linked items. Indirect links through intermediary work items in other projects require additional configuration. |
| **Same server required** | All linked projects must be on the same Polarion server instance. |
| **Assignee field context** | The `userRole: 'project_assignable'` property fetches users from the Risksheet project, not the task's project. Use a global role as a workaround. |
## Verify Your Configuration
After setting up cross-project linking:
1. Open the Risksheet document and confirm that linked items from other projects appear in the configured columns
2. Create a new linked item and verify it is stored in the expected project
3. Confirm that autocomplete suggestions show items from all configured projects
4. Check that unlinking and deletion work correctly for cross-project items
You should now see work items from other Polarion projects displayed in your Risksheet grid with full linking, creation, and editing capabilities.
## See Also
* [Manage Cross-Project Resources](/risksheet/guides/advanced/cross-project-resources) — shared resources across projects
* [Configure Target Document Creation](/risksheet/guides/advanced/target-document-creation) — controlling where new items are stored
* [Configure Multi-Project Setup](/risksheet/guides/configuration/multi-project-setup) — project-level settings
* [Configure Downstream Tasks](/risksheet/guides/risk-management/downstream-tasks) — task configuration
* [Configure Upstream Traceability Columns](/risksheet/guides/columns/upstream-traceability) — upstream column setup
# Manage Cross-Project Resources
Source: https://learn.nextedy.com/risksheet/guides/advanced/cross-project-resources
Share enumeration values, rating scales, templates, and linked work items across multiple Polarion projects to maintain consistency in multi-project risk management environments.
## Use Global Templates for Shared Configuration
Global templates provide the primary mechanism for sharing Nextedy RISKSHEET configuration across projects. When a document inherits from a template, it receives the template's sheet configuration including all shared definitions.
1. Create a Risksheet template document containing the shared configuration
2. Configure the template path in Risksheet Project Properties so all projects reference the same template
3. Documents created from the template automatically inherit the shared configuration:
| Shared Resource | Configuration Key | What It Provides |
| --------------- | ----------------- | ---------------------------------------------------------- |
| Enumerations | `enums` | Dropdown options with IDs, names, descriptions, and icons |
| Rating scales | `ratings` | Severity, occurrence, detection scales for risk assessment |
| Formulas | `formulas` | Named formula functions (e.g., RPN calculation) |
| Styles | `styles` | CSS class definitions for conditional formatting |
| Cell decorators | `cellDecorators` | Conditional formatting functions mapped to columns |
| Views | `views` | Saved column visibility presets |
Documents can override specific parts of the inherited configuration by attaching their own sheet configuration.
**Template Changes Propagate on Reload**
When you update a global template's sheet configuration, documents inheriting from it pick up the changes on the next page load. No manual update is needed per document.
## Share Enumerations Across Projects
Enum columns automatically filter values based on column type and project context. When a column loads items from multiple projects via the `project` parameter in `typeProperties`, enum values from all configured projects are merged:
```yaml theme={null}
{
"columns": [
{
"header": "Risk Type",
"bindings": "riskType",
"type": "enum:riskCategory",
"typeProperties": {
"project": "SafetyProject,CyberProject"
}
}
]
}
```
Task-type enums filter across configured task types in multiple projects. Risk-type enums filter by configured risk types. Project enum columns show only projects allowed in the configuration.
## Configure Cross-Project Reviews
Work item-based reviews can store review items in a dedicated project while linking them back to risk items in the originating project:
```yaml theme={null}
reviews:
reviewManager: WorkItemBased
typeProperties:
linkTypes: reviewItem
linkRole: reviews
project: ReviewsProject
document: Reviews/FMEAReviews
```
When `document` is specified, review work items are created as document work items and positioned after the last existing review item in the target document.
**Required Configuration**
Work item-based reviews require `typeProperties.linkTypes` and `typeProperties.linkRole` to be set. Missing either property results in a runtime error when creating reviews.
## Cross-Project Workflow Status Transitions
When editing cross-project linked items, the workflow status dropdown correctly loads available transitions for the item's home project. The status field presents only valid workflow actions based on the work item's current state in its originating project.
**New Items**
Workflow status transitions are not available for newly created work items until they are saved. The status dropdown remains disabled for unsaved items.
## Manage User Roles Across Projects
When downstream tasks reside in a different project, the assignee column's `userRole: 'project_assignable'` fetches users from the Risksheet project context, not the task's home project.
**Workaround:** Use a global role where needed users are added across all relevant projects:
```json theme={null}
{
"columns": [
{
"header": "Assignee",
"bindings": "assignee",
"type": "ref:user",
"typeProperties": {
"userRole": "global_risk_team"
}
}
]
}
```
## Cross-Project Autocomplete and Suggestions
Autocomplete suggestions for link columns are automatically scoped to the configured projects. When `typeProperties.project` lists multiple projects, the suggestion API returns matching items from all listed projects:
* Users type a fragment and see results from all configured project scopes
* Invalid suggestions from projects that do not match the column's type filters are automatically excluded
* Configure `suggester.limit` in Risksheet Project Properties to control the maximum number of suggestions (default: 20)
## Verify Your Configuration
After setting up cross-project resources:
1. Open a Risksheet document that inherits from the global template
2. Confirm enumerations, ratings, and formulas load correctly from the shared configuration
3. Verify that link columns show suggestions from all configured projects
4. Create a new linked item and confirm it appears in the correct target project
5. Test workflow status transitions on cross-project items
You should now see shared resources loading consistently across all projects using the same template and cross-project configuration.
## See Also
* [Configure Cross-Project Linking](/risksheet/guides/advanced/cross-project-linking) — displaying and linking items from other projects
* [Set Up Global Templates](/risksheet/guides/configuration/global-templates) — template inheritance setup
* [Configure Multi-Project Setup](/risksheet/guides/configuration/multi-project-setup) — project-level settings
* [Manage Cross-Project Reviews](/risksheet/guides/reviews/cross-project-reviews) — cross-project review workflows
# Configure Dependent Enums
Source: https://learn.nextedy.com/risksheet/guides/advanced/dependent-enums
Set up cascading enumeration relationships so that selecting a value in one column automatically filters the available options in another column.
## Prerequisites
* Nextedy RISKSHEET version 25.3.1 or later (single-value enums) or 25.4.0 or later (multi-value enums)
* Parent and child enumerations already defined in Polarion (**Administration > Enumerations**)
* Custom fields on your risk work item type that bind to those enumerations
* Administrator access to edit the sheet configuration
Dependent enums reference enumerations that already exist in Polarion. Enums are **not** defined inside the sheet configuration.
1. In Polarion, go to **Administration > Enumerations**.
2. Create or open the parent enumeration (for example, `risk-category`).
3. Add the parent values (for example, `hardware`, `software`, `mechanical`).
4. Create the child enumeration (for example, `risk-type`).
5. Add all possible child values (for example, `esd`, `shortCircuit`, `memoryLeak`, `deadlock`, `fatigue`, `wear`).
6. Bind both enumerations to custom fields on your risk work item type.
The sheet configuration references these enumeration IDs but does not contain the values themselves. The server loads the values automatically when the column is rendered.
In the sheet configuration, add the parent and child columns to the `columns` array. Use `type: enum:` to reference the Polarion enumeration ID, and `bindings` (plural) to map the column to its Polarion custom field:
```yaml theme={null}
columns:
- id: riskCategory
header: Risk Category
bindings: riskCategory
type: enum:risk-category
- id: riskType
header: Risk Type
bindings: riskType
type: enum:risk-type
```
The dependent enum mapping is declared on the **child column** through its `typeProperties`. It identifies the parent column and lists which child enum values are valid for each parent value:
```yaml theme={null}
columns:
- id: riskType
header: Risk Type
bindings: riskType
type: enum:risk-type
typeProperties:
dependsOn: riskCategory
mapping:
hardware:
- esd
- shortCircuit
software:
- memoryLeak
- deadlock
mechanical:
- fatigue
- wear
```
With this configuration, selecting **Hardware** in the Risk Category column filters the Risk Type dropdown to show only **ESD Failure** and **Short Circuit**.
## How the Cascading Behavior Works
* When the parent field value changes, Risksheet automatically updates the child dropdown options.
* If the parent field is empty or has no mapping entry, all child options are shown.
* If the parent value maps to an empty array, no child options are shown.
* Cascading changes are tracked in the undo stack — you can revert the entire chain with a single undo.
**Same Row Scope Only**
Dependent enum mappings only apply between two columns bound to the same risk item row. Cross-level relationships (for example, a risk-level field driving a task-level field) are not supported and are ignored at runtime.
For multi-select enum columns, use the `multiEnum:` type prefix instead of `enum:`. The `typeProperties.mapping` works the same way:
```yaml theme={null}
columns:
- id: riskType
header: Risk Type
bindings: riskType
type: multiEnum:risk-type
typeProperties:
dependsOn: riskCategory
mapping:
hardware:
- esd
- shortCircuit
```
When a parent value is deselected, any child multi-enum values that depended on that parent are automatically removed. This prevents invalid data combinations.
**Bidirectional Propagation**
Risksheet supports both forward (parent to child) and backward (child to parent) updates. If a child value requires a specific parent value and only one valid parent exists, the parent is auto-populated.
When you select multiple rows and edit a parent enum field, all dependent child fields across all selected rows update automatically according to the configured mapping rules.
## Verification
Open the risksheet document and confirm that selecting a value in the parent column filters the child column dropdown to show only the mapped options. Changing the parent value should automatically clear or update the child value if the current selection is no longer valid.
## See Also
* [Configure Enum Columns](/risksheet/guides/columns/enum-columns)
* [Configure Multi-Enum Columns](/risksheet/guides/columns/multi-enum-columns)
* [Configure Multi-Select Enums](/risksheet/guides/advanced/enum-multiselect)
* [Use Undo and Redo](/risksheet/guides/advanced/undo-redo)
# Configure Multi-Select Enums
Source: https://learn.nextedy.com/risksheet/guides/advanced/enum-multiselect
Set up Nextedy RISKSHEET columns that allow users to select multiple enumeration values from a dropdown, with optional dependent enum filtering driven by another column on the same row.
In Risksheet, enum values are NOT defined inside the sheet configuration. They come from Polarion enumerations defined in Siemens Polarion ALM. The sheet configuration only references those enumerations from individual column definitions.
## Step 1: Define the Enumeration in Polarion
Multi-select enum values are managed in Polarion, not in the sheet configuration.
1. Open Polarion **Administration > Enumerations** for your project (or globally).
2. Create a new enumeration (for example, `allocation`) and add the items you want to expose: `mech`, `elec`, `sw`, `sys`, with display names such as "Mechanical", "Electrical", "Software", "System".
3. Create or reuse a custom field on the risk work item type that is bound to this enumeration and allows multiple values.
The enumeration ID (here `allocation`) is what the sheet configuration will reference. You do not redeclare options, names, or visibility in the sheet configuration file.
To hide deprecated values, mark them as not visible in the Polarion enumeration definition. Risksheet will simply not offer them in the dropdown.
## Step 2: Add a Multi-Enum Column
In the sheet configuration (the configuration editor supports YAML editing since v25.5.0), add a column that references the enumeration via the `multiEnum:` type prefix and binds it to the Polarion custom field through `bindings`:
```yaml theme={null}
columns:
- id: allocation
header: Allocation
bindings: allocation
type: multiEnum:allocation
```
Key points:
* `type: multiEnum:` tells Risksheet to render a multi-select dropdown backed by the Polarion enumeration whose ID is ``.
* `bindings` (plural) is the Polarion field ID on the risk work item that stores the selected values.
* The server loads the enumeration values automatically; no list of options lives in the sheet configuration.
**Use `multiEnum:` Not `enum:`**
The column type **must** use the `multiEnum:` prefix (for example, `type: multiEnum:allocation`). Using `type: enum:allocation` renders a single-select dropdown even if the underlying Polarion field supports multiple values.
## Multi-Select Display Behavior
| Selected Count | Display |
| -------------- | ----------------------------------- |
| 0 | Empty cell |
| 1 | Single value name |
| 2 | Both value names shown |
| 3+ | First 2 names + "+N more" indicator |
Multi-enum cells are optional by default — a row can have no selection. Risksheet stores enum IDs internally and resolves them to the display names from the Polarion enumeration during rendering.
## Step 3: Configure Dependent Multi-Enum Filtering (Optional)
Dependent enumerations are a **column-level** feature (v25.3.1+). They are NOT a top-level configuration section — the filtering rules live directly on the dependent multi-enum column, not in a separate global block.
The pattern is:
* Pick a controlling column on the same row (for example, a `riskCategory` enum column).
* On the multi-enum column, declare which values become available for each value of the controlling column.
```yaml theme={null}
columns:
- id: riskCategory
header: Risk Category
bindings: riskCategory
type: enum:riskCategory
- id: allocation
header: Allocation
bindings: allocation
type: multiEnum:allocation
typeProperties:
dependsOn: riskCategory
mapping:
hardware: [mech, elec]
software: [sw]
system: [mech, elec, sw, sys]
```
When the controlling column changes:
* The multi-enum dropdown filters to show only the values listed for the new controlling value.
* Any currently selected values that are no longer valid for the new controlling value are automatically removed.
* If the controlling cell is cleared, the full set of enumeration values becomes available again.
**Undo Support for Cascading Changes**
Cascading updates triggered by a dependent-enum change are tracked together in the undo stack. A single undo (Ctrl+Z) reverts the controlling change and any dependent values that were cleared.
## Filtering Multi-Enum Columns
Column filtering is enabled by default on multi-enum columns. Users can filter rows by one or more selected enumeration values; matching is value-based, so a row is included when its selected set intersects the filter set. If you need to opt a column out of filtering, set `filterable: false` on the column definition.
## Verification
You should now see a multi-select dropdown when clicking a cell in the configured column. Selecting multiple values displays them as chips, with a "+N more" indicator when more than two values are selected. If a dependent mapping is configured, changing the controlling cell should immediately reshape the available options and drop any invalid selections.
## See Also
* [Configure Enum Columns](/risksheet/guides/columns/enum-columns)
* [Configure Multi-Enum Columns](/risksheet/guides/columns/multi-enum-columns)
* [Configure Dependent Enums](/risksheet/guides/advanced/dependent-enums)
* [Perform Bulk Editing](/risksheet/guides/advanced/bulk-editing)
# Work with Formulas and Hidden Columns
Source: https://learn.nextedy.com/risksheet/guides/advanced/formulas-hidden-columns
Configure formula columns to calculate values automatically and understand how column visibility affects formula execution, with strategies for reconciling stale values when columns are hidden.
## Prerequisites
* A Nextedy RISKSHEET document with at least one configured column
* Access to the sheet configuration sheet configuration (admin privileges required --- `canAdmin` must be `true`)
* Familiarity with [calculated columns](/risksheet/guides/columns/calculated-columns) basics
## Understanding Formula and Visibility Interaction
Formula columns in Risksheet execute client-side JavaScript functions to compute derived values such as Risk Priority Numbers (RPN). A critical behavior to understand is that **formulas only execute when their column is visible** in the current grid view. Hidden columns skip formula execution entirely, which leads to stale or missing values in the underlying Polarion work items.
This happens because formulas run during the cell rendering phase. If a column is not rendered (because it is hidden), the formula function is never invoked. The stored Polarion value remains whatever it was the last time the formula executed with the column visible --- or empty if the item was created while the column was hidden.
**Hidden Formula Columns Do Not Execute**
If a formula column (such as a title column driven by a formula) is hidden when you create new risk items, the Polarion work item will receive an incorrect or empty value. For example, hiding a title formula column during item creation causes new items to show just a number instead of the computed title. This is by design --- Risksheet cannot run formulas for columns that are not rendered in the grid.
Add formula definitions to the `formulas` section of your sheet configuration. Each formula is a named JavaScript function that receives an `info` object containing the current row data. The function must return the computed value, or `null` if the computation cannot be performed (e.g., when input fields are empty).
### Basic RPN Formula
The most common formula pattern calculates Risk Priority Numbers by multiplying severity, occurrence, and detection ratings:
```yaml theme={null}
formulas:
commonRpn: function(info){ var value = info.item['occ']*info.item['det']*info.item['sev'];
return value?value:null;}
commonRpnNew: function(info){ var value = info.item['occNew']*info.item['detNew']*info.item['sevNew'];
return value?value:null; }
```
### Title Concatenation Formula
Another common pattern concatenates multiple fields into a title or description:
```yaml theme={null}
formulas:
titleFormula: function(info){ return info.item['failureMode'] + ' - ' + info.item['effect'];
}
```
### The `info` Object Reference
The formula function receives a single `info` parameter with these properties:
| Property | Type | Description |
| ------------ | ------ | ------------------------------------------------------------------------------------------------------------------------ |
| `info.item` | object | The current row's data object. Access any column's value using the column binding as a key (e.g., `info.item['sev']`). |
| `info.value` | any | The current cell value before formula execution. Useful for formulas that modify rather than replace the existing value. |
**Return `null` for Empty Inputs**
Always guard against empty or undefined input values. If any of the formula's input fields are empty, returning `null` prevents displaying `NaN` or `0` in the cell. The pattern `return value ? value : null;` handles this for multiplication-based formulas.
Reference a named formula in the column definition using the `formula` property. When a column has a `formula` set, Risksheet automatically sets `readOnly` to `true` for that column, preventing users from manually overriding computed values.
```yaml theme={null}
{
"columns": [
{
"id": "rpn",
"header": "Initial RPN",
bindings: "rpn",
"type": "int",
"formula": "commonRpn",
"level": 2
},
{
"id": "rpnNew",
"header": "Revised RPN",
bindings: "rpnNew",
"type": "int",
"formula": "commonRpnNew",
"level": 2
}
]
}
```
Key properties for formula columns:
| Property | Type | Default | Description |
| ---------- | ------- | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `formula` | string | `None` | Name of the formula function defined in the `formulas` section. When set, the column becomes read-only by default. |
| `readOnly` | boolean | `false` (auto-set to `true` for formula columns) | Formula columns are automatically read-only. Setting `readOnly: false` explicitly allows external reconciliation via Check stored formulas. |
| `visible` | boolean | `true` | Controls whether the column appears in the grid. **Directly affects formula execution** --- hidden columns do not calculate. |
| `level` | number | `1` | Hierarchical level at which this column appears. Not relevant to formula behavior but important for FMEA structures. |
| `type` | string | auto-detected | Data type of the column. For RPN formulas, use `int` or `float`. |
You can control column visibility through the `visible` property on individual columns, through saved views, or through user-toggled column visibility. Each approach has different implications for formula execution.
### Option A: Permanent Visibility with `visible` Property
Set `visible: true` on formula columns that must always compute:
```yaml theme={null}
{
"columns": [
{
"id": "rpn",
"header": "RPN",
bindings: "rpn",
"formula": "commonRpn",
"visible": true
}
]
}
```
This is the safest approach --- the formula always executes because the column is always rendered.
### Option B: Saved Views for Context-Specific Visibility
If you need different column layouts for interactive editing versus export, use saved views. Define a full editing view that includes all formula columns, and a separate export view that omits them:
```yaml theme={null}
views:
- name: Editing View
columnIds:
- id
- title
- severity
- occurrence
- detection
- rpn
- rpnNew
- name: Export View
columnIds:
- id
- title
- severity
- occurrence
- detection
```
**Never Set an Export View as Default**
Formulas execute on sheet load. If the default view hides formula columns, the formulas will not recalculate when the sheet opens. Always keep the full editing view (with all formula columns visible) as the default. Switch to the export view only immediately before exporting.
### Option C: Column Visibility Toggle
Users can hide and show columns interactively through the grid's column visibility controls. When a user hides a formula column and later shows it again, the formula recalculates on the next render. However, any items created or modified while the column was hidden will retain their stale values until the formula re-executes.
Starting with version 24.5.1, Risksheet provides a **Check stored formulas** feature that synchronizes formula-computed values with the values stored in Polarion. This feature addresses several scenarios where stored values diverge from formula outputs:
* **External edits**: Changes made to risk items outside of Risksheet (e.g., via Polarion's native work item editor or a bulk import) are not reflected in formula-dependent fields.
* **Hidden column creation**: Items created while formula columns were hidden have empty or incorrect computed fields.
* **Data migration drift**: Polarion upgrades or migrations may truncate or alter stored values (e.g., title fields truncated to 80 characters), causing formula outputs to differ from stored values on subsequent loads.
### Running the Reconciliation
1. Open the Risksheet document in your browser.
2. Ensure all formula columns are **visible** in the current view. Switch to the editing view if needed.
3. Navigate to **Menu** > **Rows** > **Check stored formulas**.
4. Risksheet recalculates every formula column for every visible row and compares the computed values against the stored Polarion values.
5. Any discrepancies are flagged, and the items are marked as edited.
6. Save the document to persist the corrected values back to Polarion.
**When to Use Check Stored Formulas**
Run this reconciliation after any of these events: bulk data imports via Polarion's XLSX importer, Polarion version upgrades, manual edits to work items outside Risksheet, or after discovering that formula columns were hidden during a data entry session.
**Permission Conflicts with Formula Reconciliation**
When formula columns are explicitly set to `readOnly: false`, the Check stored formulas feature can update their values. However, if Polarion Permissions Management restricts editing of those fields in the current workflow state, the save will fail. Risksheet attempts to save the recalculated values, but the permission check blocks the write. To resolve this, either temporarily change the work item status to one that allows editing, or adjust the field permissions.
A common FMEA pattern uses a formula to compute the work item title by concatenating fields like failure mode and effect. Title columns require special care because Polarion uses the title for display throughout its interface (work item lists, search results, traceability views).
### Recommended Approach
1. **Always keep the title formula column visible** during item creation. This ensures new items receive the correct computed title immediately.
2. After initial creation, if you must hide the title column for layout reasons, do so only after saving the document with all formulas executed.
3. If items were created with the title column hidden, use **Check stored formulas** (v24.5.1+) to reconcile the title values.
### Example Title Formula Configuration
```yaml theme={null}
{
"formulas": {
"riskTitle": "function(info){ var fm = info.item['failureMode'] || ''; var eff = info.item['effect'] || ''; if(!fm && !eff) return null; return fm + ' - ' + eff; }"
},
"columns": [
{
"id": "title",
"header": "Title",
bindings: "title",
"formula": "riskTitle",
"visible": true
}
]
}
```
**Title Truncation After Migration**
Polarion may truncate title fields during platform migrations (e.g., to 80 characters). After such a migration, the stored title is shorter than what the formula produces. On next Risksheet load, the formula regenerates the full title, detects a difference from the stored value, and marks the item as edited. If permissions block title editing in the current workflow state, this triggers a save failure. Use Check stored formulas in a draft or editable workflow state to resolve the discrepancy.
Formula columns work particularly well with `cellDecorators` to provide color-coded visual feedback on computed values. For RPN columns, apply threshold-based styling to highlight risk levels:
```yaml theme={null}
formulas:
commonRpn: function(info){ var value = info.item['occ']*info.item['det']*info.item['sev'];
return value?value:null;}
cellDecorators:
rpn: function(info){ var val = info.value; $(info.cell).toggleClass('boldCol', true);
$(info.cell).toggleClass('rpn1', val>0 && val <= 150); $(info.cell).toggleClass('rpn2',
val > 150 && val <= 250); $(info.cell).toggleClass('rpn3', val > 250);}
styles:
.boldCol: '{font-weight:600;}'
.rpn1: '{background-color: #eaf5e9 !important;color: #1d5f20 !important;}'
.rpn2: '{background-color: #fff3d2 !important; color: #735602 !important;}'
.rpn3: '{background-color: #f8eae7 !important;color: #ab1c00 !important;}'
```
This configuration produces a three-tier visual indicator:
| CSS Class | RPN Range | Background | Text Color | Risk Level |
| --------- | --------- | ------------------------ | ---------------------- | ---------- |
| `rpn1` | 1--150 | Light green (`#eaf5e9`) | Dark green (`#1d5f20`) | Low |
| `rpn2` | 151--250 | Light yellow (`#fff3d2`) | Dark amber (`#735602`) | Medium |
| `rpn3` | > 250 | Light red (`#f8eae7`) | Dark red (`#ab1c00`) | High |
The cell decorator executes after the formula, so it always operates on the freshly computed RPN value.
## Verification
After configuring formula columns and visibility settings, you should now see:
1. ✅ Formula columns display computed values automatically (e.g., RPN = Severity x Occurrence x Detection)
2. ✅ Hiding a formula column and then showing it again causes the formula to recalculate on the next render
3. ✅ New items created while formula columns are visible receive correct computed values
4. ✅ The **Check stored formulas** option is available under **Menu** > **Rows** (requires version 24.5.1 or later)
5. ✅ Saved views correctly toggle formula column visibility without losing stored values
6. ✅ Conditional formatting (cell decorators) reflects the computed formula values with appropriate color coding
## See Also
* [Configure Calculated Columns](/risksheet/guides/columns/calculated-columns) --- full guide to column formulas and the `formula` property
* [Apply Conditional Formatting](/risksheet/guides/styling/conditional-formatting) --- style cells based on formula output using cell decorators
* [Control Column Visibility](/risksheet/guides/columns/column-visibility) --- manage which columns appear in the grid
* [Create Saved Views](/risksheet/guides/customization/saved-views) --- define view presets for editing and export workflows
* [Control Column Visibility in Exports](/risksheet/guides/export/column-visibility-export) --- export-specific column settings
* [Configure Permissions](/risksheet/guides/administration/permissions) --- understand how field permissions interact with formula saves
# Advanced Configuration
Source: https://learn.nextedy.com/risksheet/guides/advanced/index
These guides cover power-user Nextedy RISKSHEET configuration patterns including query customization, dependent enums, formula techniques, cross-project linking, and bulk operations.
## Query and Filtering
* **[Configure Queries](/risksheet/guides/advanced/query-configuration)** -- Customize Lucene queries for work item filtering, SQL query support, and escaped quotation marks in JSON
* **[Use Query Factory](/risksheet/guides/advanced/query-factory)** -- Create dynamic query factories for context-aware filtering of linked items in autocomplete dropdowns
## Enum Configuration
* **[Configure Dependent Enums](/risksheet/guides/advanced/dependent-enums)** -- Set up cascading enum dropdowns where child options filter based on parent selection
* **[Configure Multi-Select Enums](/risksheet/guides/advanced/enum-multiselect)** -- Enable multi-value selection for enum columns
## Formula and Column Techniques
* **[Work with Formulas and Hidden Columns](/risksheet/guides/advanced/formulas-hidden-columns)** -- Manage formula dependencies on column visibility and export-specific layouts
* **[Create Personal Filters](/risksheet/guides/advanced/personal-filters)** -- Configure user-specific data filtering for large Nextedy RISKSHEETs
## Document and Item Operations
* **[Configure Target Document Creation](/risksheet/guides/advanced/target-document-creation)** -- Control where downstream documents are created from Risksheet actions
* **[Perform Bulk Editing](/risksheet/guides/advanced/bulk-editing)** -- Edit multiple risk items simultaneously with batch operations
* **[Use Undo and Redo](/risksheet/guides/advanced/undo-redo)** -- Revert and reapply changes during editing sessions
## Cross-Project Features
* **[Configure Cross-Project Linking](/risksheet/guides/advanced/cross-project-linking)** -- Link risk items across multiple Polarion projects
* **[Manage Cross-Project Resources](/risksheet/guides/advanced/cross-project-resources)** -- Share and reference resources between projects
**Start with Basic Configuration**
If you are new to Risksheet configuration, complete the [Basic Configuration](/risksheet/getting-started/basic-configuration) tutorial before exploring these advanced topics.
# Create Personal Filters
Source: https://learn.nextedy.com/risksheet/guides/advanced/personal-filters
Set up personal column filters in Nextedy RISKSHEET that persist between sessions, allowing you to resume work with your preferred data view every time you open a document.
## Prerequisites
* Risksheet version 24.8.1 or later (personal filter storage was introduced in this version)
* At least one column in your risksheet with `filterable` enabled (this is the default for most columns)
## How Personal Filters Work
Personal filters are stored per user and per document. When you set a filter on one or more columns and close the risksheet, your filter selections are remembered. The next time you open the same document, Risksheet automatically re-applies your personal filters so you see the same filtered view you left.
**Personal, Not Shared**
Personal filters are stored in your individual user settings. Other users opening the same document will see their own filters (or no filters if they have not set any). Personal filters do not affect saved views or the sheet configuration.
## Set a Column Filter
1. Open the risksheet document you want to filter
2. Locate the column header you want to filter by (e.g., "Severity", "Status", "Assignee")
3. Click the **filter icon** in the column header area
4. Select the filter criteria:
* For **enum columns** (severity, occurrence, detection, status): check or uncheck the values you want to include
* For **text columns** (Title, Description): type the text to filter by
* For **numeric columns** (RPN): specify a range or threshold
5. Confirm the filter selection
The grid immediately updates to show only rows matching your filter criteria. A visual indicator appears on the column header to show that a filter is active.
### Filter Multiple Columns
You can apply filters to multiple columns simultaneously. The filters combine with AND logic — only rows matching **all** active filters are displayed.
| Column Filter | Example Values | Result |
| -------------------- | ----------------------------- | ---------------------------------------- |
| Severity = "High" | Only rows with high severity | Rows filtered to high severity |
| + Assignee = "John" | Combined with severity filter | Only high severity rows assigned to John |
| + Status != "Closed" | Combined with both above | High severity, John's items, not closed |
To add filters to additional columns, repeat the steps above for each column header.
## Clear a Single Column Filter
1. Click the **filter icon** on the filtered column header (the icon appears highlighted when a filter is active)
2. In the filter dropdown, click **Clear** to remove the filter from that column
3. The grid updates immediately, and the column header filter indicator is removed
## Clear All Filters
To remove all active filters at once and return to the unfiltered view, open the filter dropdown on any column header and use the **Clear All** action:
1. Click the **filter icon** on any column header (filtered or unfiltered)
2. In the filter dropdown, click **Clear All** — this removes filters from every column in the grid simultaneously
3. All rows become visible again, and the filter indicators are removed from every column header
The **Clear All** action is part of the standard column filter dropdown, so it is always available regardless of which column you open it from. Personal filter state is updated immediately, so the next time you open the document, no filters will be re-applied until you set new ones.
## Filter Persistence Behavior
Personal filters persist according to these rules:
| Action | Filter Behavior |
| ---------------------------------------- | ------------------------------------------------------------------------------- |
| Close and reopen the same document | Filters restored automatically |
| Navigate away and return to the document | Filters restored automatically |
| Open a different risksheet document | That document has its own independent filter settings |
| Switch to a saved view | Saved view column visibility applies; personal filters may reset |
| Another user opens the same document | They see their own personal filters, not yours |
| Clear browser cache | Filters are stored server-side in user settings, so they survive cache clearing |
**Saved Views vs Personal Filters**
Saved views (configured in the sheet configuration under the `views` array) control column **visibility** — which columns are shown or hidden. Personal filters control row **visibility** — which rows are shown based on data values. These are independent features. Switching to a saved view may reset your active filters depending on the view configuration.
## Configuration Requirements
Personal filters rely on the `filterable` column property. By default, all columns have `filterable` set to `true`, meaning users can filter by any column. Administrators can disable filtering on specific columns by setting `filterable` to `false` in the column configuration.
```yaml theme={null}
columns:
- id: title
header: Failure Mode
bindings: title
filterable: true
- id: rpn
header: RPN
formula: commonRpn
filterable: true
- id: internalNotes
header: Internal Notes
bindings: description
filterable: false
```
In this example, "Failure Mode" and "RPN" columns support filtering and personal filter persistence. The "Internal Notes" column has filtering disabled, so users cannot set a filter on it.
## Practical Scenarios
### Scenario 1: Daily Review of High-Priority Items
A safety engineer reviews high-priority risk items each morning. They set these filters:
* **Severity**: "Critical" and "High"
* **Status**: "Open" and "In Review"
* **Assignee**: Their own name
Every time they open the risksheet, the view is pre-filtered to show only the items requiring their attention. No manual re-filtering is needed.
### Scenario 2: FMEA Analysis by System Component
An engineer working on a specific subsystem filters the risksheet to show only failure modes related to their component:
* **System Requirement** column: Filter to show only linked items for "Braking System"
This filter persists across sessions, so the engineer always sees only their relevant scope when opening the document.
### Scenario 3: Audit Preparation
A quality manager preparing for an ISO 26262 audit filters the risksheet to focus on items with incomplete mitigations:
* **Mitigation Task** column: Filter to show rows where the task column is empty or has status "Not Started"
* **RPN** column: Filter for values above a specific threshold (e.g., > 150)
The personal filter ensures this audit-focused view is always ready without needing to reconfigure it each time.
## Sorting and Filtering Combined
Personal filters work alongside the sort order configured in `sortBy` and any manual column sorting applied by clicking column headers. The interaction follows this order:
1. **Filtering** is applied first — rows not matching the filter criteria are hidden
2. **Sorting** is applied to the remaining visible rows
3. **Merging** groups the sorted, filtered rows according to the `levels` configuration
**Sorting with Filters**
Client-side sorting and filtering happen instantly in the browser without server round-trips. This provides immediate visual feedback when you change filter criteria or sort columns, even on large datasets.
## Verification
After setting up personal filters, you should see:
1. The filtered view applies immediately when you set the filter
2. A visual indicator on filtered column headers confirms which filters are active
3. After closing and reopening the document, the same filters are automatically re-applied
4. The row count reflects only the filtered subset of items
## See Also
* [Configure Column Sorting](/risksheet/guides/columns/sorting) — Set up default and custom sort orders
* [Control Column Visibility](/risksheet/guides/columns/column-visibility) — Show or hide columns independently from filtering
* [Create Saved Views](/risksheet/guides/customization/saved-views) — Configure named column visibility presets
* [Configure Queries](/risksheet/guides/advanced/query-configuration) — Advanced query-based data selection
* [Use Query Factory](/risksheet/guides/advanced/query-factory) — Dynamic filtering for linked item suggestions
# Configure Queries
Source: https://learn.nextedy.com/risksheet/guides/advanced/query-configuration
Customize the Lucene queries that control which work items are loaded and displayed in your Nextedy RISKSHEET, including custom filters, SQL queries, and multi-type configurations.
Risksheet builds Lucene queries to retrieve work items from Polarion. The query combines three components using AND logic:
1. **Type filter** -- which work item types to include
2. **Project/document scope** -- restricts to the current document
3. **Custom query** -- your optional additional filter
```text theme={null}
Query Assembly:
Work Item Type Filter (from dataTypes.risk.type)
+
Project & Document Scope (automatic)
+
Custom Query (from dataTypes.risk.query)
=
Final Lucene Query
```
Specify which work item types appear in the Risksheet using the `dataTypes` configuration. Multiple types are combined with OR logic.
```yaml theme={null}
dataTypes:
risk:
type: fmeaRisk
role: relates_to
task:
type: mitigationTask
role: has_parent
```
**At Least One Type Required**
The `type` property must specify at least one work item type. If no type is configured, the system raises an error and no items are loaded.
Add a `query` property to your data type configuration to apply additional Lucene filters:
```yaml theme={null}
dataTypes:
risk:
type: fmeaRisk
query: status:open OR status:draft
```
The custom query is ANDed with the type and scope filters. Empty or whitespace-only queries are automatically ignored.
When embedding queries with quotation marks in sheet configuration, use backslash escaping:
```yaml theme={null}
dataTypes:
risk:
type: fmeaRisk
query: customField:"Product Family A"
```
**SQL Query Support**
Risksheet supports SQL queries for complex work item filtering using the `SQL:(...)` prefix syntax. This is useful when Lucene queries cannot express the required filtering logic.
Control how the item search and autocomplete behaves when linking items. These properties are set in **Administration** > **Nextedy Risksheet** at the project level:
| Property | Default | Description |
| ----------------------- | ------- | ------------------------------------ |
| Fuzzy Search | `true` | Allows approximate matches for typos |
| Wildcard Search | `true` | Enables `*` and `?` wildcards |
| Keyword Search Required | `false` | When true, keywords are mandatory |
| Suggestion Result Limit | `20` | Maximum autocomplete results |
| All-Field Search | `false` | Search all fields, not just primary |
**Enable All-Field Search for Linked Items**
Set `nextedy.risksheet.isSearchAllFieldsWhenSearchingLinkedItems=true` in Polarion Configuration Properties to search through all fields when searching linked items, not just the default fields.
When working with cross-project Risksheets, you can define multiple projects for upstream columns using configuration properties with Velocity snippets.
**Empty Configuration Property Values**
When using configuration properties to define multi-project upstream columns, empty property values after the `=` sign cause errors. Always ensure configuration properties have valid values, and use direct project IDs rather than nested configuration property variables.
## Verification
Open your Risksheet document and verify that:
1. Only work items matching your configured types appear in the grid.
2. Custom query filters correctly limit the displayed items.
3. Autocomplete search returns relevant results when linking items.
You should now see only the work items that match your query configuration, with autocomplete suggestions filtered according to your search settings.
## See Also
* [Use Query Factory](/risksheet/guides/advanced/query-factory) -- dynamic query generation for autocomplete filtering
* [Configure Upstream Traceability Columns](/risksheet/guides/columns/upstream-traceability) -- set up linked item columns
* [Configure Cross-Project Linking](/risksheet/guides/advanced/cross-project-linking) -- queries across multiple projects
# Use Query Factory
Source: https://learn.nextedy.com/risksheet/guides/advanced/query-factory
Create named query factory functions that dynamically filter autocomplete suggestions in `itemLink` and `multiItemLink` columns.
A query factory is a JavaScript function that returns a Lucene query string. When a user edits an `itemLink` or `multiItemLink` column, Nextedy RISKSHEET calls the factory function and appends its returned query to the autocomplete search, restricting which items appear in the dropdown.
Query factories are defined under a top-level `queryFactories` section in the sheet configuration (the `risksheet.json` file, editable as YAML since v25.5.0) and referenced by name from an `itemLink` column's `typeProperties.queryFactory` property.
Add a named function to the `queryFactories` section of the sheet configuration, then reference it from a column via `typeProperties.queryFactory`:
```yaml theme={null}
queryFactories:
filterByLinkedElement: "function(info){ return 'type:requirement AND linkedElement:' + info.item['systemElement']; }"
columns:
- id: requirement
header: Requirement
bindings: linkedRequirement
type: itemLink
typeProperties:
linkRole: implements
linkTypes: requirement
queryFactory: filterByLinkedElement
```
The factory function receives an `info` object describing the current row and context. It returns a Lucene query string that the server appends to the autocomplete search.
A common pattern is filtering one upstream column based on the value selected in another. For example, restrict the Requirements autocomplete to requirements that are already linked to the row's selected System Element:
1. Define the first column (System Element) as a standard `itemLink` column.
2. Define the second column (Requirement) with `typeProperties.queryFactory` pointing to a factory that reads the System Element value from `info.item`.
3. The factory returns a Lucene query that restricts results to requirements related to that element.
```yaml theme={null}
queryFactories:
byElement: "function(info){ var el = info.item['systemElement']; return el ? 'linkedElement:' + el : ''; }"
```
**Dependent upstream filtering**
Combine `queryFactory` with `canCreate: false` on the dependent column so users can only link to pre-existing items in the tracker. This keeps the cell active for linking and unlinking, while preventing accidental creation of new items that bypass the upstream filter.
Control whether users can create new items inline from the link editor:
```yaml theme={null}
columns:
- id: hazardousSituation
header: Hazardous Situation
bindings: linkedHazSit
type: itemLink
canCreate: false
typeProperties:
linkRole: relates_to
linkTypes: hazard
queryFactory: filterBySequenceOfEvents
```
Setting `canCreate: false` lets users select and unlink existing items but disables inline creation from the autocomplete editor. The default is `true`. The flag can also be set globally for all task columns via `dataTypes.task.canCreate`.
Query factories work identically with `multiItemLink` columns. Reference the factory through `typeProperties.queryFactory`; the function shape and `info` parameter are the same.
**Column ID consistency**
Column IDs used in `levels` (as `controlColumn` or `zoomColumn`) and `sortBy` must exactly match the `id` of a defined column. Mismatched IDs can cause row duplication and unexpected query behavior in factories that read `info.item['someColumn']`.
Query factory functions are plain JavaScript and run in the browser, so they can read live values from DOM elements that the top panel template (`risksheetTopPanel.vm`) renders. This turns the top panel from a passive display into an interactive filter for the grid.
The pattern:
1. Render an interactive control in the top panel template, for example a `` with options such as `all`, `ASIL_B`, `ASIL_D`.
2. In the sheet configuration's `queryFactories` section, define a factory that reads the selected value via jQuery and returns a Lucene query based on it.
3. Reference the factory from an `itemLink` column's `typeProperties.queryFactory`.
```yaml theme={null}
queryFactories:
# Simple: scope autocomplete to the current document
functionQuery: "function(info){ return 'type:function AND document.id:' + info.documentId; }"
# Interactive: read a in the top panel and filter accordingly
hazardQuery: "function(info){ var cars = $('#cars').val(); if (cars == 'all') return ''; return 'hazardClassification:' + cars; }"
```
When the user changes the dropdown in the top panel, the next autocomplete invocation re-runs the factory and updates the suggestion list. This pattern keeps the top panel and the grid loosely coupled through DOM-readable values, and is a clean way to expose document-level filters without hard-coding them in the configuration.
For filters driven by document-level metadata rather than runtime UI, render the value into the top panel template with Velocity and read it from the factory:
1. In `risksheetTopPanel.vm`, write a document custom field into a hidden element or a JavaScript variable.
2. In the factory, read the rendered value (via jQuery or a global variable) and include it in the returned Lucene query.
This allows the same column configuration to filter differently per document — for example, restricting linked items to a particular project, release, or domain encoded as a document custom field.
## Verification
1. Open a Risksheet document with the `queryFactories` section configured and at least one column referencing a factory via `typeProperties.queryFactory`.
2. Click into a cell in that column and type at least three characters.
3. Confirm the autocomplete dropdown shows only items that match both the user input and the Lucene query returned by your factory.
4. If the factory depends on another column, change that column's value and verify the dropdown updates accordingly.
5. If the factory reads top panel controls, change the control and verify the next autocomplete reflects the new selection.
## See Also
* [Configure Queries](/risksheet/guides/advanced/query-configuration) — static Lucene query configuration
* [Enable Conditional Linking](/risksheet/guides/columns/conditional-linking) — alternative approach to link filtering
* [Configure Upstream Traceability Columns](/risksheet/guides/columns/upstream-traceability) — set up the link columns that use query factories
* [Customize the Top Panel](/risksheet/guides/customization/top-panel) — Velocity templates and DOM controls for document-level data
# Configure Target Document Creation
Source: https://learn.nextedy.com/risksheet/guides/advanced/target-document-creation
Control where new work items are stored when created from Nextedy RISKSHEET by configuring the `createInDocument` parameter to decouple item loading from item creation paths.
## Why Configure a Target Document
By default, when you create a new linked work item from a Risksheet column, the item is stored in the Polarion tracker rather than in a specific document. For regulated workflows (FMEA, HARA), you typically need new risk controls, mitigation tasks, or verification activities stored in designated documents to maintain document-level traceability.
The `createInDocument` parameter lets you specify exactly which document receives new items, independently of where existing items are loaded from.
The read and write paths are completely independent. You can load items from the entire project while creating new ones in a specific document.
For downstream task and mitigation items, place `createInDocument` inside the `dataTypes` section of your sheet configuration:
```yaml theme={null}
dataTypes:
task:
type: mitigationAction
role: mitigates
createInDocument: Risks/Tasks
```
The `createInDocument` value uses the `folder/docID` path format, matching the Polarion document structure.
**Without createInDocument, Items Go to the Tracker**
If `createInDocument` is not set, newly created linked items are stored in the project's work item tracker rather than in any document. This breaks document-based traceability and audit trails required for ISO 26262 and ISO 14971 compliance.
For upstream linked items, place `createInDocument` in the column's `typeProperties`:
```yaml theme={null}
{
"columns": [
{
"header": "System Req",
bindings: "sysReq",
"type": "itemLink",
"typeProperties": {
"linkTypes": "systemRequirement",
"linkRole": "refines",
"createInDocument": "Requirements/SystemReqs"
}
}
]
}
```
| Item Direction | Configuration Location | Example |
| ------------------------------ | ------------------------------------------- | --------------------------- |
| Downstream (tasks, measures) | `dataTypes.task.createInDocument` | `"Risks/Tasks"` |
| Upstream (requirements, links) | `columns[].typeProperties.createInDocument` | `"Requirements/SystemReqs"` |
When you want new items stored in the current document rather than a separate one, use `createInCurrentDocument`:
```yaml theme={null}
typeProperties:
linkTypes: riskControl
linkRole: controls
createInCurrentDocument: true
```
This is useful when each Risksheet document should contain its own risk items rather than storing them in a shared document.
**Multi-Project Columns**
For `itemLink` and `multiItemLink` columns that load items from multiple projects, use `createInCurrentDocument: true` to ensure new items are always stored in the current project's document context.
## Common Pattern: Load Project-Wide, Create in Specific Document
A frequent configuration pattern loads existing items from the entire project (no `document` parameter) while directing new items to a specific document:
```yaml theme={null}
dataTypes:
task:
type: mitigationAction
role: mitigates
query: type:mitigationAction
createInDocument: Risks/MitigationTasks
```
This loads all mitigation actions from the project but creates new ones exclusively in `Risks/MitigationTasks`.
## Limitations
| Limitation | Notes |
| -------------------------- | -------------------------------------------------------------------------------------------------------------- |
| No chapter-level placement | Risksheet creates items at the document level; placement within specific chapters or headings is not supported |
| Target document must exist | The document specified in `createInDocument` must already exist in the Polarion project structure |
| Path format is fixed | Use `folder/docID` format only -- no wildcards or expressions |
**Dynamic Document References**
Reading document custom field values dynamically in sheet configuration (e.g., referencing a `subsheetName` custom field) is not natively supported. If you need dynamic document targets, consider using importer scripts to populate the configuration before opening the Risksheet.
## Verification
After configuring `createInDocument`:
1. Open the Risksheet document and create a new downstream task or linked item
2. Save the document
3. Navigate to the target document in Polarion
You should now see the newly created work item stored in the specified target document rather than in the project tracker.
## See Also
* [Configure Downstream Tasks](/risksheet/guides/risk-management/downstream-tasks) -- task data type configuration
* [Configure Multiple Downstream Types](/risksheet/guides/risk-management/multiple-downstream-types) -- multiple task types with different target documents
* [Configure Cross-Project Linking](/risksheet/guides/advanced/cross-project-linking) -- cross-project item creation and display
* [Configure Multi-Project Setup](/risksheet/guides/configuration/multi-project-setup) -- project-level configuration
# Use Undo and Redo
Source: https://learn.nextedy.com/risksheet/guides/advanced/undo-redo
Revert and reapply changes in Nextedy RISKSHEET using the undo/redo system, which tracks cell edits, row operations, paste actions, and cascading dependent enum updates.
## Undo a Change
1. Press **Ctrl+Z** (or **Cmd+Z** on macOS) to undo the most recent change
2. The grid reverts to its previous state and scrolls automatically to show the affected row
3. Repeat to undo additional changes, up to the last 50 actions
## Redo a Change
1. Press **Ctrl+Y** (or **Ctrl+Shift+Z** on macOS) to reapply the most recently undone change
2. The grid restores the change and positions the view on the affected row
**New Edits Clear the Redo Stack**
If you undo several changes and then make a new edit, all undone changes are permanently removed from the redo history. You cannot redo them after making a new edit.
## What Can Be Undone
The undo stack tracks the following types of operations:
| Operation | Undo Behavior |
| --------------------------- | ---------------------------------------------------------------------------- |
| **Cell edits** | Restores previous cell value and row height |
| **Paste operations** | Reverts all pasted cells as a single action |
| **Row addition** | Removes the added row and scrolls to previous position |
| **Row deletion** | Restores the deleted row (with limitations for unsaved items) |
| **Dependent enum cascades** | Reverts all cascading child field changes together |
| **Task removal** | Restores removed task or cleared task fields |
| **Linked column changes** | Restores dependent column values for `itemLink`, `multiItemLink`, `taskLink` |
## Undo Cascading Dependent Enum Changes
When you edit a parent enum field that triggers cascading updates to child fields via the configured dependent enum mapping, the entire cascade is tracked as a single undo action:
1. Change a parent enum value — child fields update automatically
2. Press **Ctrl+Z** — both the parent change and all child field updates are reverted together
3. Press **Ctrl+Y** — the parent change and all cascading updates are reapplied
This applies to both single-row edits and bulk edits across multiple selected rows.
## Undo Multi-Cell Paste Operations
When you paste values into multiple cells, the entire paste operation is bundled as a single undo action. Pressing **Ctrl+Z** reverts all pasted cells at once rather than requiring individual cell-by-cell undo.
## Undo Linked Column and Merged Cell Changes
Undo operations on `itemLink`, `multiItemLink`, `taskLink`, and `multiEnum` columns automatically restore dependent column values. For merged cells (common in `itemLink` columns within hierarchical levels), the undo operation applies across all rows in the merged cell range.
Multi-enum fields use specialized undo logic that converts between internal IDs and visible values, ensuring the display remains consistent after undo/redo.
## Undo Task Operations
Task operations support full undo:
* **Task addition**: Undoing a task addition removes the added task row and restores the grid to the previous position
* **Task removal**: Undoing a task removal restores the task. For single-task items where task fields were cleared, undo restores all cleared task attributes
**Cannot Undo Deletion of Unsaved Items**
If you delete a row for a newly created work item that has not been saved (identifiable by a temporary ID), undo cannot restore it. A warning message appears: "It is not possible to Undo deletion of unsaved items." Always save new items before performing delete operations.
## Limitations
| Limitation | Details |
| ------------------------- | ------------------------------------------------------------------- |
| **Stack size** | Maximum 50 undo actions. Older actions are automatically discarded. |
| **Unsaved item deletion** | Deleted new (unsaved) items cannot be restored via undo. |
| **Save operations** | Saving the document is not an undoable action. |
| **Redo after new edit** | Making any new change clears the entire redo stack. |
| **Page reload** | Undo history does not persist across page reloads. |
**Save Frequently**
Since undo history is limited to 50 actions and resets on page reload, save your document regularly. After saving, undo still works within the current session for reverting unsaved changes.
## Verify Undo/Redo
After making changes:
1. Edit a cell value, then press **Ctrl+Z** — the original value should reappear
2. Press **Ctrl+Y** — the edited value should be restored
3. Add a row, then undo — the row should be removed and the grid scrolls to the previous position
4. Edit a parent enum with cascading dependents, then undo — all cascading child fields should also revert
You should now see undo and redo working consistently for cell edits, row operations, paste actions, and cascading enum changes.
## See Also
* [Perform Bulk Editing](/risksheet/guides/advanced/bulk-editing) — multi-cell operations that create undo entries
* [Configure Dependent Enums](/risksheet/guides/advanced/dependent-enums) — cascading enum relationships tracked by undo
* [Configure Remove/Delete Actions](/risksheet/guides/risk-management/remove-delete-risk) — task removal behavior
# Add Assignee Column
Source: https://learn.nextedy.com/risksheet/guides/columns/add-assignee-column
Add a user reference column to your Nextedy RISKSHEET grid so analysts can assign risk items or mitigation tasks to team members.
Open sheet configuration and add a column entry with `type` set to `ref:user`:
```json theme={null}
{
"columns": [
{
"id": "riskAssignee",
"bindings": "assignee",
"header": "Assignee",
"type": "ref:user",
"width": 140
}
]
}
```
The `ref:user` type renders the column as a user selection dropdown, displaying Polarion user IDs and allowing single-user assignment. This allows user to display/select assignee for the main risk item.
To restrict which users appear in the dropdown, set a `userRole` property **inside the column's `typeProperties` block** to control the list of selectable users:
```json theme={null}
{
"id": "riskAssignee",
"bindings": "assignee",
"header": "Assignee",
"type": "ref:user",
"typeProperties": {
"userRole": "project_assignable"
},
"width": 140
}
```
Always nest `userRole` inside the column's `typeProperties` block. Placing it as a **top-level** column property (a sibling of `type`) makes the **entire Risksheet fail to load** -- not just the column -- with a fatal configuration error:
```text theme={null}
Cannot invoke "com.nextedy.risksheet.config.AppConfig$TypeProperties.getUserRole()" because "typeProperties" is null
```
| userRole Value | Users Shown |
| -------------------- | -------------------------------------------- |
| `project_assignable` | Users assignable in the current project |
| *(global role name)* | Users belonging to the specified global role |
When mitigation tasks reside in a different project than the Risksheet document, the `userRole: "project_assignable"` property fetches users from the Risksheet's project context -- not the task's project. If your tasks are in a separate project, use a global role instead so that users from the target project appear in the dropdown.
To add an assignee column for downstream mitigation tasks rather than the main risk item, nest the column under the task configuration:
```json theme={null}
{
"id": "taskAssignee",
"bindings": "task.assignee",
"header": "Task Assignee",
"type": "ref:user",
"typeProperties": {
"userRole": "project_assignable"
},
"width": 140
}
```
The `task.` prefix in the binding indicates this column maps to the downstream task work item (column with the "id": task), not the main risk item. Use the singular `task.assignee` (matching the other downstream bindings `task.title`, `task.type`, `task.status`).
User reference columns are editable by default for main risk items. For upstream linked item columns, you must explicitly set `readOnly` to `false`:
```json theme={null}
{
"id": "upstreamAssignee",
"bindings": "requirement.assignee",
"header": "Req. Assignee",
"type": "ref:user",
"readOnly": false,
"width": 140
}
```
User reference columns support single-user assignment only. Selecting a new user replaces the previous assignee. The column displays the Polarion user ID of the assigned person.
## Verification
Save the configuration and reload your Risksheet. You should now see the Assignee column in the grid. Click on a cell in the column to open the user selection dropdown. Select a user and verify the assignment is saved correctly by refreshing the page.
## See Also
* [Add a Basic Column](/risksheet/guides/columns/add-basic-column) -- general column configuration
* [Enable Editing of Upstream Columns](/risksheet/guides/columns/edit-upstream-columns) -- make linked columns editable
* [Configure Permissions](/risksheet/guides/administration/permissions) -- control who can edit assignments
* [Configure Enum Columns](/risksheet/guides/columns/enum-columns) -- set up dropdown selection columns
# Add a Basic Column
Source: https://learn.nextedy.com/risksheet/guides/columns/add-basic-column
Add a new column to your Nextedy RISKSHEET grid by defining it in the sheet configuration sheet configuration.
Open the sheet configuration file attached to your Risksheet document. You can edit it through the configuration editor or directly as an attachment.
Add a new object to the `columns` array in your configuration. Each column requires at minimum a `bindings` and `header`:
```yaml theme={null}
{
"columns": [
{
"id": "failureDescription",
"bindings": "description",
"header": "Failure Description",
"width": 200
}
]
}
```
Set the properties that control column behavior:
| Property | Default | Description |
| ------------- | ------------------------------------------ | -------------------------------------------------------------- |
| `id` | Auto-generated from `header` or `bindings` | Unique identifier for the column |
| `bindings` | *(required)* | Polarion work item field name |
| `header` | *(required)* | Display text in column header |
| `type` | Auto-detected from bindings | Data type: `string`, `int`, `float`, `enum`, `date`, `boolean` |
| `width` | Auto | Column width in pixels |
| `readOnly` | `false` | Prevents editing when set to `true` |
| `visible` | `true` | Controls column visibility |
| `filterable` | `true` | Enables filtering by column values |
| `level` | `1` | Hierarchical level (1 = top level) |
| `headerGroup` | *(none)* | Groups columns under a shared header |
Use `headerGroup` to organize columns under a shared group header:
```yaml theme={null}
{
"columns": [
{
"id": "sev",
"bindings": "severity",
"header": "S",
"headerGroup": "Initial Rating",
"type": "rating:severity",
"width": 60
},
{
"id": "occ",
"bindings": "occurrence",
"header": "O",
"headerGroup": "Initial Rating",
"type": "rating:occurrence",
"width": 60
},
{
"id": "det",
"bindings": "detection",
"header": "D",
"headerGroup": "Initial Rating",
"type": "rating:detection",
"width": 60
}
]
}
```
The group header height is controlled by `headers.columnGroupHeader.height` (default: `32` pixels).
If you omit the `type` property, Risksheet automatically detects the type from the Polarion field definition. For standard Polarion fields like `description`, `title`, or `severity`, auto-detection works reliably. Explicitly set `type` when binding to custom fields or when you want to override the default rendering.
Certain columns become read-only automatically:
* Columns with a `formula` property
* Columns with a `serverRender` property
* System fields: `id`, `status`, `type`, `project`, `outlineNumber`
* Fields where Polarion permissions deny modification
To make a column explicitly non-editable:
```yaml theme={null}
{
"id": "riskCategory",
"bindings": "riskCategory",
"header": "Category",
"readOnly": true
}
```
## Verification
Reload your Risksheet page after saving the configuration. You should now see the new column in the grid with the specified header text. Click on a cell in the column to verify it is editable (unless marked `readOnly`).
## See Also
* [Column Configuration](/risksheet/guides/columns/index) -- overview of all column configuration options
* [Configure Calculated Columns](/risksheet/guides/columns/calculated-columns) -- add formula-driven columns
* [Control Column Visibility](/risksheet/guides/columns/column-visibility) -- show and hide columns
* [Configure Enum Columns](/risksheet/guides/columns/enum-columns) -- set up dropdown columns
* [Add Header Tooltips](/risksheet/guides/styling/header-tooltips) -- add descriptions to column headers
# Configure Calculated Columns
Source: https://learn.nextedy.com/risksheet/guides/columns/calculated-columns
Add formula-driven columns to your Nextedy RISKSHEET that automatically compute values from other cells — for example, Risk Priority Numbers (RPN), weighted scores, or aggregated data from linked items.
## Prerequisites
* Access to the sheet configuration (the configuration editor at **Menu > Configuration > Edit Risksheet Configuration** supports YAML editing since v25.5.0)
* Understanding of which Polarion fields hold the source data for your calculations (the `bindings` of the source columns)
* Familiarity with JavaScript expression syntax
## Two Ways to Define Formulas
Risksheet supports two complementary places to write formula functions:
| Method | Where | When to use |
| -------------------------------------- | ------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| **Method 1 — Sheet configuration** | The `formulas` section of the sheet configuration | Simple, self-contained calculations (RPN = S \* O \* D, conditional thresholds, value combinations) |
| **Method 2 — Top panel configuration** | A `
```
**Functions must be on the global window object**
Because `enableFn` and `executeFn` are resolved by name, functions defined inside closures, IIFEs, or module scopes will not be found at runtime and the menu action will silently fail. Always attach them to `window`.
## Control New Item Menu Options
The "New \[Level] Item" menu options are generated dynamically from the `levels` configuration in the sheet configuration. Use `showInMenu` to control which levels appear:
```yaml theme={null}
levels:
- name: Failure Mode
controlColumn: systemItemId
zoomColumn: systemItemId
showInMenu: true
- name: Cause
controlColumn: cause
zoomColumn: cause
showInMenu: true
- name: Internal Reference
controlColumn: reference
zoomColumn: reference
showInMenu: false
```
Setting `showInMenu` to `false` hides that level from the context menu while keeping it functional in the grid hierarchy. This is useful for levels populated automatically or through imports.
## Customize Task Menu Labels
The "Open Task Item" menu label dynamically reflects the configured task type name. Set `dataTypes.task.name` in the sheet configuration:
```yaml theme={null}
dataTypes:
task:
name: Mitigation Action
type: mitigationAction
role: mitigates
```
With this configuration, the context menu displays "Open Mitigation Action" instead of the default "Open Task".
## Overwrite Row Item
The "Overwrite Row Item" action converts a referenced item to overwrite mode, enabling local modifications to be saved back to the source. This action appears only when the selected item has `systemReferenceType` set to `reference`.
**Use Debug mode to inspect item state**
When **Debug** is available in the context menu, it logs the ghost status, column ID, cell value, full item object, and comparison manager state to the browser console — invaluable when diagnosing why an overwrite action is unavailable.
Debug mode is a developer/runtime mode and is **not** enabled through the sheet configuration. Setting `debug: true` in the `global` section has no effect (the key is silently ignored), and there is no `appConfig.debug` setting that turns it on.
**Document workflow transitions**
Triggering Polarion document workflow transitions (for example, changing document status from within Risksheet) is not provided as a built-in menu item. Use the `customContextMenuActions` extensibility point to call the appropriate Polarion endpoint from your custom function.
## Verify Your Changes
After configuring custom context menu actions:
1. Reload the Risksheet page to load your top panel script changes.
2. Right-click on a grid cell — you should now see your custom menu items alongside the built-in actions.
3. Verify that the `enableFn` condition correctly enables and disables the action based on the selected item.
4. Check the browser console for errors if a custom action does not appear (a common cause is a function defined inside a closure rather than on `window`).
## See Also
* [Customize the Top Panel](/risksheet/guides/customization/top-panel) — add scripts and custom fields to the top panel area
* [Configure Remove/Delete Actions](/risksheet/guides/risk-management/remove-delete-risk) — control how items are removed from the grid
* [Understanding the Interface](/risksheet/getting-started/understanding-interface) — overview of Risksheet UI components
* [Create Custom Renderers](/risksheet/guides/customization/custom-renderers) — extend cell rendering with custom display logic
* [Use the AI Assistant](/risksheet/guides/risk-management/use-the-ai-assistant) — run a configured AI action from the cell menu
# Create Custom Renderers
Source: https://learn.nextedy.com/risksheet/guides/customization/custom-renderers
Register custom JavaScript rendering functions to control how individual cells and row headers display data in the Nextedy RISKSHEET grid.
Risksheet provides two distinct customization mechanisms that are often confused:
* **Cell decorators** — JavaScript functions that toggle CSS classes on cells. Functions live in the `cellDecorators` section of the sheet configuration; columns reference them via the `cellRenderer` property.
* **Custom cell renderers** — JavaScript functions that replace cell HTML content entirely. Functions live in the `cellRenderers` section of the sheet configuration; columns also reference them via the `cellRenderer` property.
Both mechanisms are configured in the sheet configuration file, edited through the YAML editor available in Polarion (v25.5.0+).
Cell decorators are JavaScript functions registered in the `cellDecorators` section of the sheet configuration. Each function receives an `info` object and uses jQuery to toggle CSS classes on the cell element based on data values.
The `info` object provides:
| Property | Type | Description |
| ------------ | ------------- | ------------------------------------------------------------------------ |
| `info.cell` | `HTMLElement` | The DOM element of the cell being rendered |
| `info.item` | `object` | The current row's data object (access fields via `info.item['fieldId']`) |
| `info.value` | `any` | The cell's current value |
Add a decorator to the `cellDecorators` section:
```yaml theme={null}
cellDecorators:
rpn: "function(info){ var val = info.value; $(info.cell).toggleClass('boldCol', true); $(info.cell).toggleClass('rpn1', val > 0 && val <= 150); $(info.cell).toggleClass('rpn2', val > 150 && val <= 250); $(info.cell).toggleClass('rpn3', val > 250); }"
```
This example applies CSS classes based on RPN (Risk Priority Number) value thresholds:
* `boldCol` — always applied (bold text)
* `rpn1` — applied when value is 1 to 150 (low risk)
* `rpn2` — applied when value is 151 to 250 (medium risk)
* `rpn3` — applied when value exceeds 250 (high risk)
The thresholds shown above are illustrative — RPN thresholds are user-configurable in cellDecorators and vary per deployment; pick values that match your project's risk-acceptance criteria.
**Always Use toggleClass**
Cell decorators MUST use `$(info.cell).toggleClass()` rather than directly setting inline styles. The grid reuses DOM cells when scrolling, so classes set with `toggleClass` are properly added and removed as rows recycle. Inline styles set with `.css()` will persist on the recycled cell and corrupt the display of unrelated rows.
**Multiple Decorators**
You can define as many named decorators as needed in the `cellDecorators` object. Each column can reference a different decorator via the `cellRenderer` property.
Create CSS class definitions in the `styles` section of the sheet configuration to define the visual appearance applied by your decorators. Style names must be valid CSS selectors prefixed with a dot, and the rule body MUST be wrapped in braces:
```yaml theme={null}
styles:
".boldCol": "{font-weight:600;}"
".rpn1": "{background-color: #eaf5e9 !important; color: #1d5f20 !important;}"
".rpn2": "{background-color: #fff3d2 !important; color: #735602 !important;}"
".rpn3": "{background-color: #f8eae7 !important; color: #ab1c00 !important;}"
```
| CSS Class | Risk Level | Background Color | Text Color | Description |
| ---------- | ---------------- | ------------------------ | ----------------------- | ----------------------------- |
| `.boldCol` | All | — | — | Bold font weight for emphasis |
| `.rpn1` | Low (1–150) | `#eaf5e9` (light green) | `#1d5f20` (dark green) | Acceptable risk |
| `.rpn2` | Medium (151–250) | `#fff3d2` (light yellow) | `#735602` (dark yellow) | Review recommended |
| `.rpn3` | High (>250) | `#f8eae7` (light red) | `#ab1c00` (dark red) | Mitigation required |
**Use `!important` for Background and Text Colors**
Always use `!important` on `background-color` and `color` properties in cell decorator styles. Without `!important`, the grid's default cell styling may override your conditional formatting.
Reference your decorator on a column using the `cellRenderer` property. The value is the name of a function in the `cellDecorators` section. This activates the decorator for all cells in that column:
```yaml theme={null}
columns:
- id: rpn
bindings: rpn
header: RPN
formula: commonRpn
cellRenderer: rpn
- id: rpnNew
bindings: rpnNew
header: RPN (New)
formula: commonRpnNew
cellRenderer: rpn
```
The same decorator can be applied to multiple columns. In the example above, both the initial RPN and the revised RPN columns use the same `rpn` decorator for consistent color coding.
**cellRenderer Points Into cellDecorators**
The column-level property is named `cellRenderer`, but the function it references is registered in the `cellDecorators` section of the sheet configuration. This is the standard pattern verified in production configurations and KB article #48001172969 — the column property and the registration section have different names by design.
Use `headers.rowHeader.renderer` to apply conditional styling to the row header (the leftmost column showing row numbers). The renderer references a function registered in the `cellDecorators` section. Row header decorators use the same `$(info.cell).toggleClass(...)` jQuery form as cell decorators, which is what the product's reference templates use:
```yaml theme={null}
headers:
rowHeader:
renderer: rowHeaderRpnNew
cellDecorators:
rowHeaderRpnNew: "function(info){ var val = info.item['rpnNew']; $(info.cell).toggleClass('rpn1', val > 0 && val <= 150); $(info.cell).toggleClass('rpn2', val > 150 && val <= 250); $(info.cell).toggleClass('rpn3', val > 250); }"
```
The row header renderer accesses `info.item` to read any property from the row's work item. In this example, it reads the revised RPN value (`rpnNew`) to color the row header based on the post-mitigation risk level, providing at-a-glance risk assessment for each row.
**Row Header Rendering Flow:**
headers.rowHeader.renderer cellDecorators.rowHeaderRpnNew styles.rpn1 / rpn2 / rpn3
────────────────────────── ─► ────────────────────────────── ─► ───────────────────────────
references decorator name function evaluates row data CSS classes applied to cell
For complete control over cell display — replacing the default rendering entirely rather than adding CSS classes — register custom cell renderer functions in the `cellRenderers` section of the sheet configuration. Custom cell renderers differ from cell decorators:
| Feature | Cell Decorators | Custom Cell Renderers |
| -------------------- | ------------------------------------------- | ---------------------------------- |
| Purpose | Add/remove CSS classes on the existing cell | Replace cell HTML content entirely |
| Registration section | `cellDecorators` | `cellRenderers` |
| Column property | `cellRenderer` | `cellRenderer` |
| Parameters | `info` (cell, item, value) | grid, cell, item, value |
| Comparison mode | Disabled | Disabled |
The column-level property name is the same in both cases (`cellRenderer`), but the function it points to lives in a different registration namespace. Risksheet resolves the reference by looking up the function name in both sections.
Custom renderers receive four parameters and can modify the cell appearance completely:
```yaml theme={null}
cellRenderers:
statusIcon: "function(grid, cell, item, value){ cell.innerHTML = value === 'open' ? 'Open ' : 'Closed '; }"
```
Reference the renderer on a column:
```yaml theme={null}
columns:
- id: riskStatus
bindings: riskStatus
header: Status
cellRenderer: statusIcon
```
**Custom Renderers Are Disabled During Comparison Mode**
When comparing against a baseline revision, custom cell renderers are not applied. The comparison highlighting takes precedence to clearly show changes between revisions. Plan your renderers knowing that comparison mode will display raw values.
**Two Registration Namespaces, One Column Property**
`cellDecorators` and `cellRenderers` are distinct registration sections — they are not the same namespace. If you give a decorator and a renderer the same name, the column's `cellRenderer` reference will resolve to one of them depending on lookup order. Use descriptive, distinct names to avoid ambiguity (e.g., `rpn` for decorators, `statusIcon` for renderers).
Use styles with `.firstRow` and `.lastRow` selectors to differentiate column group header appearance. This is useful when organizing columns into header groups:
```yaml theme={null}
styles:
".firstRow .headSysReq": "{background-color: rgba(62, 175, 63, 0.12) !important; color: #2A792D !important;}"
".lastRow .headSysReq": "{background-color: #FFF !important; color: #2A792D !important;}"
".firstRow .headFinalRanking": "{background-color: rgba(62, 175, 63, 0.12) !important; color: #2A792D !important;}"
".lastRow .headFinalRanking": "{background-color: #FFF !important; color: #2A792D !important;}"
```
Apply the CSS class to a column's header group:
```yaml theme={null}
columns:
- id: sysReq
header: System Requirement
headerGroup: Upstream
headerGroupCss: headSysReq
```
**Column Header Group Styling**
Use `.firstRow` and `.lastRow` selectors to differentiate the top and bottom rows of multi-level column group headers. The `.firstRow` selector targets the group header row, while `.lastRow` targets the individual column header row beneath the group.
## Complete Configuration Example
A full sheet configuration snippet combining cell decorators, styles, row header renderer, and column configuration:
```yaml theme={null}
formulas:
commonRpn: "function(info){ var value = info.item['occ']*info.item['det']*info.item['sev']; return value?value:null; }"
commonRpnNew: "function(info){ var value = info.item['occNew']*info.item['detNew']*info.item['sevNew']; return value?value:null; }"
cellDecorators:
rpn: "function(info){ var val = info.value; $(info.cell).toggleClass('boldCol', true); $(info.cell).toggleClass('rpn1', val > 0 && val <= 150); $(info.cell).toggleClass('rpn2', val > 150 && val <= 250); $(info.cell).toggleClass('rpn3', val > 250); }"
rowHeaderRpnNew: "function(info){ var val = info.item['rpnNew']; $(info.cell).toggleClass('rpn1', val > 0 && val <= 150); $(info.cell).toggleClass('rpn2', val > 150 && val <= 250); $(info.cell).toggleClass('rpn3', val > 250); }"
styles:
".boldCol": "{font-weight:600;}"
".rpn1": "{background-color: #eaf5e9 !important; color: #1d5f20 !important;}"
".rpn2": "{background-color: #fff3d2 !important; color: #735602 !important;}"
".rpn3": "{background-color: #f8eae7 !important; color: #ab1c00 !important;}"
headers:
rowHeader:
renderer: rowHeaderRpnNew
columnHeader:
height: 32
columns:
- id: rpn
header: RPN
bindings: rpn
formula: commonRpn
cellRenderer: rpn
level: 2
headerGroup: Initial Assessment
- id: rpnNew
header: RPN (New)
bindings: rpnNew
formula: commonRpnNew
cellRenderer: rpn
level: 2
headerGroup: Final Ranking
```
## Verification
You should now see:
* RPN cells colored green, yellow, or red based on their calculated values
* Bold text applied to all RPN cells via the `boldCol` class
* Row headers colored according to the revised RPN value for at-a-glance risk assessment
* Column group headers with differentiated styling for first and last rows (if configured)
* No JavaScript errors in the browser developer console (`F12`)
Open the browser developer tools and inspect a cell element to verify that the expected CSS classes (e.g., `rpn1`, `boldCol`) are present on the cell's DOM element.
## See Also
* [Apply Conditional Formatting](/risksheet/guides/styling/conditional-formatting) — broader conditional formatting patterns beyond cell decorators
* [Configure Cell Styles](/risksheet/guides/styling/cell-styles) — CSS style definition reference
* [Configure Row Header Styles](/risksheet/guides/styling/row-header-styles)