Rally Kanban for Logged In Owner - rally

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.

Related

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); }

Show to be deleted items in popup window

I am using Odoo 10e. I want a simple functionality that whenever i wanted to delete one or more then one item from a list view or from a specific list view only. I want to show all of the items which are selected for deleted to show their name in popup window so that user can have a quick review what's he is going to delete. I know user can see details in list view but i want to give a glimpse to user in shape of model window that this is going to be deleted. Are you sure to delete ?
If user click Confirm then normal delete case should work.
As far i research and worked on it, i have idea that it should be something regarding overriding the do_delete method in the list_view.js in the web module. But i didn't know much about javascript overriding for Odoo.
This is an example how I do it.
I called the name_get for your model and records ids, this names list, I change the text of confirming message with the information of ids selected.
do_delete: function (ids) {
new Model(this.model)
.call('name_get', [ids, this.dataset.get_context()]).done(function (names) {
var text = _t("Do you really want to remove these records?") + ' '+ names.join(' \n')
if (!(ids.length && confirm(text))) {
return;
}
var self = this;
return $.when(this.dataset.unlink(ids)).done(function () {
_(ids).each(function (id) {
self.records.remove(self.records.get(id));
});
// Hide the table if there is no more record in the dataset
if (self.display_nocontent_helper()) {
self.no_result();
} else {
if (self.records.length && self.current_min === 1) {
// Reload the list view if we delete all the records of the first page
self.reload();
} else if (self.records.length && self.dataset.size() > 0) {
// Load previous page if the current one is empty
self.pager.previous();
}
// Reload the list view if we are not on the last page
if (self.current_min + self._limit - 1 < self.dataset.size()) {
self.reload();
}
}
self.update_pager(self.dataset);
self.compute_aggregates();
});
});;
},

How do I delete data in gun DB when path has multiple objects

How do I delete data when my path contains multiple objects? gun.path('saving_accounts').put(null) would delete all savings accounts.
Or, do you have a way to handle the null errors when iterating over data that has a 'deleted' object? I'm providing fully working examples to try to help in answering. Say I create gun data with this:
// localStorage.clear();
var gun = Gun();
////////////////////////////////////////////////////////////////// create record
var saving1 = gun.put({
name: "Bank of America",
accType: "Saving",
last4: "5555",
favorite: true,
status: true,
created: "some date created"
});
var saving2 = gun.put({
name: "Bank of America",
accType: "Saving",
last4: "4123",
favorite: true,
status: true,
created: "some date created"
});
var saving_accounts = gun.get('saving_accounts')
saving_accounts.set(saving1);
saving_accounts.set(saving2);
Then i can query all savings accounts with something like this:
const queryMultiple = (data_path) => {
console.log("Query for: " + data_path);
gun.get(data_path).map().val((name, ID) => {
// console.log(ID);
console.log(name.name, name.accType, ID);
});
};
queryMultiple('saving_accounts');
I tried to delete a record based on the gundb question here and wiki gun.path('object3').put(null) but I'm not sure how to change it for my application. On the savings account path, there are multiple savings accounts. So if i want to delete a specific savings account, i delete it by id but I think i'm doing it wrong. Say the id of the account i want to delete is FesxPaup8gzuNSsLFlWXMKaL:
// delete record
const deletebyID = (data_path, qID) => {
console.log("DELETE record");
gun.get(data_path).path(qID).put(null);
};
deletebyID('saving_accounts', 'FesxPaup8gzuNSsLFlWXMKaL');
But the .put(null) above will make the object FesxPaup8gzuNSsLFlWXMKaL point to null and when i list all savings accounts again with queryMultiple('saving_accounts'); I get a cannot read property name of null.
How do I delete data when my path contains multiple objects?
Side note: eventually i will nest multi transactions for a savings account under each savings account so I will have to do the same thing when deleting a account transaction that was made by mistake. Also hopefully when i delete a savings account, it automatically deletes/nulls all of that accounts transactions too but i haven't gotten past playing playing with data at this first layer.
#jtlindsey great question! You are correct though on how to delete data, even about how to delete an item inside a list/collection/table. But here is how to get the results you want:
Quick Solution:
Change your query to this:
const queryMultiple = (data_path) => {
console.log("Query for: " + data_path);
gun.get(data_path).map().val((name, ID) => {
if(!name){ return }
// console.log(ID);
console.log(name.name, name.accType, ID);
});
};
queryMultiple('saving_accounts');
And it will work. Why? Because it filters out any nulled account.
Why All the Nulls?
Deletes in GUN work like Mac OSX or Windows or Linux. The nulling tells every machine to "Put this data in the trash/recycle bin". The reason this is useful is because it lets you change your mind about deleting something, so you can recover it later if you want. (Recovering deleted content/files happens a LOT, but it something most people don't think about).
The null data also is useful for notifications! This is very applicable when you are designing frontend websites and you are rendering HTML. Let's go over a simple example:
Example
Imagine your user is checking the site on his phone, and realizes he needs to get clear up some issues that are a little bit more complicated so he logs on with his laptop. After checking the details on the laptop he decides to delete the account. Underneath his "click" action causes your run code to run:
// delete record
const deletebyID = (data_path, qID) => {
console.log("DELETE record");
gun.get(data_path).path(qID).put(null);
};
deletebyID('saving_accounts', 'FesxPaup8gzuNSsLFlWXMKaL');
Which is correct. However, if he then closes his laptop and picks his phone back up... he'll notice his account is still there!!! Which is not a good experience. But with GUN fixing this is easy because of the null notification:
gun.get(data_path).map().on((account, ID) => {
var UI = $("#account-" + ID);
if(!account){
UI.remove();
return;
}
updateUI(ID, account);
});
Now when they pick up their phone it will reflect the current state of their accounts! They'll see that it had been removed on all their devices because the null got synced to all devices.
Does that make sense? Does that your answer your question? Need help with anything else? As always, https://gitter.im/amark/gun and https://github.com/amark/gun/wiki/delete and http://gun.js.org/ .

extjs 4.1 how to reset the itemselector

I am using extjs 4.1.1a for developing some application.
I had a form consisting of two combo-boxes and an item-selector.
Based on the value selected in first combo-box , the itemselector will load its data from database. This is working fine.
My problem is, if i reselect the first combo-box the new data will be displayed in itemselector along with previous data displayed in itemseletor .That is previous data displayed in itemselector will remain there itself.
for example: name "test1" consists of ids 801,2088,5000. on selecting test1 in firstcombobox itemselector must show output as below.
and if "test2" consists of ids 6090,5040. on selecting test2 in firstcombobox itemselector must show output as below.
problem is. for first time if i select "test1" from firstcombobox , output will come as expected. if i reselect "test2" from firstcombobox , output will come as below.
as you can see, previous data displayed (marked in red rectagle) remains there itself with new data displayed (marked with green rectangle).
I want for every reselection of first combobox, previously displayed data in itemselector to be erased before printing new data on itemselector.
How can I reset the itemselector for every reselection of first combobox?
You should remove all items from the store of the itemselector by the removeAll command. After that you should load the store of the itemselector.
itemselector.store.removeAll();
itemselector.store.load();
Any solutions above solve my problem.
i found solution from Sencha Forum.
https://www.sencha.com/forum/showthread.php?142276-closed-Ext-JS-4.0.2a-itemselector-not-reloading-the-store
in the itemselector.js file, change the line marked below.
populateFromStore: function(store) {
var fromStore = this.fromField.store;
// Flag set when the fromStore has been loaded
this.fromStorePopulated = true;
// THIS LINE BELOW MUST BE CHANGED!!!!!!!!!!!!
fromStore.loadData(store.getRange()); //fromStore.add(store.getRange());
// setValue waits for the from Store to be loaded
fromStore.fireEvent('load', fromStore);
},
You need to insert...
this.reset();
at the head of the function that is inserting the data.
As an example...
Ext.override( Ext.ux.ItemSelector, {
setValue: function(val) {
this.reset();
if (!val) return;
val = val instanceof Array ? val : val.split(this.delimiter);
var rec, i, id;
for (i = 0; i < val.length; i++) {
var vf = this.fromMultiselect.valueField;
id = val[i];
idx = this.toMultiselect.view.store.findBy(function(record){
return record.data[vf] == id;
});
if (idx != -1) continue;
idx = this.fromMultiselect.view.store.findBy(function(record){
return record.data[vf] == id;
});
rec = this.fromMultiselect.view.store.getAt(idx);
if (rec) {
this.toMultiselect.view.store.add(rec);
this.fromMultiselect.view.store.remove(rec);
}
}
}
});
are u got it?
when u select that combobox frist stoe of item selector is null after store load with ur pass the para meters
for example
store.load(null),
store.proxey.url='jso.php?id='+combobox.getrawvalue(),
store.load();
like that so when ur select a value in ur combobox that time ur used a listeners to ur combobox in that listners ur used above code , select ur some value in combobox that time frist store is get null after ur pass some values to json.php then store load with responce so that time old data is remove and new data load in that store
if u post ur code i will give correct code
I ran into the same issue with ExtJS 4.2.1. I got it to work by calling reload() on the data store and then setValue() with an empty string on the item selector in the data store's reload() callback.
Ext.create("Ext.form.field.ComboBox", {
// Other properties removed for brevity
listeners: {
change: function(field, newValue, oldValue, eOpts) {
Ext.getStore("ExampleStore").reload({
callback: function() {
Ext.getCmp("ExampleItemSelector").setValue("");
}
});
}
}
});
Ext.create("Ext.data.Store", {
storeId: "ExampleStore",
// Other properties removed for brevity
});
Ext.create("Ext.form.FormPanel", {
// Other properties removed for brevity
items:[{
xtype: "itemselector",
id: "ExampleItemSelector",
// Other properties removed for brevity
}]
});
For any folks that are curious, I'm fairly convinced there's a bug in the item selector's populateFromStore() function. When the function is called, it blindly adds all of the values from the bound store (store) to the internal store (fromStore). I suspect there should be a call to fromStore.removeAll() prior to the call to fromStore.add(). Here's the relevant code from ItemSelector.js.
populateFromStore: function(store) {
var fromStore = this.fromField.store;
// Flag set when the fromStore has been loaded
this.fromStorePopulated = true;
fromStore.add(store.getRange());
// setValue waits for the from Store to be loaded
fromStore.fireEvent('load', fromStore);
},
EDIT 12/18/2013
If you've configured any callback events on the item selector (e.g. change), you may want to disable the events temporarily when you call setValue(""). For example:
var selector = Ext.getCmp("ExampleItemSelector");
selector.suspendEvents();
selector.setValue("");
selector.resumeEvents();
I had the same problem and finally I decided to modify the extjs source code, not considering it a big issue as extjs itself its saying in the start of the file
Note that this control will most likely remain as an example, and not as a core Ext form
control. However, the API will be changing in a future release and so should not yet be
treated as a final, stable API at this time.
Based on that, as jstricker guessed (and sadly I didn't read and took me a while to arrive to the same conclusion), adding fromStore.removeAll() before fromStore.add() solves the problem.
Outside of the problem (but I think it can be interesting as well), additionally, I also added listConfig: me.listConfig in the MultiSelect configuration (inside createList), that way it's possible to format each item additional options (such as images, etc.) setting in the 'itemselector' the option listConfig as it's explained in the (irrealistic) documentation.
Need to reset the store used in ItemSelector that can be done by setting Empty object like below. Also need to call clearValue() method of ItemSelector component.
store.setData({});
ItemSelectorComponent.clearValue();

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...