1 1
May 12, 2015
1
1
Go Go Gadgets!• Building Gadgets for Atlassian Products
2
• Mark Halvorson• Chief Imagineer• Atlassian Software
2
What is an ʻImagineerʼ?3
Take things that exist...
!" #"
4
...and make something different.
5
6
6
Agenda
• What it is OpenSocial• Why we chose it• How it has helped us
• Why you should use it!• How you can get involved
7
7
What is OpenSocial?
8
8
Social Data Model
9
9
Web Service APIs
10
10
Gadgets
11
11
Our Problem
12
12
• Enterprise Apps are Silos
Before
FishEye Source Code
JIRA Issues & Tasks
Confluence Wiki
13
13
14
Emphasize Teams, Projects & Tasks over Tools
14
Too Many Dashboards
15
15
16
Cross-Product Sharing
16
Integration with Non-Atlassian apps
17
17
Solution: OpenSocial Gadgets
18
18
Gadgets are a Great Solution for Dashboards
19
19
After
view complete
• Open standard for enterprise• application connection
20
20
Managers Do Email
view acAvity & status
• Not just about portals,• or internal applications.
21
21
Open Standards,Industry Support
22
22
Why Write Gadgets?
• Theyʼre easy!
• They use stable, widely accessible and understood technologies
• Write once, display everywhere
23
23
The Obligatory Hello World Example
24
24
Anatomy of a Gadget
• XML Spec File• Metadata, HTML Content, and JavaScript
• Core JavaScript API• Access Preferences, Make Requests
• Gadget Features• Additional, Optional Capabilities & APIs
25
25
XML Spec File
26
26
<ModulePrefs>
<?xml version="1.0" encoding="UTF-8" ?><Module> <ModulePrefs title="JIRA Issues" author="Atlassian" thumbnail="http://labs.atlassian.com/svn/GADGETS/trunk/jira-issues/basic/jira-issues-thumbnail.png" description="A list of recently created Issues">
<Require feature="minimessage" /> <Require feature="dynamic-height" />
</ModulePrefs>
27
27
<UserPref>
<UserPref name="show_date" display_name="Show Dates?" datatype="bool" default_value="true"/> <UserPref name="show_summ" display_name="Show Summaries?" datatype="bool" default_value="true"/> <UserPref name="num_entries" display_name="Number of Entries:" default_value="5" required="true"/>
28
28
<Content>
<Content type="html"><![CDATA[ <link rel="stylesheet" href="http://labs.atlassian.com/svn/GADGETS/trunk/jira-issues/basic/jira-issues.css">
<div id="content_div"></div>
<script type="text/javascript" src="http://labs.atlassian.com/svn/GADGETS/trunk/jira-issues/basic/jira-issues.js"></script> ]]></Content></Module>
29
29
Views - Default
30
30
Views - Default
31
31
Views - Canvas
32
32
Views - “nav”
33
33
Views - Canvas
34
34
Views - Custom
35
35
Dashboards, Gadgets & OpenSocial•Gadgets go beyond the JIRA Dashboard - onto your wall!
36
36
JavaScript
// Create minimessage factoryvar msg = new gadgets.MiniMessage();// Show a small loading message to the uservar loadMessage = msg.createStaticMessage("loading...");
// Get configured user prefsvar prefs = new gadgets.Prefs();var showDate = prefs.getBool("show_date");var showSummary = prefs.getBool("show_summ");var numEntries = prefs.getInt("num_entries");
// Fetch issues when the gadget loadsgadgets.util.registerOnLoadHandler(fetchIssues);
37
37
Requesting Data from Web Services
• AJAX + DOM
• OAuth
• Request Proxy
•
38
38
39
39
40
40
41
41
42
42
gadgets.io.makeRequest()
43
43
What Can You Call?
• Any URL
• XML and JSON are the most useful•
44
44
Fetching Issues
function fetchIssues() { var url = "http://jira.atlassian.com/sr/" + "jira.issueviews:searchrequest-xml" + "/temp/SearchRequest.xml?" + "created%3Aprevious=-1w&resolution=-1" + "&sorter/field=issuekey&sorter/order=DESC" + "&sorter/field=created&sorter/order=DESC" + "&tempMax=20";
var params = {}; params[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType.DOM;
gadgets.io.makeRequest(url, handleResponse, params);}
45
45
Handling the Response
function handleResponse(obj) { var domData = obj.data;
var jiraIssues = { title : getTitle(domData), items : getItems(domData) }; renderJiraIssues(jiraIssues);
msg.dismissMessage(loadMessage); gadgets.window.adjustHeight();}
46
46
TextText
An ExampleReal World Example...47
The Goal
The Goal48
48
The Result
The Result49
49
Preferences50
50
Statistics
51
51
Letʼs Take a Step Back.
52
52
Q: What is the purpose of an application?• A: DO Something. Complete some process.
53
53
Anatomy of an Application
Context Content Ac)on
54
54
An Example
Gmail
Communica)on
ContactsMail
Read WriteReply
55
55
Q: What is the purpose of an gadget?
• A: DO Something. Complete some process.
56
56
Gadget = Reusable
Mini-‐ApplicaAon
Context
Content
Ac)on
AtomicUnit of Work
Ac)on
Context
Content
• or
57
57
Example - “Mini-Application”
JIRA Comment Gadget
JIRA-‐1234
Add Comment
Users Comment
Users Comment
58
58
Example - Unit of Work
JIRA Comment Gadget
Context
Users Comment
Add Comment
59
59
Lesson Learned over time: Gadgets as “Units of Work” are...
• Easier to build
• Easier to use
• Easier to reuse
60
60
Composite Application
Gadget
Ac)on
Context
Content
Gadget
Ac)on
Context
Content
Context
Gadget
Ac)on
Add’l Context
ContentContent
Ac)on
61
61
Example - Gmail
Google CommunicaAon ApplicaAon
Gmail
Communica)on
ContactsMail
Read WriteReply
Google Talk
IM
Read WriteReply
Presence
62
62
Demonstration• My FedEx 13 Project “Flapjack for Confluence”
63
63
Get Satisfaction
64
64
Gadgets?
Gadget? Gadget?
65
65
66
Gadget!
Gadget
Gadget
66
67
67
Get Satisfactionpowered by JIRA
68
68
Gadgets!
Gadget!
Gadget!
Gadget!
69
69
Feedback Tab on Different Website
70
70
Feedback on Google.com
71
71
Feedback on Google.com
72
72
Summary - Why write gadgets?
• Easy!
• Reusable!
• Fun!
73
73
• Email: [email protected]• Twitter: @halv0112
Questions?
74
Resources• http://www.atlassian.com/opensocial
• http://www.opensocial.org
74