Custom UI bridge
Custom UI Jira bridge

Rate this page:

uiModifications (preview)

To consume the UI Modifications (UIM) API, your app needs to import the @forge/jira-bridge package:

1
2
import { uiModificationsApi } from '@forge/jira-bridge';

This API is strictly related to the Jira UI modifications module

Initialization

onInit method signature

1
2
onInit(<initCallback>, <registerFieldsCallback>): void

onInit method description

initCallback is where apps can query field data and request modifications. registerFieldsCallback is used to specify which fields will be changed by initCallback. The information returned by registerFieldsCallback is used to display a loading indicator next to the relevant fields until initCallback finishes.

Both callback functions are called every time:

  • the Global Issue Create (GIC) form opens
  • the project or issueType (from context) changes
  • an issue is created with the create another issue checkbox enabled

The initCallback function will receive one object as an argument. This object contains the following attributes:

  • api - the API used to find and modify the GIC fields
  • uiModifications - an array of UIM entities registered for a given context

The registerFieldsCallback function will receive an object containing:

  • uiModifications - an array of UIM entities registered for a given context
1
2
uiModificationsApi.onInit(({ api, uiModifications }) => {
  // You can find form fields using the FieldQueryingAPI here
  const summaryField = api.getFieldById('summary');
  // You can manipulate the fields you found
  if (summaryField) {
    summaryField.setDescription('New summary description');
  }
}, ({ uiModifications }) => {
  // This function should return an array of the IDs of the fields
  // which are going to be changed in initCallback
  return ['summary'];
})

All modifications requested synchronously using this API will be batched and applied at once.

If a Promise is returned from the callback, all of the modifications will be postponed until the Promise resolves. This may be useful in a scenario when the app needs to perform an async operation before it requests a change.

Warning

UIM blocks any changes requested for fields within initCallback for any field IDs not in the array returned from registerFieldsCallback.

Warning

If the initCallback doesn’t return a Promise which resolves after all field modification requests are made, then field modifications requested asynchronously will be ignored.

Reacting to change

onChange method signature

1
2
onChange(<changeCallback>, <registerFieldsCallback>): void

onChange method description

changeCallback is where apps can query field data and request modifications. registerFieldsCallback is used to specify which fields will be changed by changeCallback. The information returned by registerFieldsCallback is used to display a loading indicator next to the relevant fields until changeCallback finishes.

Both callback functions are called every time:

  • the blur form field event is triggered by one of the GIC-supported text fields, which are summary and description
  • the change form field event is triggered by any other GIC-supported field

The changeCallback function will receive one object as an argument. This object contains the following attributes:

  • api - the API used to find and modify the GIC fields
  • change - an object with the current attribute containing the object exposing the FieldAPI of the field which triggered the change event
  • uiModifications - an array of UIM entities registered for a given context

The registerFieldsCallback function will receive an object containing:

  • change - an object with the current attribute containing the object exposing the FieldAPI of the field which triggered the change event
  • uiModifications - an array of UIM entities registered for a given context
1
2
uiModificationsApi.onChange(({ api, change, uiModifications }) => {
  // You can find form fields using the FieldQueryingAPI here
  // You can also manipulate the fields you found or access the field
  // that triggered the change
  const { current } = change;
  if (current.getId() === 'summary') {
    // hint: You may want to read the content of uiModifications before
    // deciding what changes need to be applied here
    current.setDescription('New summary description');
  }
}, ({ change, uiModifications }) => {
  // This function should return an array of the IDs of the fields
  // which are going to be changed in changeCallback
  return ['summary'];
})

All modifications requested synchronously using this API will be batched and applied at once.

If a Promise is returned from the callback, all of the modifications will be postponed until the Promise resolves. This may be useful in a scenario when the app needs to perform an async operation before it requests a change.

Warning

UIM blocks any changes requested for fields within changeCallback for any field IDs not in the array returned from registerFieldsCallback.

Warning

If the changeCallback doesn’t return a Promise which resolves after all field modification requests are made, then field modifications requested asynchronously will be ignored.

Querying fields

getFieldById method signature

1
2
getFieldById<fieldType>(<fieldId>): FieldAPI | undefined

getFieldById method description

Uses the generic: fieldType (string) - the type of the field that the app wants to work on.

Accepts one argument: fieldId (string) - the ID of the field which the app wants to work on.

Returns the FieldAPI object if the field exists on the GIC form.

Returns undefined if the field doesn't exist on the GIC form.

Example of usage with regular field:

1
2
uiModificationsApi.onInit(({ api }) => {
  const { getFieldById } = api;
  const description = getFieldById('description')
  // You can perform operations on 'description'
  // field using the FieldAPI here
}, () => ['description'])

Example of usage with custom field:

1
2
    uiModificationsApi.onInit(({ api }) => {
    const { getFieldById } = api;
    const select = getFieldById<'com.atlassian.jira.plugin.system.customfieldtypes:select'>('customfield_10035')
    // You can perform operations on 'customfield_10035'
    // single select field using the FieldAPI here
}, () => ['customfield_10035'])

Common FieldAPI

Warning

The changes requested by setters in this API are not applied immediately. They are batched and their application is postponed until the onInit or onChange callback execution ends. This means that reading the values using getters will always provide the initial form field state, which is immutable.

getId

1
2
getId(): string

Returns the field's ID.

setName

1
2
setName(value: string): FieldAPI

Changes the field's name.

Example:

1
2
field.setName('New name for the field');

getName

1
2
getName(): string

Returns the field's name.

setDescription

1
2
setDescription(value: string): FieldAPI

Changes the field's description.

Example:

1
2
field.setDescription('This the description!');

getDescription

1
2
getDescription(): string

Returns the field’s description.

setVisible

1
2
setVisible(value: boolean): FieldAPI

Changes field visibility. The form payload will contain the field’s value, but the field won’t be visible in the UI if this is set to false.

Example:

1
2
field.setVisible(false);

isVisible

1
2
isVisible(): boolean

Returns true if the field is currently visible. Returns false otherwise.

setValue

1
2
setValue(value: unknown): FieldAPI

Set a given field's value. See the specific field value contracts in the supported fields below to make sure the changes requested by this method will be applied.

getValue

1
2
getValue(): unknown

Set a given field's value. See the specific field value contracts in the supported fields below to make sure the changes requested by this method will be applied.

setReadOnly

1
2
setReadOnly(value: boolean): FieldAPI

Set if a given field’s value is read-only. If true, the form payload will contain the field’s value, but the user won’t be able to modify the value in the UI.

Example:

1
2
field.setReadOnly(true);

isReadOnly

1
2
isReadOnly(): boolean

Returns true if the field's value currently can't be modified. Returns false otherwise.

Supported fields

priority

type: priority

Value contract for getValue and setValue

1
2
{ 
  id: string,   // '2'
  name: string, // 'High'
  iconUrl?: string,
}

Reference screenshot

summary

type: summary

Value contract for getValue and setValue

1
2
string

Reference screenshot

assignee

type: assignee

Value contract for getValue and setValue

Special values

1
2
null | {
  accountId: string,
  displayName: string,
  avatarUrls?: {
    '48x48': string,
  }
}

Reference screenshot

labels

type: labels

Value contract for getValue and setValue

1
2
string[]

Reference screenshot

description

type: description

Warning

Value contract for getValue and setValue

1
2
string // Plain-text editor
| 
type ADF = {
  version: 1,
  type: 'doc',
  content: Node[]
} // Rich-text editor (ADF format)
// https://developer.atlassian.com/cloud/jira/platform/apis/document/structure/

Reference screenshots

single select

type: com.atlassian.jira.plugin.system.customfieldtypes:select

Value contract for getValue and setValue

Special values

Use null to unset the value.

1
2
null | {
    id: string,
    name: string,
}

Reference screenshots

multiple select

type: com.atlassian.jira.plugin.system.customfieldtypes:multiselect

Value contract for getValue and setValue

Special values

Use [] to unset the value.

1
2
[
    {
        id: string,
        name: string,
    },
    {
        id: string,
        name: string,
    }, 
    ...
]

Reference screenshots

paragraph

type: com.atlassian.jira.plugin.system.customfieldtypes:textarea

Warning

Value contract for getValue and setValue

1
2
string // Plain-text editor
| 
type ADF = {
  version: 1,
  type: 'doc',
  content: Node[]
} // Rich-text editor (ADF format)
// https://developer.atlassian.com/cloud/jira/platform/apis/document/structure/

Reference screenshots

text field

type: com.atlassian.jira.plugin.system.customfieldtypes:textfield

Value contract for getValue and setValue

1
2
string

Reference screenshots

user picker

type: com.atlassian.jira.plugin.system.customfieldtypes:userpicker

Value contract for getValue and setValue

Special values

Use null to unset the value.

1
2
null | {
    accountId: string,
    displayName: string,
    avatarUrls?: {
        '48x48': string,
    }
}

Reference screenshots

multiple user picker

type: com.atlassian.jira.plugin.system.customfieldtypes:multiuserpicker

Value contract for getValue and setValue

Special values

Use [] to unset the value.

1
2
[
    {
        accountId: string,
        displayName: string,
        avatarUrls?: {
            '48x48': string,
        }
    },
    {
        accountId: string,
        displayName: string,
        avatarUrls?: {
            '48x48': string,
        }
    }, 
    ...
]

Reference screenshots

Rate this page: