I'm displaying a link to a defect in a Rally Grid in the simple way:
columnCfgs: ['FormattedID', 'Name', ...]
This creates a link to the defect, just like it should. But the column width is way too big. But if I do the following, I loose the link:
columnCfgs: [{dataIndex: 'FormattedID', width: 50, text:'ID'}', 'Name', ...]
Is there a convenient xtype I can use to adjust the width, but still have a link to my defect?
Unfortunately there is not an easy way to do this right now. We are going to fix this before we GA the SDK 2.0. For now here is a workaround:
Ext.define('DefectGridApp', {
extend: 'Rally.app.App',
launch: function() {
Rally.data.ModelFactory.getModel({
type: 'Defect',
success: function(model) {
//Get the default field config
var field = model.getField('FormattedID');
var fieldConfig = Rally.ui.grid.FieldColumnFactory.getColumnConfigFromField(field);
//Override with your values
fieldConfig.width = 10;
this.grid = this.add({
xtype: 'rallygrid',
model: model,
columnCfgs: [
fieldConfig, //pass your overridden formatted id field here
'Name',
'Owner'
]
});
},
scope: this
});
}
});
For a slightly differnt solution see: this question for how to add the link back to your original try.
Related
I'm creating an overview of features and their feature dependencies (not user stories).
I'm fetching the wsapi store filtered on release in step 1 and in step 2 I'm fetching the predecessor and successor collections in order to display their values.
I would like to use this wsapi store directly in a grid, but when performing an onScopeChange (release filtered app) the rendering of the grid happens before my loading of predecessor + successor collections. Thus, I'm trying to store the data in a custom.store to use in the grid - so far so good.
My issue is that I need to do all (most) formatting in the grid on my own. I'm setting the custom store model to PortfolioItem/Feature and would expect this to be used on the grid, but it just doesn't. Is this possible? If so, what am I doing wrong?
Custom store
_getViewStore: function () {
var me = this;
/*
Extract data from featureStore
*/
var records = me.myFeatureStore.getRecords();
/*
Create new, update, store for adding into grid
*/
if (!me.myViewStore) {
me.myViewStore = Ext.create('Rally.data.custom.Store', {
model: 'PortfolioItem/Feature',
data: records,
});
} else {
me.myViewStore.removeAll();
me.myViewStore.add(records);
}
},
Grid
_createGrid: function () {
var me = this;
me.myGrid = Ext.create('Ext.Container', {
items: [{
xtype: 'rallygrid',
store: me.myViewStore,
columnCfgs: [{
xtype: 'gridcolumn',
align: 'left',
tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate'),
text: 'Predecessors',
dataIndex: 'Predecessors',
width: 200,
renderer: function (value, metaData, record) {
var mFieldOutputPre = '';
var records = record.predecessorStore.getRecords();
_.each(records, function (feature) {
mFieldOutputPre += Rally.nav.DetailLink.getLink({
record: feature,
text: feature.get('FormattedID'),
showTooltip: true
});
// Add the feature name and a line break.
mFieldOutputPre += ' - ' + feature.get('Name') + '<br>';
}); //_.each
return mFieldOutputPre;
},
},
{
text: 'FormattedID',
dataIndex: 'FormattedID',
xtype: 'templatecolumn',
tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate')
},
{
text: 'Name',
dataIndex: 'Name',
flex: 1
},
{
text: 'Release',
dataIndex: 'Release',
flex: 1
},
{
text: 'State',
dataIndex: 'State',
flex: 1
},
{ // Column 'Successors'
xtype: 'templatecolumn',
align: 'left',
tpl: Ext.create('Rally.ui.renderer.template.FormattedIDTemplate'),
text: 'Successors',
dataIndex: 'Successors',
width: 200,
renderer: function (value, metaData, record) {
var mFieldOutputSuc = '';
var records = record.successorStore.getRecords();
_.each(records, function (feature) {
//console.log('feature = ', feature);
mFieldOutputSuc += Rally.nav.DetailLink.getLink({
record: feature,
text: feature.get('FormattedID'),
showTooltip: true
});
// Add the feature name and a line break.
mFieldOutputSuc += ' - ' + feature.get('Name') + '<br>';
});
return mFieldOutputSuc;
},
}
]
}],
renderTo: Ext.getBody()
});
me.add(me.myGrid);
}
The Release + State fields does not display data correct when using my custom store, but if I use my wsapi (feature) store that are formatted correctly.
Thank you in advance
I'd probably load all the stores first and then add the rallygrid configured with your already loaded feature store. Then you don't have to worry about the timing issues. I'm guessing you already found this example in the docs for loading the child collections?
https://help.rallydev.com/apps/2.1/doc/#!/guide/collections_in_v2-section-collection-fetching
This example is also pretty helpful, as it shows how to load hierarchical data much like you're doing, and uses promises to help manage all of that and then do something when everything has finished loading:
https://help.rallydev.com/apps/2.1/doc/#!/guide/promises-section-retrieving-hierarchical-data
I am trying to get the label for the combobox to show correctly in the example below. I am trying to get it to work in Sencha Fiddle. The text if too long, is getting truncated.
Ext.application({
name : 'Fiddle',
launch : function() {
// The data store containing the list of states
var states = Ext.create('Ext.data.Store', {
fields: ['abbr', 'name'],
data : [
{"abbr":"AL", "name":"Alabama"},
{"abbr":"AK", "name":"Alaska"},
{"abbr":"AZ", "name":"Arizona"}
//...
]
});
// Create the combo box, attached to the states data store
Ext.create('Ext.form.ComboBox', {
fieldLabel: 'Reaaaaaaaaaaaaaaallllllllly long',
fieldlabelStyle: 'width:600px',//doesn't do anything
store: states,
queryMode: 'local',
displayField: 'name',
valueField: 'abbr',
renderTo: Ext.getBody()
});
}
});
Try with labelStyle
Ext.application({
name : 'Fiddle',
launch : function() {
// The data store containing the list of states
var states = Ext.create('Ext.data.Store', {
fields: ['abbr', 'name'],
data : [
{"abbr":"AL", "name":"Alabama"},
{"abbr":"AK", "name":"Alaska"},
{"abbr":"AZ", "name":"Arizona"}
//...
]
});
// Create the combo box, attached to the states data store
Ext.create('Ext.form.ComboBox', {
fieldLabel: 'Reaaaaaaaaaaaaaaallllllllly long',
labelStyle: 'width:600px',
//fieldlabelStyle: 'width:600px',//doesn't do anything
store: states,
queryMode: 'local',
displayField: 'name',
valueField: 'abbr',
renderTo: Ext.getBody()
});
}
});
Use labelWidth: config for this. Define like this
labelWidth: '60%',
I'm currently working with comboboxes and filters to implement an option to select all instances of a desired field. With that said, I know to use the noEntryText attribute to set what originally defaults to "--No Entry--" as "All". However, the changes do not seem to apply when I use this on custom fields provided by my Web Services API (those fields with the "c_" before them).
Strangely enough though, this convention works for other fields that I use that do not have the "c_" before them. So is this a known defect just for custom fields or is there a workaround to this issue?
I filed a defect that replacing noEntryText to a custom value works for rallyfieldvaluecombobox for standard fields, but not custom fields.
If rallyfieldvaluecombobox uses a standard field, e.g. Environment, then no entry can be replaced successfully:
Here is the js file:
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
this.add({
xtype: 'rallyfieldvaluecombobox',
itemId: 'aBox',
fieldLabel: 'Filter by filed:',
model: 'defect',
//field: 'c_CustomBox',
field: 'Environment',
noEntryText: 'All',
useNullForNoEntryValue: true,
allowNoEntry: true,
listeners: {
select: this._onSelect,
ready: this._onLoad,
scope: this
}
});
},
_onLoad: function() {
this.add({
xtype: 'rallygrid',
columnCfgs: [
'FormattedID',
'Name',
//'c_CustomBox'
'Environment'
],
context: this.getContext(),
storeConfig: {
model: 'defect',
filters: [this._getStateFilter()]
},
width: 500
});
},
_getStateFilter: function() {
if (!this.down('#aBox').getValue()) {
return 1;
}
else{
return {
//property: 'c_CustomBox',
property: 'Environment',
operator: '=',
value: this.down('#aBox').getValue()
};
}
},
_onSelect: function() {
var grid = this.down('rallygrid'),
store = grid.getStore();
store.clearFilter(true);
store.filter(this._getStateFilter());
}
});
If the same rallyfieldvaluecombobox uses a custom field, then no entry string cannot be replaced:
In both cases the functionality of replacing the filtering behavior works fine.
I have a few custom fields on my portfolio item such as c_TrafficLightCost. but when I pass it in the fetch, to create my grid, it doesn't create a columns with the value of the custom field.
Here is my code:
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
console.log('Our First App woot!');
this._loadData();
},
// Get data from Rally
_loadData: function() {
var myStore = Ext.create('Rally.data.wsapi.Store', {
model: 'portfolioitem/deliverable',
autoLoad: true,
listeners: {
load: function(myStore, myData, success) {
console.log('got data!', myStore, myData, success);
this._loadGrid(myStore);
},
scope: this
},
fetch: ['FormattedID', 'Name', 'c_TrafficLightCost' ]
});
},
// Create and Show a Grid of given stories
_loadGrid: function(myStoryStore) {
var myGrid = Ext.create('Rally.ui.grid.Grid', {
store: myStoryStore,
columnCfgs: [
'FormattedID', 'Name', 'c_TrafficLightCost'
]
});
this.add(myGrid);
console.log('what is this?', this);
console.log(this.c_TrafficLightCost);
}
});
What I want is for the traffic light to be a column in the grid
Can anyone help me?
Thanks.
Best regards Martin
Remove c_ in front of the custom field name. Try TrafficLightCost and see if that does it. I confirmed that the code posted in this git hub repo does not show values for custom fields (the column is empty) when c_ is prepended to the field name. I think this is a defect.
Using the 2.0p4 JavaScript SDK, I am trying to recreate a grid app I created previously using 1.30 JavaScript SDK, and am having problems creating a complex filter (with multiple ANDs and ORs).
Here is the query from the 1.30 version:
function itemQuery() {
var queryObject = {
key: 'defect',
type: 'defect',
fetch: 'FormattedID,Name,State,ScheduleState,SupportNumber,OpenedDate,Priority,Rank,Severity,SubmittedBy,Owner,Iteration,Release,Project',
query: '(((((SupportNumber contains "RNT") OR (SupportNumber contains "NS")) OR (SupportNumber contains ":")) OR (SupportNumber contains "CASE")) AND (State != Closed))',
project: null
};
So I querying for items that contains "RNT", ":", "NS", or "CASE" AND are not closed.
(SupportNumber is a custom field, which people have entered data in differently at different points)
And here is my App.js from the new version I am trying to create:
Ext.define('CustomApp', {
extend: 'Rally.app.App',
componentCls: 'app',
launch: function() {
Rally.data.ModelFactory.getModel({
type: 'Defect',
context: {
workspace: 'workspace/12345',
project: null,
},
success: function(model) {
this.grid = this.add({
xtype: 'rallygrid',
model: model,
columnCfgs: [
'FormattedID',
'Name',
'SupportNumber',
'Priority',
'Severity',
'State',
'Iteration',
'Release',
'Project',
'Owner',
'SubmittedBy'
],
storeConfig: {
filters: [
{
property: 'State',
operator: '!=',
value: 'Closed'
},
{
property: 'SupportNumber',
operator: 'contains',
value: 'RNT'
}
]
}
});
},
scope: this
});
}
});
I can see that just by adding filters to the config, you create ANDs, however I am lost in the documentation with how to create ANDs and ORs filters in the same config.....
Any direction anyone can give on how to create filter configs for App SDK 2.0, that use multiple ANDs and ORs, would be greatly appreciated.
Check out:
Rally.data.QueryFilter
Along with this Stackoverflow Answer:
Rally App SDK 2.0: Cannot modify QueryFilter object after initial creation
Which shows a nice example of using Rally.data.QueryFilter to prepare an array of filters representing multiple conditions.