Hi
Is there some example of how i can add Field screens programatically in a plugin?
I have created a AddProjectHook class thats called buy my project-blueprint plugin and when this is added i want to create some customer field screens, but cannot find any examples of how to do this.
I am new to JIRA dev so would welcome some examples thank you in advance
Andy
Community moderators have prevented the ability to post new answers.
You will need FieldScreenManager
to create a new screen, FieldScreenSchemeManager
to add the screen to a scheme and IssueTypeScreenSchemeManager to assign the scheme to a Project
and IssueType
s. A screen consists of a list of FieldScreenTab
s, each containing a list of FieldScreenLayoutItem
s, which is essentially an OrderableField
and its position in the tab.
Try something like this:
// component dependencies, get via Constructor Injection FieldScreenManager fieldScreenManager; FieldScreenSchemeManager fieldScreenSchemeManager; FieldManager fieldManager; IssueTypeScreenSchemeManager issueTypeScreenSchemeManager; ConstantsManager constantsManager; // create screen FieldScreen myScreen = new FieldScreenImpl(fieldScreenManager); myScreen.setName(myName); myScreen.setDescription(myDescription); myScreen.store(); // create tab FieldScreenTab myTab = myScreen.addTab(myTabName); // add field to tab OrderableField myField = fieldManager.getOrderableField(myFieldId); // e.g. "assignee", "customfield_12345" myTab.addFieldScreenLayoutItem(myField.getId()); // add screen to scheme // get existing scheme... FieldScreenScheme myScheme = fieldScreenSchemeManager.getFieldScreenScheme(mySchemeId); // ... or create new scheme FieldScreenScheme myScheme = new FieldScreenSchemeImpl(fieldScreenSchemeManager); myScheme.setName(mySchemeName); myScheme.setDescription(mySchemeDescription); myScheme.store(); // add screen FieldScreenSchemeItem mySchemeItem = new FieldScreenSchemeItemImpl(fieldScreenSchemeManager, fieldScreenManager); mySchemeItem.setIssueOperation(IssueOperations.CREATE_ISSUE_OPERATION); // or: EDIT_ISSUE_OPERATION, VIEW_ISSUE_OPERATION mySchemeItem.setFieldScreen(myScreen); myScheme.addFieldScreenSchemeItem(mySchemeItem); // create issueTypeScreenScheme IssueTypeScreenScheme myIssueTypeScreenScheme = new IssueTypeScreenSchemeImpl(issueTypeScreenSchemeManager, null); myIssueTypeScreenScheme.setName(myIssueTypeScreenSchemeName); myIssueTypeScreenScheme.setDescription(myIssueTypeScreenSchemeDescription); myIssueTypeScreenScheme.store(); // add scheme to issueTypeScreenScheme IssueTypeScreenSchemeEntity myEntity = new IssueTypeScreenSchemeEntityImpl( issueTypeScreenSchemeManager, (GenericValue) null, fieldScreenSchemeManager, constantsManager); IssueType issueType; myEntity.setIssueTypeId(issueType != null ? issueType.getId() : null); // an entity can be for all IssueTypes (-> null), or just for 1 myEntity.setFieldScreenScheme(myScheme); myIssueTypeScreenScheme.addEntity(myEntity); // assign to project issueTypeScreenSchemeManager.addSchemeAssociation(myProject, myIssueTypeScreenScheme);
Hi Thank you for the repose its helped me loads. I am struggling to compile though as it complains that I have not initialised some of the component dependencies, how do I do this or should they be passed into the function.. FieldScreenManager fieldScreenManager; FieldScreenSchemeManager fieldScreenSchemeManager; FieldManager fieldManager; IssueTypeScreenSchemeManager issueTypeScreenSchemeManager; ConstantsManager constantsManager; I am running this in the AddProjectHook from a project blueprint project. I am new to this type of development so sorry for the questions! Should i be using the IssueTypeScreenSchemeManager issueTypeScreenSchemeManager; = ComponentAccessor.getIssueTypeScreenSchemeManager() ? If this is the case i cannot find a get command for the FieldScreenSchemeManager or the IssueType? Andy
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
We're talking about Dependency Injection here. In many places JIRA will inject the dependent components if you simply write them as parameters in the constructor, where you can save them to variables and use them later. If that is not possible with AddProjectHooks, then you indeed have to use ComponentAccessor instead. But only for the components: "IssueType" is not a component. I merely put it in the code to point out that you could set the IssueTypeScreenSchemeEntity for a specific IssueType. But you don't have to. You could just use "null" there to assign the entity to all IssueTypes. For all components without a getter-method in ComponentAccessor you have to use ComponentAccessor.getComponent(Class<T> componentClass) instead, like so: ComponentAccessor.getComponent(FieldScreenSchemeManager.class)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi This is great and i have managed to get it to work perfectly thank you. Also where can i find more documentation on how to use some of these class plus any examples as now i want to be able to add customer fields and import a workflow from a workflow backup in the same procedure as i am doing the above? Using the example blueprint code and using the JSON file example means it keeps creating separate workflows for every new project created with it when i want it to reuse the same workflow for all projects created with the blueprint so i think doing it in code and checking if it exists first is the best way.? Andy
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I sometimes find useful code examples by googling for short code snippets, e.g. for AddProjectHook I used this search: https://www.google.de/search?q=%22implements+addprojecthook%22 You can do the same for other components, e.g. "workflowmanager.getworkflow"
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@Andrew Gilbert, if my answer helped you, please "officially" mark it as correct by ticking the checkmark next to it. Thanks.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@Andreas Ebert, Thanks for the solution. I am able to follow the steps and succesfully compiled the code but I dont know how can ii check the output screen? can you please share the steps to verify the output screen created?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
@Andreas Ebert ,according to your suggestion,i create a new issuetypescreenscheme and copy some fieldscreenscheme. assign fieldscreenscheme and issyetype to the new issuetypescreenscheme.when i assign the new issuetypescreenscheme to my project ,it is Error. Is it because of my new issuetypescreenscheme don't set dafault fieldscreenscheme ?
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hey guys,
Thanks for sharing all this stuff, including the answer by @Rusi Popov that inspired my solution.
After digging a lot, I've found that is possible to create workflows, issue types, screens, resolutions, issue type screen schemes and screen schemes using only a .json config file. Here is an example:
{ "issue-type-scheme": { "name": "my.translations.project.issuetype.scheme.name", "description": "my.translations.project.issuetype.scheme.description", "default-issue-type": "issueType1", "issue-types": [ { "key": "issueType1", "name": "my.translations.issuetype.improvement.name", "description": "my.translations.issuetype.improvement.desc", "icon": "/images/issuetypes/improvement.png", "avatar": "improvement.svg" }, { "key": "issueType2", "name": "my.translations.issuetype.sub-task.name", "description": "my.translations.issuetype.sub-task.desc", "icon": "/images/issuetypes/subtask.png", "sub-task": true, "avatar": "subtask.svg" }, { "key": "issueType3", "name": "my.translations.issuetype.sales.name", "description": "my.translations.issuetype.sales.desc", "icon": "/images/issuetypes/sales.png", "avatar": "sales.svg", "screen-scheme": "salesScreenScheme" } ] }, "issue-type-screen-scheme": { "name": "my.translations.project.issuetype.screen.scheme.name", "description": "my.translations.project.issuetype.screen.scheme.description", "default-screen-scheme": "defaultScreenScheme", "screens": [ { "key": "defaultScreen", "name": "my.translations.project.screen.default.name", "description": "my.translations.project.screen.default.description", "tabs": [ { "name": "my.translations.project.screen.tab.name", "fields": [ "summary", "issuetype", "security", "priority", "duedate", "components", "fixVersions", "assignee", "reporter", "description", "attachment", "issuelinks", "labels", "timetracking" ] } ] }, { "key": "salesScreen", "name": "my.translations.project.screen.sales.name", "description": "my.translations.project.screen.sales.description", "tabs": [ { "name": "my.translations.project.screen.tab.name", "fields": [ "summary", "issuetype", "security", "priority", "duedate", "components", "versions", "fixVersions", "assignee", "reporter", "environment", "description", "attachment", "issuelinks", "labels", "timetracking" ] } ] } ], "screen-schemes": [ { "key": "defaultScreenScheme", "name": "my.translations.project.screen.scheme.default.name", "description": "my.translations.project.screen.scheme.default.description", "default-screen": "defaultScreen" }, { "key": "salesScreenScheme", "name": "my.translations.project.screen.scheme.sales.name", "description": "my.translations.project.screen.scheme.sales.description", "default-screen": "salesScreen" } ] }, "resolutions": [ { "name": "my.translations.resolution.done.name", "description": "my.translations.resolution.done.desc" }, { "name": "my.translations.resolution.wontdo.name", "description": "my.translations.resolution.wontdo.desc" } ] }
If you need to add custom fields to the created screens, it is possible to be done on the "AddProjectHook" class.
I hope it helps!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Sure,
In my case I've just declared a project-blueprint module in my atlassian-plugin.xml and referenced the xml files:
<project-blueprint key="project-template" weight="90">
<label key="project_template.name"/>
<projectTypeKey>business</projectTypeKey>
<description key="project_template.description"/>
<longDescription key="project_template.description.long"/>
<infoPage soy-template="JIRA.Templates.ProjectTemplates.MyTemplate.renderTemplateExplanation" />
<icon location="imagesproject-template-icon.png"/>
<add-project>
<hook class="com.my.company.blueprint.AddProjectHook"/>
<descriptor file="/com/my/company/config/project-template-config.json"/>
</add-project>
<condition class="com.my.company.conditions.ValidLicenseCondition"/>
</project-blueprint>
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hi there. Sure, this is what I have for mine, just with the implementation of each method omitted. But I suppose you'll figure out what to do once you implement the correct interface:
@Scanned
public class AddProjectHook implements com.atlassian.jira.project.template.hook.AddProjectHook {
private final WorkflowManager workflowManager;
private final WorkflowFunctionDescriptorFactory workflowFunctionDescriptorFactory;
private final CustomFieldManager customFieldManager;
private final OptionsManager optionsManager;
private final PluginSettingsFactory pluginSettingsFactory;
public AddProjectHook(@ComponentImport final WorkflowManager workflowManager,
@ComponentImport final WorkflowFunctionDescriptorFactory workflowFunctionDescriptorFactory,
@ComponentImport final CustomFieldManager customFieldManager,
@ComponentImport final OptionsManager optionsManager,
@ComponentImport final PluginSettingsFactory pluginSettingsFactory) {
this.workflowManager = workflowManager;
this.workflowFunctionDescriptorFactory = workflowFunctionDescriptorFactory;
this.customFieldManager = customFieldManager;
this.optionsManager = optionsManager;
this.pluginSettingsFactory = pluginSettingsFactory;
}
@Override
public ValidateResponse validate(final ValidateData validateData) { ...}
@Override
public ConfigureResponse configure(final ConfigureData configureData) { ...}
}
And then, you link this class into your atlassian-plugin.xml:
<project-blueprint key="my-project-template" weight="90">
<label key="com.sample.project_template.name"/>
<projectTypeKey>business</projectTypeKey>
<description key="com.sample.project_template.description"/>
<longDescription key="com.sample.project_template.description.long"/>
<infoPage soy-template="JIRA.Templates.ProjectTemplates.MySample.renderTemplateExplanation" />
<icon location="images/sample-project-template-icon.png"/>
<add-project>
<hook class="com.sample.blueprint.AddProjectHook"/>
<descriptor file="/com/sample/config/project-template-config.json"/>
</add-project>
</project-blueprint>
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Thank you very much, that helped a lot!
But I have another question now, with which you maybe can help me.
I am not able to import the FieldScreenImp. I try to use
import com.atlassian.jira.issue.fields.screen.FieldScreenImpl;
but Intellij tells me, that it cannot resolve symbol. I need this to create a screen I want to add my custom field then.
Do I do something wrong, or did they change FieldScreenImp to something else?
Other import statements like
import com.atlassian.jira.issue.fields.screen.FieldScreen
do work well.
Thank you very much for your help!
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
I don't know that one, but I don't think you are supposed to import the Impl class. Probably what you need is to use some other service to create the screen and then return the screen object for you, instead of doing something like new FieldScreen.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
Hmm ok.
I was checking the internet for the last few days, but I did not find anything else than the Impl class and fortunately I am not that good yet at plugin development.
But I will have another look, thank for the suggestion :)
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
In order to avoid copying the workflows when instantiating a new project from template, in the from the project-template-config.json file remove the "workflow-scheme" section and the "workflow" references from from "issue-type-scheme"/"issue-types" sections. In this case JIRA assigns the default workflow schema, which one could replace with another (ready made) workflow schema in the configure() method of the project hook class:
public ConfigureResponse configure(final ConfigureData configureData) { AssignableWorkflowScheme workflowSchema; Scheme scheme; // assign the specific existing workflow schema workflowSchema = workflowSchemeManager.getWorkflowSchemeObj( "workflow schema name" ); if ( workflowSchema != null ) { scheme = workflowSchemeManager.getSchemeObject( workflowSchema.getId() ); workflowSchemeManager.addSchemeToProject(configureData.project(), scheme); } return ConfigureResponse.create(); }
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.