# Conditional Widgets

Some widgets only need to appear in certain conditions. You may want to display a widget only when specific requirements are met and hide them otherwise. Widget guard conditions help you with such scenarios.

To define a condition for showing a widget, add a `guard` function to the widget description in the app manifest.

A widget guard is a JavaScript function that takes a context object as its argument and lets you check its properties. For the widget to be shown to the user, such a function must return `true`. When the function returns `false`, the widget is hidden.

The context object always contains the current user as `me`. For extension points that are evaluated in the context of a specific YouTrack entity, the context object also contains `entity`. To view the mapping between extension points and YouTrack entities, see [Guard Entity Reference](#guard-entity-reference).

Guard functions are synchronous. They cannot return promises or use the async/await syntax. Guard functions are executed in an isolated sandbox and can't refer to any resources except function arguments. If a guard function returns a value that isn't boolean, or throws an error, the widget is hidden.

## Sample Conditional Widget

Here is an example of a conditional widget with a guard function. In the manifest, add a `guard` property to the widget description.

In this example, the guard condition checks whether the value of the State field in an issue equals to Open. If it's the case, the widget appears in the issue.

```
"widgets": [
        {
          "key": "fields-first",
          "name": "Sample Widget",
          "description": "Optional description for the issue view widget",
          "guard": "({entity}) => entity.fields.State?.value === 'Open'",
          "extensionPoint": "ISSUE_FIELD_PANEL_FIRST",
          "indexPath": "index.html",
          "iconPath": "icon.png",
          "settingsSchemaPath": "sample-widget-settings.json",
          "permissions": ["READ_USER"]
        }
      ]
```

## Guards for Global and Markdown Widgets

Global full-page widgets and Markdown widgets support guard functions, but each type of widget uses a different guard context. Use the following examples to choose the right context properties for each extension point.

### Global Full-Page Widgets

Global full-page extension points, such as `MAIN_MENU_ITEM` and `ADMINISTRATION_MENU_ITEM`, don't have a host entity. Guards for these extension points can check properties of the current user in the `me` object, for example `me.userType`, `me.login`, or `me.name`. When the guard returns `false`, YouTrack hides the corresponding item from the main menu or administration menu.

```JSON
"widgets": [
  {
    "key": "team-report",
    "name": "Team Report",
    "description": "A report page for standard users and agents",
    "guard": "({me}) => me.userType !== 'reporter'",
    "extensionPoint": "MAIN_MENU_ITEM",
    "indexPath": "team-report/index.html",
    "iconPath": "team-report/icon.png"
  }
]
```

### Markdown Widgets

Markdown widgets can also use guards. For these widgets, the `entity` argument depends on where the text with the embedded widget is displayed. For example, the entity can be an issue, a helpdesk ticket, or an article.

```JSON
"widgets": [
  {
    "key": "issue-context-card",
    "name": "Issue Context Card",
    "description": "Shows extra information in issue text",
    "guard": "({entity, me}) => me.userType !== 'reporter' && entity?.type === 'issue' && !entity.isResolved",
    "extensionPoint": "MARKDOWN",
    "indexPath": "issue-context-card/index.html",
    "settingsSchemaPath": "issue-context-card/settings.json",
    "defaultDimensions": {
      "width": "100%",
      "height": "120px"
    }
  }
]
```

## Guard Entity Reference

Here is the list of YouTrack entities that guard functions can take as arguments, along with the mapping between them and widget extension points. You can use these entities and their properties to form a JavaScript guard function and define the condition.

### Context Object

| Property | Type | Description |
| --- | --- | --- |
| `me` | User | The current YouTrack user. This property is available for guards in all supported extension points. |
| `entity` |    Issue     Ticket     Article     Project     User    |    The YouTrack entity where the widget is displayed.     This property is available for entity-related extension points. For global full-page extension points, use `me` instead.    |

### Issue

| Property | Type | Description |
| --- | --- | --- |
| `id` | String | The ID of the issue. |
| `type` | String | The entity type. The value is `issue`. |
| `summary` | String | The summary of the issue. |
| `fields` | Fields | The set of custom fields that are used in the issue.     For each custom field, you can use the following field properties:     \| Name \| Type \| Description \| \| --- \| --- \| --- \| \| `name` \| String \| The name of the field. \| \| `type` \| String \|    The type of the field.     Possible values:       * `datetime`    * `date`    * `number`    * `string`    * `text`    * `enum`    * `user`    * `group`    * `period`    * `sla`    \| \| `value` \|    String     Number     Boolean    \| The value of the field. \|    |
| `draft` | Boolean | `true` when the issue is still a draft, and `false` when the issue is already created. |
| `isEditing` | Boolean | `true` when the issue is being edited, and `false` in issue view mode. |
| `isResolved` | Boolean | `true` when the issue is resolved, and `false` when the issue is unresolved. |

The following extension points take issue entity as their guard function argument:

* `ISSUE_ABOVE_ACTIVITY_STREAM`

* `ISSUE_BELOW_SUMMARY`

* `ISSUE_FIELD_PANEL_LAST`

* `ISSUE_FIELD_PANEL_FIRST`

* `ISSUE_OPTIONS_MENU_ITEM`

### Article

| Property | Type | Description |
| --- | --- | --- |
| `id` | String | The ID of the article. |
| `type` | String | The entity type. The value is `article`. |
| `summary` | String | The title of the article. |
| `draft` | Boolean | `true` when the article is still a draft, and `false` when the article is already created. |
| `isEditing` | Boolean | `true` when the article is being edited, and `false` in article view mode. |

The following extension points take article entity as their guard function argument:

* `ARTICLE_OPTIONS_MENU_ITEM`

* `ARTICLE_BELOW_SUMMARY`

* `ARTICLE_ABOVE_ACTIVITY_STREAM`

### Ticket

| Property | Type | Description |
| --- | --- | --- |
| `id` | String | The ID of the ticket. |
| `type` | String | The entity type. The value is `ticket`. |
| `summary` | String | The summary of the ticket. |
| `fields` | Fields | The set of custom fields that are used in the ticket. |
| `isEditing` | Boolean | `true` when the ticket is being edited, and `false` in ticket view mode. |
| `isResolved` | Boolean | `true` when the ticket is resolved, and `false` when the ticket is unresolved. |

The following extension points take ticket entity as their guard function argument:

* `ISSUE_ABOVE_ACTIVITY_STREAM`

* `ISSUE_BELOW_SUMMARY`

* `ISSUE_FIELD_PANEL_LAST`

* `ISSUE_FIELD_PANEL_FIRST`

* `ISSUE_OPTIONS_MENU_ITEM`

### Project

| Property | Type | Description |
| --- | --- | --- |
| `id` | String | The ID of the project. |
| `type` | String | The entity type. The value is `project`. |
| `key` | String | The key of the project. |

The following extension points take project entity as their guard function argument:

* `HELPDESK_CHANNEL`

* `PROJECT_SETTINGS`

* `PROJECT_TAB`

### User

| Property | Type | Description |
| --- | --- | --- |
| `id` | String | The ID of the user. |
| `type` | String | The entity type. The value is `user`. |
| `login` | String | The user login. |
| `name` | String | The user display name. |
| `avatarUrl` | String | The URL of the user avatar. |
| `userType` | String |    The type of the user account.     Possible values:       * `standard`    * `agent`    * `reporter`    |

The following extension points take user entity as their guard function argument:

* `USER_CARD`

* `USER_PROFILE_SETTINGS`

### Global Full-Page Widgets

The following extension points support guards, but don't take `entity` as their guard function argument. Use the `me` object to check properties of the current user and show or hide these widgets based on those values:

* `ADMINISTRATION_MENU_ITEM`

* `MAIN_MENU_ITEM`

### Markdown Widgets

The `MARKDOWN` extension point supports guards. When a Markdown widget is evaluated in the context of a YouTrack entity, the guard function receives this entity as `entity`. Depending on where the embedded text is displayed, this value can be an issue, a helpdesk ticket, or an article.

When writing a guard for a Markdown widget, check `entity.type` before reading entity-specific properties.

