DOJO how to Add title to TableContainer - dojo

Programmatically developing a TableContainer. All the child information and properties of TableContainer are fetched from a JSON file. In the client javascript code, we process this inoformation to prepare the TableContainer.
Planned to use TableContainer label as the Header for that container, but failed , as the container label is placed in the center of the first column as shown in the screenshot-1
I am expecting the headers to appear as in the screenshot-2
FYI, I have many tablecontainers placed in Root Table container where each table container should have a header
Following is the json:
"element":[
{
"type":"container",
"propertylist":{
"property":[
{
"name":"label",
"value":"Common Parameters"
},
{
"name":"id",
"value":"commonParams"
}
]
},
"element":[
{
"type":"textfield",
"propertylist":{
"property":[
{
"name":"label",
"value":"Profile Name"
},
{
"name":"id",
"value":"profileName"
}
]
}
},
{
"type":"textfield",
"propertylist":{
"property":[
{
"name":"label",
"value":"Description"
},
{
"name":"id",
"value":"description"
}
]
}
},
{
"type":"checkbox",
"propertylist":{
"property":[
{
"name":"label",
"value":"Dual-ended"
},
{
"name":"checked",
"value":false
},
{
"name":"id",
"value":"dualEnded"
}
]
}
},
{
"type":"checkbox",
"propertylist":{
"property":[
{
"name":"label",
"value":"DST is OAM-aware"
},
{
"name":"checked",
"value":false
},
{
"name":"id",
"value":"dstIsOAMAware"
}
]
}
},
{
"type":"combobox",
"propertylist":{
"property":[
{
"name":"label",
"value":"Traffic Type"
},
{
"name":"store",
"value":"{{name='Y.1731 OAM', id:1},{name='Simulated Customer',id:2}}"
},
{
"name":"value",
"value":"1"
},
{
"name":"id",
"value":"trafficType"
}
]
}
},
{
"type":"combobox",
"propertylist":{
"property":[
{
"name":"label",
"value":"MEG Level"
},
{
"name":"store",
"value":"{{id:0},{id:1},{id:2},{id:3},{id:4},{id:5}{id:6},{id:7}}"
},
{
"name":"value",
"value":"8"
},
{
"name":"id",
"value":"megLevel"
}
]
}
},
{
"type":"combobox",
"actionlist":{
"action":[
{
"name":"onclick",
"value":"handleUserDefinedFramesize"
}
]
},
"propertylist":{
"property":[
{
"name":"label",
"value":"Frame Size"
},
{
"name":"values",
"value":"{{id:1,name:'64 bytes'},{id:1,name:'128 bytes'},{id:1,name:'256 bytes'},{id:1,name:'512 bytes'},{id:1,name:'1024 bytes'},{id:1,name:'1280 bytes'},{id:1,name:'1518 bytes'},{id:1,name:'MTU'},{id:1,name:'User-defined'}}"
},
{
"name":"value",
"value":"4"
},
{
"name":"id",
"value":"frameSize"
}
]
}
},
{
"type":"textfield",
"propertylist":{
"property":[
{
"name":"label",
"value":"User-defined Frame Size"
},
{
"name":"units",
"value":"bytes"
},
{
"name":"disabled",
"value":"true"
},
{
"name":"value",
"value":"2000"
},
{
"name":"id",
"value":"userDefinedFS"
}
]
}
},
{
"type":"textfield",
"propertylist":{
"property":[
{
"name":"label",
"value":"Dwell Time"
},
{
"name":"units",
"value":"msecs"
},
{
"name":"value",
"value":"500"
},
{
"name":"id",
"value":"dwellTime"
}
]
}
}
]
}
Code to process the json:
function process(metaData){
//alert(JSON.stringify(metaData));
switch(metaData.type){
case "container":
var tableContainer = new dojox.layout.TableContainer({
cols: 1,
"labelWidth": "150"
});
if(metaData.propertylist){
metaData.propertylist.property.forEach(function(prop) {
//var row = domConstruct.toDom('<div class="greyHeader" style="width:40% !important;">' + prop.value + '</div>');
//tabContainer.addChild(row);
tableContainer.set(prop.name, prop.value);
});
}
return tableContainer;
break;
case "textfield":
var textBox = new dijit.form.TextBox();
metaData.propertylist.property.forEach(function(prop) {
textBox.set(prop.name, prop.value);
});
return textBox;
break;
case "checkbox":
var checkBox = new dijit.form.CheckBox();
metaData.propertylist.property.forEach(function(prop) {
checkBox.set(prop.name, prop.value);
});
return checkBox;
break;
case "combobox":
// store is a mandatory param that is required otherwise this.domNode is null
var filteringSelect = new dijit.form.FilteringSelect({store:new Memory({data:[]})});
console.log(JSON.stringify(metaData.propertylist.property));
metaData.propertylist.property.forEach(function(prop) {
if(prop.name == 'store'){
filteringSelect.store = new Memory({data: prop.value});
}else{
filteringSelect.set(prop.name, prop.value);
}
});
return filteringSelect;
break;
case "button":
var button = new Button();
metaData.propertylist.property.forEach(function(prop) {
button.set(prop.name, prop.value);
});
return button;
break;
case "contentpane":
var contentPane = new ContentPane();
if(metaData.propertylist){
metaData.propertylist.property.forEach(function(prop) {
contentPane.set(prop.name, prop.value);
});
}
return contentPane;
break;
}
}
Please let me know, how i can use table container's label as a header
Curious to know how we can add html text to a table container.

I have found a solution for this problem
Written a custom widget which takes label as a constructor parameter, and overridden the buildRendering function to return the following
this.domNode = domConstruct.toDom('' + '' + '');
then it appears as a label

Related

Hide nested fields with "name" in $project mongodb

This is the document available that needs to be projected by hiding all the "name" fields in the document. Not sure if we have any specific way in mongo aggregation framework to search for all the nested fields with name - "name" and hide it. Please suggest
"group1":{
"field1":{
"name":"a"
},
"field2":{
"data":{
"name":"b"
}
},
"group2":{
"field2":{
"name":"a"
},
"field3":{
"data":{
"name":"b"
}
}
}
}
}
Expected output:
{
group1: {
field1: {
}, "field2": {
"data": {
}
},
"group2": {
"field2": {
}, "field3": {
"data": {
}
}
}
}
}

Using Created and Watcher in VUE.JS

I am using watch and created method for the same data.Is it duplicate code? Is there a better way to do it?
props: {
regionList: {
type: Array,
},
},
data() {
return {
regions: [],
};
},
watch: {
regionList() {
if (this.regionList) {
this.regions = this.regionList;
}
},
},
created() {
if (!this.regionList) {
this.getApi();
} else {
this.regions = this.regionList;
}
},
It is what immediate watcher is for:
watch: {
regionList: {
immediate: true,
handler(newVal) {
if (newVal.length) {
this.regions = newVal;
}
}
},
},
created() {
if (!this.regionList) {
this.getApi();
}
},

Vuejs2: Vue Tables 2 - Multiple Custom filters

I'm trying to use a Vue table 2 filter to filter data by date, unfortunately it is not wroking and I am not able to find the reason. Has anyone tried such multiple filters with Vue table 2?
I went through the documentation but cannot find a solution.
https://matanya.gitbook.io/vue-tables-2/custom-filters
Html code to filter the data by date
<div class="col-md-4">
<div class="form-group">
<label for="sel1">Start Date:</label>
<input type="text" class="form-control" #keyup="applyFilterSearchText(searchText)" v-model="searchText" placeholder="End date" />
</div>
</div>
import { Event } from "vue-tables-2";
import axios from "axios";
export default {
title: "HelloWorld",
props: {
msg: String
},
data() {
return {
letters: ["Filled", "Unfilled", "Expired"],
selectedLetter: "",
searchText: "",
columns: ["refNumber", "vacancyTitle", "sector", "startDate", "endDate", "vacancyStatus"],
//data: getdetails(),
options: {
headings: {
refNumber: "Ref",
vacancyTitle: "Title",
sector: "Sector",
startDate: "Start",
endDate: "End",
vacancyStatus: "Status"
},
customFilters: [
{
name: "alphabet",
callback: function(row, query) {
return row.vacancyStatus == query;
}
},
{
name: "datefilter",
callback: function(row, query) {
return row.startDate == query;
}
}
],
// filterAlgorithm: {
// textsearch(row, query) {
// return (row.title).includes(query);
// }
// },
sortable: ["startDate", "vacancyTitle","endDate"],
sortIcon: {
base: "fa",
is: "fa-sort",
up: "fa-sort-asc",
down: "fa-sort-desc"
},
texts: {
filter: "Search by text:"
}
},
tableData:[],
};
},
methods: {
applyFilter(event) {
this.selectedLetter = event.target.value;
Event.$emit("vue-tables.filter::alphabet", this.selectedLetter);
},
applyFilterSearchText() {
console.log(this.searchText,"heiiiiiiiiiiii");
Event.$emit("vue-tables.filter::datefilter", this.searchText);
},
getdetails(){
axios.get("https://localhost:44399/api/Vacancy")
.then((res) => {
console.log(res.data,"ressssssss");
this.tableData = res.data;
})
.catch(function(error) {
console.log("Error: ", error);
});
}
},
mounted() {
this.getdetails();
}
};
A potential solution to that is to sort the data before using it in your data-table. Start by creating a computed of your data but with all your potential filters in it and create data variables with "parameters" (sort direction, sort column...)
export default {
title: "HelloWorld",
props: {
msg: String
},
data () {
return {
yourData: [],
sortBy: 'name',
sortDir: 'asc',
filterSearch: ''
}
},
computed: {
filteredData () {
if (filterSearch != '') {
let _this = this;
return this.sortedData.filter(item => {
return item.name.toLowerCase().includes(_this.filterSearch.toLowerCase());
})
} else {
return this.sortedData;
}
},
sortedData() {
return this.yourData.sort((a, b) => {
let modifier = 1;
if (this.sortBy == "order") {
if (this.sortDir === 'asc') {
return a[this.sortBy] - b[this.sortBy]
} else if (this.sortDir === 'desc') {
return b[this.sortBy] - a[this.sortBy]
}
} else {
if (this.sortDir === 'desc') modifier = -1;
if (a[this.sortBy] < b[this.sortBy]) return -1 * modifier;
if (a[this.sortBy] > b[this.sortBy]) return modifier;
return 0;
}
});
}
}
}
With that you just have to replace the props value you use to pass data to your VueTables

Creating a custom rally list from source using app-catalog on github

I am trying to use the Rally App Catalog and the custom list app
I would like to add an additional selector (item type) and rename some of the headers on the fly. First I just want the sample to run. As it currently stands, it looks broken to me.
When I use the rally-app-builder build function and then paste the result app.html into a custom app I get a blank page with working app settings.
Here the uncompressed version from my initial attempt.
<script src="https://rally1.rallydev.com/apps/2.1/sdk-debug.js"></script>
<!DOCTYPE html>
<html>
<head>
<title>Custom List</title>
<script type="text/javascript" src="/apps/2.1/sdk.js"></script>
<script type="text/javascript">
Rally.onReady(function() {
(function() {
var Ext = window.Ext4 || window.Ext;
var getHiddenFieldConfig = function(name) {
return {
name: name,
xtype: 'rallytextfield',
hidden: true,
handlesEvents: {
typeselected: function(type) {
this.setValue(null);
}
}
};
};
Ext.define('Rally.apps.customlist.Settings', {
singleton: true,
requires: [
'Rally.ui.combobox.FieldComboBox',
'Rally.ui.combobox.ComboBox',
'Rally.ui.CheckboxField'
],
getFields: function(app) {
this.app = app;
return [{
name: 'type',
xtype: 'rallycombobox',
allowBlank: false,
autoSelect: false,
shouldRespondToScopeChange: true,
context: this.app.getContext(),
initialValue: 'HierarchicalRequirement',
storeConfig: {
model: Ext.identityFn('TypeDefinition'),
sorters: [{
property: 'DisplayName'
}],
fetch: ['DisplayName', 'ElementName', 'TypePath', 'Parent', 'UserListable'],
filters: [{
property: 'UserListable',
value: true
}],
autoLoad: false,
remoteSort: false,
remoteFilter: true
},
displayField: 'DisplayName',
valueField: 'TypePath',
listeners: {
select: function(combo) {
this.app.clearFiltersAndSharedViews();
combo.fireEvent('typeselected', combo.getRecord().get('TypePath'), combo.context);
},
scope: this
},
bubbleEvents: ['typeselected'],
readyEvent: 'ready',
handlesEvents: {
projectscopechanged: function(context) {
this.refreshWithNewContext(context);
}
}
}, {
type: 'query'
}, {
name: 'showControls',
xtype: 'rallycheckboxfield',
fieldLabel: 'Show Control Bar'
},
getHiddenFieldConfig('columnNames'),
getHiddenFieldConfig('order')
];
}
});
})();
(function() {
var Ext = window.Ext4 || window.Ext;
Ext.define('Rally.apps.customlist.CustomListApp', {
extend: 'Rally.app.GridBoardApp',
requires: [
'Deft.Promise',
'Rally.apps.customlist.Settings',
'Rally.data.BulkRecordUpdater',
'Rally.data.ModelTypes',
'Rally.data.PreferenceManager',
'Rally.data.util.Sorter',
'Rally.data.wsapi.Filter',
'Rally.ui.gridboard.plugin.GridBoardInlineFilterControl',
'Rally.ui.gridboard.plugin.GridBoardSharedViewControl',
'Rally.ui.notify.Notifier',
'Rally.util.String'
],
disallowedAddNewTypes: ['user', 'userprofile', 'useriterationcapacity', 'testcaseresult', 'task', 'scmrepository', 'project', 'changeset', 'change', 'builddefinition', 'build', 'program'],
orderedAllowedPageSizes: [10, 25, 50, 100, 200],
readOnlyGridTypes: ['build', 'change', 'changeset'],
statePrefix: 'customlist',
allowExpansionStateToBeSaved: false,
isEditable: true,
config: {
defaultSettings: {
showControls: true
}
},
initComponent: function() {
this.appName = 'CustomList-' + this.getAppId();
this.callParent(arguments);
},
getSettingsFields: function() {
return Rally.apps.customlist.Settings.getFields(this);
},
loadModelNames: function() {
this.modelNames = _.compact([this._getTypeSetting()]);
this._setColumnNames(this._getColumnNamesSetting());
return Deft.Promise.when(this.modelNames);
},
addGridBoard: function() {
this.callParent(arguments);
if (!this.getSetting('showControls')) {
this.gridboard.getHeader().hide();
}
},
loadGridBoard: function() {
if (_.isEmpty(this.modelNames)) {
Ext.defer(function() {
this.fireEvent('settingsneeded', this);
this.publishComponentReady();
}, 1, this);
} else {
this.enableAddNew = this._shouldEnableAddNew();
this.enableRanking = this._shouldEnableRanking();
this.callParent(arguments);
}
},
getGridConfig: function() {
var config = _.merge(this.callParent(arguments), {
allColumnsStateful: true,
enableEditing: !_.contains(this.readOnlyGridTypes, this._getTypeSetting().toLowerCase()),
listeners: {
beforestaterestore: this._onBeforeGridStateRestore,
beforestatesave: this._onBeforeGridStateSave,
scope: this
},
pagingToolbarCfg: {
hidden: !this.getSetting('showControls'),
pageSizes: this.orderedAllowedPageSizes
}
});
var invalidQueryFilters = Rally.util.Filter.findInvalidSubFilters(this._getQueryFilter(), this.models);
if (invalidQueryFilters.length) {
config.store.on('beforeload', function(store) {
Ext.defer(function() {
store.fireEvent('load', store, store.getRootNode(), [], true);
}, 1);
return false;
});
this._showInvalidQueryMessage(config, _.map(invalidQueryFilters, function(filter) {
return 'Could not find the attribute "' + filter.property.split('.')[0] + '" on type "' + this.models[0].displayName + '" in the query segment "' + filter.toString() + '"';
}, this));
}
return config;
},
getColumnCfgs: function() {
return _.union(this.callParent(arguments), _.isEmpty(this.columnNames) && this.enableRanking ? ['DragAndDropRank'] : []);
},
getFilterControlConfig: function() {
return _.merge(this.callParent(arguments), {
listeners: {
beforestaterestore: {
fn: this._onBeforeFilterButtonStateRestore,
scope: this
}
}
});
},
getGridBoardCustomFilterControlConfig: function() {
var context = this.getContext();
var isArtifactModel = this.models[0].isArtifact();
var blackListFields = isArtifactModel ? ['ModelType', 'PortfolioItemType'] : ['ArtifactSearch', 'ModelType'];
var whiteListFields = isArtifactModel ? ['Milestones', 'Tags'] : [];
if (this.models[0].isProject()) {
blackListFields.push('SchemaVersion');
} else if (this.models[0].isRelease()) {
blackListFields.push('ChildrenPlannedVelocity', 'Version');
}
var config = {
ptype: 'rallygridboardinlinefiltercontrol',
inlineFilterButtonConfig: {
stateful: true,
stateId: context.getScopedStateId('custom-list-inline-filter'),
legacyStateIds: [
this.getScopedStateId('owner-filter'),
this.getScopedStateId('custom-filter-button')
],
filterChildren: true,
inlineFilterPanelConfig: {
quickFilterPanelConfig: {
defaultFields: isArtifactModel ? ['ArtifactSearch', 'Owner'] : [],
addQuickFilterConfig: {
blackListFields: blackListFields,
whiteListFields: whiteListFields
}
},
advancedFilterPanelConfig: {
advancedFilterRowsConfig: {
propertyFieldConfig: {
blackListFields: blackListFields,
whiteListFields: whiteListFields
}
}
}
}
}
};
if (isArtifactModel) {
config.inlineFilterButtonConfig.modelNames = this.modelNames;
} else {
config.inlineFilterButtonConfig.model = this.models[0];
}
return config;
},
getSharedViewConfig: function() {
var context = this.getContext();
return {
ptype: 'rallygridboardsharedviewcontrol',
sharedViewConfig: {
stateful: true,
stateId: context.getScopedStateId('custom-list-shared-view'),
enableUrlSharing: this.isFullPageApp !== false
}
};
},
getGridBoardConfig: function() {
var config = this.callParent(arguments);
return _.merge(config, {
listeners: {
viewchange: function() {
this.loadGridBoard();
},
filterchange: function() {
this.gridboard.getGridOrBoard().noDataPrimaryText = undefined;
this.gridboard.getGridOrBoard().noDataSecondaryText = undefined;
},
scope: this
}
});
},
onTreeGridReady: function(grid) {
if (grid.store.getTotalCount() > 10) {
this.gridboard.down('#pagingToolbar').show();
}
this.callParent(arguments);
},
getGridStoreConfig: function() {
var sorters = this._getValidSorters(Rally.data.util.Sorter.sorters(this.getSetting('order')));
if (_.isEmpty(sorters)) {
var rankField = this.getContext().getWorkspace().WorkspaceConfiguration.DragDropRankingEnabled ? 'DragAndDropRank' : 'Rank';
var defaultSort = Rally.data.ModelTypes.areArtifacts(this.modelNames) ? rankField : Rally.data.util.Sorter.getDefaultSort(this.modelNames[0]);
sorters = Rally.data.util.Sorter.sorters(defaultSort);
}
return {
listeners: {
warning: {
fn: this._onGridStoreWarning,
scope: this
}
},
pageSize: 10,
sorters: sorters
};
},
getAddNewConfig: function() {
var config = {
minWidth: 700,
openEditorAfterAddFailure: false,
margin: 0
};
if (!this.getContext().isFeatureEnabled('F6971_REACT_DASHBOARD_PANELS')) {
config.disableAddButton = this.appContainer.slug === 'incompletestories';
}
return _.merge(this.callParent(arguments), config);
},
getFieldPickerConfig: function() {
return _.merge(this.callParent(arguments), {
buttonConfig: {
disabled: !this._userHasPermissionsToEditPanelSettings()
},
gridAlwaysSelectedValues: function() {
return [];
},
gridFieldBlackList: this._getTypeSetting().toLowerCase() === 'task' ? ['Rank'] : []
});
},
getPermanentFilters: function() {
return this._getQueryFilter().concat(this._getTimeboxScopeFilter()).concat(this._getProjectFilter());
},
onTimeboxScopeChange: function() {
this.callParent(arguments);
this.loadGridBoard();
},
clearFiltersAndSharedViews: function() {
var context = this.getContext();
if (this.gridboard) {
this.gridboard.down('rallyinlinefilterpanel').clear();
this.gridboard.down('rallysharedviewcombobox').reset();
}
Ext.create('Rally.data.wsapi.Store', {
model: Ext.identityFn('preference'),
autoLoad: true,
filters: [{
property: 'AppId',
value: context.getAppId()
}, {
property: 'Type',
value: 'View'
}, {
property: 'Workspace',
value: context.getWorkspace()._ref
}],
context: context.getDataContext(),
listeners: {
load: function(store, records) {
if (!_.isEmpty(records)) {
var batchStore = Ext.create('Rally.data.wsapi.batch.Store', {
requester: this,
data: records
});
batchStore.removeAll();
batchStore.sync();
}
store.destroyStore();
},
scope: this
}
});
},
_getTypeSetting: function() {
return this.getSetting('type') || this.getSetting('url');
},
_getColumnNamesSetting: function() {
return this.getSetting('columnNames') ||
(this.getSetting('fetch') || '').split(',');
},
_getQueryFilter: function() {
var query = new Ext.Template(this.getSetting('query')).apply({
projectName: this.getContext().getProject().Name,
projectOid: this.getContext().getProject().ObjectID,
user: this.getContext().getUser()._ref
});
if (query) {
try {
return [Rally.data.wsapi.Filter.fromQueryString(query)];
} catch (e) {
Rally.ui.notify.Notifier.showError({
message: e.message
});
}
}
return [];
},
_getProjectFilter: function() {
return this.modelNames[0].toLowerCase() === 'milestone' ? [
Rally.data.wsapi.Filter.or([{
property: 'Projects',
operator: 'contains',
value: this.getContext().getProjectRef()
}, {
property: 'TargetProject',
operator: '=',
value: null
}])
] : [];
},
_getTimeboxScopeFilter: function() {
var timeboxScope = this.getContext().getTimeboxScope();
var hasTimeboxField = timeboxScope && _.any(this.models, timeboxScope.isApplicable, timeboxScope);
return hasTimeboxField ? [timeboxScope.getQueryFilter()] : [];
},
_shouldEnableAddNew: function() {
return !_.contains(this.disallowedAddNewTypes, this._getTypeSetting().toLowerCase());
},
_shouldEnableRanking: function() {
return this._getTypeSetting().toLowerCase() !== 'task';
},
_setColumnNames: function(columnNames) {
this.columnNames = _.compact(_.isString(columnNames) ? columnNames.split(',') : columnNames);
},
_onBeforeFilterButtonStateRestore: function(filterButton, state) {
if (state && state.filters && state.filters.length) {
var stateFilters = _.map(state.filters, function(filterStr) {
return Rally.data.wsapi.Filter.fromQueryString(filterStr);
});
var validFilters = Rally.util.Filter.removeNonapplicableTypeSpecificFilters(stateFilters, this.models);
state.filters = _.invoke(validFilters, 'toString');
}
},
_hasViewSelected: function() {
var sharedViewConfig = this.getSharedViewConfig().sharedViewConfig;
if (sharedViewConfig && sharedViewConfig.stateId) {
var value = (Ext.state.Manager.get(sharedViewConfig.stateId) || {}).value;
return !_.isEmpty(value);
}
return false;
},
_onBeforeGridStateRestore: function(grid, state) {
if (!state) {
return;
}
if (state.columns) {
var appScopedColumnNames = this._getValidUuids(grid, this.getColumnCfgs());
var userScopedColumnNames = this._getValidUuids(grid, state.columns);
if (this._hasViewSelected()) {
state.columns = userScopedColumnNames;
} else {
// Get the columns that are present in the app scope and not in the user scope
var differingColumns = _.difference(appScopedColumnNames, userScopedColumnNames);
// If there are columns in the app scope that are not in the
// user scope, append them to the user scope to preserve
// user scope column order
if (differingColumns.length > 0) {
state.columns = state.columns.concat(differingColumns);
}
// Filter out any columns that are in the user scope that are not in the
// app scope
state.columns = _.filter(state.columns, function(column) {
return _.contains(appScopedColumnNames, _.isObject(column) ? column.dataIndex : column);
}, this);
}
}
if (state.sorters) {
state.sorters = this._getValidSorters(state.sorters);
if (_.isEmpty(state.sorters)) {
delete state.sorters;
}
}
},
_getValidUuids: function(grid, columns) {
return _.reduce(columns, function(result, column) {
var dataIndex = this._getColumnDataIndex(column);
var field = this._getModelField(grid, dataIndex);
if (field) {
result.push(dataIndex);
}
return result;
}, [], this);
},
_getModelField: function(grid, dataIndex) {
return grid.getModels()[0].getField(dataIndex);
},
_getColumnDataIndex: function(column) {
return _.isObject(column) ? column.dataIndex : column;
},
_onBeforeGridStateSave: function(grid, state) {
var newColumnNames = this._getColumnNamesFromState(state);
if (!_.isEmpty(newColumnNames)) {
this._setColumnNames(newColumnNames);
if (this._userHasPermissionsToEditPanelSettings()) {
this.updateSettingsValues({
settings: {
columnNames: newColumnNames.join(',')
}
});
}
}
},
_onGridStoreWarning: function(store, warnings, operation) {
var couldNotParseWarnings = _.filter(warnings, function(warning) {
return Rally.util.String.startsWith(warning, 'Could not parse ');
});
if (couldNotParseWarnings.length) {
_.assign(operation.resultSet, {
count: 0,
records: [],
total: 0,
totalRecords: 0
});
this._showInvalidQueryMessage(this.gridboard.getGridOrBoard(), couldNotParseWarnings);
}
},
_showInvalidQueryMessage: function(gridOrGridConfig, secondaryTextStrings) {
gridOrGridConfig.noDataPrimaryText = 'Invalid Query';
gridOrGridConfig.noDataSecondaryText = _.map(secondaryTextStrings, function(str) {
return '<div>' + str + '</div>';
}).join('');
},
_getValidSorters: function(sorters) {
return _.filter(sorters, function(sorter) {
return _.any(this.models, function(model) {
var field = model.getField(sorter.property);
return field && field.sortable;
});
}, this);
},
_userHasPermissionsToEditPanelSettings: function() {
return this.isEditable;
},
_getColumnNamesFromState: function(state) {
return _(state && state.columns).map(function(newColumn) {
return _.isObject(newColumn) ? newColumn.dataIndex : newColumn;
}).compact().value();
}
});
})();
Rally.launchApp('Rally.apps.customlist.CustomListApp', {
name: "Custom List",
parentRepos: ""
});
});
</script>
</head>
<body>
</body>
</html>
Ok, I got results by commenting out the following lines in getAddNewConfig:
getAddNewConfig: function () {
var config = {
minWidth: 700,
openEditorAfterAddFailure: false,
margin: 0
};
//if(!this.getContext().isFeatureEnabled('F6971_REACT_DASHBOARD_PANELS')) {
// config.disableAddButton = this.appContainer.slug === 'incompletestories';
//}
return _.merge(this.callParent(arguments), config);
},
It seems that 'this.appContainer.slug' is undefined for me.
Here's the final working CustomListApp.js generated from the comment stream in the answer above. The main tweaks were deleting some old code checking a feature toggle and giving it a default type to display (defect in this case) in the defaultSettings block.
(function() {
var Ext = window.Ext4 || window.Ext;
Ext.define('Rally.apps.customlist.CustomListApp', {
extend: 'Rally.app.GridBoardApp',
requires: [
'Deft.Promise',
'Rally.apps.customlist.Settings',
'Rally.data.BulkRecordUpdater',
'Rally.data.ModelTypes',
'Rally.data.PreferenceManager',
'Rally.data.util.Sorter',
'Rally.data.wsapi.Filter',
'Rally.ui.gridboard.plugin.GridBoardInlineFilterControl',
'Rally.ui.gridboard.plugin.GridBoardSharedViewControl',
'Rally.ui.notify.Notifier',
'Rally.util.String'
],
disallowedAddNewTypes: ['user', 'userprofile', 'useriterationcapacity', 'testcaseresult', 'task', 'scmrepository', 'project', 'changeset', 'change', 'builddefinition', 'build', 'program'],
orderedAllowedPageSizes: [10, 25, 50, 100, 200],
readOnlyGridTypes: ['build', 'change', 'changeset'],
statePrefix: 'customlist',
allowExpansionStateToBeSaved: false,
isEditable: true,
config: {
defaultSettings: {
showControls: true,
type: 'defect' //important to include a default type to display
}
},
initComponent: function () {
this.appName = 'CustomList-' + this.getAppId();
if (this.defaultSettings.url) {
Ext.apply(this.defaultSettings, { type: this.defaultSettings.url });
}
this.callParent(arguments);
},
getSettingsFields: function() {
return Rally.apps.customlist.Settings.getFields(this);
},
loadModelNames: function () {
this.modelNames = _.compact(this.getTypeSetting());
this._setColumnNames(this._getColumnNamesSetting());
return Deft.Promise.when(this.modelNames);
},
addGridBoard: function () {
this.callParent(arguments);
if (!this.getSetting('showControls')) {
this.gridboard.getHeader().hide();
}
},
loadGridBoard: function () {
if (_.isEmpty(this.modelNames)) {
Ext.defer(function () {
this.fireEvent('settingsneeded', this);
this.publishComponentReady();
}, 1, this);
} else {
this.enableAddNew = this._shouldEnableAddNew();
this.enableRanking = this._shouldEnableRanking();
this.callParent(arguments);
}
},
getGridConfig: function () {
var config = _.merge(this.callParent(arguments), {
allColumnsStateful: true,
enableEditing: _.intersection(this.readOnlyGridTypes, this.getTypeSetting()).length === 0,
listeners: {
beforestaterestore: this._onBeforeGridStateRestore,
beforestatesave: this._onBeforeGridStateSave,
scope: this
},
pagingToolbarCfg: {
hidden: !this.getSetting('showControls'),
pageSizes: this.orderedAllowedPageSizes
}
});
var invalidQueryFilters = Rally.util.Filter.findInvalidSubFilters(this._getQueryFilter(), this.models);
if (invalidQueryFilters.length) {
config.store.on('beforeload', function (store) {
Ext.defer(function () {
store.fireEvent('load', store, store.getRootNode(), [], true);
}, 1);
return false;
});
this._showInvalidQueryMessage(config, _.map(invalidQueryFilters, function (filter) {
return 'Could not find the attribute "'+ filter.property.split('.')[0] +'" on type "'+ this.models[0].displayName +'" in the query segment "'+ filter.toString() + '"';
}, this));
}
return config;
},
getColumnCfgs: function() {
return _.union(this.callParent(arguments), _.isEmpty(this.columnNames) && this.enableRanking ? ['DragAndDropRank'] : []);
},
getFilterControlConfig: function () {
return _.merge(this.callParent(arguments), {
listeners: {
beforestaterestore: {
fn: this._onBeforeFilterButtonStateRestore,
scope: this
}
}
});
},
getGridBoardCustomFilterControlConfig: function() {
var context = this.getContext();
var isArtifactModel = this.models[0].isArtifact();
var blackListFields = isArtifactModel ? ['ModelType', 'PortfolioItemType', 'LastResult'] : ['ArtifactSearch', 'ModelType'];
var whiteListFields = isArtifactModel ? ['Milestones', 'Tags'] : [];
if (this.models[0].isProject()) {
blackListFields.push('SchemaVersion');
} else if (this.models[0].isRelease()) {
blackListFields.push('ChildrenPlannedVelocity', 'Version');
}
var config = {
ptype: 'rallygridboardinlinefiltercontrol',
inlineFilterButtonConfig: {
stateful: true,
stateId: context.getScopedStateId('custom-list-inline-filter'),
legacyStateIds: [
this.getScopedStateId('owner-filter'),
this.getScopedStateId('custom-filter-button')
],
filterChildren: true,
inlineFilterPanelConfig: {
quickFilterPanelConfig: {
defaultFields: isArtifactModel ? ['ArtifactSearch', 'Owner'] : [],
addQuickFilterConfig: {
blackListFields: blackListFields,
whiteListFields: whiteListFields
}
},
advancedFilterPanelConfig: {
advancedFilterRowsConfig: {
propertyFieldConfig: {
blackListFields: blackListFields,
whiteListFields: whiteListFields
}
}
}
}
}
};
if (isArtifactModel) {
config.inlineFilterButtonConfig.modelNames = this.modelNames;
} else {
config.inlineFilterButtonConfig.model = this.models[0];
}
return config;
},
getSharedViewConfig: function() {
var context = this.getContext();
return {
ptype: 'rallygridboardsharedviewcontrol',
sharedViewConfig: {
stateful: true,
stateId: context.getScopedStateId('custom-list-shared-view'),
enableUrlSharing: this.isFullPageApp !== false
}
};
},
getGridBoardConfig: function () {
var config = this.callParent(arguments);
return _.merge(config, {
listeners: {
viewchange: function() {
this.loadGridBoard();
},
filterchange: function() {
this.gridboard.getGridOrBoard().noDataPrimaryText = undefined;
this.gridboard.getGridOrBoard().noDataSecondaryText = undefined;
},
scope: this
}
});
},
onTreeGridReady: function (grid) {
if (grid.store.getTotalCount() > 10) {
this.gridboard.down('#pagingToolbar').show();
}
this.callParent(arguments);
},
getGridStoreConfig: function () {
var sorters = this._getValidSorters(Rally.data.util.Sorter.sorters(this.getSetting('order')));
if (_.isEmpty(sorters)) {
var rankField = this.getContext().getWorkspace().WorkspaceConfiguration.DragDropRankingEnabled ? 'DragAndDropRank' : 'Rank';
var defaultSort = Rally.data.ModelTypes.areArtifacts(this.modelNames) ? rankField : Rally.data.util.Sorter.getDefaultSort(this.modelNames[0]);
sorters = Rally.data.util.Sorter.sorters(defaultSort);
}
return {
listeners: {
warning: {
fn: this._onGridStoreWarning,
scope: this
}
},
pageSize: 10,
sorters: sorters
};
},
getAddNewConfig: function () {
var config = {
minWidth: 700,
openEditorAfterAddFailure: false,
margin: 0
};
return _.merge(this.callParent(arguments), config);
},
getFieldPickerConfig: function () {
return _.merge(this.callParent(arguments), {
buttonConfig: {
disabled: !this._userHasPermissionsToEditPanelSettings()
},
gridAlwaysSelectedValues: function () { return []; },
gridFieldBlackList: this._shouldEnableRanking() ? [] : ['Rank']
});
},
getPermanentFilters: function () {
return this._getQueryFilter().concat(this._getTimeboxScopeFilter()).concat(this._getProjectFilter());
},
onTimeboxScopeChange: function() {
this.callParent(arguments);
this.loadGridBoard();
},
clearFiltersAndSharedViews: function() {
var context = this.getContext();
if (this.gridboard) {
this.gridboard.down('rallyinlinefilterpanel').clear();
this.gridboard.down('rallysharedviewcombobox').reset();
}
Ext.create('Rally.data.wsapi.Store', {
model: Ext.identityFn('preference'),
autoLoad: true,
filters: [
{property: 'AppId', value: context.getAppId()},
{property: 'Type', value: 'View'},
{property: 'Workspace', value: context.getWorkspace()._ref}
],
context: context.getDataContext(),
listeners: {
load: function(store, records) {
if(!_.isEmpty(records)) {
var batchStore = Ext.create('Rally.data.wsapi.batch.Store', {
requester: this,
data: records
});
batchStore.removeAll();
batchStore.sync();
}
store.destroyStore();
},
scope: this
}
});
},
getTypeSetting: function() {
return (this.getSetting('type') || this.getSetting('url') || '').toLowerCase().split(',');
},
_getColumnNamesSetting: function() {
return this.getSetting('columnNames') ||
(this.getSetting('fetch') || '').split(',');
},
_getQueryFilter: function () {
var query = new Ext.Template(this.getSetting('query')).apply({
projectName: this.getContext().getProject().Name,
projectOid: this.getContext().getProject().ObjectID,
user: this.getContext().getUser()._ref
});
if (query) {
try {
return [ Rally.data.wsapi.Filter.fromQueryString(query) ];
} catch(e) {
Rally.ui.notify.Notifier.showError({ message: e.message });
}
}
return [];
},
_getProjectFilter: function () {
return this.modelNames[0].toLowerCase() === 'milestone' ? [
Rally.data.wsapi.Filter.or([
{ property: 'Projects', operator: 'contains', value: this.getContext().getProjectRef() },
{ property: 'TargetProject', operator: '=', value: null }
])
] : [];
},
_getTimeboxScopeFilter: function () {
var timeboxScope = this.getContext().getTimeboxScope();
var hasTimeboxField = timeboxScope && _.any(this.models, timeboxScope.isApplicable, timeboxScope);
return hasTimeboxField ? [ timeboxScope.getQueryFilter() ] : [];
},
_shouldEnableAddNew: function() {
return _.intersection(this.disallowedAddNewTypes, this.getTypeSetting()).length === 0;
},
_shouldEnableRanking: function() {
return !_.contains(this.getTypeSetting(), 'task');
},
_setColumnNames: function (columnNames) {
this.columnNames = _.compact(_.isString(columnNames) ? columnNames.split(',') : columnNames);
},
_onBeforeFilterButtonStateRestore: function (filterButton, state) {
if (state && state.filters && state.filters.length) {
var stateFilters = _.map(state.filters, function (filterStr) {
return Rally.data.wsapi.Filter.fromQueryString(filterStr);
});
var validFilters = Rally.util.Filter.removeNonapplicableTypeSpecificFilters(stateFilters, this.models);
state.filters = _.invoke(validFilters, 'toString');
}
},
_hasViewSelected: function() {
var sharedViewConfig = this.getSharedViewConfig().sharedViewConfig;
if (sharedViewConfig && sharedViewConfig.stateId) {
var value = (Ext.state.Manager.get(sharedViewConfig.stateId) || {}).value;
return !_.isEmpty(value);
}
return false;
},
_onBeforeGridStateRestore: function (grid, state) {
if (!state) {
return;
}
if (state.columns) {
var appScopedColumnNames = this._getValidUuids(grid, this.getColumnCfgs());
var userScopedColumnNames = this._getValidUuids(grid, state.columns);
if (this._hasViewSelected()) {
state.columns = userScopedColumnNames;
} else {
// Get the columns that are present in the app scope and not in the user scope
var differingColumns = _.difference(appScopedColumnNames, userScopedColumnNames);
// If there are columns in the app scope that are not in the
// user scope, append them to the user scope to preserve
// user scope column order
if (differingColumns.length > 0) {
state.columns = state.columns.concat(differingColumns);
}
// Filter out any columns that are in the user scope that are not in the
// app scope
state.columns = _.filter(state.columns, function (column) {
return _.contains(appScopedColumnNames, _.isObject(column) ? column.dataIndex : column);
}, this);
}
}
if (state.sorters) {
state.sorters = this._getValidSorters(state.sorters);
if (_.isEmpty(state.sorters)) {
delete state.sorters;
}
}
},
_getValidUuids: function(grid, columns) {
return _.reduce(columns, function(result, column) {
var dataIndex = this._getColumnDataIndex(column);
var field = this._getModelField(grid, dataIndex);
if (field) {
result.push(dataIndex);
}
return result;
}, [], this);
},
_getModelField: function(grid, dataIndex) {
return grid.getModels()[0].getField(dataIndex);
},
_getColumnDataIndex: function(column) {
return _.isObject(column) ? column.dataIndex : column;
},
_onBeforeGridStateSave: function (grid, state) {
var newColumnNames = this._getColumnNamesFromState(state);
if (!_.isEmpty(newColumnNames)) {
this._setColumnNames(newColumnNames);
if (this._userHasPermissionsToEditPanelSettings()) {
this.updateSettingsValues({
settings: {
columnNames: newColumnNames.join(',')
}
});
}
}
},
_onGridStoreWarning: function(store, warnings, operation) {
var couldNotParseWarnings = _.filter(warnings, function(warning){
return Rally.util.String.startsWith(warning, 'Could not parse ');
});
if(couldNotParseWarnings.length) {
_.assign(operation.resultSet, {
count: 0,
records: [],
total: 0,
totalRecords: 0
});
this._showInvalidQueryMessage(this.gridboard.getGridOrBoard(), couldNotParseWarnings);
}
},
_showInvalidQueryMessage: function(gridOrGridConfig, secondaryTextStrings) {
gridOrGridConfig.noDataPrimaryText = 'Invalid Query';
gridOrGridConfig.noDataSecondaryText = _.map(secondaryTextStrings, function(str){
return '<div>' + str + '</div>';
}).join('');
},
_getValidSorters: function (sorters) {
return _.filter(sorters, function (sorter) {
return _.any(this.models, function (model) {
var field = model.getField(sorter.property);
return field && field.sortable;
});
}, this);
},
_userHasPermissionsToEditPanelSettings: function () {
return this.isEditable;
},
_getColumnNamesFromState: function (state) {
return _(state && state.columns).map(function (newColumn) {
return _.isObject(newColumn) ? newColumn.dataIndex : newColumn;
}).compact().value();
}
});
})();

Curve Line Graphic and Jsonfile

I realized this curve line graph using d3 and nvd3:
d3.json('/Models/Scripts/test_data2.json', function(data) {
nv.addGraph(function() {
var chart = nv.models.lineWithFocusChart();
// chart.transitionDuration(500);
chart.xAxis
.tickFormat(d3.format(',f'));
chart.x2Axis
.tickFormat(d3.format(',f'));
chart.yAxis
.tickFormat(d3.format(',.2f'));
chart.y2Axis
.tickFormat(d3.format(',.2f'));
d3.select('#chart svg')
.datum(data)
.call(chart);
nv.utils.windowResize(chart.update);
return chart;
});
});
The question is, how should I write my json file to recognize different curves?
If I have the following json it doesn't work with two or more lines. I did several tries.
[{"CurveArray":[{
"Line1":[
{
"x":-52482.23046875,
"y":0.0
},
{
"x":-51380.384892578128,
"y":0.4
},
{
"x":-50278.539316406248,
"y":2
},
{
"x":-49176.693740234376,
"y":0.9
},
{
"x":-48074.848164062496,
"y":0.7
}
]},
"Line2":[
{
"x":-52482.23046875,
"y":0.0
},
{
"x":-51380.384892578128,
"y":0.4
},
{
"x":-50278.539316406248,
"y":2
},
{
"x":-49176.693740234376,
"y":0.9
},
{
"x":-48074.848164062496,
"y":0.7
}
]}
]}]
I tried to modify so:
It doesn't work again.
[
{
key: "Line1",
value: [
{
"x":-52482.23046875,
"y":0.0
},
{
"x":-51380.384892578128,
"y":0.4
},
{
"x":-50278.539316406248,
"y":2
},
{
"x":-49176.693740234376,
"y":0.9
},
{
"x":-48074.848164062496,
"y":0.7
}
]
},
{
key: "Line2",
value: [
{
"x":-50000,
"y":0.0
},
{
"x":-59000,
"y":0.4
},
{
"x":-48000,
"y":2
},
{
"x":-49100,
"y":0.9
},
{
"x":-49800,
"y":0.7
}
]
}
]