Reading a panel content

In this section, you will learn how to get a panel content. The examples are in Java but they are applicable to Groovy

Main service

You will need to use the PanelContentService:

...
import com.valiantys.software.elements.api.content.PanelContentService;

@Named
public class MyService {
	private final PanelContentService panelContentService;

	public MyService(PanelContentService panelContentService) {
		this.panelContentService = panelContentService;
	}

}

Getting a panel content

You will need to use PanelContentService.getPanel.

Example

Example
Panel panel = panelContentService.getPanel(IssueRef.byId(issue.getId()), PanelRef.byId("abc12345"), new ReadOptions().overrideSecurity().withCalculate().withEntities());
for (PanelItem panelItem : panel.getPanelItems()) {
	...
}


There are many definitions of the getPanel method, most of which are helper methods to this one :

Panel getPanel(IssueRef issueRef, PanelRef panelRef, ReadOptions readOptions)

Parameters

  • IssueRef represents a reference to an issue. Ex.: IssueRef.byId(12345) or IssueRef.byKey("ISSUE-123")
  • PanelRef represents a reference to a panel. Ex.: PanelRef.byName("My panel")
  • ReadOptions is a modifier that controls the behaviour of the method. This is explained below.

Panel read options

The ReadOptions parameter above controls the following behaviour of the getPanel method.

Security

  • Using readOptions.overrideSecurity() will allow to read panel without checking current logged-in user permissions.
  • Using readOptions.withUser(anotherUser) will read the panel with the permission of the user in parameter

Calculate

  • Using readOptions.withCalculate() will enable calculate attributes and footers in the result.

This is an important option. When calculate is not enabled, calculate attributes will not be present in the result. The same applies to footers.


Entity resolution

  • Using readOptions.withEntities() will enable entities resolution. For example, if your panel contains a project component attribute, enabling entity resolution will give you access to the Component object. Otherwise, you would only have access to the component identifier.

This options applies to every entity attributes (see the list in Attribute Content Model)


Panel object structure

PanelItem / rows

A panel in composed of panel items (rows). Every panel item represents a rows. It has a content (PanelItemContent) which is every attribute content in the row.

public void doStuff() throws ElementsException {
    Issue issue = ...;
    Panel panel = panelContentService.getPanel(issue, "My panel");

    for (PanelItem panelItem : panel.getPanelItems()) {
        for (AttributeContent attributeContent : panelItem.getContent().getAttributeContents()) {
            Object value = attributeContent.getValue();
            // process value ...
        }
    }
}


Attribute content

Check Attribute Content Model for details about AttributeContent API

Example

If your panel has the following structure :

PlayerDateScore
Martin12/5/20162 300.50
Nadia5/1/20173260.00

The following code displays one text line per row.

public void doStuff() throws ElementsException {
    Issue issue = ...;
    Panel panel = panelContentService.getPanel(issue, "My panel");

    for (PanelItem panelItem : panel.getPanelItems()) {
		PanelItemContent panelItemContent = panelItem.getContent();
		ApplicationUser player = ((UserAttributeContent) panelItemContent.get(0)).getEntity();
		Date date = (Date) panelItemContent.get(1);
		Double score = (Double) panelItem.content.get(2);
		
		System.out.println(player.getDisplayName() + " " + score + "/" + date);
    }
}

Calculate attributes

If your panel contains calculate attributes, you need to explicitely use the ReadOptions parameter in the getPanel method:

new ReadOptions().withCalculate();

If this parameter is not set, the calculate attributes will be missing in the Panel structure.

Entities

In the example above, we want to access the player information :

public void doStuff() throws ElementsException {
    Issue issue = ...;
    Panel panel = panelContentService.getPanel(IssueRef.byId(issue.getId()), PanelRef.byName("My panel"), new ReadOptions());

    for (PanelItem panelItem : panel.getPanelItems()) {
		PanelItemContent panelItemContent = panelItem.getContent();
		UserAttributeContent content = (UserAttributeContent) panelItemContent.get(0);
		String userKey = content.getValue();
		ApplicationUser player = content.getEntity();
		
		
		System.out.println(player.getDisplayName() + " (" + userKey + ")");
    }
}

This example will not work unless you add the following :

new ReadOptions().withEntities();

If you do not explicitely ask for entities, only the userKey stored in the panel will be available.

When asking for entities, getPanel tries to resolve the associated entity and makes is available if found.


Missing imports

If you encountered problems when importing class ReadOptions into your groovy script, you should use another way to load this class :

import com.atlassian.jira.component.ComponentAccessor;

def pluginAccessor = ComponentAccessor.getPluginAccessor();
Class readOptionClass = pluginAccessor.getClassLoader().findClass("com.valiantys.software.elements.api.content.ReadOptions");
def readOptions = ComponentAccessor.getOSGiComponentInstanceOfType(readOptionClass);

// Then use directly instantiated class to call withEntities() method
readOptions.withEntities()


Missing entities

In the case the referenced entity is not found, the content.getEntity() above will still return null

In Elements Checklist, a panel has a footer. The Panel structure has a getFooter() method that returns a PanelFooter instance.

As for calculate attributes, the footer is only available when using new ReadOptions().withCalculate()

Getting a defined attribute footer

In the example above (table with players and scores), if the score attribute has a sum footer defined in panel configuration, you can get it like this:

public void doStuff() throws ElementsException {
    Issue issue = ...;
    Panel panel = panelContentService.getPanel(IssueRef.byId(issue.getId()), PanelRef.byName("My panel"), new ReadOptions().withCalculate());
	PanelFooter footer = panel.getFooter();
	Double totalScores = (Double) footer.getContent().get(2).getValue();
}

Calculating any footer

Even if your attribute does not have a footer defined, you can calculate any footer :

public void doStuff() throws ElementsException {
    Issue issue = ...;
    Panel panel = panelContentService.getPanel(IssueRef.byId(issue.getId()), PanelRef.byName("My panel"), new ReadOptions().withCalculate());
	PanelFooter footer = panel.getFooter();
	Double maxScore = footer.calculateFooter(AttributeRef.byName("Score"), FooterType.MAX).getValue();
}