How can I configure my custom field type forge app on each new custom field

Hi! I’m currently working on creating forge custom field types. My goal is to create a custom field type which is calculates the time difference between two “Date” or “Datetime” type custom fields. So, I created a context-config page where I can configure custom field config.
In my context config, there are 2 selects where I can select my date or datetime custom fields. When onSubmit event triggered, I store custom field name via Storage API. And I get my stored data at my view.jsx and do calculations and actually it works pretty good.

The issue is when I try to create a new custom field with my custom field type, both of my new and previous custom fields take my last custom field’s configuration even their configurations are different because of storage api.

The problem is obviously clear above. But I need a logical approach to solve this problem from this experienced community.

const onSubmit = async (formData) => {
      setFormState(formData);
      await storage.set('cfDate1', formData.cfDate1);
      await storage.set('cfDate2', formData.cfDate2);
  };

Thanks already!
Mert

I am working on a similar issue at the moment. My approach is to set up a trigger module that listens to new custom fields and custom field contexts and then uses the api to set up a default config. I am still debugging my manifest since my trigger doesn’t seem to be triggering yet but I think that approach should work

Hello :wave:

@AliMert, you need to store the configuration in the context instead of the Storage API. Your onSubmit should look something like this:

  const onSubmit = () => ({ configuration: { cfDate1: formData.cfDate1, cfDate2: formData.cfDate2 } });

See the documentation for more details: https://developer.atlassian.com/platform/forge/manifest-reference/modules/jira-custom-field-type/#configuration. You might also check the example provided by forge create.

@MichaelIlewicz, The custom field created event is known to not work at the moment. Follow this issue for the latest updates: [FRGE-569] Events "avi:jira:created:field" and "avi:jira:deleted:field" not being triggered - Ecosystem Jira

2 Likes

@kkercz seems that the triggers are working again since this morning but thanks this prevented me from several hours of debugging yesterday

1 Like

Yes, the issue is now resolved, all events should be working fine :slight_smile:

Hello, thanks for your answer.

But I need to know how can I get this value at my view.jsx.

I created a simple example which is goal is showing selected value from context-config in a custom field.
For example;
Let’s say my context-config.jsx is like that:

import ForgeUI, {useProductContext, CustomFieldContextConfig, TextField, Select, Option} from "@forge/ui";

export const ContextConfig = () => {
  const {extensionContext: {configuration = {}}} = useProductContext();

  const onSubmit = (formData) => ({ configuration: { cfDate1: formData.cfDate1 } });


  return (
    <CustomFieldContextConfig onSubmit={onSubmit}>
      <Select label="Select the first Date Custom Field" name="cfDate1" defaultValue={{label: configuration.cfDate1, value: 1}}>
        <Option label='0' value='0' />
        <Option label='1' value='1' />
      </Select>
    </CustomFieldContextConfig>
  );
};

And this is my view.jsx
Is that below code appropriate usage?

import ForgeUI, {useProductContext, CustomField, Text, useState} from "@forge/ui";

export const View = () => {
  const {extensionContext: {configuration}} = useProductContext();

    return (
    <CustomField>
      <Text>Hello, {configuration[0].cfDate1 || "World"}!</Text>
    </CustomField>
  );
};

Scenario: User selects ‘1’ from select list at context config and expects to see ‘Hello, 1’ in custom field.

Also, somehow I can’t run forge tunnel while I’m working on Custom Field Type. Unfortunately, this restricts me about testing and speed.

Thanks already,
Mert

As stated in the documentation, the configuration variable is not available in the extension context. You will need to fetch it using the Get custom field configurations REST API, providing the issue ID (which in turn you do have in the context) in the query param.

1 Like

Okay, but this request needs fieldIdOrKey. When I was developing some other custom fields based on issueId, the below code was enough to grab current issue’s id.

const context = useProductContext();
const [ids] = useState(async () => await theTimeBetweenDates(context.platformContext.issueKey));

But now, how can I get my custom field id based on my custom field?

I checked from my browser and I get this result when I was requested for /rest/api/2/app/field/customfield_10142/context/configuration :
Screen Shot 2021-12-15 at 18.10.15

and this is my current view.jsx:

import ForgeUI, {useProductContext, CustomField, Text, useState} from "@forge/ui";
import api, { route } from "@forge/api";

const theTimeBetweenDates = async (fieldIdOrKey) => {
  const res = await api
      .asUser()
      .requestJira(route`/rest/api/2/app/field/${fieldIdOrKey}/context/configuration`);
  return res;
};

export const View = () => {
  const { extensionContext: { fieldValue, fieldId, fieldType }} = useProductContext();
  const [ids] = useState(async () => await theTimeBetweenDates(fieldId));

  return (
    <CustomField>
      <Text>Hello, {ids.values.configuration.cfDate1}</Text>
    </CustomField>
  );
};

In case with custom UI, can we access configuration data from static resource react app? for example, with custom ui hook requestJira?

or i must define resolver in forge app index file, and make admin permission needed request in it?

@AliMert, your code looks good. If it doesn’t work because of permissions to the API, try making the request .asApp() instead of .asUser().

@mikhail.gorev, the API to fetch the configuration is available only for admins, so you will need a resolver.

1 Like

@kkercz , thanks for your answer. I get this error on my custom field and makes no difference If I am using .asApp() or .asUser():

Something went wrong
There was an error invoking the function - async()=>e.data could not be cloned.

TypeError: async()=>e.data could not be cloned.
    at n.wrapValue (bootstrap.js:1:2984)
    at n.wrap (bootstrap.js:1:2344)
    at bootstrap.js:1:3109
    at Array.map (<anonymous>)
    at n.wrapArray (bootstrap.js:1:3097)
    at n.wrap (bootstrap.js:1:2414)
    at bootstrap.js:1:1642
    at Array.map (<anonymous>)
    at n.applyIgnored (bootstrap.js:1:1630)
    at bootstrap.js:1:9840

I’m kinda new at Forge development and thanks for your patience :slight_smile:

1 Like

When I update my code as below, the error was gone.

const theTimeBetweenDates = async (fieldIdOrKey) => {
  const res = await api
      .asApp()
      .requestJira(route`/rest/api/2/app/field/${fieldIdOrKey}/context/configuration`);

  const config = await res.json(); //I was forgot this line of code
  return config;
};

Now everything works well, thanks and regards.
Mert

2 Likes