Modules
Display conditions

Rate this page:

Jira custom field (beta)

The jira:customField module creates a new custom field in Jira, which makes it easier for users to add information to issues, specific to their teams' needs.

This module can only be used in Jira company-managed projects.

Read-only fields

Read-only fields are those that have the read-only set to true in their definition in the manifest. They aren't editable by users, neither through the UI nor the Edit issue REST API.

They are great for showing values derived from the issue state. While you can show anything using issue panels or issue glances, custom fields may be a better choice if you need all their benefits, such as JQL search, configuration on screens, or being part of the issue import and export.

The value of such fields has to be calculated beforehand and set with the dedicated REST API. One pattern to achieve this is to listen to product triggers for events that may affect the values and update the values as necessary.

Data types

Each field type has to be based on a predefined data type.

The data type controls what kind of values the REST API accepts and returns for the field, the field's behavior in JQL, and the default rendering behavior.

The available data types are:

  • string - values represent plain strings. JQL offers autocomplete and exact comparison.
  • number - values represent numbers (double-precision 64-bit IEEE 754 floating points).
  • user - values represent users identified by Atlassian account IDs. The field behaves like any other user field in Jira when you interact with it in the UI or the REST API.
  • group - values represent groups identified by names. The field behaves like any other group field in Jira when you interact with it in the UI or the REST API.
  • object - values are arbitrary JSON objects. See below for more details.

Object type

The object type makes use of additional properties compared to other types.

The required formatter property contains a Jira expression that returns a string. This string is used to represent the value if the rendering function is not provided, or where the rendering function is not supported. For example, the column view in the Global Issue Navigator.

The optional schema property contains the JSON schema that is used to validate values stored in the field.

By default, you can search for a text string anywhere in the content of an object-type field. To enable more fine-grained searching, create Field properties with the searchAlias schema property .

This means that, for a field named X:

  • using the default behavior you can search the entire value stored in this field using X ~ "text to search for"
  • by defining a field property, such as Y, in the schema with searchAlias, you can search that field property using X.Y = value.

The JQL type of each property created with searchAlias is derived from the schema type, using these rules:

  • string schema type becomes a string in JQL.
  • number schema type becomes a number in JQL.
  • intger schema type becomes a number in JQL.
  • boolean schema type becomes a string in JQL.
  • array schema type becomes an array of items of a type following these rules. For example, an array containing items with the schema type integer becomes an array of items with the type number in JQL.
  • search aliases for any other schema type are ignored.

It's possible to override the schema type with searchType. This enables you to use the complex types supported in JQL but not available in the JSON schema. The following search types are available:

Note: pairs of conflicting field properties, those with the same name and path but different types, are ignored.

Object type JQL search example

This is an example of a field that stores money. It showcases the use of:

  • the formatter and schema properties.
  • JQL search aliases.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
  jira:customField:
    - key: cf-type-money
      name: Development cost
      description: Tracks the development cost of features, in different currencies
      type: object
      formatter: 
        expression: "`${value.amount} ${value.currency}`"
      schema:
        properties:
          amount:
            type: number
            searchAlias: Amount
          currency:
            type: string
            enum: [ "USD", "EURO", "AUD" ]
            searchAlias: Currency
          spender:
            type: string
            searchType: user
            searchAlias: Spender
        required: [ "amount", "currency" ]

The schema ensures that values of this field look like this:

1
2
3
4
5
{
  "amount": 100,
  "currency": "USD",
  "spender": "<account-id>"
}

With the formatter in place, displayed on the issue search, the value will be a string 100 USD.

In addition to the default text search of the entire field value, more fine-grained search using these field properties is available:

  • Amount (JQL type: number),
  • Currency (JQL type: string),
  • Spender (JQL type: user).

Collection types

A Forge custom field can store a collection of values. This is done by declaring the collection property, which specifies the collection type. For example, to create a field that stores a list of strings, declare it as:

1
2
type: string
collection: list

These data types can be part of a collection:

  • string
  • group
  • user

Note, using any other data type in combination with collection:list prevents the field from appearing in Jira.

Field lifecycle

A locked instance of each field defined in the manifest is created upon deployment. Whenever a field is added to the app, or an existing field is modified or removed, you must redeploy the app to make these changes appear in Jira.

To make a custom field appear in Jira, you must add the custom field to a screen first. It may take some time for the custom field to be created in Jira. Try visiting or refreshing the custom fields page after a few minutes if your field is not visible.

The created field has its key set to {app-id-uuid}__{environment}__{extension-key}, where:

  • {app-id-uuid} is the tail part of your app ID defined in the manifest (for example: ari:cloud:ecosystem::app/{app-id-uuid}).
  • {environment} is the uppercase environment in which the app is installed.
  • {extension_key} is the key of the custom field extension defined in the manifest.

For example: 2bcdc120-765b-40a1-842b-887bdfd852ea__DEVELOPMENT__field-key.

This key can be used to uniquely identify the field in Jira REST APIs.

The field disappears when the app is uninstalled or if the field is removed from the manifest. If the app is reinstalled, or the field is restored, the field will reappear with all the previous data intact.

Rendering

Forge apps can optionally provide their own rendering of the field by specifying the function property.

The rendering function must return a CustomField UI kit component. Inside the function, you can obtain the current value, id, and full type of the field from the useProductContext hook, like this:

1
const { extensionContext: { fieldValue, fieldId, fieldType } = useProductContext();

Default rendering, appropriate to the field's data type, is used if the function is not provided.

Check out this example app to see custom rendering in action: Issue Progress Custom Field.

Editing

Forge apps can optionally provide their own editing experience of the field by specifying the edit property.

UI kit

The edit function must return a CustomFieldEdit UI kit component. Inside the function, you can obtain the current value, id, and full type of the field from the useProductContext hook, like this:

1
const { extensionContext: { fieldValue, fieldId, fieldType } = useProductContext();

Default editing, appropriate to the field's data type, is used if the edit function is not provided.

Check out this example app to see custom editing in action: Risk assessment custom field.

Custom UI

You can obtain the current value of the field from the getContext API, like this:

1
const { fieldValue } = await view.getContext();

To update the field value, use the submit API, like this:

1
await view.submit(fieldValue);

Default editing, appropriate to the field's data type, is used if the edit resource is not provided.

Issue creation dialog

Jira custom fields created by Forge apps that have rendering and editing functions defined can be added to the create issue dialog by users with the appropriate permission. Validation of these fields is performed when the create issue form is submitted.

Your app can find out which view a field is rendered on using the renderContext property from the product context:

1
const { extensionContext: { renderContext } = useProductContext();

Properties

PropertyTypeRequiredDescription
key

string

Yes A key for the module, which other modules can refer to. Must be unique within the manifest.

This key becomes a part of the custom field key as described in the Field lifecycle section.

Regex: ^[a-zA-Z0-9_-]+$

namestringYesThe name of the field.
descriptionstringYesThe description of the field.
typestringYesThe type of the value stored by the field. Available types are:
  • string
  • number
  • user
  • group
collectionnone|list (default: none) The kind of collection that the field values should be stored in. See collection types for more details.
validation:
  expression
stringA Jira expression that validates the field's value before it's set by the user.

Does not apply when the app updates the value directly with the dedicated REST API.

The expression can return either a boolean value or a string. Returning a string overrides the error message defined in the manifest – the returned string is shown to the user as the error message instead.

The expression is evaluated with the following context variables:

  • user (User): The current user.
  • issue (Issue): The edited issue.
  • project (Project): The project to which the issue belongs.
  • value: The value that’s being set on the field. The type of this variable depends on the data type of the field and can be one of the following:
    • String, if the data type is string or group.
    • Number, if the data type is number.
    • User, if the data type is user.
    • Map, if the data type is object.
    If the field stores a collection, the value type will be a List with items of the type as specified above.

validation:
  errorMessage
stringThe error message to show when the validation expression returns false.
formatter:
  expression
stringRequired for the `object` type; otherwise, optionalA Jira expression that renders the value as a string. The expression is evaluated with the following context variables:
  • user (User): The current user.
  • issue (Issue): The edited issue.
  • project (Project): The project to which the issue belongs.
  • value: The field's value. The type of this variable depends on the data type of the field and can be one of the following:
    • String, if the data type is string or group.
    • Number, if the data type is number.
    • User, if the data type is user.
    • Map, if the data type is object.
    If the field stores a collection, the value type will be a List with items of the type as specified above.
schemaobjectAllowed only for the `object` typeA JSON schema that desribes values stored in the field.
readOnlybooleanWhether or not the field is read-only. Read-only fields can't be edited by users. Defaults to false.
functionstringA reference to the function module that provides the field rendering. This function must return the CustomField component.
resolver{ function: string } Contains a function property, which references the function module that defines the configuration of the resource property. Can only be set if the module uses the resource property.
edit:
 function
stringA reference to the function module that provides the field editing experience.
edit:
 resource
string A reference to the static resources entry that your edit entry point wants to display. See Resources for more details. To submit the view, use the submit API.
displayConditionsobjectThe object that defines whether or not the field is displayed on the issue view (other views or REST APIs are not affected). See display conditions.

Extension context

Custom UI

PropertyTypeDescription
typestringThe type of the module.
issue:
  id
stringThe id of the issue on which the module is rendered.
issue:
  key
stringThe key of the issue on which the module is rendered.
issue:
  type
stringThe type of the issue on which the module is rendered.
project:
  id
stringThe id of the project where the module is rendered.
project:
  key
stringThe key of the project where the module is rendered.
project:
  type
stringThe type of the project where the module is rendered.
fieldValuestring|string[]|number|objectThe value of the field.
fieldIdstringThe id of the field.
fieldTypestringThe type of the field.
renderContextissue-view|issue-createThe context on which the extension is rendered.
entryPointedit|undefinedThe entry point of the module.

UI kit

PropertyTypeDescription
typestringThe type of the module.
fieldValuestring|string[]|number|objectThe value of the field.
fieldIdstringThe id of the field.
fieldTypestringThe type of the field.
renderContextissue-view|issue-createThe context on which the extension is rendered.
issueIdstringThe id of the issue on which the module is rendered.
issueKeystringThe key of the issue on which the module is rendered.
issueTypestringThe type of the issue on which the module is rendered.
projectIdstringThe id of the project where the module is rendered.
projectKeystringThe key of the project where the module is rendered.
projectTypestringThe type of the project where which the module is rendered.
entryPointedit|undefinedThe entry point of the module.

Example

The following example declares a number-type field whose values must be numbers between 0 and 100:

1
2
3
4
5
6
7
8
9
10
11
12
jira:customField:
  - key: issue-progress
    name: Issue progress
    description: The progress of the issue, on a scale from 0 to 100.
    type: number
    validation:
      expression: value == null || (value >= 0 && value <= 100)
      errorMessage: The value must be a number between 0 and 100.
    readOnly: false
    function: renderIssueProgress
    edit:
      function: editIssueProgress

Rate this page: