Create
cancel
Showing results for 
Search instead for 
Did you mean: 
Sign up Log in

How to build a Gadget (Charts)?

mohamed assedmer November 11, 2024 edited

Hi, I'm new to Jira plugin development and have just learned the basics. I'm working on creating a gadget, but the documentation is not helping well 😅. So far, I’ve been able to set up the initial steps and my gadget is now listed alongside others. I’ve also managed to build a line chart using Chart.js.

However, I’d like to accept some user inputs before rendering the chart, and I think this involves using something like UserPrefs. Can anyone help with how to implement this functionality or point me in the right direction?

You will find my gadget.xml and atlassian-plugin.xml  files down.

Thanks! 😊

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="__MSG_gadget.title__" directory_title="__MSG_gadget.title__" description="__MSG_gadget.description__">
<Optional feature="gadget-directory">
<Param name="categories">JIRA</Param>
</Optional>
<Optional feature="atlassian.util" />
<Optional feature="auth-refresh" />
<Require feature="views" />
<Require feature="settitle"/>
<Require feature="oauthpopup" />
<Require feature="minimessage" />
<Require feature="dynamic-height" />
<!-- OAuth configuration -->
<Locale messages="__ATLASSIAN_BASE_URL__/download/resources/com.atlas.tuto.atlastuto/i18n/ALL_ALL.xml"/>
</ModulePrefs>

<Content type="html" view="profile">
<![CDATA[
#requireResource("com.atlassian.jira.gadgets:common")
#requireResource("com.atlassian.gadgets.publisher:ajs-gadgets")
#includeResources()

<h4>Tuto Gadget</h4>

<!-- Chart.js CDN -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

<style>
/* Set a fixed height for the chart */
#chart-container {
width: 100%;
height: 300px; /* Adjust height as needed */
padding: 10px 0;
}
</style>

<script type="text/javascript">
(function () {
var gadget = AJS.Gadget({
baseUrl: "__ATLASSIAN_BASE_URL__",
useOauth: true,
view: {
template: function(args) {

// Set up the chart data
var ctx = document.getElementById('myChart').getContext('2d');
var myChart = new Chart(ctx, {
type: 'line',
data: {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
datasets: [
{
label: 'Tickets',
data: Array.from({length: 7}, () => Math.floor(Math.random() * 100)),
borderColor: 'rgba(255, 99, 132, 1)',
backgroundColor: 'rgba(255, 99, 132, 0.2)',
fill: false
},
{
label: 'Solved',
data: Array.from({length: 7}, () => Math.floor(Math.random() * 100)),
borderColor: 'rgba(54, 162, 235, 1)',
backgroundColor: 'rgba(54, 162, 235, 0.2)',
fill: false
},
{
label: 'Remain',
data: Array.from({length: 7}, () => Math.floor(Math.random() * 100)),
borderColor: 'rgba(75, 192, 192, 1)',
backgroundColor: 'rgba(75, 192, 192, 0.2)',
fill: false
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
max: 100
}
}
}
});
},
args: [{
key: "projectData",
ajaxOptions: function() {
return {
url: "/rest/gadgetresource/1.0/message",
contentType: "application/json"
};
}
}]
}
});
})();
</script>

<!-- Container and canvas for Chart.js -->
<div id="chart-container">
<canvas id="myChart"></canvas>
</div>
]]>
</Content>
</Module>
atlassian-plugin.xml

 

<?xml version="1.0" encoding="UTF-8"?>

<atlassian-plugin key="${atlassian.plugin.key}" name="${project.name}" plugins-version="2">
<plugin-info>
<description>${project.description}</description>
<version>${project.version}</version>
<vendor name="${project.organization.name}" url="${project.organization.url}"/>
<param name="plugin-icon">images/pluginIcon.png</param>
<param name="plugin-logo">images/pluginLogo.png</param>
</plugin-info>
<!-- add our i18n resource -->
<resource type="i18n" name="i18n" location="atlastuto"/>
<!-- add our web resources -->
<web-resource key="atlastuto-resources" name="atlastuto Web Resources">
<dependency>com.atlassian.auiplugin:ajs</dependency>
<resource type="download" name="atlastuto.css" location="/css/atlastuto.css"/>
<resource type="download" name="atlastuto.js" location="/js/atlastuto.js"/>
<resource type="download" name="images/" location="/images"/>
<context>atlastuto</context>
</web-resource>
<rest name="Gadget Resource" i18n-name-key="gadget-resource.name" key="gadget-resource" path="/gadgetresource" version="1.0">
<description key="gadget-resource.description">The Gadget Resource Plugin</description>
</rest>
<web-item name="REST test" i18n-name-key="res-ttest.name" key="res-ttest" section="system.top.navigation.bar" weight="1000">
<description key="res-ttest.description">The REST test Plugin</description>
<label key="res-ttest.label"/>
<link linkId="res-ttest-link">/rest/gadgetresource/1.0/message</link>
</web-item>


<gadget name="Learning Gadget" i18n-name-key="learning-gadget.name" key="learning-gadget" location="gadget.xml">
<description key="learning-gadget.description">The Learning Gadget Plugin</description>
</gadget>

<resource type="download" name="i18n/ALL_ALL.xml" location="i18n/ALL_ALL.xml">
<param name="content-type" value="text/xml; charset=UTF-8"/>
</resource>


</atlassian-plugin>

1 answer

1 accepted

0 votes
Answer accepted
mohamed assedmer November 12, 2024

I fixe it:

<?xml version="1.0" encoding="UTF-8" ?>
<Module>
<ModulePrefs title="__MSG_gadget.title__" directory_title="__MSG_gadget.title__" description="__MSG_gadget.description__">
<Optional feature="gadget-directory">
<Param name="categories">JIRA</Param>
</Optional>
<Require feature="setprefs" />
<Require feature="views" />
<Require feature="dynamic-height" />
<Require feature="oauthpopup" />

<!-- OAuth configuration -->
<Locale messages="__ATLASSIAN_BASE_URL__/download/resources/com.atlas.tuto.atlastuto/i18n/ALL_ALL.xml"/>
</ModulePrefs>

<UserPref name="isConfigured" datatype="hidden" default_value="false" />


<Content type="html" view="profile">
<![CDATA[
#requireResource("com.atlassian.jira.gadgets:common")
#requireResource("com.atlassian.gadgets.publisher:ajs-gadgets")
#includeResources()


<!-- Chart.js CDN -->
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

<style>
/* Set a fixed height for the chart */
#chart-container {
width: 100%;
height: 300px; /* Adjust height as needed */
padding: 10px 0;
}
</style>
<script type="text/javascript">
(function () {
var gadget = AJS.Gadget({
baseUrl: "__ATLASSIAN_BASE_URL__",
useOauth: false,
config:{
descriptor: function(args){
var gadget = this;
return {
theme: "",
fields:[
{
id: "projectKey",
userpref: "projectKey",
class: "projectKey",
label: "Select the project",
description: "Find the project to apply the chart",
type: "text",
value: gadget.getPref("projectKey")
},
{
userpref: "isConfigured",
type: "hidden",
value: "true"
},
]
};
}

},
view: {
template: function(args) {
var gadget = this;


var chartContainer = AJS.$("<div/>").attr({ id: "chart-container" });
var chartCanvas = AJS.$("<canvas/>").attr({ id: "myChart" });
chartContainer.append(chartCanvas);


gadget.getView().html(chartContainer);



var ctx = chartCanvas[0].getContext("2d");
new Chart(ctx, {
type: 'line',
data: {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
datasets: [
{
label: 'Tickets',
data: Array.from({length: 7}, () => Math.floor(Math.random() * 100)),
borderColor: 'rgba(255, 99, 132, 1)',
backgroundColor: 'rgba(255, 99, 132, 0.2)',
fill: false
},
{
label: 'Solved',
data: Array.from({length: 7}, () => Math.floor(Math.random() * 100)),
borderColor: 'rgba(54, 162, 235, 1)',
backgroundColor: 'rgba(54, 162, 235, 0.2)',
fill: false
},
{
label: 'Remain',
data: Array.from({length: 7}, () => Math.floor(Math.random() * 100)),
borderColor: 'rgba(75, 192, 192, 1)',
backgroundColor: 'rgba(75, 192, 192, 0.2)',
fill: false
}
]
},
options: {
responsive: true,
maintainAspectRatio: false,
scales: {
y: {
beginAtZero: true,
max: 100
}
}
}
});


},
args: [{
key: "projectData",
ajaxOptions: function() {
return {
url: "/rest/gadgetresource/1.0/message",
contentType: "application/json"
};
}
}]
}
});
})();
</script>
]]>
</Content>

</Module>

Suggest an answer

Log in or Sign up to answer
TAGS
atlassian, team '25, conference, certifications, bootcamps, training experience, anaheim ca,

Want to make the most of Team ‘25?

Spend the day sharpening your skills in Atlassian Cloud Organization Admin or Jira Administration, then take the exam onsite. Already ready? Take one - or more - of 12 different certification exams while you’re in Anaheim at Team' 25.

Learn more
AUG Leaders

Upcoming Jira Events