Send Mail to a user if count of open issues greater a specific limit - youtrack

how could i create a workflow which on every change of the current issue user checks the total amount of open issues for this user and if the amount is greater then lets say 5 the user gets a mail with a little warning message?
I guess this here is close to my topic, but only close:
https://youtrack-support.jetbrains.com/hc/en-us/community/posts/206582955-How-to-count-user-s-issues-
All our users have a mail in youtrack, the workflow should only work for one usergroup/project however.
Thank you and best regards

The How to count user's issues? illustrates the approach that valid for old workflow.
For the new JavaScript workflow, I suggest you use the search method for getting all open issues assigned to the required user. Then, you can use the user.notify method to send an email to this user.
You can find common information about JavaScript workflow in the JavaScript Workflow Quick Start Guide article. I hope this helps.
Here is an example that illustrates how to send a message with the assigned issues count to the user:
var entities = require('#jetbrains/youtrack-scripting-api/entities');
var search = require('#jetbrains/youtrack-scripting-api/search');
exports.rule = entities.Issue.onChange({
title: 'Assignee count',
guard: function(ctx) {
return ctx.issue.isChanged(ctx.Assignee) && ctx.issue.fields.Assignee;
},
action: function(ctx) {
var issue = ctx.issue;
var user = issue.fields.Assignee;
var query = 'for: ' + user.login + ' #Unresolved';
var assignedToUser = search.search(issue.project, query, ctx.currentUser);
var count = assignedToUser.size;
var subj = 'Attention!';
var body = 'You have ' + count + ' assigned issues';
user.notify(subj, body);
},
requirements: {
Assignee: {
type: entities.User.fieldType
}
}
});

Related

Mark a search unrestricted in suitescript 2.0

I am using a restlet to check whether a contact exist in netsuite or not. I am calling this restlet from an external environment. The problem I'm facing is the search should be marked unrestricted in order to get results otherwise its returning nothing. How should I mark the search unrestricted? This is my code
var result = search.create({
type : record.Type.CONTACT,
filters:['email','IS',contact_mail],
ispublic : true,
unrestricted: true,
columns: ['email']
}).run().getRange({
start: 0,
end: 1
});
Can someone help me with this!
You can create the contact saved search in the UI without any filters and mark it as unrestricted.
In your script, load the search with search.load, and then add the the email filter to the search before running it.
var searchObj = search.load({
type: record.Type.CONTACT,
id: customsearch_contact_search
});
searchObj.filters.push(['email','IS',contact_mail]);
var result = searchObj.run().getRange({start:0, end:1});

lucene query filter not working

I am using this filter hook in my Auth0 Delegated Administration Extension.
function(ctx, callback) {
// Get the company from the current user's metadata.
var company = ctx.request.user.app_metadata && ctx.request.user.app_metadata.company;
if (!company || !company.length) {
return callback(new Error('The current user is not part of any company.'));
}
// The GREEN company can see all users.
if (company === 'GREEN') {
return callback();
}
// Return the lucene query.
return callback(null, 'app_metadata.company:"' + company + '"');
}
When user logged in whose company is GREEN can see all users. But when user logged in whose company is RED can't see any users whose company is RED.
I need to make this when user logged in, user should only be able to access users within his company. (except users from GREEN company).
But above code is not giving expected result. What could be the issue?
This might be related to a little warning note on the User Search documentation page
Basically they don't let you search for properties in the app_metadata field anymore. Unfortunately, this change was breaking and unannounced.
We had to make changes to our API so that we keep a copy of the app_metadatas in a separate database and convert lucene syntax to MongoDB queries, so that we can query by a chain of user_id:"<>" OR user_id:"<>" OR ....
One caveat though, you can't pass a query that's longer than 72 user_ids long. This number is so far undocumented and obtained empirically.
Also, you can't rely on Auth0's hooks to add new users to your database, as these don't fire for social logins, only for Username-Password-Authentication connections.
I hope this gave you some explanation as for why it wasn't working as well as a possible solution.
If I were you, I would look for an alternative for Auth0, which is what we are currently doing.
I finally ended up with this solution.
Used search functionality to filter users. I had to change below two files.
fetchUsers function in client\actions\user.js
changed
export function fetchUsers(search = '', reset = false, page = 0)
to
export function fetchUsers(search = '#red.com', reset = false,
page = 0)
AND
onReset function in client\containers\Users\Users.jsx
changed
onReset = () => { this.props.fetchUsers('', true); }
to
onReset = () => { this.props.fetchUsers('#red.com', true); }

WL.download with multiple files (OneDrive API)

I'm trying to implement a OneDrive picker. The user can select his files and then, when saving, i can get these files and download them.
I follow the OneDrive API Documentation, and i get this :
WL.init({ client_id: clientId, redirect_uri: redirectUri });
WL.login({ "scope": "wl.skydrive wl.signin" }).then(
function(response) {
openFromSkyDrive();
},
function(response) {
log("Failed to authenticate.");
}
);
function openFromSkyDrive() {
WL.fileDialog({
mode: 'open',
select: 'single'
}).then(
function(response) {
log("The following file is being downloaded:");
log("");
var files = response.data.files;
for (var i = 0; i < files.length; i++) {
var file = files[i];
log(file.name);
WL.download({ "path": file.id + "/content" });
}
},
function(errorResponse) {
log("WL.fileDialog errorResponse = " + JSON.stringify(errorResponse));
}
);
}
function log(message) {
var child = document.createTextNode(message);
var parent = document.getElementById('JsOutputDiv') || document.body;
parent.appendChild(child);
parent.appendChild(document.createElement("br"));
}
In the select options, you can set 'single' or 'multi' to permit to the user to select one or more files from the picker.
But when i try to set 'multi', the WL.download method only work for the last file.
Thanks for help !
ps: i didn't found real solution on stackoverflow or any forum
This is a quirk with the WL.Download() function. It creates a hidden iframe to execute the download, but it uses the same iframe for all the downloads it does. So if you queue up two downloads in quick succession, it will navigate the iframe twice and you'll only end up actually downloading the last file. WL.Download() does not expose when a download is complete, so you can't simply wait for one to finish before starting the next.
Unfortunately, the code sample is a bit misleading, putting the WL.Download() calls in a for-loop. We've taken note of these issues.
In the meantime, to unblock yourself, you can get the download URL from the 'file.source' property and initiate the download yourself.

Rally Kanban for Logged In Owner

I'm new to Rally's SDK. I'm trying to create a Kanban board that only shows the cards where the owner field = the person who's logged in (i.e. a My Kanban Board). What code should I add and where should I add it?
The following isn't my ideal answer to this issue, but I'd thought I'd post in case it helps someone else. I took the code from the Filter Epic post as suggested and modified it. It's not ideal for me because the filter occurs after the initial data pull, so it is only filtering the first 100 records the initial query pulled. Ideally, I want to change the initial pull of data to filter on username.
After this code in the Filtering Epic:
for (i=0;i<workproducts.length;i++) {
thisWorkProduct = workproducts[i];
Add:
//get the owner field value
var owner = "";
if (thisWorkProduct.Owner) {
if (thisWorkProduct.Owner.DisplayName) {
owner = thisWorkProduct.Owner.DisplayName;
}
else if (thisWorkProduct.Owner.UserName) {
owner = thisWorkProduct.Owner.UserName;
}
}
And then change:
if (thisWorkProduct.Children.length === 0) {
To:
if ((thisWorkProduct.Children.length === 0) && (owner === "__USER_NAME__")) {
And add in an if in the defects else (so it will now look like this):
else {
// If it's a Defect, it has no children so push it
if (owner === "__USER_NAME__") {
childlessWorkProducts.push(thisWorkProduct);
}
It's probably not the most efficient code because I'm new to javascript.
And if anyone has suggestions on how to do the username filter in the initial data pull, I'd love to hear them.
You can filter on the initial data pull by including a query in the cardboardConfig object:
var cardboardConfig = {
//... other properties
query: new rally.sdk.util.Query('Owner = /user/__USER_OID__')
};
Check out this answer:
Filtering epics from Kanban board
It would be pretty straightforward to adapt the filtering callback to filter by Owner instead of just child-less artifacts.

Dojo: Can't update drop down list after adding a new group

I've been playing around with IBM's tutorial at this link.
http://www.ibm.com/developerworks/web/tutorials/wa-dojotoolkit/section6.html
I've done very well so far, but I can't seem to get the drop down list to populate the new group entry. Even the original code isn't working.
//Refresh the data store for the groups dropdown (in case groups added, edited or deleted)
function refreshGroupDropDown() {
var theStore = dijit.byId("edit_contact_group").store;
theStore.close();
theStore.url = "data/groups.php";
theStore.fetch();
}
Thanks!
Update: Still having trouble. I tried this below and still nothing. The function refreshGroupDropDown() is called when the user opens the edit contact windows or new contact window.
//Refresh the data store for the groups dropdown (in case groups added, edited or deleted)
function refreshGroupDropDown() {
var new_store = new ItemFileReadStore({url: 'data/groups.php' , clearOnClose: true});
var theStore = dijit.byId("edit_contact_group");
theStore.store = new_store;
theStore.close();
theStore.fetch();
}
//Clears the "Edit Contact" form, sets it up for adding a new contact
function newContact() {
var contact = contactsGrid.selection.getSelected()[0];
refreshGroupDropDown();
dojo.byId("edit_contact_real_id").value = "";
dojo.byId("edit_contact_id").value = "[NEW]";
dijit.byId("edit_contact_group").reset();
dijit.byId("edit_contact_first_name").reset();
dijit.byId("edit_contact_last_name").reset();
dijit.byId("edit_contact_email_address").reset();
dijit.byId("edit_contact_home_phone").reset();
dijit.byId("edit_contact_work_phone").reset();
dijit.byId("editContactDialog").set("title", "New Contact");
dijit.byId("editContactDialog").show();
}
//Process the adding of a new group to the database
function doNewGroup(e) {
e.preventDefault();
e.stopPropagation();
dojo.byId("new_group_ajax").value = "1";
if(this.isValid()) {
dojo.xhrPost({
form: this.domNode,
handleAs: "json",
load: function(data) {
if(data.success) {
okDialog.set("title","Group created successfully");
okDialogMsg.innerHTML = "The group <strong>"+data.name+"</strong> was created successfully.";
groupsStore.newItem({"id":data.id.toString(),"name":data.name}, {"parent": groupsModel.root, "attribute":"groups"});
groupsStore.save();
newGroupDialog.hide();
okDialog.show();
}
else {
okDialog.set("title","Error creating group");
okDialogMsg.innerHTML = data.error;
okDialog.show();
}
},
error: function(error) {
okDialog.set("title","Error creating group");
okDialogMsg.innerHTML = error;
okDialog.show();
}
});
}
}
Hopefully this helps! I'm a beginner so any help is appreciated.
I figured it out! The issue was with the index.html. The input tag for the groups drop-down list looks like this
<input dojoType="dijit.form.FilteringSelect" name="move_contact_new" store="groupsStore" searchAttr="name" query="{type:'node'}" id="move_contact_new" required="true" style="margin-bottom: 6px" />
The query attribute was never set correctly. Once I deleted query="{type:'node'}" the groups re-populate after adding, editing, or deleting groups.
A beginner answer for a beginner question.
Hope this can help any beginners out there.
Based on what you've posted, the only problem I see is with the line var theStore = dijit.byId("edit_contact_group").store;because it doesn't acutally create a dataStore. You need to make sure you also include something like `var edit_contact_group = new dojo.data.ItemFileReadStore();or an equivalent. Othewise, have you connected the refreshGroupDropDown() function to the appropriated event ('onclick' or whatever) using dojo.connect()? Have you loaded the function refreshGroupDropDown() using dojo.ready? ie. dojo.ready(function(){refreshGroupDropDown();});Those are always the first things that come to mind...