Integrate CFS custom fields
Custom Field Suite brings you the most common custom field types to boost the user experience and customize Jira to suit various use cases. The JQL filter is compatible with all custom field types.
👏Our custom field types:
Completed Issues in Epic 🆕
Completed Story Points in Epic 🆕
Unsized issues in Epic 🆕
Unit 🆕
Panels 🆕
Sum (Average) of numeric values in linked issues 🆕
Abbreviate Numbers 🆕
Vision
Work together with customers and build custom field types based on their use cases
Cooperation with Jira consultants in order to collect valuable use case and build customer success stories
Focus in Forge to support Atlassian as much as possible
MoSCoW
Two values are being stored inside of the configuration. Those are Text and Color. Both values are being saved by using the storage API: https://developer.atlassian.com/platform/forge/runtime-reference/storage-api/ We store them as JSON format with key “moscow-config”. When rendering the field in View Issue Screen, we just pull both values from the storage and pass them to the StatusLozenge component: https://developer.atlassian.com/platform/forge/ui-kit-components/text/#StatusLozenge It accepts 2 parameters: text and appearance (color).
T-Shirt
This field has hardcoded values that can be turned on and off. Descriptions can be changed also. Both values are saved by using the storage API. When rendering the value in View Issue Screen, depending on the selected value in the field, we render an SVG image and display it in the field. All SVG images are represented as HTML and are located inside the CFS app.
Progress / Completed Issues in Epic / Completed Story Points in Epic / Unsized issues in Epic
Completed issues in epic, Completed story points in Epic and Unsized issues in Epic are all hardcoded fields
The progress bar is being loaded through our own component. Basically, it's an SVG image that takes a parameter (number). The number is the value of the custom field. It represents a percentage, so one can only select values from 0 to 100. We pass the selected number to the progress bar’s HTML and render the SVG image. There is also a tooltip for displaying the percentage. The tooltip is part of the Forge UI. The configuration is used for saving the color. Colors are hardcoded by using their hexadecimal representations and are saved by using the storage API.
Completed Issues in Epic and Completed Story Points in Epic fields use the same logic as the progress bar. We get the color from the configuration (separate configuration page for each field). The only difference is that both of these fields are calculated fields, which means that the user can’t define values for these fields. Completed Issues in Epic field returns the percentage of completed issues in epics. Completed Story Points in Epic field returns the percentage of completed story points in epics, meaning it calculates story points of completed issues in comparison to all issues in epics.
// Loading the progress bar
const calculatedProgress = progress !== 0 && progress !== null ? progress * 2 : "";
return `<svg xmlns="http://www.w3.org/2000/svg" width="204" height="4"><g fill="none" fillRule="evenodd"><path d="M2 0h200a1.5 1.5 0 0 1 0 4h-200a1.5 1.5 0 1 1 0-4z" fill="#DFE1E6" /><path d="M2 0h${calculatedProgress}a1.5 1.5 0 0 1 0 4h-${calculatedProgress}a1.5 1.5 0 0 1 0-4z" fill="${builtColor}" /></g></svg>`;
Traffic Lights
The traffic lights field works almost the same as the t-shirt field. Depending on the selected value in the field, we render our own SVG images through HTML codes, which are defined inside our own CFS app. All 3 traffic light fields are hardcoded and are not changeable. We use a tooltip from the Forge UI for displaying the description of each traffic light. Descriptions can be configured in the configuration. They are being saved by using the storage API.
// Traffic light images
red: `<svg width="200" height="16" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h200v16H0z"/>
<rect fill="#403C3C" width="46" height="16" rx="2"/>
<circle fill="#F42834" cx="8.667" cy="8" r="6"/>
<circle fill="#C3B9B9" opacity=".15" cx="23" cy="8" r="6"/>
<circle fill="#C3B9B9" opacity=".15" cx="37.333" cy="8" r="6"/>
</g>
</svg>`,
yellow: `<svg width="200" height="16" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h200v16H0z"/>
<rect fill="#403C3C" width="46" height="16" rx="2"/>
<circle fill="#C3B9B9" opacity=".15" cx="8.667" cy="8" r="6"/>
<circle fill="#FEF22F" cx="23" cy="8" r="6"/>
<circle fill="#C3B9B9" opacity=".15" cx="37.333" cy="8" r="6"/>
</g>
</svg>`,
green: `<svg width="200" height="16" xmlns="http://www.w3.org/2000/svg">
<g fill="none" fill-rule="evenodd">
<path d="M0 0h200v16H0z"/>
<rect fill="#403C3C" width="46" height="16" rx="2"/>
<circle fill="#C3B9B9" opacity=".15" cx="8.667" cy="8" r="6"/>
<circle fill="#C3B9B9" opacity=".15" cx="23" cy="8" r="6"/>
<circle fill="#45B934" cx="37.333" cy="8" r="6"/>
</g>
</svg>`
Rating
The same technique is being used for the rating field. Depending on the selected value in the field, we render our own SVG images through HTML codes, which are defined inside our own CFS app. They are 5 different SVG images, one for each rating possibility. We use a tooltip from the Forge UI for displaying the description of each rating possibility. Descriptions can be configured in the configuration. They are being saved by using the storage API.
Single select picker (Multiple and Single), Multilevel select picker (Multiple and Single)
No special storing from our side, because each field has its own configuration. No global configuration is needed. Uses Jira’s view context from @forge/bridge for saving values.
Abbreviate
There is no configuration for this field. We simply get the saved value and upon displaying it, we do some formatting to display the number in an abbreviated format.
// Formatting abbreviated fields
const formatNumber = () => {
const isNegative = fieldValue < 0;
const absValue = Math.abs(fieldValue);
let formated = 0;
if (absValue < 1e3) formated = absValue;
if (absValue >= 1e3 && absValue < 1e6)
formated = `${Math.round((absValue / 1e3) * 100 + 0.05) / 100}K`;
if (absValue >= 1e6 && absValue < 1e9)
formated = `${Math.round((absValue / 1e6) * 100 + 0.05) / 100}M`;
if (absValue >= 1e9 && absValue < 1e12)
formated = `${Math.round((absValue / 1e9) * 100 + 0.05) / 100}B`;
if (absValue >= 1e12)
formated = `${Math.round((absValue / 1e12) * 100 + 0.05) / 100}t`;
return isNegative ? `-${formated}` : formated;
};
Currency
Uses currencies that are hardcoded as objects in an array saved in a .js file. Upon installing the application, those currencies are saved by using the storage API and are being loaded from there for any further use. The currencies can be enabled / disabled on the configuration page, but no other manipulation is allowed.
Unit
This field has also predefined (hardcoded) values in the configuration, which are saved by the Storage API when the application is installed. Unlike the currency field, here you can add, edit and delete values. There is also a tooltip from the Forge UI, which displays the description defined in the configuration.
Min/Max range
No special storing from our side. Uses Jira’s view context from @forge/bridge for saving values. Allowing only 2 values to be saved: min and max.
Comment
Comment fields are locked. No configuration for these fields. Simply getting necessary data from Jira by using the official REST API.
Sum/Average
No special storing (configuration page) from our side. Uses Jira’s view context from @forge/bridge for saving values.
Secure fields
For secure fields, there is a global configuration page that uses the Storage API. There is also Jira’s configuration page (specific for each field) which uses the view context from @forge/bridge for saving values. One can define different view and edit permissions for displaying sensitive information based on users, groups, and project roles. Could also be the reporter or current assignee.