855 lines
27 KiB
JavaScript
855 lines
27 KiB
JavaScript
/*
|
|
* The contents of this file are subject to the Mozilla Public
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code is the Bugzilla Testopia System.
|
|
*
|
|
* The Initial Developer of the Original Code is Greg Hendricks.
|
|
* Portions created by Greg Hendricks are Copyright (C) 2006
|
|
* Novell. All Rights Reserved.
|
|
*
|
|
* Contributor(s): Greg Hendricks <ghendricks@novell.com>
|
|
* Ryan Hamilton <rhamilton@novell.com>
|
|
* Daniel Parker <dparker1@novell.com>
|
|
*/
|
|
|
|
Testopia.Util.displayStatusIcon = function(name){
|
|
return '<img src="extensions/testopia/img/' + name + '_small.gif" alt="' + name + '" title="' + name + '">';
|
|
};
|
|
|
|
Testopia.Util.makeLink = function(id, m, r, ri, ci, s, type){
|
|
if (type == 'bug') {
|
|
if (s.isTreport === true)
|
|
return '<a href="show_bug.cgi?id=' + id + '" target="_blank">' + id + '</a>';
|
|
return '<a href="show_bug.cgi?id=' + id + '">' + id + '</a>';
|
|
}
|
|
if (s.isTreport === true)
|
|
return '<a href="tr_show_' + type + '.cgi?' + type +'_id=' + id + '" target="_blank">' + id + '</a>';
|
|
return '<a href="tr_show_' + type +'.cgi?' + type + '_id=' + id + '">' + id + '</a>';
|
|
};
|
|
|
|
Testopia.Util.CascadeProductSelection = function(){
|
|
addOption = function(selectElement, newOption){
|
|
try {
|
|
selectElement.add(newOption, null);
|
|
}
|
|
|
|
catch (e) {
|
|
selectElement.add(newOption, selectElement.length);
|
|
}
|
|
};
|
|
lsearch = function(val, arr){
|
|
if (typeof arr != 'object') {
|
|
if (arr == val)
|
|
return true;
|
|
return false;
|
|
}
|
|
for (var i in arr) {
|
|
if (arr[i] == val)
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
this.addOption = addOption;
|
|
var fillSelects = function(data, prods){
|
|
var s = Testopia.Util.urlQueryToJSON(window.location.search);
|
|
if (prods) {
|
|
s.product = prods;
|
|
}
|
|
for (var i in data.selectTypes) {
|
|
if (typeof data.selectTypes[i] != 'function') {
|
|
try {
|
|
document.getElementById(data.selectTypes[i]).options.length = 0;
|
|
for (var j in data[data.selectTypes[i]]) {
|
|
if (typeof data[data.selectTypes[i]][j] != 'function') {
|
|
var newOption = new Option(data[data.selectTypes[i]][j], data[data.selectTypes[i]][j], false, lsearch(data[data.selectTypes[i]][j], s[data.selectTypes[i]]));
|
|
addOption(document.getElementById(data.selectTypes[i]), newOption);
|
|
}
|
|
}
|
|
document.getElementById(data.selectTypes[i]).disabled = false;
|
|
document.getElementById(data.selectTypes[i])
|
|
}
|
|
catch (err) {
|
|
}
|
|
}
|
|
}
|
|
};
|
|
this.fillSelects = fillSelects;
|
|
this.onProductSelection = function(prod){
|
|
var ids = [];
|
|
for (var i = 0; i < prod.options.length; i++) {
|
|
if (prod.options[i].selected === true) {
|
|
ids.push(prod.options[i].value);
|
|
}
|
|
}
|
|
var form = new Ext.form.BasicForm('testopia_helper_frm', {});
|
|
var type = prod.id == 'classification' ? 'classification' : 'product';
|
|
form.submit({
|
|
url: "tr_query.cgi",
|
|
params: {
|
|
value: ids.join(","),
|
|
action: "getversions",
|
|
type: type
|
|
},
|
|
success: function(f, a){
|
|
fillSelects(a.result.objects);
|
|
},
|
|
failure: Testopia.Util.error
|
|
});
|
|
};
|
|
|
|
return this;
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
* Testopia.User.Lookup - This generates a typeahead lookup for usernames.
|
|
* It can be used anywhere in Testopia. Extends Ext ComboBox
|
|
*/
|
|
Testopia.User.Lookup = function(cfg){
|
|
Testopia.User.Lookup.superclass.constructor.call(this, {
|
|
id: cfg.id || 'user_lookup',
|
|
store: new Ext.data.JsonStore({
|
|
url: 'tr_quicksearch.cgi',
|
|
listeners: { 'exception': Testopia.Util.loadError },
|
|
baseParams: {
|
|
action: 'getuser'
|
|
},
|
|
root: 'users',
|
|
totalProperty: 'total',
|
|
id: 'login',
|
|
fields: [{
|
|
name: 'login',
|
|
mapping: 'id'
|
|
}, {
|
|
name: 'name',
|
|
mapping: 'name'
|
|
}]
|
|
}),
|
|
listeners: {
|
|
'valid': function(f){
|
|
f.value = f.getRawValue();
|
|
},
|
|
'beforequery': function(o){
|
|
if (cfg.multistring) {
|
|
var term = o.query.match(/(^.*),(.*)/);
|
|
if (term) {
|
|
o.combo.multivalue = term[1];
|
|
o.query = term[2];
|
|
}
|
|
}
|
|
},
|
|
'select': function(c, r, i){
|
|
if (cfg.multistring) {
|
|
var v = c.multivalue || '';
|
|
v = v ? v + ', ' + r.get('login') : r.get('login');
|
|
c.setValue(v);
|
|
}
|
|
}
|
|
},
|
|
queryParam: 'search',
|
|
loadingText: 'Looking up users...',
|
|
displayField: 'login',
|
|
valueField: 'login',
|
|
typeAhead: true,
|
|
hideTrigger: true,
|
|
minListWidth: 300,
|
|
forceSelection: false,
|
|
emptyText: 'Type a username...',
|
|
pageSize: 20,
|
|
tpl: '<tpl for="."><div class="x-combo-list-item"><table><tr><td>{name}</td></tr><tr><td><b>{login}</td></tr></table></div></tpl>'
|
|
});
|
|
Ext.apply(this, cfg);
|
|
};
|
|
Ext.extend(Testopia.User.Lookup, Ext.form.ComboBox);
|
|
|
|
//TODO: Implement this (see bug 340461)
|
|
DocCompareToolbar = function(object, id){
|
|
var store = new Ext.data.JsonStore({
|
|
url: 'tr_history.cgi',
|
|
listeners: { 'exception': Testopia.Util.loadError },
|
|
baseParams: {
|
|
action: 'getdocversions',
|
|
object: object,
|
|
object_id: id
|
|
},
|
|
root: 'list',
|
|
fields: [{
|
|
name: 'id',
|
|
mapping: 'id'
|
|
}, {
|
|
name: 'name',
|
|
mapping: 'name'
|
|
}]
|
|
});
|
|
this.toolbar = new Ext.Toolbar({
|
|
id: 'doc_compare_tbar',
|
|
items: [ // new Ext.form.ComboBox({
|
|
// id: 'doc_compare_v1',
|
|
// store: store,
|
|
// displayField: 'name',
|
|
// valueField: 'id',
|
|
// width: 50,
|
|
// mode: 'local',
|
|
// triggerAction: 'all'
|
|
// }),
|
|
// new Ext.form.ComboBox({
|
|
// id: 'doc_compare_v2',
|
|
// store: store,
|
|
// displayField: 'name',
|
|
// valueField: 'id',
|
|
// width: 50,
|
|
// mode: 'local',
|
|
// triggerAction: 'all'
|
|
// }),{
|
|
// xtype: 'button',
|
|
// id: 'doc_compare_btn',
|
|
// text: 'Compare',
|
|
// handler: function(){
|
|
//
|
|
// }
|
|
// },
|
|
// new Ext.Toolbar.Spacer(),
|
|
// new Ext.Toolbar.Separator(),
|
|
new Ext.Toolbar.Fill(), new Ext.form.ComboBox({
|
|
id: 'doc_view',
|
|
store: store,
|
|
displayField: 'name',
|
|
valueField: 'id',
|
|
width: 50,
|
|
triggerAction: 'all'
|
|
}), {
|
|
xtype: 'button',
|
|
id: 'doc_view_btn',
|
|
text: 'View Version',
|
|
handler: function(){
|
|
var tab = Ext.getCmp('object_panel').add({
|
|
title: 'Version ' + Ext.getCmp('doc_view').getValue(),
|
|
closable: true,
|
|
autoScroll: true
|
|
});
|
|
tab.show();
|
|
tab.load({
|
|
url: 'tr_history.cgi',
|
|
params: {
|
|
action: 'showdoc',
|
|
object: object,
|
|
object_id: id,
|
|
version: Ext.getCmp('doc_view').getValue()
|
|
},
|
|
failure: Testopia.Util.error
|
|
});
|
|
}
|
|
}]
|
|
});
|
|
|
|
return this.toolbar;
|
|
};
|
|
/*
|
|
* Testopia.Util.HistoryList -
|
|
*/
|
|
Testopia.Util.HistoryList = function(object, id){
|
|
this.store = new Ext.data.JsonStore({
|
|
url: 'tr_history.cgi',
|
|
listeners: { 'exception': Testopia.Util.loadError },
|
|
baseParams: {
|
|
action: 'show',
|
|
object: object,
|
|
object_id: id
|
|
},
|
|
root: 'list',
|
|
fields: [{
|
|
name: "what",
|
|
mapping: "what"
|
|
}, {
|
|
name: "who",
|
|
mapping: "who"
|
|
}, {
|
|
name: "oldvalue",
|
|
mapping: "oldvalue"
|
|
}, {
|
|
name: "newvalue",
|
|
mapping: "newvalue"
|
|
}, {
|
|
name: "when",
|
|
mapping: "changed"
|
|
}]
|
|
});
|
|
this.columns = [{
|
|
header: "What",
|
|
width: 150,
|
|
dataIndex: 'what',
|
|
sortable: true
|
|
}, {
|
|
header: "Who",
|
|
width: 180,
|
|
sortable: true,
|
|
dataIndex: 'who'
|
|
}, {
|
|
header: "When",
|
|
width: 150,
|
|
sortable: true,
|
|
dataIndex: 'when'
|
|
}, {
|
|
header: "Old",
|
|
width: 180,
|
|
sortable: true,
|
|
dataIndex: 'oldvalue'
|
|
}, {
|
|
id: 'new',
|
|
header: "New",
|
|
width: 180,
|
|
sortable: true,
|
|
dataIndex: 'newvalue'
|
|
}];
|
|
Testopia.Util.HistoryList.superclass.constructor.call(this, {
|
|
title: 'Change History',
|
|
id: 'history-grid',
|
|
layout: 'fit',
|
|
loadMask: {
|
|
msg: 'Loading History...'
|
|
},
|
|
autoExpandColumn: "new",
|
|
autoScroll: true,
|
|
sm: new Ext.grid.RowSelectionModel({
|
|
singleSelect: false
|
|
})
|
|
});
|
|
this.on('rowcontextmenu', this.onContextClick, this);
|
|
this.on('activate', this.onActivate, this);
|
|
};
|
|
Ext.extend(Testopia.Util.HistoryList, Ext.grid.GridPanel, {
|
|
onActivate: function(){
|
|
if (!this.store.getCount()) {
|
|
this.store.load();
|
|
}
|
|
},
|
|
onContextClick: function(grid, index, e){
|
|
if (!this.menu) { // create context menu on first right click
|
|
this.menu = new Ext.menu.Menu({
|
|
id: 'history-ctx-menu',
|
|
enableScrolling: false,
|
|
items: [{
|
|
text: 'Refresh',
|
|
icon: 'extensions/testopia/img/refresh.png',
|
|
iconCls: 'img_button_16x',
|
|
handler: function(){
|
|
grid.store.reload();
|
|
}
|
|
}]
|
|
});
|
|
}
|
|
e.stopEvent();
|
|
this.menu.showAt(e.getXY());
|
|
}
|
|
|
|
});
|
|
|
|
Testopia.Util.PagingBar = function(type, store){
|
|
this.type = type;
|
|
var baseParams = clone(store.baseParams);
|
|
function doUpdate(){
|
|
this.updateInfo();
|
|
}
|
|
function clone(orig){
|
|
var clone = new Object();
|
|
for (var i in orig) {
|
|
clone[i] = orig[i];
|
|
}
|
|
return clone;
|
|
}
|
|
function viewallUpdate(){
|
|
this.cursor = 0;
|
|
this.afterTextEl.el.innerHTML = String.format(this.afterPageText, 1);
|
|
this.field.dom.value = 1;
|
|
this.updateInfo();
|
|
}
|
|
var sizer = new Ext.form.ComboBox({
|
|
store: new Ext.data.SimpleStore({
|
|
fields: ['value', 'name'],
|
|
id: 0,
|
|
data: [[25, 25], [50, 50], [100, 100], [500, 500]],
|
|
autoLoad: true
|
|
}),
|
|
id: type + '_page_sizer',
|
|
mode: 'local',
|
|
displayField: 'name',
|
|
valueField: 'value',
|
|
triggerAction: 'all',
|
|
editable: false,
|
|
width: 50
|
|
});
|
|
|
|
sizer.on('select', function(c, r, i){
|
|
this.pageSize = r.get('value');
|
|
Ext.state.Manager.set('TESTOPIA_DEFAULT_PAGE_SIZE', r.get('value'));
|
|
store.baseParams.limit = r.get('value');
|
|
store.load({
|
|
params: {
|
|
start: 0
|
|
},
|
|
callback: doUpdate.createDelegate(this)
|
|
});
|
|
}, this);
|
|
this.sizer = sizer;
|
|
var viewall = new Ext.Button({
|
|
text: 'View All',
|
|
enableToggle: true
|
|
});
|
|
viewall.on('toggle', function(b, p){
|
|
if (p) {
|
|
this.pageSize = 0;
|
|
store.load({
|
|
params: {
|
|
viewall: 1
|
|
},
|
|
callback: viewallUpdate.createDelegate(this)
|
|
});
|
|
}
|
|
else {
|
|
this.pageSize = sizer.getValue();
|
|
store.load({
|
|
params: {
|
|
start: 0,
|
|
limit: sizer.getValue()
|
|
}
|
|
});
|
|
}
|
|
}, this);
|
|
var filter = new Ext.form.TextField({
|
|
allowBlank: true,
|
|
id: type + '_paging_filter',
|
|
selectOnFocus: true
|
|
});
|
|
|
|
filter.on('specialkey', function(f, e){
|
|
var key = e.getKey();
|
|
if (key == e.ENTER) {
|
|
var params = {
|
|
start: 0,
|
|
limit: sizer.getValue()
|
|
};
|
|
if (this.getValue().length === 0) {
|
|
store.baseParams = clone(baseParams);
|
|
store.load({
|
|
params: params
|
|
});
|
|
Ext.getCmp(type + '_filtered_txt').hide();
|
|
return;
|
|
}
|
|
var params = {
|
|
start: 0,
|
|
limit: sizer.getValue()
|
|
};
|
|
var s = this.getValue();
|
|
var term = s.match(/(^.*?):/);
|
|
if (term) {
|
|
term = term[1];
|
|
var q = Testopia.Util.trim(s.substr(s.indexOf(':') + 1, s.length));
|
|
if (term.match(/^start/i)) {
|
|
term = 'start_date';
|
|
}
|
|
if (term.match(/^stop/i)) {
|
|
term = 'stop_date';
|
|
}
|
|
if (term.match(/^manager/i)) {
|
|
term = 'manager';
|
|
}
|
|
switch (term) {
|
|
case 'status':
|
|
if (type == 'case') {
|
|
term = 'case_status';
|
|
}
|
|
else
|
|
if (type == 'caserun') {
|
|
term = 'case_run_status';
|
|
}
|
|
else {
|
|
term = 'run_status';
|
|
if (q.match(/running/i)) {
|
|
q = 0;
|
|
}
|
|
else {
|
|
q = 1;
|
|
}
|
|
}
|
|
break;
|
|
case 'tester':
|
|
term = 'default_tester';
|
|
break;
|
|
case 'plan':
|
|
term = 'plan_id';
|
|
break;
|
|
case 'case':
|
|
term = 'case_id';
|
|
break;
|
|
case 'run':
|
|
term = 'run_id';
|
|
break;
|
|
case 'product_version':
|
|
term = 'default_product_version';
|
|
break;
|
|
|
|
}
|
|
store.baseParams[term] = q;
|
|
store.baseParams[term + '_type'] = 'substring';
|
|
}
|
|
else {
|
|
if (type == 'case' || type == 'run') {
|
|
store.baseParams.summary = this.getValue();
|
|
store.baseParams.summary_type = 'allwordssubst';
|
|
}
|
|
else
|
|
if (type == 'caserun') {
|
|
store.baseParams.case_summary = this.getValue();
|
|
store.baseParams.case_summary_type = 'allwordssubst';
|
|
}
|
|
else {
|
|
store.baseParams.name = this.getValue();
|
|
store.baseParams.name_type = 'allwordssubst';
|
|
}
|
|
}
|
|
store.load({
|
|
params: params
|
|
});
|
|
Ext.getCmp(type + '_filtered_txt').show();
|
|
}
|
|
if ((key == e.BACKSPACE || key == e.DELETE) && this.getValue().length === 0) {
|
|
store.baseParams = baseParams;
|
|
store.load({
|
|
params: {
|
|
start: 0,
|
|
limit: sizer.getValue()
|
|
}
|
|
});
|
|
Ext.getCmp(type + '_filtered_txt').hide();
|
|
}
|
|
});
|
|
|
|
sizer.on('render', function(){
|
|
var tt = new Ext.ToolTip({
|
|
target: type + '_paging_filter',
|
|
title: 'Quick Search Filter',
|
|
hideDelay: '500',
|
|
html: "Enter column and search term separated by ':'<br> <b>Example:</b> priority: P3<br>Blank field and ENTER to clear"
|
|
});
|
|
});
|
|
Testopia.Util.PagingBar.superclass.constructor.call(this, {
|
|
id: type + '_pager',
|
|
pageSize: Ext.state.Manager.get('TESTOPIA_DEFAULT_PAGE_SIZE', 25),
|
|
displayInfo: true,
|
|
displayMsg: 'Displaying test ' + type + 's {0} - {1} of {2}',
|
|
emptyMsg: 'No test ' + type + 's were found',
|
|
store: store,
|
|
items: ['Filter: ', filter, ' ', '-', 'View ', ' ', sizer, ' ', viewall, ' ',
|
|
{
|
|
type: 'tbtext',
|
|
text: '(FILTERED)',
|
|
hidden: true,
|
|
id: type + '_filtered_txt',
|
|
style: 'font-weight:bold;color:red'
|
|
}]
|
|
});
|
|
this.on('render', this.setPager, this);
|
|
this.cursor = 0;
|
|
};
|
|
Ext.extend(Testopia.Util.PagingBar, Ext.PagingToolbar, {
|
|
setPager: function(){
|
|
Ext.getCmp(this.type + '_page_sizer').setValue(Ext.state.Manager.get('TESTOPIA_DEFAULT_PAGE_SIZE', 25));
|
|
}
|
|
});
|
|
|
|
Testopia.Util.updateFromList = function(type, params, grid){
|
|
var form = new Ext.form.BasicForm('testopia_helper_frm', {});
|
|
params.ctype = 'json';
|
|
params.action = 'update';
|
|
form.submit({
|
|
url: 'tr_list_' + type + 's.cgi',
|
|
params: params,
|
|
success: function(f, a){
|
|
if (type == 'caserun') {
|
|
Ext.getCmp('run_progress').updateProgress(a.result.passed, a.result.failed, a.result.blocked, a.result.complete);
|
|
}
|
|
Testopia.Util.notify.msg('Test ' + type + 's updated', 'The selected {0}s were updated successfully', type);
|
|
if (grid.selectedRows) {
|
|
grid.store.baseParams.addcases = grid.selectedRows.join(',');
|
|
Ext.getCmp(type + '_filtered_txt').show();
|
|
}
|
|
try {
|
|
Ext.getCmp('case_details_panel').store.reload();
|
|
}
|
|
catch (err) {
|
|
}
|
|
grid.store.reload({
|
|
callback: function(){
|
|
if (grid.selectedRows) {
|
|
var sm = grid.getSelectionModel();
|
|
var sel = [];
|
|
for (var i = 0; i < grid.selectedRows.length; i++) {
|
|
var index = grid.store.find('case_id', grid.selectedRows[i]);
|
|
if (index >= 0)
|
|
sel.push(index);
|
|
}
|
|
sm.selectRows(sel);
|
|
if (sm.getCount() < 1) {
|
|
Ext.getCmp('case_details_panel').disable();
|
|
}
|
|
}
|
|
}
|
|
});
|
|
},
|
|
failure: function(f, a){
|
|
Testopia.Util.error(f, a);
|
|
grid.store.reload({
|
|
callback: function(){
|
|
if (grid.selectedRows) {
|
|
grid.getSelectionModel().selectRows(grid.selectedRows);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
});
|
|
};
|
|
|
|
Testopia.Util.ComboRenderer = function(v, md, r, ri, ci, s){
|
|
f = this.getColumnModel().getCellEditor(ci, ri).field;
|
|
record = f.store.getById(v);
|
|
if (record) {
|
|
return record.data[f.displayField];
|
|
}
|
|
else {
|
|
return v;
|
|
}
|
|
};
|
|
|
|
/*
|
|
* Testopia.Util.error - global public function for displaying Bugzilla error messages
|
|
* when ERROR_MODE_AJAX is set. All failure branches of Ext.basicForm submit calls
|
|
* should point here.
|
|
*/
|
|
Testopia.Util.error = function(f, a){
|
|
f.el.unmask();
|
|
var message;
|
|
if (a.response.status && a.response.status != 200) {
|
|
message = {
|
|
title: 'System Error!',
|
|
msg: a.response.responseText,
|
|
buttons: Ext.Msg.OK,
|
|
icon: Ext.MessageBox.ERROR,
|
|
minWidth: 450
|
|
};
|
|
}
|
|
else {
|
|
message = {
|
|
title: 'An Error Has Occurred',
|
|
msg: a.result.message,
|
|
buttons: Ext.Msg.OK,
|
|
icon: Ext.MessageBox.ERROR,
|
|
prompt: true,
|
|
value: a.result.message,
|
|
multiline: true,
|
|
minWidth: 450
|
|
};
|
|
}
|
|
Ext.Msg.show(message);
|
|
};
|
|
|
|
Testopia.Util.loadError = function(dp, errtype, a,o,r,ar,args){
|
|
var message = 'There was an error loading the data: ';
|
|
if (errtype == 'response'){
|
|
message += r.responseText;
|
|
}
|
|
Ext.Msg.show({
|
|
title: 'An Error Has Occurred',
|
|
width: 450,
|
|
msg: message,
|
|
prompt: true,
|
|
multiline: true,
|
|
value: message,
|
|
buttons: Ext.Msg.OK,
|
|
icon: Ext.MessageBox.ERROR
|
|
});
|
|
};
|
|
|
|
Testopia.Util.getSelectedObjects = function(grid, field){
|
|
var selections = grid.getSelectionModel().getSelections();
|
|
var arIDs = [];
|
|
var ids;
|
|
for (var i = 0; i < selections.length; i++) {
|
|
arIDs.push(selections[i].get(field));
|
|
}
|
|
ids = arIDs.join(',');
|
|
return ids;
|
|
};
|
|
|
|
Testopia.Util.editFirstSelection = function(grid){
|
|
if (grid.store.getCount() === 0) {
|
|
return;
|
|
}
|
|
var row = grid.store.indexOf(grid.getSelectionModel().getSelected());
|
|
if (row == -1){
|
|
row = 0;
|
|
}
|
|
grid.plugins[0].startEditing(row);
|
|
};
|
|
|
|
Testopia.Util.urlQueryToJSON = function(url){
|
|
url = url.replace(/.*\//, '');
|
|
var params = {};
|
|
var loc = url.split('?', 2);
|
|
var file = loc[0];
|
|
var search = loc[1] ? loc[1] : file;
|
|
var pairs = search.split('&');
|
|
|
|
for (var i = 0; i < pairs.length; i++) {
|
|
var pair = pairs[i].split('=');
|
|
if (params[pair[0]]){
|
|
if (typeof params[pair[0]] == 'object'){
|
|
params[pair[0]].push(decodeURI(pair[1]));
|
|
}
|
|
else {
|
|
params[pair[0]] = new Array(params[pair[0]]);
|
|
params[pair[0]].push(decodeURI(pair[1]));
|
|
}
|
|
}
|
|
else{
|
|
params[pair[0]] = decodeURI(pair[1]);
|
|
}
|
|
}
|
|
|
|
return params;
|
|
};
|
|
|
|
Testopia.Util.JSONToURLQuery = function(params, searchStr, drops){
|
|
searchStr = searchStr || '';
|
|
for (var key in params) {
|
|
if (drops.indexOf(key) != -1) {
|
|
continue;
|
|
}
|
|
if (typeof params[key] == 'object'){
|
|
for(i=0; i<params[key].length; i++){
|
|
searchStr = searchStr + key + '=' + encodeURI(params[key][i]) + '&';
|
|
}
|
|
}
|
|
else{
|
|
searchStr = searchStr + key + '=' + encodeURI(params[key]) + '&';
|
|
}
|
|
}
|
|
if (searchStr.lastIndexOf('&') == searchStr.length - 1) {
|
|
searchStr = searchStr.substr(0, searchStr.length - 1);
|
|
}
|
|
return searchStr;
|
|
};
|
|
/*
|
|
* Testopia.notify - Displays a floating notification area.
|
|
* Taken from ext/examples/examples.js
|
|
*/
|
|
Testopia.Util.notify = function(){
|
|
var msgCt;
|
|
|
|
function createBox(t, s){
|
|
return ['<div class="msg">', '<div class="x-box-tl"><div class="x-box-tr"><div class="x-box-tc"></div></div></div>', '<div class="x-box-ml"><div class="x-box-mr"><div class="x-box-mc"><h3>', t, '</h3>', s, '</div></div></div>', '<div class="x-box-bl"><div class="x-box-br"><div class="x-box-bc"></div></div></div>', '</div>'].join('');
|
|
}
|
|
return {
|
|
msg: function(title, format){
|
|
if (!msgCt) {
|
|
msgCt = Ext.DomHelper.insertFirst(document.getElementById('bugzilla-body'), {
|
|
id: 'msg-div'
|
|
}, true);
|
|
}
|
|
msgCt.alignTo(document, 't-t');
|
|
var s = String.format.apply(String, Array.prototype.slice.call(arguments, 1));
|
|
var m = Ext.DomHelper.append(msgCt, {
|
|
html: createBox(title, s)
|
|
}, true);
|
|
m.slideIn('t').pause(1).ghost("t", {
|
|
remove: true
|
|
});
|
|
},
|
|
|
|
init: function(){
|
|
return;
|
|
}
|
|
};
|
|
}();
|
|
|
|
Testopia.Util.trim = function(input){
|
|
input = input.replace(/^\s+/g, '');
|
|
input = input.replace(/\s+$/g, '');
|
|
return input;
|
|
};
|
|
|
|
Testopia.Util.PlanSelector = function(product_id, cfg){
|
|
var single = cfg.action.match('case') ? false : true;
|
|
var pg = new Testopia.TestPlan.Grid({
|
|
product_id: product_id
|
|
}, {
|
|
id: 'plan_selector_grid',
|
|
height: 300,
|
|
single: single
|
|
});
|
|
|
|
var pchooser = new Testopia.Product.Combo({
|
|
mode: 'local',
|
|
value: product_id
|
|
});
|
|
pchooser.on('select', function(c, r, i){
|
|
pg.store.baseParams = {
|
|
ctype: 'json',
|
|
product_id: r.get('id')
|
|
};
|
|
pg.store.load();
|
|
});
|
|
|
|
Testopia.Util.PlanSelector.superclass.constructor.call(this, {
|
|
items: [pg],
|
|
buttons: [{
|
|
text: 'Use Selected',
|
|
handler: function(){
|
|
var loc = cfg.action + '?plan_id=' + Testopia.Util.getSelectedObjects(pg, 'plan_id');
|
|
if (cfg.bug_id) {
|
|
loc = loc + '&bug=' + cfg.bug_id;
|
|
}
|
|
window.location = loc;
|
|
}
|
|
}]
|
|
});
|
|
|
|
pg.on('render', function(){
|
|
var items = pg.getTopToolbar().items.items;
|
|
for (var i = 0; i < items.length; i++) {
|
|
items[i].destroy();
|
|
}
|
|
pg.getTopToolbar().add('Product: ', pchooser);
|
|
pg.getSelectionModel().un('rowselect', pg.getSelectionModel().events['rowselect'].listeners[0].fn);
|
|
pg.getSelectionModel().un('rowdeselect', pg.getSelectionModel().events['rowdeselect'].listeners[0].fn);
|
|
pg.store.load();
|
|
});
|
|
}
|
|
Ext.extend(Testopia.Util.PlanSelector, Ext.Panel);
|
|
|
|
Testopia.Util.DisableTools = function(tbar, ex){
|
|
if (typeof ex != 'object'){
|
|
ex = [];
|
|
}
|
|
for (var i in tbar.items.items) {
|
|
if (ex.indexOf(tbar.items.items[i].id) != -1) {
|
|
continue;
|
|
}
|
|
try {
|
|
tbar.items.items[i].disable();
|
|
}
|
|
catch (e) {
|
|
|
|
}
|
|
}
|
|
}
|