Skip to content

Commit

Permalink
#17 specific projects only (#37)
Browse files Browse the repository at this point in the history
- #17 define configuration page for admins; 
- add resources to atlassian-plugin.xml; 
- add WebAction; 
- Add store functions (plugin settings); 
- add form to define projects

Co-authored-by: Marcel Frank <[email protected]>
  • Loading branch information
marcelfrank-dev and mfrank-decadis authored Jan 24, 2023
1 parent e1d5aac commit 8accd3e
Show file tree
Hide file tree
Showing 11 changed files with 540 additions and 2 deletions.
30 changes: 28 additions & 2 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@
<version>${jira.version}</version>
<scope>provided</scope>
</dependency>
<!-- For Jira 8/9 compatibility-->
<dependency>
<groupId>com.sevidev</groupId>
<artifactId>jira9-compatibility</artifactId>
<version>1.0.0</version>
<scope>provided</scope>
</dependency>
<!-- Add dependency on jira-core if you want access to JIRA implementation classes as well as the sanctioned API. -->
<!-- This is not normally recommended, but may be required eg when migrating a plugin originally developed against JIRA 4.x -->
<!--
Expand All @@ -55,6 +62,18 @@
<version>4.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.atlassian.jira</groupId>
<artifactId>jira-tests</artifactId>
<version>${jira.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.powermock</groupId>
<artifactId>powermock-api-mockito2</artifactId>
<version>2.0.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.atlassian.plugin</groupId>
<artifactId>atlassian-spring-scanner-annotation</artifactId>
Expand Down Expand Up @@ -158,6 +177,12 @@
<artifactId>jira-maven-plugin</artifactId>
<version>${amps.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<id>default-test-jar</id>
<phase>none</phase>
</execution>
</executions>
<configuration>
<productVersion>${jira.version}</productVersion>
<productDataVersion>${jira.version}</productDataVersion>
Expand All @@ -172,7 +197,7 @@
</pluginArtifacts>
-->
<enableQuickReload>true</enableQuickReload>
<enableFastdev>false</enableFastdev>
<compressResources>false</compressResources>
<!-- See here for an explanation of default instructions: -->
<!-- https://developer.atlassian.com/docs/advanced-topics/configuration-of-instructions-in-atlassian-plugins -->
<instructions>
Expand All @@ -181,7 +206,8 @@
<Export-Package>com.aprey.jira.plugin.openpoker.api,</Export-Package>
<!-- Add package import here -->
<Import-Package>org.springframework.osgi.*;resolution:="optional",
org.eclipse.gemini.blueprint.*;resolution:="optional", *
org.eclipse.gemini.blueprint.*;resolution:="optional", *;
*;resolution:="optional"
</Import-Package>
<!-- Ensure plugin is spring powered -->
<Spring-Context>*</Spring-Context>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.aprey.jira.plugin.openpoker.api.config;

import java.util.List;

import com.atlassian.jira.plugin.webfragment.conditions.AbstractWebCondition;
import com.atlassian.jira.plugin.webfragment.model.JiraHelper;
import com.atlassian.jira.user.ApplicationUser;

/**
* Class that defines a condition for the web fragment visibility
*/
public class AllowedProjectsCondition extends AbstractWebCondition {

/**
* Method to determine whether the web fragment should be displayed or not
* @param applicationUser The user currently viewing the page
* @param jiraHelper The JiraHelper that provides access to various Jira-related objects
* @return boolean value indicating whether the web fragment should be displayed or not
*/
@Override
public boolean shouldDisplay(ApplicationUser applicationUser, JiraHelper jiraHelper) {
List<String> allowedProjects = ConfigurationManager.getStoredAllowedProjects();
if ( allowedProjects.isEmpty() ) {
return true;
}
if ( jiraHelper.getProject() != null ) {
return allowedProjects.contains(jiraHelper.getProject().getKey());
}
return true;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.aprey.jira.plugin.openpoker.api.config;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.Collectors;

import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.sal.api.pluginsettings.PluginSettings;
import com.atlassian.sal.api.pluginsettings.PluginSettingsFactory;

public abstract class ConfigurationManager {
//Key for plugin settings
private static String OPEN_POKER_KEY = "com.aprey.jira.plugin.openpoker";

/**
* Method to get the plugin settings
*
* @return pluginSettings instance
*/
public static PluginSettings getPluginSettings() {
PluginSettingsFactory pluginSettingsFactory = ComponentAccessor.getOSGiComponentInstanceOfType(PluginSettingsFactory.class);
PluginSettings pluginSettings = pluginSettingsFactory.createSettingsForKey(OPEN_POKER_KEY);
return pluginSettings;
}

/**
* Method to get the stored allowed projects from plugin settings
*
* @return ArrayList of allowed projects
*/
public static ArrayList<String> getStoredAllowedProjects() {
PluginSettings pluginSettings = getPluginSettings();
String storedProjects = ((String) pluginSettings.get("allowedProjects"));
if ( storedProjects != null && !storedProjects.isEmpty() ) {
return Arrays.stream(storedProjects.split(",")).collect(Collectors.toCollection(ArrayList::new));
}
return new ArrayList<>();
}

/**
* Method to store the updated allowed projects in plugin settings
*
* @param updatedAllowedProjects String of allowed projects
*/
public static void storeAllowedProjects(String updatedAllowedProjects) {
PluginSettings pluginSettings = getPluginSettings();
pluginSettings.put("allowedProjects", updatedAllowedProjects);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
package com.aprey.jira.plugin.openpoker.config;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.List;

import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.project.Project;
import com.atlassian.jira.security.request.RequestMethod;
import com.atlassian.jira.security.request.SupportedMethods;
import com.atlassian.jira.web.action.JiraWebActionSupport;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import webwork.action.Action;
import webwork.action.ServletActionContext;

import static com.aprey.jira.plugin.openpoker.api.config.ConfigurationManager.getStoredAllowedProjects;
import static com.aprey.jira.plugin.openpoker.api.config.ConfigurationManager.storeAllowedProjects;

@SupportedMethods({ RequestMethod.GET })
public class PokerConfigPage extends JiraWebActionSupport {

//List of allowed projects
private List<String> allowedProjects = new ArrayList<>();

/**
* Method is called when the page is first loaded
*/
@Override
public String doDefault() throws Exception {
allowedProjects.addAll(getStoredAllowedProjects());
return Action.INPUT;
}

/**
* Method is called when the form is submitted
*/
@Override
@SupportedMethods({ RequestMethod.POST })
protected String doExecute() throws Exception {
String updatedAllowedProjects = getUpdatedAllowedProjects();
storeAllowedProjects(updatedAllowedProjects);

if ( !getHasErrorMessages() ) {
return returnComplete("openPokerConfig!default.jspa");
}
return Action.INPUT;
}

/**
* Method to get the updated allowed projects from the form
*
* @return String of allowed projects
*/
private static String getUpdatedAllowedProjects() {
HttpServletRequest request = ServletActionContext.getRequest();
String updatedAllowedProjects = request.getParameter("allowedProjects");
return updatedAllowedProjects;
}

public List<String> getAllowedProjects() {
return allowedProjects;
}

public String getAllowedProjectsValue() {
return String.join(",", allowedProjects);
}

public void setAllowedProjects(List<String> allowedProjects) {
this.allowedProjects = allowedProjects;
}

public List<Project> getProjects() {
return ComponentAccessor.getProjectManager().getProjects();
}

public String getURL() {
return "openPokerConfig.jspa";
}
}
33 changes: 33 additions & 0 deletions src/main/resources/atlassian-plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -47,25 +47,58 @@
<context>jira.navigator.advanced</context>
<context>jira.navigator.simple</context>
</web-resource>
<web-resource key="open-poker-config-resources" name="open-poker config web resources">
<context>open-poker-config</context>
<dependency>com.atlassian.auiplugin:ajs</dependency>
<dependency>com.atlassian.auiplugin:aui-select2</dependency>
<dependency>com.atlassian.auiplugin:aui-tooltips</dependency>
<resource type="download" name="open-poker-config.css" location="/css/config/open-poker-config.css"/>
<resource type="download" name="open-poker-config.js" location="/js/config/open-poker-config.js"/>
<resource type="download" name="images/" location="/images"/>
</web-resource>

<web-panel name="PlanningPoker" i18n-name-key="planning-poker.name" key="planning-poker"
location="atl.jira.view.issue.right.context" weight="1000">
<description key="planning-poker.description">The PlanningPoker Plugin</description>
<context-provider class="com.aprey.jira.plugin.openpoker.api.PlanningPokerWebPanelProvider"/>
<resource name="view" type="velocity" location="templates/planning-poker.vm"/>
<label key="planning-poker.title"/>
<condition class="com.aprey.jira.plugin.openpoker.api.config.AllowedProjectsCondition"/>
</web-panel>

<ao key="ao-module">
<description>The module configuring the Active Objects service used by this plugin</description>
<entity>com.aprey.jira.plugin.openpoker.persistence.PokerSessionEntity</entity>
<entity>com.aprey.jira.plugin.openpoker.persistence.EstimateEntity</entity>
<entity>com.aprey.jira.plugin.openpoker.persistence.FinalEstEntity</entity>
</ao>

<servlet name="Poker Planning Servlet" class="com.aprey.jira.plugin.openpoker.api.PokerSessionServlet"
key="poker-session">
<description>A servlet to add new Planning Poker session</description>
<url-pattern>/open-poker/session</url-pattern>
</servlet>

<rest key="rest" path="/open-poker" version="1.0">
<description>Rest resource for</description>
</rest>

<web-section key="openpoker-section" name="Openpoker" location="admin_plugins_menu" weight="80">
<label key="Openpoker"/>
</web-section>

<web-item key="openpokerConfiguration" section="admin_plugins_menu/openpoker-section" name="openpokerConfiguration" weight="200">
<description>Page, to configure open poker.</description>
<label key="Configuration"/>
<description>xOpenpoker Configuration</description>
<link linkId="open-poker-configuration">/secure/admin/open-poker/openPokerConfig!default.jspa</link>
</web-item>

<webwork1 key="open-poker-pages" name="Openpoker administration pages" class="java.lang.Object">
<actions>
<action name="com.aprey.jira.plugin.openpoker.config.PokerConfigPage" alias="openPokerConfig" roles-required="admin">
<view name="input">/templates/config/open-poker-config.vm</view>
</action>
</actions>
</webwork1>
</atlassian-plugin>
10 changes: 10 additions & 0 deletions src/main/resources/css/config/open-poker-config.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
.allowedProjectsSelectLabel
{
display: flex;
width: 100%;
}

#s2id_allowedProjectsSelect
{
max-width: 800px;
}
16 changes: 16 additions & 0 deletions src/main/resources/js/config/open-poker-config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
AJS.$(document).ready(() => {
const initialize = () => {
let $allowedProjectsSelect = AJS.$("#allowedProjectsSelect");
$allowedProjectsSelect.auiSelect2(
{
placeholder: "Open poker will be available for each project",
allowClear: true
});

$allowedProjectsSelect.on("change", () => {
AJS.$("#allowedProjects").val(AJS.$("#allowedProjectsSelect").val());
});
};

initialize();
});
36 changes: 36 additions & 0 deletions src/main/resources/templates/config/open-poker-config.vm
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
$webResourceManager.requireResource("com.aprey.jira.plugin.openpoker.open-poker:open-poker-config-resources")
<html>
<head>
<title>Open poker configuration</title>
</head>
<body>

<header class="aui-page-header">
<div class="aui-page-header-inner">
<div class="aui-page-header-main">
<h1>Open poker configuration</h1>
</div>
</div>
</header>
<h2>Permissions</h2>
<form action="$action.getURL()" class="aui" method="POST">
<input type="hidden" name="atl_token" value="$atl_token" />
<input type="hidden" id="allowedProjects" name="allowedProjects" value="$action.getAllowedProjectsValue()"/>
<fieldset>
<label for="allowedProjects" class="allowedProjectsSelectLabel">Projects:</label>
<select id="allowedProjectsSelect" name="allowedProjectsSelect" style="padding: 5px 0 0 0" multiple>
#foreach ($project in $projects)
<option #if(${allowedProjects.contains(${project.getKey()})}) selected #end value="${project.getKey()}">${project.getName()} (${project.getKey()})</option>
#end
</select>
<div class="description">Define the projects, where open poker should be rendered on the issue view. If no project is selected, it will be enabled for all projects.</div>
</fieldset>

<div class="buttons-container" style="padding: 10px 0 4px 0;">
<div class="buttons">
<button id="save_button" class="aui-button aui-button-primary" type="submit">Save</button>
</div>
</div>
</form>
</body>
</html>
Loading

0 comments on commit 8accd3e

Please sign in to comment.