/* * 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 * Ryan Hamilton * Daniel Parker */ Testopia.Search = {}; Testopia.Search.dashboard_urls = []; Testopia.Search.fillInForm = function(type, params, name){ var f = document.getElementById(type + '_search_form'); for (var i=0; i < f.length; i++){ if (f[i].type == 'select-multiple'){ for (k=0; k < f[i].options.length; k++){ f[i].options[k].selected = false; } var list = params[f[i].name]; if(!list){ continue; } if (typeof list != 'object'){ list = new Array(list); } for (j=0; j < list.length; j++){ for (k=0; k < f[i].options.length; k++){ if(f[i].options[k].value == list[j]){ f[i].options[k].selected = true; break; } } } } else{ if (params[f[i].name]){ f[i].value = params[f[i].name] || ''; } } } }; SearchPopup = function(tab, params){ var win = new Ext.Window({ id: 'search_win', closable: true, width: Ext.getBody().getViewSize().width - 150, height: Ext.getBody().getViewSize().height - 150, plain: true, shadow: false, layout: 'fit', items: [new SearchPanel(tab, params)] }); win.show(); }; SearchPanel = function(tab, params){ params = params || {}; SearchPanel.superclass.constructor.call(this,{ title: 'Create a Search', id: 'search_panel', autoScroll: true, activeTab: tab + '_search_panel', defaults: { // applied to each contained panel bodyStyle:'padding:10px', autoScroll: true }, items:[ new PlanSearch(params), new CaseSearch(params), new RunSearch(params), new CaseRunSearch(params) ] }); }; Ext.extend(SearchPanel, Ext.TabPanel); PlanSearch = function(params){ this.params = params; PlanSearch.superclass.constructor.call(this,{ title: 'Plan Search', id: 'plan_search_panel', layout:'fit', buttons:[{ text: 'Submit', handler: function(){ var form = new Ext.form.BasicForm('plan_search_form'); var values = form.getValues(); var searchnum = Math.round(Math.random()*100); try { // EXT BUG - Closing always causes an error: // http://extjs.com/forum/showthread.php?t=20930 Ext.getCmp('search_win').close(); } catch(err){} if (params.report){ Ext.getCmp('object_panel').add(new Ext.Panel({ id: 'plan_search' + searchnum, closable: true, title: 'Plan Report', autoScroll: true, listeners: { 'render': function(){ this.load({ url: 'tr_plan_reports.cgi', params: values }); }}, tbar:[new Ext.Toolbar.Fill(), { xtype: 'button', id: 'save_plan_report_btn', icon: 'testopia/img/save.png', iconCls: 'img_button_16x', tooltip: 'Save this report', handler: function(b,e){ saveSearch('plan', values); } },{ xtype: 'button', id: 'link_plan_report_btn', icon: 'testopia/img/link.png', iconCls: 'img_button_16x', tooltip: 'Create a link to this report', handler: function(b,e){ linkPopup(values); } }] })); Ext.getCmp('object_panel').activate('plan_search' + searchnum); } else{ Ext.getCmp('object_panel').add(new PlanGrid(values,{ id: 'plan_search' + searchnum, closable: true, title: 'Plan Search' })); Ext.getCmp('object_panel').activate('plan_search' + searchnum); } } }] }); this.on('activate', this.onActivate, this); }; Ext.extend(PlanSearch, Ext.Panel,{ onActivate: function(event){ if (Ext.get('case_search_form')){ Ext.get('case_search_form').remove(); } if (Ext.get('run_search_form')){ Ext.get('run_search_form').remove(); } if (Ext.get('caserun_search_form')){ Ext.get('caserun_search_form').remove(); } this.params.current_tab = 'plan'; this.load({ url: 'tr_query.cgi', params: this.params, scripts: true, text: 'Loading search form...', callback: Testopia.Search.fillInForm.createDelegate(this,['plan',this.params]) }); } }); CaseSearch = function(params){ this.params = params; CaseSearch.superclass.constructor.call(this,{ title: 'Case Search', id: 'case_search_panel', layout:'fit', buttons:[{ text: 'Submit', handler: function(){ var form = new Ext.form.BasicForm('case_search_form'); var values = form.getValues(); var searchnum = Math.round(Math.random()*100); try { // EXT BUG - Closing always causes an error: // http://extjs.com/forum/showthread.php?t=20930 Ext.getCmp('search_win').hide(); } catch(err){} if (params.report){ Ext.getCmp('object_panel').add(new Ext.Panel({ id: 'case_search' + searchnum, closable: true, title: 'Case Report', autoScroll: true, listeners: { 'render': function(){ this.load({ url: 'tr_case_reports.cgi', params: values }); }}, tbar:[new Ext.Toolbar.Fill(), { xtype: 'button', id: 'save_case_report_btn', icon: 'testopia/img/save.png', iconCls: 'img_button_16x', tooltip: 'Save this report', handler: function(b,e){ saveSearch('case', values); } },{ xtype: 'button', id: 'link_case_report_btn', icon: 'testopia/img/link.png', iconCls: 'img_button_16x', tooltip: 'Create a link to this report', handler: function(b,e){ linkPopup(values); } }] })); Ext.getCmp('object_panel').activate('plan_search' + searchnum); } else{ Ext.getCmp('object_panel').add(new CaseGrid(values,{ id: 'case_search' + searchnum, closable: true, title: 'Case Search' })); } Ext.getCmp('object_panel').activate('case_search' + searchnum); } }] }); this.on('activate', this.onActivate, this); }; Ext.extend(CaseSearch, Ext.Panel,{ onActivate: function(event){ if (Ext.get('run_search_form')){ Ext.get('run_search_form').remove(); } if (Ext.get('plan_search_form')){ Ext.get('plan_search_form').remove(); } if (Ext.get('caserun_search_form')){ Ext.get('caserun_search_form').remove(); } this.params.current_tab = 'case'; this.load({ url: 'tr_query.cgi', params: this.params, scripts: true, text: 'Loading search form...', callback: Testopia.Search.fillInForm.createDelegate(this,['case',this.params]) }); } }); RunSearch = function(params){ this.params = params; RunSearch.superclass.constructor.call(this,{ title: 'Run Search', id: 'run_search_panel', layout:'fit', buttons:[{ text: 'Submit', handler: function(){ var form = new Ext.form.BasicForm('run_search_form'); var values = form.getValues(); if (params.qname) values.qname = params.qname; var searchnum = Math.round(Math.random()*100); try { // EXT BUG - Closing always causes an error: // http://extjs.com/forum/showthread.php?t=20930 Ext.getCmp('search_win').close(); } catch(err){} if (params.report){ Ext.getCmp('object_panel').add(new Ext.Panel({ id: 'run_search' + searchnum, closable: true, title: 'Run Report', autoScroll: true, listeners: { 'render': function(){ this.load({ url: 'tr_run_reports.cgi', params: values }); }}, tbar:[new Ext.Toolbar.Fill(), { xtype: 'button', id: 'save_run_report_btn', icon: 'testopia/img/save.png', iconCls: 'img_button_16x', tooltip: 'Save this report', handler: function(b,e){ saveSearch('run', values); } },{ xtype: 'button', id: 'link_run_report_btn', icon: 'testopia/img/link.png', iconCls: 'img_button_16x', tooltip: 'Create a link to this report', handler: function(b,e){ linkPopup(values); } }] })); Ext.getCmp('object_panel').activate('run_search' + searchnum); } else{ Ext.getCmp('object_panel').add(new RunGrid(values,{ id: 'run_search' + searchnum, closable: true, title: 'Run Search' })); } Ext.getCmp('object_panel').activate('run_search' + searchnum); } }] }); this.on('activate', this.onActivate, this); }; Ext.extend(RunSearch, Ext.Panel,{ onActivate: function(event){ if (Ext.get('case_search_form')){ Ext.get('case_search_form').remove(); } if (Ext.get('plan_search_form')){ Ext.get('plan_search_form').remove(); } if (Ext.get('caserun_search_form')){ Ext.get('caserun_search_form').remove(); } this.params.current_tab = 'run'; this.load({ url: 'tr_query.cgi', params: this.params, scripts: true, text: 'Loading search form...', callback: Testopia.Search.fillInForm.createDelegate(this,['run',this.params]) }); } }); CaseRunSearch = function(params){ this.params = params; CaseRunSearch.superclass.constructor.call(this,{ title: 'Case-Run Search', id: 'caserun_search_panel', layout:'fit', buttons:[{ text: 'Submit', handler: function(){ var form = new Ext.form.BasicForm('caserun_search_form'); var values = form.getValues(); var searchnum = Math.round(Math.random()*100); try { // EXT BUG - Closing always causes an error: // http://extjs.com/forum/showthread.php?t=20930 Ext.getCmp('search_win').close(); } catch(err){} if (params.report){ Ext.getCmp('object_panel').add(new Ext.Panel({ id: 'case_run_search' + searchnum, closable: true, title: 'Case-Run Report', autoScroll: true, listeners: { 'render': function(){ this.load({ url: 'tr_caserun_reports.cgi', params: values }); }}, tbar:[new Ext.Toolbar.Fill(), { xtype: 'button', id: 'save_caserun_report_btn', icon: 'testopia/img/save.png', iconCls: 'img_button_16x', tooltip: 'Save this report', handler: function(b,e){ saveSearch('caserun', values); } },{ xtype: 'button', id: 'link_plan_list_btn', icon: 'testopia/img/link.png', iconCls: 'img_button_16x', tooltip: 'Create a link to this report', handler: function(b,e){ linkPopup(values); } }] })); Ext.getCmp('object_panel').activate('case_run_search' + searchnum); } else{ Ext.getCmp('object_panel').add(new CaseRunListGrid(values,{ id: 'case_run_search' + searchnum, closable: true, title: 'Case-Run Search' })); } Ext.getCmp('object_panel').activate('case_run_search' + searchnum); } }] }); this.on('activate', this.onActivate, this); }; Ext.extend(CaseRunSearch, Ext.Panel,{ onActivate: function(event){ if (Ext.get('case_search_form')){ Ext.get('case_search_form').remove(); } if (Ext.get('run_search_form')){ Ext.get('run_search_form').remove(); } if (Ext.get('plan_search_form')){ Ext.get('plan_search_form').remove(); } this.params.current_tab = 'case_run'; this.load({ url: 'tr_query.cgi', params: this.params, scripts: true, text: 'Loading search form...', callback: Testopia.Search.fillInForm.createDelegate(this,['caserun',this.params]) }); } }); ReportGrid = function(cfg){ this.store = new Ext.data.JsonStore({ url: 'tr_query.cgi', baseParams: {action: 'get_saved_searches', type: cfg.type}, root: 'searches', fields: ["name","query","author","type"] }); var ds = this.store; var current_col = 'dashboard_leftcol'; this.columns = [ {header: "Name", width: 30, dataindex: "name", sortable: true} ]; ReportGrid.superclass.constructor.call(this, { id: cfg.id || "reports_grid", loadMask: {msg: "Loading ..."}, autoScroll: true, sm: new Ext.grid.RowSelectionModel({ singleSelect: true, listeners: {'rowselect': function(sm, i, r){ var name = r.get('name'); if(r.get('type') == 1){ Ext.getCmp('object_panel').setActiveTab('dashboardpanel'); var newPortlet = new Ext.ux.Portlet({ title: name, id: name, closable: true, autoScroll: true, tools: PortalTools, url: r.get('query') }); Ext.getCmp(current_col).add(newPortlet); Ext.getCmp(current_col).doLayout(); Testopia.Search.dashboard_urls.push(r.get('query')); newPortlet.load({ scripts: true, url: r.get('query') }); current_col = current_col == 'dashboard_leftcol' ? 'dashboard_rightcol' : 'dashboard_leftcol'; } else{ sm.grid.loadPanel(r); } }} }), viewConfig: { forceFit:true } }); Ext.apply(this,cfg); this.on('rowcontextmenu', this.onContextClick, this); this.on('activate', this.onActivate, this); }; Ext.extend(ReportGrid, Ext.grid.GridPanel, { onContextClick: function(grid, index, e){ var d = grid.store.getAt(index).get('query').match(/(tr_list_|_reports)/); if (d){ var g = grid.store.getAt(index).get('query').match(/completion/); if (g) d = null; } this.menu = new Ext.menu.Menu({ id:'run-ctx-menu', items: [{ text: 'Open in a new tab', disabled: d ? false : true, handler: function(){ var r = grid.store.getAt(index); if (r.get('type') == 0){ grid.loadPanel(r); } else{ var newTab = new Ext.Panel({ title: r.get('name'), closable: true, id: 'search' + r.get('name'), autoScroll: true }); Ext.getCmp('object_panel').add(newTab); Ext.getCmp('object_panel').activate('search' + r.get('name')); newTab.load({ url: r.get('query') }); } } },{ text: 'Edit', icon: 'testopia/img/edit.png', iconCls: 'img_button_16x', disabled: d ? false : true, handler: function(){ var r = grid.store.getAt(index); var name = r.get('name'); var q = r.get('query'); var type; type = q.match(/tr_list_(run|case|plan|caserun)s/); if (!type) { type = q.match(/tr_(run|case|plan|caserun)_reports/); if (!type) { Ext.Msg.show({ title: "Non-editable", msg: "This Search or Report cannot be edited", icon: Ext.MessageBox.ERROR, buttons: Ext.MessageBox.OK }); return; } } type = type[1]; var params = searchToJson(r.get('query')); SearchPopup(type, params); } },{ text: 'Delete', icon: 'testopia/img/delete.png', iconCls: 'img_button_16x', handler: function (){ var form = new Ext.form.BasicForm('testopia_helper_frm',{}); Ext.Msg.show({ msg: 'Are you sure you want to delete this search?', buttons: Ext.MessageBox.YESNO, icon: Ext.MessageBox.QUESTION, fn: function(btn, text){ if (btn == 'yes'){ var r = grid.store.getAt(index); form.submit({ url: 'tr_query.cgi', params: {action: 'delete_query', query_name: r.get('name')}, success: function(){ if (grid){ grid.store.load(); } }, failure: testopiaError }); } } }); } },{ text: 'Refresh List', icon: 'testopia/img/refresh.png', iconCls: 'img_button_16x', handler: function(){ grid.store.reload(); } }] }); e.stopEvent(); this.menu.showAt(e.getXY()); }, onActivate: function(event){ if (!this.store.getCount()){ this.store.load(); } }, loadPanel: function(r){ var cfg = { id: 'search' + r.get('name'), closable: true, title: r.get('name'), lc: 'lc_' + r.get('name'), rc: 'rc_' + r.get('name') }; if (r.get('type') == 3){ Ext.getCmp('object_panel').add(new DashboardPanel(cfg)); Ext.getCmp('object_panel').activate('search' + r.get('name')); Ext.getCmp('search' + r.get('name')).getTopToolbar().add({ xtype: 'button', id: 'link_dashboard_btn', icon: 'testopia/img/link.png', iconCls: 'img_button_16x', tooltip: 'Create a link to this dashboard', handler: function(b,e){ var l = window.location; var pathprefix = l.pathname.match(/(.*)[\/\\]([^\/\\]+\.\w+)$/); pathprefix = pathprefix[1]; var win = new Ext.Window({ width: 300, plain: true, shadow: false, items: [new Ext.form.TextField({ value: encodeURI(l.protocol + '//' + l.host + pathprefix + '/' + 'tr_show_product.cgi?dashboard=' + r.get('name') + '&userid=' + Testopia_user.id), width: 287 })] }); win.show(); } }); var current_col = 'lc_' + r.get('name'); var urls = r.get('query').split('::>'); var newPortlet; for (var i in urls){ if (typeof urls[i] != 'string'){ continue; } var p = searchToJson(urls[i]); var t; typeof p.qname == 'object' ? t = p.qname[0] : t = p.qname; newPortlet = new Ext.ux.Portlet({ title: t || ' ', id: 'search' + r.get('name') + i, closable: true, autoScroll: true, tools: PortalTools, url: urls[i] }); Ext.getCmp(current_col).add(newPortlet); Ext.getCmp(current_col).doLayout(); current_col = current_col == 'lc_' + r.get('name') ? 'rc_' + r.get('name') : 'lc_' + r.get('name'); newPortlet.load({ scripts: true, url: urls[i] }); } } else{ var params = searchToJson(r.get('query')); var tab = params.current_tab; switch(tab){ case 'plan': Ext.getCmp('object_panel').add(new PlanGrid(params,cfg)); break; case 'run': Ext.getCmp('object_panel').add(new RunGrid(params,cfg)); break; case 'case': Ext.getCmp('object_panel').add(new CaseGrid(params,cfg)); break; default: Ext.Msg.show({ title:'No Type Found', msg: 'There must have been a problem saving this search. I can\'t find a type', buttons: Ext.Msg.OK, icon: Ext.MessageBox.ERROR }); return; } Ext.getCmp('object_panel').activate('search' + r.get('name')); } } }); PortalTools = [{ id:'gear', handler: function(e,target,panel){ var form = new Ext.form.BasicForm('testopia_helper_frm',{}); this.menu = new Ext.menu.Menu({ id: 'portal_tools_menu', items: [ { text: 'Save', handler: function(){ Ext.Msg.prompt('Save Report As', '', function(btn, text){ if (btn == 'ok'){ form.submit({ url: 'tr_query.cgi', params: {action: 'save_query', query_name: text, query_part: panel.url, type: 1}, success: function(){ Ext.getCmp('reports_grid').store.load(); panel.title = text; }, failure: testopiaError }); } }); } },{ text: 'Refresh', icon: 'testopia/img/refresh.png', iconCls: 'img_button_16x', handler: function(){ panel.load({url: panel.url}); } },{ text: 'Link to this report', handler: function(){ var path; if (panel.url.match(/^http/)){ path = panel.url; path = path.replace(/\&noheader=1/gi, ''); } else{ var l = window.location; var pathprefix = l.pathname.match(/(.*)[\/\\]([^\/\\]+\.\w+)$/); pathprefix = pathprefix[1]; path = l.protocol + '//' + l.host + pathprefix + '/' + panel.url; path = path.replace(/\&noheader=1/gi, ''); } var win = new Ext.Window({ width: 300, plain: true, shadow: false, items: [new Ext.form.TextField({ value: path, width: 287 })] }); win.show(); } },{ text: 'Delete', handler: function(){ Ext.Msg.show({ title:'Confirm Delete?', icon: Ext.MessageBox.QUESTION, msg: 'Are you sure you want to delete this report?', buttons: Ext.Msg.YESNO, fn: function(btn, text){ if (btn == 'yes'){ form.submit({ url: 'tr_query.cgi', params: {action: 'delete_query', query_name: panel.title}, success: function(){ Ext.getCmp('reports_grid').store.load(); panel.ownerCt.remove(panel, true); }, failure: testopiaError }); } } }); } }] }); e.stopEvent(); this.menu.showAt(e.getXY()); } },{ id:'close', handler: function(e, target, panel){ panel.ownerCt.remove(panel, true); } }];