First off, I am new to Jira development, with that said I am trying to build a simple Jira plugin to display all projects and all issues inside each project. I am able to successfully display all projects directly from a velocity template like this:
<div class="aui-group">
#foreach ( $project in $projectManager.getProjectObjects() )
<div class="aui-item">
<h4>$project.getName() - $project.getId() <span>$projectManager.getCurrentCounterForProject($project.getId())</span></h4>
</div>
#end
</div>
However, I don't see anything in the documentation to get all issues inside a given project from the ProjectManager interface.
ProjectManager Docs
I would expect something like
$project.getIsses()
I do see under IssueManager interface documentation getIssueIdsForProject() So does this means that there is no easy way to get all issues on a given project from a velocity template, that I would have to create an endpoint to retrieve this using IssueManager interface by passing each project id as I loop? Please help. Code samples are welcome, as I mentioned I am new to Jira development and my Java is really rusty.
You will need to run a JQL query to get issues related to a known project. You can get JSON output which will allow you to do some post-processing, but there does not appear to be a simple way of getting this information without using the API or JQL.
I was not aware there is Rest API which I can leverage from the javascript :)
https://docs.atlassian.com/jira-software/REST/cloud/
So I did this:
AJS.$.ajax({
url: "/jira/rest/api/2/project",
type: "GET",
dataType: "json",
success: function (projects) {
AJS.$.each(projects, function (index, project) {
getProjectIssues(project);
});
}
});
var getProjectIssues = function (project) {
var pKey = project.key;
AJS.$.ajax({
url: "/jira/rest/api/2/search?jql=project=" + pKey,
type: "GET",
dataType: "json",
success: function (results) {
console.log('results ', results);
}
});
};
Related
I'm wondering how to use the Asana APIs to send the command to complete a task.
I was trying something like:
https://app.asana.com/api/1.0/tasks/417207316735809/?opt_pretty&completed=true
but it doesn't work like that, I've checked the documentation, but couldn't find an answer.
Asana doc (someone requested it in comments): https://asana.com/developers/documentation/getting-started/input-output-options
Since I want to use it in my chrome extension I can't use curl so I treid ajax:
$.ajax({
type : "GET",
url : "https://app.asana.com/api/1.0/tasks/417207316174232/?opt_pretty",
data: {
completed: true,
},
success : function(result) {
result = JSON.stringify(result);
alert(result);
},
error : function(result) {
alert('xxx');
}
});
Any idea how to pass "completed=true" from doc in js?
If you are updating a resource you need to make a PUT request, not a GET request.
When I made this change, your AJAX request worked.
I am looking to create a file on the fly and offer a download link to the user in a GRAILS application.
I followed the approach from here. I have no errors however it doesn't seem to work. Here's my controller code.
`render (file: pptFile, fileName:'someppt.pptx', contentType: 'application/octet-stream')
Client side code makes an AJAX call to retrieve the file from server. It does not cause the server to force downloading of the file on the client (browser). Here's the client side code.
$.ajax({
type : 'POST',
url : '<<URL>>',
success: function(result) {
var uri = 'data:application/octet-stream;charset=UTF-8,' +
encodeURIComponent(result);
window.open(uri, 'somePPT.pptx');
},
failure: function(){
alert ('failure')
}
});
Perhaps something akin to this (paraphrased, but used for downloading a json file):
def someControllerMethod() {
def dlContent = someService.marshalJson()
def contentType = "application/octet-stream"
def filename = "someFilename.json"
response.setHeader("Content-Disposition", "attachment;filename=${filename}")
render(contentType: contentType, text: dlContent as JSON)
}
okay. So I finally got this to work. As proposed by #railsdog and many others (This problem has been discussed on other threads in stackoverflow but the specific case I had was slightly different from those) I ended up writing to response directly from server and took out the AJAX call. The only reason I was doing an AJAX call was because I did not want to submit the current page that had the "generate file" functionality (There are many data elements on the page and I did not want to re-do the entire page just for downloading the file). So I ended up using an anchor tag with target as "_blank". Here's the code snippet
<a href="myControllerMethodToGenerateFileAndWriteToHTTPResponseDirectlyAsSuggestedByOthersInThisPost"
target="_blank"/>
This actually opened a new page and did the submission to initiate the download. Problem solved. It's working fine in CHROME. :) Thanks guys!
I like the solution using the render method from #railsdog !
A slightly other approach which I used so far was:
def controllerMethod() {
...
File file = sepaXmlService.createTransfersFile(...)
response.setContentType("application/xml")
response.setHeader("Content-disposition", "attachment;filename=${file.getName()}")
OutputStream out = response.getOutputStream()
out.write(file.bytes)
out.close()
file.delete()
return
...
}
In the view I use the following statement in the form:
<g:actionSubmit action="controllerMethod" class="btn" value="Get XML!" /></td>
I think it should also be possible to use a
<g:link controller="foobar" action="controllerMethod" class="btn">GetXML</g:link>
This is a question about best practices for making the JavaScript call that generates the standard "Connect to QuickBooks" button (for establishing a connection to QuickBooks Harmony via Intuit's v3 REST API).
If I follow Intuit's example, I would:
Reference https://appcenter.intuit.com/Content/IA/intuit.ipp.anywhere.js in a script tag.
Place the <ipp:connectToIntuit></ipp:connectToIntuit> tagset where I want the "Connect to QuickBooks" button to display
Cross my fingers and hope that intuit.ipp.anywhere.js isn't redirecting to a downtime message, again still exists
Make my call to intuit.ipp.anywhere.setup()
See the "Connect to QuickBooks" button
... which works (for many values of "works"), but feels pretty fragile:
If intuit.ipp.anywhere.js is redirecting to a downtime message (read: not JavaScript) or is otherwise unavailable, I'll get a script error.
If I get a script error (or something else goes wrong with Intuit's copy of the script), there isn't any feedback to the user, just a blank space where the "Connect to QuickBooks" button should be.
To make this all a little more resilient, I'm combining the reference to intuit.ipp.anywhere.js and the call to intuit.ipp.anywhere.setup() into a JQuery .ajax() call:
$.ajax({
url: 'https://appcenter.intuit.com/Content/IA/intuit.ipp.anywhere.js',
type: 'GET',
dataType: 'script',
timeout: 4000,
success: function(response) {
if (typeof intuit !== 'undefined') {
intuit.ipp.anywhere.setup({
menuProxy: 'MYMENUPROXYURL.aspx',
grantUrl: 'MYGRANTURL.aspx'
});
}
},
error: function(x, t, m) {
// show some friendly error message about Intuit downtime
}
});
... which also works (for a few more values of "works"):
My call to setup() is wrapped inside the success handler (and an additional check on the existence of the intuit Object), so I shouldn't get a script error if things go wrong.
If the GET of Intuit's script times out (after 4000ms) or returns something that isn't script, I'll show a friendly error message to the user.
Has anyone else taken a different approach?
And is Intuit back online?
That's similar to how we've handled it. We had wrapped it in jQuery.getScript call, but apparently the .fail handler doesn't work with cross domain script tags. Our solution is as follows:
<script type="text/javascript>
var timeoutID;
timeoutID = window.setTimeout(function () {
$("#ippConnectToIntuit").replaceWith('<p class="error-message">There was a problem communicating with QuickBooks. The service may be down or in heavy use. Try again later.</p>');
}, 5000);
$.getScript("https://appcenter.intuit.com/Content/IA/intuit.ipp.anywhere.js")
.done(function () {
window.clearTimeout(timeoutID);
intuit.ipp.anywhere.setup({
menuProxy: '/path/to/our/menu/proxy',
grantUrl: '/path/to/our/grant/url'
});
});
</script>
<div id="ippConnectToIntuit"><ipp:connecttointuit></ipp:connecttointuit></div>
I have a Durandal/Hot Towel test app I'm trying to wire up. I have the below ajax call but I'm getting a 404 error.
GET http/.../api/Pizza/GetPizzasByOrderId?%22a8926610-a713-494c-bb15-46f6487a01c7%22 404 (Not Found)
I can manually change the url to:
http/.../api/GetPizzasByOrderId?orderId=a8926610-a713-494c-bb15-46f6487a01c7
It works. But I would like to know why the other call isn't working or more so, why is the ajax messing the parameter up in the URL and not as data like it does with complex objects. I have a get and a save that is working just fine. The get has zero params and the save is passing a complex object in.
C# Web Api Controller:
public class PizzaController : ApiController
{
[HttpGet]
public IEnumerable<Pizza> GetPizzasByOrderId(Guid orderId)
{
return DATA.GetPizzasByOrderId(orderId);
}
}
JAVASCRIPT:
var dataCall = $.ajax(config.getPizzasByOrderIdUrl, {
data: ko.toJSON(orderId),
type: "get",
contentType: "application/json"
});
Should I just change my JavaScript code to the below and be done with it or is there a better way to talk to the Api?
var getPizzasByOrderId = function (orderId) {
return Q.when($.getJSON(config.getPizzasByOrderIdUrl + "?orderId=" + orderId));
};
You could either use the code as you have it in that last code block, or you could pass in an object in place of your orderId as in the code block below. Either way, the difference is that the orderId parameter is being named.
var dataCall = $.ajax({
url: config.getPizzasByOrderIdUrl,
type: "GET",
data: {orderId : orderId},
});
In regard to why $.ajax() works fine for your POST, you can check this out pretty easily by running these two bits of code and viewing the requests that go across the wire. I recommend using google chrome.
Load a page that has jQuery loaded
Open the developer tools and go to the console
Enter the following code snippet
$.ajax("", {
data: {orderId: 123},
type: "get",
contentType: "application/json"
});
Switch to the network tab and click on the one that ends in ?orderId=123
Notice that it does have the data appended as query string parameters
In the snippet above, replace the "get" with "post"
After you hit enter, you should see another request on the network tab of the developer tools.
Notice that when changing nothing but the request type, the data is moved from the query string to the body. As noted in the comments, WebApi will pull from the body of the request and use the model binder to populate the complex object.
How to configure the Kendo UI grid, so it would issue requests only for specific (displayed) fields?
In my instance, a Kendo UI grid is bound to a OData service. The service exposes a table with many (200+) fields. The app allows users to configure displayed field set of the Grid, set initial filters and sort parameters. The app configures the Grid, which then goes off and queries OData service.
The grid kendo.Data.DataSource is defined as:
var gridDataSource = new kendo.data.DataSource({
type: "odata",
transport: {
read: {
url: "#Url.Content(dynDataSource.Url)",
contentType: "application/json; charset=utf-8",
type: "GET",
dataType: "json"
}
},
pageSize: #Model.MaxPageSize,
serverPaging: true,
serverFiltering: true,
serverSorting: true,
filter: ...
}
Here's a sample request issued by the Grid (captured by Firebug):
http://localhost:22411/Data/Comp?%24inlinecount=allpages&%24top=1000&%24filter=DistrictCode+eq+%27460800%27
This returns all the fields of the table, which is a problem. The fields need to be limited by selecting only the required fields, the request for which would look like:
http://localhost:22411/Data/Comp?%24inlinecount=allpages&%24top=1000&%24filter=DistrictCode+eq+%27460800%27&%24select=DistrictCode,DistrictName,DistrictNumber
Again, how to configure the grid for this to happen?
I realize the source is available for Kendo UI, but I'm currently still on a trial version which doesn't include the source.
I think I've got a workable solution for this myself. I used an idea from this blog post:
http://community.dynamics.com/product/crm/crmtechnical/b/zhongchenzhoustipstricksandportaldevelopment/archive/2012/05/20/how-to-use-kendo-ui-datasource-kendo-ui-grid-with-dynamics-crm-2011-rest-endpoint.aspx
I attach an event handler the ajaxSend event, watch for my OData Service URL, and once such a request is detected, append the select column list to the URL. Here's the code:
$(document).ajaxSend(function (e, jqxhr, settings) {
if (settings.url.toLowerCase().indexOf("#Url.Content(dynDataSource.Url)".toLowerCase()) >= 0) {
settings.url += "&%24select=#requestColumnList";
}
});
Hope this helps. Still, if someone has got a better solution, I'd like to hear it.
I've also posted this question to Telerik forums: http://www.kendoui.com/forums/framework/data-source/configure-the-kendo-ui-datasource-so-it-would-issue-requests-only-for-specific-displayed-fields.aspx#2131604
I ran into a similar issue and implemented an approach that constructs an array of included columns in the transport's read data callback:
dataSource.transport.read.data = function(options) {
var data = {};
data["$select"] = columns.map(function(c) {
return c.field;
});
return data;
}
If you are using column menu and have hidden columns, you can also filter based on which columns are visible and force a grid refresh as columns are enabled.
columnShow: function (e) {
e.sender.dataSource.read();
}