Bitbucket modules
Common modules
Compass modules
Confluence modules
Jira modules
Jira Service Management modules

Jira custom field

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.

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.
  • datetime - values are strings that represent dates with time and timezone. The field behaves like any other datetime field in Jira when you interact with it in the UI or the REST API. However, if milliseconds are provided, they are ignored.
  • date - values are strings that represent dates. The field behaves like any other date field in Jira when you interact with it in the UI or the REST API.

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.
  • integer 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:

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
  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
{
  "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 up to 100 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

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

Field lifecycle

A locked instance of each custom field defined in the manifest is created upon deployment. For the field to be visible on issues, a Jira admin must first add it to screens.

The field disappears when the app is uninstalled or if the field is removed from the manifest. If the app is reinstalled within 30 days, or the field is restored, the field will reappear with all the previous data intact. All changes made to the field in the manifest (e.g. changing the name) are reflected in Jira after the app is deployed. (Warning: changing the data type after the field has been used with the old type is not supported, and will result in undefined behavior, potentially making the field unusable.)

The type of the field (accessible through the schema.custom property in the response of the Get fields REST API) is equal to the exact ID of the module, that is: ari:cloud:ecosystem::extension/{app-id}/{environment-id}/static/{module-key}, where:

  • {app-id} is your app ID defined in the manifest.
  • {environment-id} is the ID associated with the installation environment.
  • {module-key} is the key of the custom field module defined in the manifest.

If you need to fetch this ID in your app (for example, to identify the field in the response of the Get fields REST API), use the localId property from the product context. It has the following format:

1
2
ari:cloud:ecosystem::extension/<app-id>/<environment-id>/static/<invoked-module-key>

You can use it to create the ID of your custom field type. There are two ways to get the product context, depending on your app's rendering method:

Read-only fields

Read-only fields are those that have readOnly 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, issue glances or issue context panels, 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.

Additionally, updating the value on every issue view can be achieved with the value function.

Note that read-only fields won't be rendered on issue create or transition screens.

Validation

A field value can be validated with Jira expressions.

Validation takes place whenever an issue is edited or created, but not when the app updates the value directly with the private field update REST API.

The following context variables are available in the validation expression:

  • user (User): The user that wants to modify the field value.

  • issue (Issue): The edited issue.

  • project (Project): The project the issue belongs to.

  • fieldId (String): The ID of the field. For example, customfield_10020.

  • configuration: The configuration stored against the custom field context. Typically a map. Depending on the value of the configuration data, this may also be any primitive (number, string, boolean) or a list.

  • 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.
    • Date, if the data type is datetime.
    • CalendarDate, if the data type is date.

    If the field stores a collection, the value type will be a List with items of one of the types specified above.

The expression can return three types of values:

  • true means that the validation was successful, and the operation is allowed.
  • false means that the value is invalid. The error message defined in the manifest's validation.errorMessage property will be shown to the user.
  • String means that the value is invalid. The returned string will be shown as the error message to the user.

Validation example 1

Allow only numbers between 0 and 100, plus empty (null) values:

1
2
validation:
  expression: value == null || value >= 0 && value <= 100
  errorMessage: Only values between 0 and 100 are allowed.

Validation example 2

Allow only users from group field-editors to edit the value of the field, unless it's a new issue being created, and the field value is empty.

1
2
validation:
  expression: |-
    let isIssueCreate = issue == null || issue.id == null;
    let isEmpty = value == null; 
    let hasPermission = user.groups().includes('field-editors');
    isIssueCreate && isEmpty || hasPermission
  errorMessage: You don't have permission to edit this field. 

See the documentation for Jira expressions to find out what else is possible.

Rendering

Forge apps can provide rendering of the field with UI Kit by specifying the function property:

1
2
modules:
  jira:customField:
    function: key

In UI Kit 1, the rendering function must return a CustomField component. Inside the function, you can obtain the value, ID, and type of the field from the useProductContext hook, like this:

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

Note that only UI Kit is supported, it's not possible to implement custom rendering with Custom UI.

Editing

Forge apps can optionally provide their own editing experience of the field with UI Kit or Custom UI by specifying the edit property.

UI Kit
1
2
modules:
  jira:customField:
    edit:
      function: key

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

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

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

Custom UI
1
2
modules:
    jira:customField:
      edit:
        resource: key

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

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

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

1
2
await view.submit(fieldValue);

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

UI kit 2

With UI kit 2, use the Form component to render the edit view.

1
2
modules:
    jira:customField:
      edit:
        resource: key
        render: native

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

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

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

1
2
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 editing functions defined can be added to the new Create issue dialog by users with the appropriate permission. Validation of these fields is performed when the Create issue form is submitted.

The rendering function must also be defined for the old Create issue dialog.

In the new Create issue dialog, users can update field values inline. This means that the edit entry point is rendered directly in the dialog. Default edit rendering is used unless you specify otherwise. In apps using UI Kit, the entered value is submitted when the user clicks outside the field or elsewhere on the dialog. An issue is created only after the value has been submitted.

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

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

To update a field's value before issue creation in apps using Custom UI or UI kit 2, use the submit API:

1
2
await view.submit(fieldValue);

For UI kit 2 it is expected to use Form component to render the edit view. In create issue dialog, the onSubmit function in the Form component will be called on blur events, so you can place the submit logic there. Otherwise, you can create your own logic to use the submit API outside the onSubmit function.

After issue creation is confirmed, non-required custom fields need to resolve a promise to update their value within 10 seconds. If they don't, the issue will be created with the default values.

Formatter

The formatter is used to render the field on views where rendering with functions is not supported, for example in email notifications or on the global issue navigator page.

Formatters are declared with Jira expressions, making them fast enough to be invoked synchronously whenever a rendered human-readable field value is required.

If a formatter expression is applied to a set of issues, the number of expensive operations executed by it must be constant. In other words, the expression must not contain any operations labeled with N.

The following context variables are available in the formatter expression:

  • user (User): The current user.

  • issue (Issue): The rendered issue.

  • project (Project): The project to which the issue belongs.

  • fieldId (String): The ID of the field. For example, customfield_10020.

  • configuration: The configuration stored against the custom field context. Typically a map. Depending on the value of the configuration data, this may also be any primitive (number, string, boolean) or a list.

  • 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.
    • Date, if the data type is datetime.
    • CalendarDate, if the data type is date.

    If the field stores a collection, the value type will be a List with items of one of the types specified above.

Using formatters in CSV export

By default, formatters aren't used for issue export to CSV. Thanks to this, exported values can be seamlessly imported back to Jira.

To change that behavior, set the export property to true:

1
2
formatter:
  expression: "formatter expression"
  export: true

We recommend using this option in combination with specifying a parser, to make importing such an export possible.

Formatter example 1

In the simplest possible case, your formatter will just transform the current value without requiring any additional information. For example, you can render a text-based progress bar for a field that stores progress as a number between 0 and 100:

1
2
formatter:
  expression: "`${'▰'.repeat(value / 10).padEnd(10, '▱')} (${value}%)`"

Formatter example 2

Imagine you have a string field whose values are IDs of some external components. A Forge function that renders this field makes a call to your service to resolve those IDs into human-readable names. While such external calls are not possible in Jira expressions, you can store the mapping between IDs and names in an entity property, and read it in the formatter:

1
2
formatter:
  expression: |- 
    let mapping = project.properties.get('idToNameMapping');
    mapping.get(value)

Since your app stores the data required to format the field on the Jira side, the user experience remains fast and reliable.

See the documentation for Jira expressions to find out what else is possible.

Value Function

Forge apps can provide a value function that computes the value of the field.

This function is invoked on every issue view, so that the freshly computed value is shown to the user whenever they open the issue page. Jira also saves this value into the database against the issue. Thanks to this, the value is not only available for that one particular user interaction, but also becomes immediately refreshed for the REST API, all other views, JQL search, etc.

This is useful mostly for read-only fields that show some derived data. Because the value function is invoked only on the issue view, you will most likely still need to listen to events and update values asynchronously. However, you can at least guarantee that users will always see a fresh value on the issue view.

Manifest example:

1
2
  jira:customField:
    - key: field-key
      name: Name
      type: string
      value:
        function: computeValue

The function receives a list of issue IDs and returns a list of values for those issues. Context configuration is provided for the issues, so the app does not have to load context configuration in the function.

Here is a payload example:

1
2
{
  "field": {
    "id": "customfield_10000",
    "key": "4886f49a-482d-41ba-bd73-6aeb5ee40e0f__DEVELOPMENT__my-custom-field-key",
    "type": "ari:cloud:ecosystem::extension/4886f49a-482d-41ba-bd73-6aec5ee40e0f/4e9fe62d-2575-4b2d-b0d7-5a37f43a80a9/static/my-custom-field-key",
    "name": "My custom field"
  },
  "issues":[
    {
      "id":10001,
      "context":10136,
      "value": "value1"
    },
    {
      "id":10002,
      "context":10136,
      "value": "value2"
    }
  ],
  "contexts": [
    {
      "id": "10136",
      "configuration": "custom data"
    }
  ]
}

Here is an example of how to define the value function:

1
2
    function valueFunctionName(arg) {
        return arg.issues.map(issue => computeCurrentValue(arg.field, issue.id));
    }

    function computeCurrentValue(field, issueId) {
       // return the value of the field for the given issue ID
    }

The values returned must be compatible with the format expected by the Edit Issue REST API operation.

For example, for the user type field the value must be an object that contains accountId. So the function would have to return a list of values like this:

1
2
[{
  "accountId": "<user-1>"
}, {
  "accountId": "<user-2>"
}, {
  "accountId": "<user-1>"
}]

The order of values returned must be the same as the order of issues received in the argument.

Note that the issue view is the only view where the value function is invoked. However, the function is still expected to work with multiple issues at once (accepting and returning lists). Other views may become supported, including ones that display more than one issue at a time. Therefore, make sure your function has constant performance regardless of the number of issues in the argument.

Rendering hierarchy

The rendering hierarchy goes from functions (highest priority), to formatter expressions, to default rendering (lowest priority).

On views that support rendering with functions, the function is used if defined. Otherwise, the formatter expression is used. If neither is defined, the default rendering for the field's data type is used.

On the issue view, if the value function is defined, it is invoked first, then its result is passed on to the rendering function, formatter expression, or the default rendering component.

On views that don't support rendering with functions, the formatter expression is used if defined in the manifest and supported on the view, otherwise the raw field value is shown.

Some views don’t support custom edit rendering, including: boards, issue navigator, bulk edit view, transition screen, and more. In these cases the default editing experience appropriate for the field’s data type is used.

Rendering example

To see custom rendering in action, check out the Issue Progress Custom Field example app.

Parser

The parser takes a string produced by the formatter and converts it into the shape expected by the field.

Use it when, on editing an issue, the user may provide a value that doesn’t conform to the underlying data type implementation of a field. In such cases, the parser will convert the input into storable values.

Formatted string values may appear when:

  • importing issues from CSV, especially when the formatter is used for export
  • interacting with Jira views that don’t support editing with Custom UI or UI Kit, such as bulk update
  • performing a JQL search
  • using the edit issue REST API

Example

As an example, let’s use an object type field that stores amounts of money in a given currency.

The actual values stored by the field would be JSON objects that look like this:

1
2
{
  "amount": 100,
  "currency": "USD"
}

To make the values human-readable, your app would declare a formatter that makes the values look like 100 USD.

Now, to make the field able to consume strings like 100 USD, the app should declare a parser that can take such a string and transform it into a JSON object:

1
2
parser:
  expression: |-
    let parts = value.split(' ');
    { 
      amount: Number(parts[0]), 
      currency: parts[1] 
    }

Specification

Parsers are declared with Jira expressions.

Parser input

The following context variables are available in the parser expression:

  • user (User): The current user.
  • issue (Issue): The issue being edited.
  • project (Project): The project to which the issue belongs.
  • fieldId (String): The ID of the field. For example, customfield_10020.
  • configuration: The configuration stored against the custom field context. Typically a map. Depending on the value of the configuration data, this may also be any primitive (number, string, boolean) or a list.
  • value: A string provided by the user.
Output

The parser is expected to return a value compatible with the underlying data type of the field, as specified in the table below.

Data typeParser return typeDetails
stringString
groupStringGroup name
numberNumber
userUser
objectMap
dateCalendarDate
datetimeDate

If the field stores a collection, the returned value should be a List with items of one of the types specified above.

Search suggestions

When writing JQL queries in advanced search, users expect to receive automatic suggestions for valid values. By default, we try to provide these suggestions automatically for Forge custom fields, differently for each data type. For example, for fields of type user, we compile the list of suggestions from the pool of all Jira users.

Apps can override this default behavior and provide their own custom suggestions. This is achieved by adding the searchSuggestions section into the field definition in the manifest. The suggestion provider can be either a Jira expression, or a Forge function.

In the search suggestions function, calls to an Atlassian API must be done as the app developer by using api.asApp(). Making requests on behalf of a user with api.asUser() won’t work.

Input

The Jira expression has access to the following context variables:

  • fieldId (String): The ID of the field. For example, customfield_10020.
  • fieldType (String): The type of the field. For example, ari:cloud:ecosystem::extension/4211172c-5e6b-4170-9fce-f3314107517e/3b0cdefc-4f24-4696-a7dd-1092d95637f9/static/module-key.
  • fieldName (String): The name of the field. For example, Issue progress.
  • user (User): The user who is receiving the suggestions.
  • query (String): The string that the user already typed into the editor as the value of the field. Use it to narrow down the list of suggestions.

Similarly, the function receives an argument object with the same set of information:

1
2
{
  "fieldId": "<The ID of the field>",
  "fieldType": "<The type of the field>",
  "fieldName": "<The name of the field>",
  "query": "<the value entered by the user>",
  "user": {
    "accountId": "<the ID of the user that is requesting the suggestions>"
  },
  "context": {
    "cloudId": "<the ID of the instance the app is running on>"
  }
}

The following example shows a signature that can serve as a starting point for your function's implementation:

1
2
export function generateSearchSuggestions({ fieldId, fieldType, query, user: { accountId }, context: { cloudId }}) {
    // your implementation goes here
}

Output

The function or expression must return a list of suggestions. Each suggestion can be either a plain string, or an object that contains the value that’s used in JQL when the user selects the suggestion, and a label that the user sees on the list:

1
2
[
  {
    "value": "340f8126-50f7-4fe7-8765-1a151678b917",
    "label": "Value 1"
  },
  {
    "value": "771617fc-7417-4a4a-8b47-9230bbac47a0",
    "label": "Value2 2"
  }
]

If your values are already human-readable, you can just return plain strings:

1
2
["Value 1", "Value 2", "Value 3"]

Known limitations

While we're working hard to make Forge custom fields indistinguishable from regular custom fields, reaching full parity takes time. This section summarizes the features missing from Forge custom fields.

UI Kit and custom UI rendering

Rich rendering with UI Kit and custom UI is fully supported on the issue view and issue create screens. Other places use the formatter to display field values, and simple built-in components are offered for editing. For more details, see rendering hierarchy.

Eventually, we're planning to introduce fully custom rendering to as many places as possible.

Support in other products

Forge custom fields may not be fully supported in products other than Jira Cloud, such as Jira Mobile, Jira Service Management, or Confluence. Additionally, support in tools within Jira Cloud (for example, Jira automation) may be lacking.

We're constantly working on bringing the power of Forge fields to as many products and tools as we can.

We are waiting for your feedback

If there is an issue that you would particularly like to be solved, let us know by creating a ticket in the Forge Jira project.

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
  • datetime
  • date
collectionnone|list (default: none) The kind of collection that the field values should be stored in. See collection types for more details.
validation.expressionstringA Jira expression that validates the field value. See validation for more details.
validation.errorMessagestringThe error message to show when the validation expression returns false.
formatter.expressionstringRequired for the object type; otherwise, optionalA Jira expression that renders the value as a string. See formatter for more details.
formatter.exportbooleanWhether to use the formatter for values exported to CSV. See Using formatters in CSV export for more details.
parser.expressionstringA Jira expression that parses strings into valid values of this field. See parser for more details.
value.functionstring A function that computes the value of the field.

See value function for more details.

schemaobjectAllowed only for the object typeA JSON schema that desribes values stored in the field.
searchSuggestions.expressionstringRequires either function or expression. Only one of the two properties must be present. A Jira expression that provides value suggestions in advanced search. See search suggestions for more details.
searchSuggestions.functionstringRequires either function or expression. Only one of the two properties must be present. A reference to the function module that provides value suggestions in advanced search. See search suggestions for more details.
readOnlybooleanWhether or not the field is read-only. Read-only fields can't be edited by users. Defaults to false.
render'native'Yes for UI Kit.Indicates the module uses UI Kit.
functionstringRequired if using UI Kit 1.A reference to the function module that defines the module. Only used in UI Kit 1.
resolver{ function: string } or
{ endpoint: string }
Yes

Set the function property if you are using a hosted function module for your resolver.

Set the endpoint property if you are using Forge remote (preview) to integrate with a remote back end.

edit.functionstringA reference to the function module that provides the field editing experience.
edit.resourcestring 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.
edit.render'native' Indicates if your edit entry point should display as UI Kit.
displayConditionsobjectThe object that defines whether or not the field is displayed on the issue view or global issue create (GIC) (other views or REST APIs are not affected). See display conditions.

Extension data

UI Kit and Custom UI

Use the useProductContext hook to access the extension context in UI Kit or getContext bridge method in custom UI.

PropertyType/valueDescription
type'jira:customFieldType'The type of the module.
entryPoint'edit'The entry point of the module.
fieldIdstringThe ID of the field. For example, customfield_10020.
fieldTypestringThe type of the field. For example, ari:cloud:ecosystem::extension/4211172c-5e6b-4170-9fce-f3314107517e/3b0cdefc-4f24-4696-a7dd-1092d95637f9/static/module-key.
fieldValuestring
string[]
number
object
The value of the field. It has a type corresponding to the data type of the field.
issue.idstringThe ID of the issue on which the module is rendered.
issue.keystringThe key of the issue on which the module is rendered.
issue.typestringThe name of the type of the issue on which the module is rendered.
issue.typeIdstringThe ID of the type of the issue on which the module is rendered.
project.idstringThe ID of the project where the module is rendered.
project.keystringThe key of the project where the module is rendered.
project.type 'business'
'software'
'product_discovery'
'service_desk'
'ops'
The type of the project where the module is rendered.
renderContext'issue-view'
'issue-create'
The context in which the extension is rendered.

UI Kit 1

Use the useProductContext hook to access the context in UI Kit 1.

Extension context

PropertyType/valueDescription
type'customFieldType'The type of the module.
entryPoint'edit'The entry point of the module. Undefined for the main function.
fieldIdstringThe ID of the field. For example, customfield_10020.
fieldTypestringThe type of the field. For example, ari:cloud:ecosystem::extension/4211172c-5e6b-4170-9fce-f3314107517e/3b0cdefc-4f24-4696-a7dd-1092d95637f9/static/module-key.
fieldValuestring
string[]
number
object
The value of the field. It has a type corresponding to the data type of the field.
renderContext'issue-view'
'issue-create'
The context in which the extension is rendered.

Platform context

PropertyType/valueDescription
issueIdstringThe ID of the issue on which the module is rendered. Not available on issue create.
issueKeystringThe key of the issue on which the module is rendered. Not available on issue create.
issueTypestringThe name of the type of the issue on which the module is rendered.
issueTypeIdstringThe ID of the 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.

Example

The following example declares a number-type field that represents issue progress:

1
2
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.
    formatter:
      expression: "`${'▰'.repeat(value / 10).padEnd(10, '▱')} (${value}%)`"
      export: true
    parser:
      expression: "Number(value.replace('[^\\d]', ''))"
    searchSuggestions:
      expression: '["0", "25", "50", "75", 100"]'
    readOnly: false
    resource: renderIssueProgress
    render: native
    edit:
      resource: editIssueProgress
      render: native
resources:
  - key: renderIssueProgress
    path: src/frontend/index.jsx
  - key: editIssueProgress
    path: src/frontend/editIssueProgress.jsx

Rate this page: