> ## Documentation Index
> Fetch the complete documentation index at: https://learn.nextedy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# JavaScript API

> Nextedy RISKSHEET exposes client-side JavaScript extension points for custom integrations through the `window.risksheet` global object.

export const LastReviewed = ({date}) => {
  if (!date) return null;
  const formatted = new Date(`${date}T00:00:00Z`).toLocaleDateString("en-US", {
    year: "numeric",
    month: "long",
    day: "numeric",
    timeZone: "UTC"
  });
  return <p className="mt-10 text-sm text-gray-400 dark:text-zinc-500 not-prose">
      Last reviewed on {formatted}
    </p>;
};

<Frame>
  <img src="https://mintcdn.com/none-17b4493f/yWl5nA2D0IzEnZC1/risksheet/diagrams/reference/api/javascript-api/diagram-1.svg?fit=max&auto=format&n=yWl5nA2D0IzEnZC1&q=85&s=ff6ad22f1d81262ec97aa05713db5758" alt="diagram" style={{ maxWidth: "520px", width: "100%" }} width="520" height="420" data-path="risksheet/diagrams/reference/api/javascript-api/diagram-1.svg" />
</Frame>

Most extension points are populated from the sheet configuration file (`risksheet.json`, editable through the YAML configuration editor since v25.5.0). Functions can also be registered directly on `window.risksheet` from a top panel Velocity template (`risksheetTopPanel.vm`) for cases requiring access to server-side document context. See [Top Panel Template](/risksheet/reference/templates/top-panel-template) for the cross-file pattern.

## Extension Points

### Query Factories

Register custom query factory functions to filter which items appear in autocomplete suggestions for `itemLink` and `multiItemLink` columns. Query factories are named functions referenced by name from the `typeProperties.queryFactory` property on a column definition.

Query factories can be declared in two equivalent ways:

1. As a named entry in the top-level `queryFactories` section of the sheet configuration.
2. By assigning a function to `window.risksheet.queryFactories["<name>"]` from a top panel template.

| Property                          | Type     | Description                                                                                                                                                        |
| --------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `window.risksheet.queryFactories` | `object` | Registry of named query factory functions. Each key is a function name, each value is a function that receives an `info` object and returns a Lucene query string. |

**Function signature:**

```javascript theme={null}
function queryFactoryName(info) {
  // info.documentId, info.projectId, info.item -- context data
  // return: a Lucene query string to filter suggestions, or "" for no filter
  return "type:requirement AND document.id:" + info.documentId;
}
```

**Declaring in the sheet configuration:**

```yaml theme={null}
queryFactories:
  functionQuery: "function(info){ return 'type:function AND document.id:' + info.documentId; }"
  hazardQuery: "function(info){ var cars = $('#cars').val(); if(cars=='all') return ''; return 'hazardClassification:'+cars; }"
```

**Referencing from a column:**

```yaml theme={null}
columns:
  - id: function
    bindings: function
    type: itemLink
    typeProperties:
      linkRole: relates_to
      linkTypes: function
      queryFactory: functionQuery
```

The `hazardQuery` example above shows the advanced pattern: the function reads a value from the top panel via jQuery (`$('#cars').val()`) and returns a Lucene filter based on the user's selection. This creates interactive filtering where the top panel UI controls which suggestions appear in autocomplete editors.

<Tip title="Return empty string for no filtering">
  If your query factory determines that no additional filtering is needed for the current context, return an empty string `""` rather than `null` or `undefined`. Empty strings are safely ignored by the query builder.
</Tip>

### Cell Decorators

Register custom cell decorator functions for conditional visual styling of grid cells. Decorators receive an `info` object and apply or remove CSS classes to control cell appearance.

Cell decorators are defined as named entries in the `cellDecorators` section of the sheet configuration. A column opts in to a decorator via the `cellRenderer` property, which references the decorator name.

| Property                          | Type     | Description                                                                                                                  |
| --------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------- |
| `window.risksheet.cellDecorators` | `object` | Registry of named cell decorator functions. Each key is a decorator name referenced from a column's `cellRenderer` property. |

**Defining in the sheet configuration:**

```yaml theme={null}
cellDecorators:
  rpn: "function(info){ var val = info.value; $(info.cell).toggleClass('rpn1', val>0 && val<=150); $(info.cell).toggleClass('rpn2', val>150 && val<=250); $(info.cell).toggleClass('rpn3', val>250); }"
```

**Function parameters (the `info` object):**

| Parameter    | Type        | Description                                        |
| ------------ | ----------- | -------------------------------------------------- |
| `info.value` | varies      | The current cell value                             |
| `info.cell`  | DOM element | The cell's DOM element for applying CSS classes    |
| `info.item`  | `object`    | The full work item data object for the current row |

<Warning title="Use toggleClass, not inline styles">
  Cells in the grid are reused as the user scrolls. Setting inline styles (`info.cell.style.background = ...`) leaves stale styling on cells when they are reused for different rows. Always use `$(info.cell).toggleClass('className', condition)` so styling is correctly applied or removed for each value. Row header decorators use the same `$(info.cell).toggleClass('className', condition)` form.
</Warning>

The decorator can also dynamically control cell editability by appending field IDs to the pipe-delimited `info.item.systemReadOnlyFields` string. Adding `'|fieldId|'` makes that cell read-only for the current row, and adding the built-in `rs-readonly` class gives a grayed-out visual treatment.

See [Cell Decorators](/risksheet/reference/styling/cell-decorators) and [Conditional Formatting](/risksheet/reference/styling/conditional-formatting) for examples and the full `info` object reference.

### Custom Context Menu Actions

Register custom actions for the grid right-click context menu. Custom actions appear alongside built-in menu items and can execute arbitrary JavaScript logic.

| Property                                    | Type    | Description                                    |
| ------------------------------------------- | ------- | ---------------------------------------------- |
| `window.risksheet.customContextMenuActions` | `array` | Array of custom menu action definition objects |

**Action definition properties:**

| Field     | Type       | Required | Description                                                                                                            |
| --------- | ---------- | -------- | ---------------------------------------------------------------------------------------------------------------------- |
| `label`   | `string`   | Yes      | Display text for the menu item shown to the user                                                                       |
| `enabled` | `function` | Yes      | Inline function that receives the current item and returns `boolean` to control whether the action is shown as enabled |
| `execute` | `string`   | Yes      | Name of a function on the `window` object to invoke when the user clicks the action                                    |

**Registration pattern (from a top panel template):**

```javascript theme={null}
// Define the execute function on the global window object
window.openInExternalTool = function(item) {
  window.open("https://tool.example.com/item/" + item.systemItemId);
};

// Register the custom context menu action
window.risksheet = window.risksheet || {};
window.risksheet.customContextMenuActions = [
  {
    label: "Open in External Tool",
    enabled: function(item) { return item && item.systemItemId; },
    execute: "openInExternalTool"
  }
];
```

<Warning title="execute is a string, enabled is an inline function">
  The `execute` field is the **name** of a function registered on the global `window` object, as a string. The `enabled` field is an **inline function** (not a name) evaluated against the current selection. Functions defined in closures or module scopes cannot be referenced by name from `execute`.
</Warning>

## Data Access API

### risksheet.ds.getDownstreamRows(riskId)

The `risksheet.ds` namespace provides client-side access to the data source backing the grid. Formulas and cell decorators can read downstream task rows linked to a given risk item using `getDownstreamRows`.

| Method                                   | Parameters                                   | Returns                                  | Description                                                                                                                                    |
| ---------------------------------------- | -------------------------------------------- | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `risksheet.ds.getDownstreamRows(riskId)` | `riskId` -- the `systemItemId` of a risk row | `Array<object>` -- task row data objects | Returns all downstream task work items linked to the given risk item. Each entry exposes task fields by binding ID for direct property access. |

**Usage in a formula:**

```javascript theme={null}
function getInitialRiskIndex(info) {
  var riskId = info.item["systemItemId"];
  var tasks = risksheet.ds.getDownstreamRows(riskId);
  var det = 1;
  tasks.forEach(function(t) {
    // Filter by enum value
    if (t.round === "initial") {
      // Enum values with decimal points are stored with underscores:
      // "0_1" represents the value 0.1
      det = parseFloat(String(t.RCMdet).replace('_', '.'));
    }
  });
  // Read another formula's stored result from the current row
  return det * info.item['ri'];
}
```

**Key patterns:**

* Task fields are accessed directly as object properties: `t.fieldId` (e.g., `t.RCMdet`, `t.round`).
* Enum values containing a decimal point are stored with an underscore. Convert with `String(value).replace('_', '.')` and `parseFloat()` to recover the numeric value -- for example, `"0_1"` becomes `0.1`.
* A formula can read another formula's stored result for the same row via `info.item['<columnId>']`.

This API is the recommended way to aggregate or compute values from downstream tasks (such as residual risk after mitigations) without falling back to server-side rendering.

## Runtime Configuration Object

The `window.risksheet` object exposes read-only runtime configuration values set during page initialization by the server. These values reflect the current document context, version information, and user permissions. All data shown by Risksheet is read from Polarion work items at runtime -- Risksheet does not maintain a separate data store, so these values reflect the live state of the underlying Polarion document.

### Environment Properties

| Property                           | Type     | Description                                                                                                               |
| ---------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------- |
| `window.risksheet.baseUrl`         | `string` | Base URL for the application, used to construct data service endpoints and navigation URLs                                |
| `window.risksheet.projectId`       | `string` | Polarion project identifier for the current document                                                                      |
| `window.risksheet.revision`        | `string` | Document revision identifier. Empty string indicates current/head revision; non-empty forces read-only mode automatically |
| `window.risksheet.currentRevision` | `string` | The latest revision number of the document, used to determine if viewing current or historical version                    |
| `window.risksheet.version`         | `string` | Full version string of the application including build metadata                                                           |
| `window.risksheet.shortVersion`    | `string` | Shortened version identifier without build metadata, suitable for display                                                 |

### Configuration Data

| Property                     | Type     | Description                                                                                                                                                                  |
| ---------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `window.risksheet.appConfig` | `object` | Full sheet configuration parsed from the configuration file, including `columns`, `dataTypes`, `levels`, `formulas`, `styles`, `cellDecorators`, `views`, and other sections |
| `window.risksheet.document`  | `object` | Document metadata, including the document path, revision info, and template source                                                                                           |

Rating scales and enumerations are NOT exposed as separate top-level properties on `window.risksheet`. They are defined as Polarion enumerations in **Administration > Nextedy Risksheet > Setup** and referenced from column definitions via `type: rating:<enumId>`, `type: enum:<enumId>`, or `type: multiEnum:<enumId>`. The server loads the enum values automatically when the grid is rendered.

### Controlling the Default View at Runtime

The default saved view normally comes from the `defaultView: true` flag on an entry in the `views` section. You can also override it at runtime from a top panel script, for example to select a default view based on the current user's role:

```javascript theme={null}
// Pick the second saved view as default
risksheet.appConfig.views[1].defaultView = true;
```

When combined with `$securityService.getRolesForUser($securityService.getCurrentUser())` in the surrounding Velocity template, this enables role-based default views (e.g., reviewers see a "Mitigations" view, analysts see "Full Analysis").

## Formulas in the Sheet Configuration

JavaScript formulas defined in the `formulas` section of the sheet configuration execute in the client-side context and have access to row data through the `info` parameter:

```yaml theme={null}
formulas:
  rpnCalculation: "function(info){ var val = info.item['occ'] * info.item['det'] * info.item['sev']; return val ? val : null; }"
```

| Parameter    | Type     | Description                                                                                  |
| ------------ | -------- | -------------------------------------------------------------------------------------------- |
| `info.item`  | `object` | The work item data for the current row, with field values accessible by column `bindings` ID |
| Return value | varies   | The computed value to display in the formula column                                          |

Formulas are referenced by name from a column definition:

```yaml theme={null}
columns:
  - id: rpn
    header: RPN
    bindings: rpn
    formula: rpnCalculation
```

For complex calculations (multi-step risk matrices, conditional logic that spans many fields), define a JavaScript helper function in the top panel template and call it from a thin wrapper in the `formulas` section. This keeps the sheet configuration declarative and minimizes the validation scope when the calculation changes. See [Top Panel Template](/risksheet/reference/templates/top-panel-template) for the bridging pattern.

## See Also

* [Suggestion and Autocomplete API](/risksheet/reference/api/suggestion-api) -- query factory usage in autocomplete editors
* [Velocity Template Context](/risksheet/reference/api/velocity-context) -- server-side template context variables, including `$securityService`
* [Cell Decorators](/risksheet/reference/styling/cell-decorators) -- cell decorator configuration reference
* [Conditional Formatting](/risksheet/reference/styling/conditional-formatting) -- visual formatting rules
* [Custom Renderer Templates](/risksheet/reference/templates/custom-renderers) -- server-side rendering templates
* [Top Panel Template](/risksheet/reference/templates/top-panel-template) -- defining JavaScript functions in top panel Velocity templates
* [Formula Syntax](/risksheet/reference/formulas/formula-syntax) -- formula function syntax and usage
* [Configuration Properties Index](/risksheet/reference/configuration/properties-index) -- complete sheet configuration property reference

<LastReviewed date="2026-06-24" />
