SpreadsheetView.java revision 9e494cc00c53f9dd0fabec3ef675cb874a9130ad
135444864c7b6f49865a7e17aa0052987b72e4728showardpackage autotest.tko;
235444864c7b6f49865a7e17aa0052987b72e4728showard
335444864c7b6f49865a7e17aa0052987b72e4728showardimport autotest.common.JsonRpcCallback;
435444864c7b6f49865a7e17aa0052987b72e4728showardimport autotest.common.JsonRpcProxy;
535444864c7b6f49865a7e17aa0052987b72e4728showardimport autotest.common.Utils;
6c674d3ea684f75f3e05f5834b598050eb1c8856dshowardimport autotest.common.CustomHistory.HistoryToken;
735444864c7b6f49865a7e17aa0052987b72e4728showardimport autotest.common.ui.ContextMenu;
835444864c7b6f49865a7e17aa0052987b72e4728showardimport autotest.common.ui.NotifyManager;
935444864c7b6f49865a7e17aa0052987b72e4728showardimport autotest.common.ui.RightClickTable;
1035444864c7b6f49865a7e17aa0052987b72e4728showardimport autotest.common.ui.SimpleHyperlink;
1135444864c7b6f49865a7e17aa0052987b72e4728showardimport autotest.common.ui.TableActionsPanel;
123d6ae118f69717e68bc15b9aed7b6a6c7dd9bab0showardimport autotest.common.ui.TableActionsPanel.TableActionsWithExportCsvListener;
139dbdcda5104991cbf344ea5cba1aa58e1af444f3showardimport autotest.common.ui.TableSelectionPanel.SelectionPanelListener;
140c31bc5ef2ecdf8edf19468e1a373520110f5bc6showardimport autotest.tko.CommonPanel.CommonPanelListener;
1535444864c7b6f49865a7e17aa0052987b72e4728showardimport autotest.tko.Spreadsheet.CellInfo;
1635444864c7b6f49865a7e17aa0052987b72e4728showardimport autotest.tko.Spreadsheet.Header;
1735444864c7b6f49865a7e17aa0052987b72e4728showardimport autotest.tko.Spreadsheet.SpreadsheetListener;
18ce12f55f4530950f7fc6ddc73d1867ebb954d356showardimport autotest.tko.TableView.TableSwitchListener;
19ce12f55f4530950f7fc6ddc73d1867ebb954d356showardimport autotest.tko.TableView.TableViewConfig;
2035444864c7b6f49865a7e17aa0052987b72e4728showardimport autotest.tko.TkoUtils.FieldInfo;
2135444864c7b6f49865a7e17aa0052987b72e4728showard
2235444864c7b6f49865a7e17aa0052987b72e4728showardimport com.google.gwt.json.client.JSONArray;
2335444864c7b6f49865a7e17aa0052987b72e4728showardimport com.google.gwt.json.client.JSONObject;
24d50ffb4b0ef514fb969d53b82e23ab41d4d3812eshowardimport com.google.gwt.json.client.JSONString;
2535444864c7b6f49865a7e17aa0052987b72e4728showardimport com.google.gwt.json.client.JSONValue;
2635444864c7b6f49865a7e17aa0052987b72e4728showardimport com.google.gwt.user.client.Command;
2735444864c7b6f49865a7e17aa0052987b72e4728showardimport com.google.gwt.user.client.Event;
28c674d3ea684f75f3e05f5834b598050eb1c8856dshowardimport com.google.gwt.user.client.History;
2935444864c7b6f49865a7e17aa0052987b72e4728showardimport com.google.gwt.user.client.Window;
3035444864c7b6f49865a7e17aa0052987b72e4728showardimport com.google.gwt.user.client.WindowResizeListener;
3135444864c7b6f49865a7e17aa0052987b72e4728showardimport com.google.gwt.user.client.ui.Button;
3277401f351bd4ef6b6af99e46a9f905b161062574showardimport com.google.gwt.user.client.ui.ChangeListener;
3335444864c7b6f49865a7e17aa0052987b72e4728showardimport com.google.gwt.user.client.ui.CheckBox;
3435444864c7b6f49865a7e17aa0052987b72e4728showardimport com.google.gwt.user.client.ui.ClickListener;
3535444864c7b6f49865a7e17aa0052987b72e4728showardimport com.google.gwt.user.client.ui.HTML;
3635444864c7b6f49865a7e17aa0052987b72e4728showardimport com.google.gwt.user.client.ui.MenuBar;
378a6eb0cf5777dded2354408e8007d9223e813c92showardimport com.google.gwt.user.client.ui.Panel;
389e494cc00c53f9dd0fabec3ef675cb874a9130adshowardimport com.google.gwt.user.client.ui.SimplePanel;
398a6eb0cf5777dded2354408e8007d9223e813c92showardimport com.google.gwt.user.client.ui.VerticalPanel;
4035444864c7b6f49865a7e17aa0052987b72e4728showardimport com.google.gwt.user.client.ui.Widget;
4135444864c7b6f49865a7e17aa0052987b72e4728showard
4235444864c7b6f49865a7e17aa0052987b72e4728showardimport java.util.HashMap;
4335444864c7b6f49865a7e17aa0052987b72e4728showardimport java.util.List;
4435444864c7b6f49865a7e17aa0052987b72e4728showardimport java.util.Map;
4535444864c7b6f49865a7e17aa0052987b72e4728showard
4635444864c7b6f49865a7e17aa0052987b72e4728showardpublic class SpreadsheetView extends ConditionTabView
473d6ae118f69717e68bc15b9aed7b6a6c7dd9bab0showard                             implements SpreadsheetListener, TableActionsWithExportCsvListener,
489dbdcda5104991cbf344ea5cba1aa58e1af444f3showard                                        CommonPanelListener, SelectionPanelListener {
498a6eb0cf5777dded2354408e8007d9223e813c92showard    private static final String HISTORY_ONLY_LATEST = "show_only_latest";
5035444864c7b6f49865a7e17aa0052987b72e4728showard    public static final String DEFAULT_ROW = "kernel";
5135444864c7b6f49865a7e17aa0052987b72e4728showard    public static final String DEFAULT_COLUMN = "platform";
5235444864c7b6f49865a7e17aa0052987b72e4728showard
538c9b839c2f5073a755952a8a865a04db3b2d4547showard    private static final String HISTORY_SHOW_INCOMPLETE = "show_incomplete";
548c9b839c2f5073a755952a8a865a04db3b2d4547showard    private static final String HISTORY_COLUMN = "column";
558c9b839c2f5073a755952a8a865a04db3b2d4547showard    private static final String HISTORY_ROW = "row";
56194a59d6976a5dbd5b464fb2b14ceb089f91c050showard    private static final String HISTORY_CONTENT = "content";
578c9b839c2f5073a755952a8a865a04db3b2d4547showard
5835444864c7b6f49865a7e17aa0052987b72e4728showard    private static enum DrilldownType {DRILLDOWN_ROW, DRILLDOWN_COLUMN, DRILLDOWN_BOTH}
5935444864c7b6f49865a7e17aa0052987b72e4728showard
6035444864c7b6f49865a7e17aa0052987b72e4728showard    private static JsonRpcProxy rpcProxy = JsonRpcProxy.getProxy();
61e732ee7d450b11261c82df0950fde8e02f839b26showard    private static JsonRpcProxy afeRpcProxy = JsonRpcProxy.getProxy(JsonRpcProxy.AFE_BASE_URL);
62ce12f55f4530950f7fc6ddc73d1867ebb954d356showard    private TableSwitchListener listener;
6335444864c7b6f49865a7e17aa0052987b72e4728showard    protected Map<String,String[]> drilldownMap = new HashMap<String,String[]>();
64f248952e42ea33c34e41a49817e50f98c65c2716showard    private Map<String, HeaderField> headerFieldMap = new HashMap<String, HeaderField>();
6535444864c7b6f49865a7e17aa0052987b72e4728showard
6635444864c7b6f49865a7e17aa0052987b72e4728showard    private HeaderSelect rowSelect = new HeaderSelect();
6735444864c7b6f49865a7e17aa0052987b72e4728showard    private HeaderSelect columnSelect = new HeaderSelect();
6877401f351bd4ef6b6af99e46a9f905b161062574showard    private ContentSelect contentSelect = new ContentSelect();
69d50ffb4b0ef514fb969d53b82e23ab41d4d3812eshoward    private CheckBox showIncomplete = new CheckBox("Show incomplete tests");
708a6eb0cf5777dded2354408e8007d9223e813c92showard    private CheckBox showOnlyLatest = new CheckBox("Show only latest test per cell");
7135444864c7b6f49865a7e17aa0052987b72e4728showard    private Button queryButton = new Button("Query");
728a6eb0cf5777dded2354408e8007d9223e813c92showard    private TestGroupDataSource normalDataSource = TestGroupDataSource.getStatusCountDataSource();
738a6eb0cf5777dded2354408e8007d9223e813c92showard    private TestGroupDataSource latestDataSource = TestGroupDataSource.getLatestTestsDataSource();
7435444864c7b6f49865a7e17aa0052987b72e4728showard    private Spreadsheet spreadsheet = new Spreadsheet();
7535444864c7b6f49865a7e17aa0052987b72e4728showard    private SpreadsheetDataProcessor spreadsheetProcessor =
768a6eb0cf5777dded2354408e8007d9223e813c92showard        new SpreadsheetDataProcessor(spreadsheet);
7735444864c7b6f49865a7e17aa0052987b72e4728showard    private SpreadsheetSelectionManager selectionManager =
7835444864c7b6f49865a7e17aa0052987b72e4728showard        new SpreadsheetSelectionManager(spreadsheet, null);
799dbdcda5104991cbf344ea5cba1aa58e1af444f3showard    private TableActionsPanel actionsPanel = new TableActionsPanel(false);
809e494cc00c53f9dd0fabec3ef675cb874a9130adshoward    private Panel jobCompletionPanel = new SimplePanel();
81313ab769319f56b940a2784cc0cbdebd005c5799showard    private boolean currentShowIncomplete, currentShowOnlyLatest;
8235444864c7b6f49865a7e17aa0052987b72e4728showard    private boolean notYetQueried = true;
83ce12f55f4530950f7fc6ddc73d1867ebb954d356showard    public SpreadsheetView(TableSwitchListener listener) {
8435444864c7b6f49865a7e17aa0052987b72e4728showard        this.listener = listener;
850c31bc5ef2ecdf8edf19468e1a373520110f5bc6showard        commonPanel.addListener(this);
8635444864c7b6f49865a7e17aa0052987b72e4728showard    }
8735444864c7b6f49865a7e17aa0052987b72e4728showard
8835444864c7b6f49865a7e17aa0052987b72e4728showard    @Override
8935444864c7b6f49865a7e17aa0052987b72e4728showard    public String getElementId() {
9035444864c7b6f49865a7e17aa0052987b72e4728showard        return "spreadsheet_view";
9135444864c7b6f49865a7e17aa0052987b72e4728showard    }
9235444864c7b6f49865a7e17aa0052987b72e4728showard
9335444864c7b6f49865a7e17aa0052987b72e4728showard    @Override
9435444864c7b6f49865a7e17aa0052987b72e4728showard    public void initialize() {
959f4500a294eea35dce003cee41c558fcde3eb09fshoward        super.initialize();
968a6eb0cf5777dded2354408e8007d9223e813c92showard        normalDataSource.setSkipNumResults(true);
978a6eb0cf5777dded2354408e8007d9223e813c92showard        latestDataSource.setSkipNumResults(true);
9835444864c7b6f49865a7e17aa0052987b72e4728showard
993d6ae118f69717e68bc15b9aed7b6a6c7dd9bab0showard        actionsPanel.setActionsWithCsvListener(this);
1009dbdcda5104991cbf344ea5cba1aa58e1af444f3showard        actionsPanel.setSelectionListener(this);
1013d6ae118f69717e68bc15b9aed7b6a6c7dd9bab0showard        actionsPanel.setVisible(false);
102f248952e42ea33c34e41a49817e50f98c65c2716showard
10335444864c7b6f49865a7e17aa0052987b72e4728showard        for (FieldInfo fieldInfo : TkoUtils.getFieldList("group_fields")) {
104f248952e42ea33c34e41a49817e50f98c65c2716showard            HeaderField field = new SimpleHeaderField(fieldInfo.name, fieldInfo.field);
105f248952e42ea33c34e41a49817e50f98c65c2716showard            headerFieldMap.put(fieldInfo.field, field);
106f248952e42ea33c34e41a49817e50f98c65c2716showard            rowSelect.addItem(field);
107f248952e42ea33c34e41a49817e50f98c65c2716showard            columnSelect.addItem(field);
10877401f351bd4ef6b6af99e46a9f905b161062574showard            contentSelect.addItem(field);
10935444864c7b6f49865a7e17aa0052987b72e4728showard        }
110c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        rowSelect.selectItem(headerFieldMap.get(DEFAULT_ROW));
111c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        columnSelect.selectItem(headerFieldMap.get(DEFAULT_COLUMN));
11277401f351bd4ef6b6af99e46a9f905b161062574showard
11377401f351bd4ef6b6af99e46a9f905b161062574showard        contentSelect.setChangeListener(new ChangeListener() {
11477401f351bd4ef6b6af99e46a9f905b161062574showard            public void onChange(Widget sender) {
11577401f351bd4ef6b6af99e46a9f905b161062574showard                if (contentSelect.hasSelection()) {
11677401f351bd4ef6b6af99e46a9f905b161062574showard                    showOnlyLatest.setChecked(true);
11777401f351bd4ef6b6af99e46a9f905b161062574showard                    showOnlyLatest.setEnabled(false);
11877401f351bd4ef6b6af99e46a9f905b161062574showard                } else {
11977401f351bd4ef6b6af99e46a9f905b161062574showard                    showOnlyLatest.setEnabled(true);
12077401f351bd4ef6b6af99e46a9f905b161062574showard                }
12177401f351bd4ef6b6af99e46a9f905b161062574showard            }
12277401f351bd4ef6b6af99e46a9f905b161062574showard        });
12377401f351bd4ef6b6af99e46a9f905b161062574showard
124c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        updateViewFromState();
125f248952e42ea33c34e41a49817e50f98c65c2716showard
12635444864c7b6f49865a7e17aa0052987b72e4728showard        queryButton.addClickListener(new ClickListener() {
12735444864c7b6f49865a7e17aa0052987b72e4728showard            public void onClick(Widget sender) {
12835444864c7b6f49865a7e17aa0052987b72e4728showard                doQuery();
12935444864c7b6f49865a7e17aa0052987b72e4728showard                updateHistory();
13035444864c7b6f49865a7e17aa0052987b72e4728showard            }
13135444864c7b6f49865a7e17aa0052987b72e4728showard        });
13235444864c7b6f49865a7e17aa0052987b72e4728showard
13335444864c7b6f49865a7e17aa0052987b72e4728showard        spreadsheet.setVisible(false);
13435444864c7b6f49865a7e17aa0052987b72e4728showard        spreadsheet.setListener(this);
13535444864c7b6f49865a7e17aa0052987b72e4728showard
13635444864c7b6f49865a7e17aa0052987b72e4728showard        SimpleHyperlink swapLink = new SimpleHyperlink("swap");
13735444864c7b6f49865a7e17aa0052987b72e4728showard        swapLink.addClickListener(new ClickListener() {
13835444864c7b6f49865a7e17aa0052987b72e4728showard            public void onClick(Widget sender) {
139f248952e42ea33c34e41a49817e50f98c65c2716showard                List<HeaderField> newRows = columnSelect.getSelectedItems();
140f248952e42ea33c34e41a49817e50f98c65c2716showard                setSelectedHeader(columnSelect, rowSelect.getSelectedItems());
14135444864c7b6f49865a7e17aa0052987b72e4728showard                setSelectedHeader(rowSelect, newRows);
14235444864c7b6f49865a7e17aa0052987b72e4728showard            }
14335444864c7b6f49865a7e17aa0052987b72e4728showard        });
14435444864c7b6f49865a7e17aa0052987b72e4728showard
1458a6eb0cf5777dded2354408e8007d9223e813c92showard        Panel filterOptions = new VerticalPanel();
1468a6eb0cf5777dded2354408e8007d9223e813c92showard        filterOptions.add(showIncomplete);
1478a6eb0cf5777dded2354408e8007d9223e813c92showard        filterOptions.add(showOnlyLatest);
1488a6eb0cf5777dded2354408e8007d9223e813c92showard
1499e494cc00c53f9dd0fabec3ef675cb874a9130adshoward        addWidget(filterOptions, "ss_filter_options");
1509e494cc00c53f9dd0fabec3ef675cb874a9130adshoward        addWidget(rowSelect, "ss_row_select");
1519e494cc00c53f9dd0fabec3ef675cb874a9130adshoward        addWidget(columnSelect, "ss_column_select");
1529e494cc00c53f9dd0fabec3ef675cb874a9130adshoward        addWidget(contentSelect, "ss_additional_content");
1539e494cc00c53f9dd0fabec3ef675cb874a9130adshoward        addWidget(swapLink, "ss_swap");
1549e494cc00c53f9dd0fabec3ef675cb874a9130adshoward        addWidget(queryButton, "ss_query_controls");
1559e494cc00c53f9dd0fabec3ef675cb874a9130adshoward        addWidget(actionsPanel, "ss_actions");
1569e494cc00c53f9dd0fabec3ef675cb874a9130adshoward        addWidget(spreadsheet, "ss_spreadsheet");
1579e494cc00c53f9dd0fabec3ef675cb874a9130adshoward        addWidget(jobCompletionPanel, "ss_job_completion");
15835444864c7b6f49865a7e17aa0052987b72e4728showard
15935444864c7b6f49865a7e17aa0052987b72e4728showard        Window.addWindowResizeListener(new WindowResizeListener() {
16035444864c7b6f49865a7e17aa0052987b72e4728showard            public void onWindowResized(int width, int height) {
16135444864c7b6f49865a7e17aa0052987b72e4728showard                if(spreadsheet.isVisible())
16235444864c7b6f49865a7e17aa0052987b72e4728showard                    spreadsheet.fillWindow(true);
16335444864c7b6f49865a7e17aa0052987b72e4728showard            }
16435444864c7b6f49865a7e17aa0052987b72e4728showard        });
16535444864c7b6f49865a7e17aa0052987b72e4728showard
16635444864c7b6f49865a7e17aa0052987b72e4728showard        setupDrilldownMap();
16735444864c7b6f49865a7e17aa0052987b72e4728showard    }
168f6348c999bc60ee048510c8e28f74f944a32d97cshoward
16935444864c7b6f49865a7e17aa0052987b72e4728showard    protected TestSet getWholeTableTestSet() {
17035444864c7b6f49865a7e17aa0052987b72e4728showard        boolean isSingleTest = spreadsheetProcessor.getNumTotalTests() == 1;
1718a6eb0cf5777dded2354408e8007d9223e813c92showard        if (isSingleTest) {
1728a6eb0cf5777dded2354408e8007d9223e813c92showard            return getTestSet(spreadsheetProcessor.getLastCellInfo());
1738a6eb0cf5777dded2354408e8007d9223e813c92showard        }
174f6348c999bc60ee048510c8e28f74f944a32d97cshoward
175f6348c999bc60ee048510c8e28f74f944a32d97cshoward        if (currentShowOnlyLatest) {
176f6348c999bc60ee048510c8e28f74f944a32d97cshoward            List<Integer> testIndices = spreadsheet.getAllTestIndices();
177f6348c999bc60ee048510c8e28f74f944a32d97cshoward            String filter = "test_idx IN (" + Utils.joinStrings(",", testIndices) + ")";
178f6348c999bc60ee048510c8e28f74f944a32d97cshoward            ConditionTestSet tests = new ConditionTestSet();
179f6348c999bc60ee048510c8e28f74f944a32d97cshoward            tests.addCondition(filter);
180f6348c999bc60ee048510c8e28f74f944a32d97cshoward            return tests;
181f6348c999bc60ee048510c8e28f74f944a32d97cshoward        }
182f6348c999bc60ee048510c8e28f74f944a32d97cshoward
1838a6eb0cf5777dded2354408e8007d9223e813c92showard        return new ConditionTestSet(getFullConditionArgs());
18435444864c7b6f49865a7e17aa0052987b72e4728showard    }
18535444864c7b6f49865a7e17aa0052987b72e4728showard
18635444864c7b6f49865a7e17aa0052987b72e4728showard    protected void setupDrilldownMap() {
18735444864c7b6f49865a7e17aa0052987b72e4728showard        drilldownMap.put("platform", new String[] {"hostname", "test_name"});
18835444864c7b6f49865a7e17aa0052987b72e4728showard        drilldownMap.put("hostname", new String[] {"job_tag", "status"});
18935444864c7b6f49865a7e17aa0052987b72e4728showard        drilldownMap.put("job_tag", new String[] {"job_tag"});
19035444864c7b6f49865a7e17aa0052987b72e4728showard
19135444864c7b6f49865a7e17aa0052987b72e4728showard        drilldownMap.put("kernel", new String[] {"test_name", "status"});
19235444864c7b6f49865a7e17aa0052987b72e4728showard        drilldownMap.put("test_name", new String[] {"job_name", "job_tag"});
19335444864c7b6f49865a7e17aa0052987b72e4728showard
19435444864c7b6f49865a7e17aa0052987b72e4728showard        drilldownMap.put("status", new String[] {"reason", "job_tag"});
19535444864c7b6f49865a7e17aa0052987b72e4728showard        drilldownMap.put("reason", new String[] {"job_tag"});
19635444864c7b6f49865a7e17aa0052987b72e4728showard
19735444864c7b6f49865a7e17aa0052987b72e4728showard        drilldownMap.put("job_owner", new String[] {"job_name", "job_tag"});
19835444864c7b6f49865a7e17aa0052987b72e4728showard        drilldownMap.put("job_name", new String[] {"job_tag"});
19935444864c7b6f49865a7e17aa0052987b72e4728showard
20035444864c7b6f49865a7e17aa0052987b72e4728showard        drilldownMap.put("test_finished_time", new String[] {"status", "job_tag"});
20135444864c7b6f49865a7e17aa0052987b72e4728showard        drilldownMap.put("DATE(test_finished_time)",
20235444864c7b6f49865a7e17aa0052987b72e4728showard                         new String[] {"test_finished_time", "job_tag"});
20335444864c7b6f49865a7e17aa0052987b72e4728showard    }
20435444864c7b6f49865a7e17aa0052987b72e4728showard
205f248952e42ea33c34e41a49817e50f98c65c2716showard    protected void setSelectedHeader(HeaderSelect list, List<HeaderField> fields) {
206f248952e42ea33c34e41a49817e50f98c65c2716showard        list.selectItems(fields);
20735444864c7b6f49865a7e17aa0052987b72e4728showard    }
20835444864c7b6f49865a7e17aa0052987b72e4728showard
20935444864c7b6f49865a7e17aa0052987b72e4728showard    @Override
21035444864c7b6f49865a7e17aa0052987b72e4728showard    public void refresh() {
21135444864c7b6f49865a7e17aa0052987b72e4728showard        notYetQueried = false;
2123d6ae118f69717e68bc15b9aed7b6a6c7dd9bab0showard        actionsPanel.setVisible(true);
21335444864c7b6f49865a7e17aa0052987b72e4728showard        spreadsheet.setVisible(false);
21435444864c7b6f49865a7e17aa0052987b72e4728showard        selectionManager.clearSelection();
21535444864c7b6f49865a7e17aa0052987b72e4728showard        spreadsheet.clear();
21635444864c7b6f49865a7e17aa0052987b72e4728showard        setJobCompletionHtml("&nbsp");
21735444864c7b6f49865a7e17aa0052987b72e4728showard
218d50ffb4b0ef514fb969d53b82e23ab41d4d3812eshoward        final JSONObject condition = getFullConditionArgs();
21977401f351bd4ef6b6af99e46a9f905b161062574showard
22077401f351bd4ef6b6af99e46a9f905b161062574showard        contentSelect.addToCondition(condition);
221c674d3ea684f75f3e05f5834b598050eb1c8856dshoward
22235444864c7b6f49865a7e17aa0052987b72e4728showard        setLoading(true);
223313ab769319f56b940a2784cc0cbdebd005c5799showard        if (currentShowOnlyLatest) {
2248a6eb0cf5777dded2354408e8007d9223e813c92showard            spreadsheetProcessor.setDataSource(latestDataSource);
2258a6eb0cf5777dded2354408e8007d9223e813c92showard        } else {
2268a6eb0cf5777dded2354408e8007d9223e813c92showard            spreadsheetProcessor.setDataSource(normalDataSource);
2278a6eb0cf5777dded2354408e8007d9223e813c92showard        }
228c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        spreadsheetProcessor.setHeaders(rowSelect.getSelectedItems(),
229c674d3ea684f75f3e05f5834b598050eb1c8856dshoward                                        columnSelect.getSelectedItems(),
230f248952e42ea33c34e41a49817e50f98c65c2716showard                                        getQueryParameters());
2318c9b839c2f5073a755952a8a865a04db3b2d4547showard        spreadsheetProcessor.refresh(condition, new Command() {
23235444864c7b6f49865a7e17aa0052987b72e4728showard            public void execute() {
23377401f351bd4ef6b6af99e46a9f905b161062574showard                condition.put("extra_info", null);
23477401f351bd4ef6b6af99e46a9f905b161062574showard
2350281350135d1216c722e1d6fb85044f505c2319bshoward                if (isJobFilteringCondition(condition)) {
2360281350135d1216c722e1d6fb85044f505c2319bshoward                    showCompletionPercentage(condition);
23735444864c7b6f49865a7e17aa0052987b72e4728showard                } else {
23835444864c7b6f49865a7e17aa0052987b72e4728showard                    setLoading(false);
23935444864c7b6f49865a7e17aa0052987b72e4728showard                }
24035444864c7b6f49865a7e17aa0052987b72e4728showard            }
24135444864c7b6f49865a7e17aa0052987b72e4728showard        });
24235444864c7b6f49865a7e17aa0052987b72e4728showard    }
24335444864c7b6f49865a7e17aa0052987b72e4728showard
244f248952e42ea33c34e41a49817e50f98c65c2716showard    private JSONObject getQueryParameters() {
245f248952e42ea33c34e41a49817e50f98c65c2716showard        JSONObject parameters = new JSONObject();
246f248952e42ea33c34e41a49817e50f98c65c2716showard        rowSelect.addQueryParameters(parameters);
247f248952e42ea33c34e41a49817e50f98c65c2716showard        columnSelect.addQueryParameters(parameters);
248f248952e42ea33c34e41a49817e50f98c65c2716showard        return parameters;
2498c9b839c2f5073a755952a8a865a04db3b2d4547showard    }
2508c9b839c2f5073a755952a8a865a04db3b2d4547showard
251d50ffb4b0ef514fb969d53b82e23ab41d4d3812eshoward    private JSONObject getFullConditionArgs() {
252c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        JSONObject args = commonPanel.getConditionArgs();
253d50ffb4b0ef514fb969d53b82e23ab41d4d3812eshoward        String condition = TkoUtils.getSqlCondition(args);
2540281350135d1216c722e1d6fb85044f505c2319bshoward        if (!condition.equals("")) {
2550281350135d1216c722e1d6fb85044f505c2319bshoward            condition = "(" + condition + ") AND ";
2560281350135d1216c722e1d6fb85044f505c2319bshoward        }
2570281350135d1216c722e1d6fb85044f505c2319bshoward        condition += "status != 'TEST_NA'";
2580281350135d1216c722e1d6fb85044f505c2319bshoward        if (!currentShowIncomplete) {
2590281350135d1216c722e1d6fb85044f505c2319bshoward            condition += " AND status != 'RUNNING'";
2600281350135d1216c722e1d6fb85044f505c2319bshoward        }
261d50ffb4b0ef514fb969d53b82e23ab41d4d3812eshoward        args.put("extra_where", new JSONString(condition));
262d50ffb4b0ef514fb969d53b82e23ab41d4d3812eshoward        return args;
2630281350135d1216c722e1d6fb85044f505c2319bshoward    }
264c674d3ea684f75f3e05f5834b598050eb1c8856dshoward
265c674d3ea684f75f3e05f5834b598050eb1c8856dshoward    private void updateStateFromView() {
266c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        rowSelect.updateStateFromView();
267c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        columnSelect.updateStateFromView();
268c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        currentShowIncomplete = showIncomplete.isChecked();
269c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        currentShowOnlyLatest = showOnlyLatest.isChecked();
270c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        commonPanel.updateStateFromView();
271c674d3ea684f75f3e05f5834b598050eb1c8856dshoward    }
2720281350135d1216c722e1d6fb85044f505c2319bshoward
27335444864c7b6f49865a7e17aa0052987b72e4728showard    public void doQuery() {
274f248952e42ea33c34e41a49817e50f98c65c2716showard        List<HeaderField> rows = rowSelect.getSelectedItems();
275f248952e42ea33c34e41a49817e50f98c65c2716showard        List<HeaderField> columns = columnSelect.getSelectedItems();
27635444864c7b6f49865a7e17aa0052987b72e4728showard        if (rows.isEmpty() || columns.isEmpty()) {
27735444864c7b6f49865a7e17aa0052987b72e4728showard            NotifyManager.getInstance().showError("You must select row and column fields");
27835444864c7b6f49865a7e17aa0052987b72e4728showard            return;
27935444864c7b6f49865a7e17aa0052987b72e4728showard        }
280c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        if (!rowSelect.checkMachineLabelHeaders() || !columnSelect.checkMachineLabelHeaders()) {
281f248952e42ea33c34e41a49817e50f98c65c2716showard            NotifyManager.getInstance().showError(
282f248952e42ea33c34e41a49817e50f98c65c2716showard                      "You must enter labels for all machine label fields");
283f248952e42ea33c34e41a49817e50f98c65c2716showard            return;
284f248952e42ea33c34e41a49817e50f98c65c2716showard        }
285c674d3ea684f75f3e05f5834b598050eb1c8856dshoward
286c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        updateStateFromView();
28735444864c7b6f49865a7e17aa0052987b72e4728showard        refresh();
28835444864c7b6f49865a7e17aa0052987b72e4728showard    }
28935444864c7b6f49865a7e17aa0052987b72e4728showard
290d50ffb4b0ef514fb969d53b82e23ab41d4d3812eshoward    private void showCompletionPercentage(JSONObject condition) {
291d50ffb4b0ef514fb969d53b82e23ab41d4d3812eshoward        rpcProxy.rpcCall("get_job_ids", condition, new JsonRpcCallback() {
29235444864c7b6f49865a7e17aa0052987b72e4728showard            @Override
29335444864c7b6f49865a7e17aa0052987b72e4728showard            public void onSuccess(JSONValue result) {
29435444864c7b6f49865a7e17aa0052987b72e4728showard                finishShowCompletionPercentage(result.isArray());
29535444864c7b6f49865a7e17aa0052987b72e4728showard                setLoading(false);
29635444864c7b6f49865a7e17aa0052987b72e4728showard            }
29735444864c7b6f49865a7e17aa0052987b72e4728showard
29835444864c7b6f49865a7e17aa0052987b72e4728showard            @Override
29935444864c7b6f49865a7e17aa0052987b72e4728showard            public void onError(JSONObject errorObject) {
30035444864c7b6f49865a7e17aa0052987b72e4728showard                super.onError(errorObject);
30135444864c7b6f49865a7e17aa0052987b72e4728showard                setLoading(false);
30235444864c7b6f49865a7e17aa0052987b72e4728showard            }
30335444864c7b6f49865a7e17aa0052987b72e4728showard        });
30435444864c7b6f49865a7e17aa0052987b72e4728showard    }
30535444864c7b6f49865a7e17aa0052987b72e4728showard
30635444864c7b6f49865a7e17aa0052987b72e4728showard    private void finishShowCompletionPercentage(JSONArray jobIds) {
30735444864c7b6f49865a7e17aa0052987b72e4728showard        final int jobCount = jobIds.size();
30835444864c7b6f49865a7e17aa0052987b72e4728showard        if (jobCount == 0) {
30935444864c7b6f49865a7e17aa0052987b72e4728showard            return;
31035444864c7b6f49865a7e17aa0052987b72e4728showard        }
31135444864c7b6f49865a7e17aa0052987b72e4728showard
31235444864c7b6f49865a7e17aa0052987b72e4728showard        JSONObject args = new JSONObject();
31335444864c7b6f49865a7e17aa0052987b72e4728showard        args.put("job__id__in", jobIds);
31435444864c7b6f49865a7e17aa0052987b72e4728showard        afeRpcProxy.rpcCall("get_hqe_percentage_complete", args, new JsonRpcCallback() {
31535444864c7b6f49865a7e17aa0052987b72e4728showard            @Override
31635444864c7b6f49865a7e17aa0052987b72e4728showard            public void onSuccess(JSONValue result) {
31735444864c7b6f49865a7e17aa0052987b72e4728showard                int percentage = (int) (result.isNumber().doubleValue() * 100);
31835444864c7b6f49865a7e17aa0052987b72e4728showard                StringBuilder message = new StringBuilder("Matching ");
31935444864c7b6f49865a7e17aa0052987b72e4728showard                if (jobCount == 1) {
32035444864c7b6f49865a7e17aa0052987b72e4728showard                    message.append("job is ");
32135444864c7b6f49865a7e17aa0052987b72e4728showard                } else {
32235444864c7b6f49865a7e17aa0052987b72e4728showard                    message.append("jobs are ");
32335444864c7b6f49865a7e17aa0052987b72e4728showard                }
32435444864c7b6f49865a7e17aa0052987b72e4728showard                message.append(percentage);
32535444864c7b6f49865a7e17aa0052987b72e4728showard                message.append("% complete");
32635444864c7b6f49865a7e17aa0052987b72e4728showard                setJobCompletionHtml(message.toString());
32735444864c7b6f49865a7e17aa0052987b72e4728showard            }
32835444864c7b6f49865a7e17aa0052987b72e4728showard        });
32935444864c7b6f49865a7e17aa0052987b72e4728showard    }
33035444864c7b6f49865a7e17aa0052987b72e4728showard
33135444864c7b6f49865a7e17aa0052987b72e4728showard    private void setJobCompletionHtml(String html) {
33235444864c7b6f49865a7e17aa0052987b72e4728showard        jobCompletionPanel.clear();
33335444864c7b6f49865a7e17aa0052987b72e4728showard        jobCompletionPanel.add(new HTML(html));
33435444864c7b6f49865a7e17aa0052987b72e4728showard    }
33535444864c7b6f49865a7e17aa0052987b72e4728showard
336d50ffb4b0ef514fb969d53b82e23ab41d4d3812eshoward    private boolean isJobFilteringCondition(JSONObject condition) {
337d50ffb4b0ef514fb969d53b82e23ab41d4d3812eshoward        return TkoUtils.getSqlCondition(condition).indexOf("job_tag") != -1;
33835444864c7b6f49865a7e17aa0052987b72e4728showard    }
33935444864c7b6f49865a7e17aa0052987b72e4728showard
34035444864c7b6f49865a7e17aa0052987b72e4728showard    public void onCellClicked(CellInfo cellInfo) {
34135444864c7b6f49865a7e17aa0052987b72e4728showard        Event event = Event.getCurrentEvent();
34235444864c7b6f49865a7e17aa0052987b72e4728showard        TestSet testSet = getTestSet(cellInfo);
34335444864c7b6f49865a7e17aa0052987b72e4728showard        DrilldownType drilldownType = getDrilldownType(cellInfo);
34435444864c7b6f49865a7e17aa0052987b72e4728showard        if (RightClickTable.isRightClick(event)) {
34535444864c7b6f49865a7e17aa0052987b72e4728showard            if (!selectionManager.isEmpty()) {
34635444864c7b6f49865a7e17aa0052987b72e4728showard                testSet = getTestSet(selectionManager.getSelectedCells());
34735444864c7b6f49865a7e17aa0052987b72e4728showard                drilldownType = DrilldownType.DRILLDOWN_BOTH;
34835444864c7b6f49865a7e17aa0052987b72e4728showard            }
34935444864c7b6f49865a7e17aa0052987b72e4728showard            ContextMenu menu = getContextMenu(testSet, drilldownType);
35035444864c7b6f49865a7e17aa0052987b72e4728showard            menu.showAtWindow(event.getClientX(), event.getClientY());
35135444864c7b6f49865a7e17aa0052987b72e4728showard            return;
35235444864c7b6f49865a7e17aa0052987b72e4728showard        }
35335444864c7b6f49865a7e17aa0052987b72e4728showard
3543b8563acf345e8327fb3f0cb4b96869ce55f5080showard        if (isSelectEvent(event)) {
35535444864c7b6f49865a7e17aa0052987b72e4728showard            selectionManager.toggleSelected(cellInfo);
35635444864c7b6f49865a7e17aa0052987b72e4728showard            return;
35735444864c7b6f49865a7e17aa0052987b72e4728showard        }
358c674d3ea684f75f3e05f5834b598050eb1c8856dshoward
359c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        HistoryToken historyToken;
36035444864c7b6f49865a7e17aa0052987b72e4728showard        if (testSet.isSingleTest()) {
361c674d3ea684f75f3e05f5834b598050eb1c8856dshoward            historyToken = listener.getSelectTestHistoryToken(testSet.getTestIndex());
362c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        } else {
363c674d3ea684f75f3e05f5834b598050eb1c8856dshoward            historyToken = getDrilldownHistoryToken(testSet,
364c674d3ea684f75f3e05f5834b598050eb1c8856dshoward                                                    getDefaultDrilldownRow(drilldownType),
365c674d3ea684f75f3e05f5834b598050eb1c8856dshoward                                                    getDefaultDrilldownColumn(drilldownType));
36635444864c7b6f49865a7e17aa0052987b72e4728showard        }
367c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        openHistoryToken(historyToken);
36835444864c7b6f49865a7e17aa0052987b72e4728showard    }
369c674d3ea684f75f3e05f5834b598050eb1c8856dshoward
370c674d3ea684f75f3e05f5834b598050eb1c8856dshoward     private DrilldownType getDrilldownType(CellInfo cellInfo) {
37135444864c7b6f49865a7e17aa0052987b72e4728showard        if (cellInfo.row == null) {
37235444864c7b6f49865a7e17aa0052987b72e4728showard            // column header
37335444864c7b6f49865a7e17aa0052987b72e4728showard            return DrilldownType.DRILLDOWN_COLUMN;
37435444864c7b6f49865a7e17aa0052987b72e4728showard        }
37535444864c7b6f49865a7e17aa0052987b72e4728showard        if (cellInfo.column == null) {
37635444864c7b6f49865a7e17aa0052987b72e4728showard            // row header
37735444864c7b6f49865a7e17aa0052987b72e4728showard            return DrilldownType.DRILLDOWN_ROW;
37835444864c7b6f49865a7e17aa0052987b72e4728showard        }
37935444864c7b6f49865a7e17aa0052987b72e4728showard        return DrilldownType.DRILLDOWN_BOTH;
38035444864c7b6f49865a7e17aa0052987b72e4728showard    }
38135444864c7b6f49865a7e17aa0052987b72e4728showard
38235444864c7b6f49865a7e17aa0052987b72e4728showard    private TestSet getTestSet(CellInfo cellInfo) {
38335444864c7b6f49865a7e17aa0052987b72e4728showard        boolean isSingleTest = cellInfo.testCount == 1;
3848a6eb0cf5777dded2354408e8007d9223e813c92showard        if (isSingleTest) {
3858a6eb0cf5777dded2354408e8007d9223e813c92showard            return new SingleTestSet(cellInfo.testIndex, getFullConditionArgs());
3868a6eb0cf5777dded2354408e8007d9223e813c92showard        }
38735444864c7b6f49865a7e17aa0052987b72e4728showard
3888a6eb0cf5777dded2354408e8007d9223e813c92showard        ConditionTestSet testSet = new ConditionTestSet(getFullConditionArgs());
38935444864c7b6f49865a7e17aa0052987b72e4728showard        if (cellInfo.row != null) {
390c674d3ea684f75f3e05f5834b598050eb1c8856dshoward            setSomeFields(testSet, rowSelect.getSelectedItems(), cellInfo.row);
39135444864c7b6f49865a7e17aa0052987b72e4728showard        }
39235444864c7b6f49865a7e17aa0052987b72e4728showard        if (cellInfo.column != null) {
393c674d3ea684f75f3e05f5834b598050eb1c8856dshoward            setSomeFields(testSet, columnSelect.getSelectedItems(), cellInfo.column);
39435444864c7b6f49865a7e17aa0052987b72e4728showard        }
39535444864c7b6f49865a7e17aa0052987b72e4728showard        return testSet;
39635444864c7b6f49865a7e17aa0052987b72e4728showard    }
39735444864c7b6f49865a7e17aa0052987b72e4728showard
398f248952e42ea33c34e41a49817e50f98c65c2716showard    private void setSomeFields(ConditionTestSet testSet, List<HeaderField> allFields,
399f248952e42ea33c34e41a49817e50f98c65c2716showard                               Header values) {
400f248952e42ea33c34e41a49817e50f98c65c2716showard        for (int i = 0; i < values.size(); i++) {
401f248952e42ea33c34e41a49817e50f98c65c2716showard            HeaderField field = allFields.get(i);
402f248952e42ea33c34e41a49817e50f98c65c2716showard            String value = values.get(i);
403f248952e42ea33c34e41a49817e50f98c65c2716showard            testSet.addCondition(field.getSqlCondition(value));
404f248952e42ea33c34e41a49817e50f98c65c2716showard        }
40535444864c7b6f49865a7e17aa0052987b72e4728showard    }
40635444864c7b6f49865a7e17aa0052987b72e4728showard
40735444864c7b6f49865a7e17aa0052987b72e4728showard    private TestSet getTestSet(List<CellInfo> cells) {
40835444864c7b6f49865a7e17aa0052987b72e4728showard        CompositeTestSet tests = new CompositeTestSet();
40935444864c7b6f49865a7e17aa0052987b72e4728showard        for (CellInfo cell : cells) {
41035444864c7b6f49865a7e17aa0052987b72e4728showard            tests.add(getTestSet(cell));
41135444864c7b6f49865a7e17aa0052987b72e4728showard        }
41235444864c7b6f49865a7e17aa0052987b72e4728showard        return tests;
41335444864c7b6f49865a7e17aa0052987b72e4728showard    }
41435444864c7b6f49865a7e17aa0052987b72e4728showard
415c674d3ea684f75f3e05f5834b598050eb1c8856dshoward    private HistoryToken getDrilldownHistoryToken(TestSet tests, String newRowField,
416c674d3ea684f75f3e05f5834b598050eb1c8856dshoward                                            String newColumnField) {
417c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        saveHistoryState();
41864aeecdec485192241e5377b3fa5ac7cf57a0c12showard        commonPanel.refineCondition(tests);
419c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        rowSelect.selectItem(headerFieldMap.get(newRowField));
420c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        columnSelect.selectItem(headerFieldMap.get(newColumnField));
421c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        HistoryToken historyArguments = getHistoryArguments();
422c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        restoreHistoryState();
423c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        return historyArguments;
424c674d3ea684f75f3e05f5834b598050eb1c8856dshoward    }
425c674d3ea684f75f3e05f5834b598050eb1c8856dshoward
426c674d3ea684f75f3e05f5834b598050eb1c8856dshoward    private void doDrilldown(TestSet tests, String newRowField, String newColumnField) {
427c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        History.newItem(getDrilldownHistoryToken(tests, newRowField, newColumnField).toString());
42835444864c7b6f49865a7e17aa0052987b72e4728showard    }
42935444864c7b6f49865a7e17aa0052987b72e4728showard
43035444864c7b6f49865a7e17aa0052987b72e4728showard    private String getDefaultDrilldownRow(DrilldownType type) {
43135444864c7b6f49865a7e17aa0052987b72e4728showard        return getDrilldownRows(type)[0];
43235444864c7b6f49865a7e17aa0052987b72e4728showard    }
43335444864c7b6f49865a7e17aa0052987b72e4728showard
43435444864c7b6f49865a7e17aa0052987b72e4728showard    private String getDefaultDrilldownColumn(DrilldownType type) {
43535444864c7b6f49865a7e17aa0052987b72e4728showard        return getDrilldownColumns(type)[0];
43635444864c7b6f49865a7e17aa0052987b72e4728showard    }
43735444864c7b6f49865a7e17aa0052987b72e4728showard
43835444864c7b6f49865a7e17aa0052987b72e4728showard    private ContextMenu getContextMenu(final TestSet tests, DrilldownType drilldownType) {
43935444864c7b6f49865a7e17aa0052987b72e4728showard        TestContextMenu menu = new TestContextMenu(tests, listener);
44035444864c7b6f49865a7e17aa0052987b72e4728showard
44135444864c7b6f49865a7e17aa0052987b72e4728showard        if (!menu.addViewDetailsIfSingleTest()) {
44235444864c7b6f49865a7e17aa0052987b72e4728showard            MenuBar drilldownMenu = menu.addSubMenuItem("Drill down");
44335444864c7b6f49865a7e17aa0052987b72e4728showard            fillDrilldownMenu(tests, drilldownType, drilldownMenu);
44435444864c7b6f49865a7e17aa0052987b72e4728showard        }
44535444864c7b6f49865a7e17aa0052987b72e4728showard
44635444864c7b6f49865a7e17aa0052987b72e4728showard        menu.addItem("View in table", new Command() {
44735444864c7b6f49865a7e17aa0052987b72e4728showard            public void execute() {
44835444864c7b6f49865a7e17aa0052987b72e4728showard                switchToTable(tests, false);
44935444864c7b6f49865a7e17aa0052987b72e4728showard            }
45035444864c7b6f49865a7e17aa0052987b72e4728showard        });
45135444864c7b6f49865a7e17aa0052987b72e4728showard        menu.addItem("Triage failures", new Command() {
45235444864c7b6f49865a7e17aa0052987b72e4728showard            public void execute() {
45335444864c7b6f49865a7e17aa0052987b72e4728showard                switchToTable(tests, true);
45435444864c7b6f49865a7e17aa0052987b72e4728showard            }
45535444864c7b6f49865a7e17aa0052987b72e4728showard        });
45635444864c7b6f49865a7e17aa0052987b72e4728showard
45735444864c7b6f49865a7e17aa0052987b72e4728showard        menu.addLabelItems();
45835444864c7b6f49865a7e17aa0052987b72e4728showard        return menu;
45935444864c7b6f49865a7e17aa0052987b72e4728showard    }
46035444864c7b6f49865a7e17aa0052987b72e4728showard
46135444864c7b6f49865a7e17aa0052987b72e4728showard    private void fillDrilldownMenu(final TestSet tests, DrilldownType drilldownType, MenuBar menu) {
46235444864c7b6f49865a7e17aa0052987b72e4728showard        for (final String rowField : getDrilldownRows(drilldownType)) {
46335444864c7b6f49865a7e17aa0052987b72e4728showard            for (final String columnField : getDrilldownColumns(drilldownType)) {
46435444864c7b6f49865a7e17aa0052987b72e4728showard                if (rowField.equals(columnField)) {
46535444864c7b6f49865a7e17aa0052987b72e4728showard                    continue;
46635444864c7b6f49865a7e17aa0052987b72e4728showard                }
46735444864c7b6f49865a7e17aa0052987b72e4728showard                menu.addItem(rowField + " vs. " + columnField, new Command() {
46835444864c7b6f49865a7e17aa0052987b72e4728showard                    public void execute() {
46935444864c7b6f49865a7e17aa0052987b72e4728showard                        doDrilldown(tests, rowField, columnField);
47035444864c7b6f49865a7e17aa0052987b72e4728showard                    }
47135444864c7b6f49865a7e17aa0052987b72e4728showard                });
47235444864c7b6f49865a7e17aa0052987b72e4728showard            }
47335444864c7b6f49865a7e17aa0052987b72e4728showard        }
47435444864c7b6f49865a7e17aa0052987b72e4728showard    }
47535444864c7b6f49865a7e17aa0052987b72e4728showard
476f248952e42ea33c34e41a49817e50f98c65c2716showard    private String[] getDrilldownFields(List<HeaderField> fields, DrilldownType type,
47735444864c7b6f49865a7e17aa0052987b72e4728showard                                        DrilldownType otherType) {
478f248952e42ea33c34e41a49817e50f98c65c2716showard        HeaderField lastField = fields.get(fields.size() - 1);
479f248952e42ea33c34e41a49817e50f98c65c2716showard        String lastFieldName = lastField.getSqlName();
48035444864c7b6f49865a7e17aa0052987b72e4728showard        if (type == otherType) {
481f248952e42ea33c34e41a49817e50f98c65c2716showard            return new String[] {lastFieldName};
48235444864c7b6f49865a7e17aa0052987b72e4728showard        } else {
483f248952e42ea33c34e41a49817e50f98c65c2716showard            if (lastField instanceof MachineLabelField) {
484f248952e42ea33c34e41a49817e50f98c65c2716showard                // treat machine label fields like platform, for the purpose of default drilldown
485f248952e42ea33c34e41a49817e50f98c65c2716showard                lastFieldName = "platform";
486f248952e42ea33c34e41a49817e50f98c65c2716showard            }
487f248952e42ea33c34e41a49817e50f98c65c2716showard            return drilldownMap.get(lastFieldName);
48835444864c7b6f49865a7e17aa0052987b72e4728showard        }
48935444864c7b6f49865a7e17aa0052987b72e4728showard    }
49035444864c7b6f49865a7e17aa0052987b72e4728showard
49135444864c7b6f49865a7e17aa0052987b72e4728showard    private String[] getDrilldownRows(DrilldownType type) {
492c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        return getDrilldownFields(rowSelect.getSelectedItems(), type,
493c674d3ea684f75f3e05f5834b598050eb1c8856dshoward                                  DrilldownType.DRILLDOWN_COLUMN);
49435444864c7b6f49865a7e17aa0052987b72e4728showard    }
49535444864c7b6f49865a7e17aa0052987b72e4728showard
49635444864c7b6f49865a7e17aa0052987b72e4728showard    private String[] getDrilldownColumns(DrilldownType type) {
497c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        return getDrilldownFields(columnSelect.getSelectedItems(), type,
498c674d3ea684f75f3e05f5834b598050eb1c8856dshoward                                  DrilldownType.DRILLDOWN_ROW);
49935444864c7b6f49865a7e17aa0052987b72e4728showard    }
50035444864c7b6f49865a7e17aa0052987b72e4728showard
501c674d3ea684f75f3e05f5834b598050eb1c8856dshoward    private void updateViewFromState() {
502c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        rowSelect.updateViewFromState();
503c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        columnSelect.updateViewFromState();
50435444864c7b6f49865a7e17aa0052987b72e4728showard        showIncomplete.setChecked(currentShowIncomplete);
505c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        showOnlyLatest.setChecked(currentShowOnlyLatest);
506c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        commonPanel.updateViewFromState();
50735444864c7b6f49865a7e17aa0052987b72e4728showard    }
50835444864c7b6f49865a7e17aa0052987b72e4728showard
50935444864c7b6f49865a7e17aa0052987b72e4728showard    @Override
510c674d3ea684f75f3e05f5834b598050eb1c8856dshoward    public HistoryToken getHistoryArguments() {
511c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        HistoryToken arguments = super.getHistoryArguments();
51235444864c7b6f49865a7e17aa0052987b72e4728showard        if (!notYetQueried) {
5138c9b839c2f5073a755952a8a865a04db3b2d4547showard            rowSelect.addHistoryArguments(arguments, HISTORY_ROW);
5148c9b839c2f5073a755952a8a865a04db3b2d4547showard            columnSelect.addHistoryArguments(arguments, HISTORY_COLUMN);
515194a59d6976a5dbd5b464fb2b14ceb089f91c050showard            contentSelect.addHistoryArguments(arguments, HISTORY_CONTENT);
5168c9b839c2f5073a755952a8a865a04db3b2d4547showard            arguments.put(HISTORY_SHOW_INCOMPLETE, Boolean.toString(currentShowIncomplete));
5178a6eb0cf5777dded2354408e8007d9223e813c92showard            arguments.put(HISTORY_ONLY_LATEST, Boolean.toString(showOnlyLatest.isChecked()));
51835444864c7b6f49865a7e17aa0052987b72e4728showard            commonPanel.addHistoryArguments(arguments);
51935444864c7b6f49865a7e17aa0052987b72e4728showard        }
52035444864c7b6f49865a7e17aa0052987b72e4728showard        return arguments;
52135444864c7b6f49865a7e17aa0052987b72e4728showard    }
52235444864c7b6f49865a7e17aa0052987b72e4728showard
52335444864c7b6f49865a7e17aa0052987b72e4728showard    @Override
52435444864c7b6f49865a7e17aa0052987b72e4728showard    public void handleHistoryArguments(Map<String, String> arguments) {
52535444864c7b6f49865a7e17aa0052987b72e4728showard        super.handleHistoryArguments(arguments);
52635444864c7b6f49865a7e17aa0052987b72e4728showard        commonPanel.handleHistoryArguments(arguments);
5278c9b839c2f5073a755952a8a865a04db3b2d4547showard        rowSelect.handleHistoryArguments(arguments, HISTORY_ROW);
5288c9b839c2f5073a755952a8a865a04db3b2d4547showard        columnSelect.handleHistoryArguments(arguments, HISTORY_COLUMN);
529194a59d6976a5dbd5b464fb2b14ceb089f91c050showard        contentSelect.handleHistoryArguments(arguments, HISTORY_CONTENT);
530c674d3ea684f75f3e05f5834b598050eb1c8856dshoward
5318c9b839c2f5073a755952a8a865a04db3b2d4547showard        currentShowIncomplete = Boolean.valueOf(arguments.get(HISTORY_SHOW_INCOMPLETE));
532194a59d6976a5dbd5b464fb2b14ceb089f91c050showard        currentShowOnlyLatest = Boolean.valueOf(arguments.get(HISTORY_ONLY_LATEST));
533c674d3ea684f75f3e05f5834b598050eb1c8856dshoward        updateViewFromState();
53435444864c7b6f49865a7e17aa0052987b72e4728showard    }
53535444864c7b6f49865a7e17aa0052987b72e4728showard
53635444864c7b6f49865a7e17aa0052987b72e4728showard    @Override
53735444864c7b6f49865a7e17aa0052987b72e4728showard    protected void fillDefaultHistoryValues(Map<String, String> arguments) {
5388c9b839c2f5073a755952a8a865a04db3b2d4547showard        Utils.setDefaultValue(arguments, HISTORY_ROW, DEFAULT_ROW);
5398c9b839c2f5073a755952a8a865a04db3b2d4547showard        Utils.setDefaultValue(arguments, HISTORY_COLUMN, DEFAULT_COLUMN);
5408c9b839c2f5073a755952a8a865a04db3b2d4547showard        Utils.setDefaultValue(arguments, HISTORY_ROW + HeaderSelect.HISTORY_FIXED_VALUES, "");
5418c9b839c2f5073a755952a8a865a04db3b2d4547showard        Utils.setDefaultValue(arguments, HISTORY_COLUMN + HeaderSelect.HISTORY_FIXED_VALUES, "");
5428a6eb0cf5777dded2354408e8007d9223e813c92showard        Utils.setDefaultValue(arguments, HISTORY_SHOW_INCOMPLETE, Boolean.toString(false));
5438a6eb0cf5777dded2354408e8007d9223e813c92showard        Utils.setDefaultValue(arguments, HISTORY_ONLY_LATEST, Boolean.toString(false));
54435444864c7b6f49865a7e17aa0052987b72e4728showard    }
54535444864c7b6f49865a7e17aa0052987b72e4728showard
54635444864c7b6f49865a7e17aa0052987b72e4728showard    private void switchToTable(final TestSet tests, boolean isTriageView) {
54764aeecdec485192241e5377b3fa5ac7cf57a0c12showard        commonPanel.refineCondition(tests);
548ce12f55f4530950f7fc6ddc73d1867ebb954d356showard        TableViewConfig config;
549ce12f55f4530950f7fc6ddc73d1867ebb954d356showard        if (isTriageView) {
550ce12f55f4530950f7fc6ddc73d1867ebb954d356showard            config = TableViewConfig.TRIAGE;
551313ab769319f56b940a2784cc0cbdebd005c5799showard            refineConditionForTriage();
552ce12f55f4530950f7fc6ddc73d1867ebb954d356showard        } else {
553ce12f55f4530950f7fc6ddc73d1867ebb954d356showard            config = TableViewConfig.DEFAULT;
554ce12f55f4530950f7fc6ddc73d1867ebb954d356showard        }
555ce12f55f4530950f7fc6ddc73d1867ebb954d356showard        listener.onSwitchToTable(config);
55635444864c7b6f49865a7e17aa0052987b72e4728showard    }
55735444864c7b6f49865a7e17aa0052987b72e4728showard
558313ab769319f56b940a2784cc0cbdebd005c5799showard    private void refineConditionForTriage() {
559313ab769319f56b940a2784cc0cbdebd005c5799showard        commonPanel.refineCondition("status != 'GOOD'");
560313ab769319f56b940a2784cc0cbdebd005c5799showard    }
561313ab769319f56b940a2784cc0cbdebd005c5799showard
56235444864c7b6f49865a7e17aa0052987b72e4728showard    public ContextMenu getActionMenu() {
56335444864c7b6f49865a7e17aa0052987b72e4728showard        TestSet tests;
56435444864c7b6f49865a7e17aa0052987b72e4728showard        if (selectionManager.isEmpty()) {
56535444864c7b6f49865a7e17aa0052987b72e4728showard            tests = getWholeTableTestSet();
56635444864c7b6f49865a7e17aa0052987b72e4728showard        } else {
56735444864c7b6f49865a7e17aa0052987b72e4728showard            tests = getTestSet(selectionManager.getSelectedCells());
56835444864c7b6f49865a7e17aa0052987b72e4728showard        }
56935444864c7b6f49865a7e17aa0052987b72e4728showard        return getContextMenu(tests, DrilldownType.DRILLDOWN_BOTH);
57035444864c7b6f49865a7e17aa0052987b72e4728showard    }
57135444864c7b6f49865a7e17aa0052987b72e4728showard
5723d6ae118f69717e68bc15b9aed7b6a6c7dd9bab0showard    public void onExportCsv() {
573194a59d6976a5dbd5b464fb2b14ceb089f91c050showard        JSONObject params = new JSONObject();
574194a59d6976a5dbd5b464fb2b14ceb089f91c050showard        contentSelect.addToCondition(params);
575194a59d6976a5dbd5b464fb2b14ceb089f91c050showard        TkoUtils.doCsvRequest(spreadsheetProcessor.getDataSource(), params);
5763d6ae118f69717e68bc15b9aed7b6a6c7dd9bab0showard    }
5773d6ae118f69717e68bc15b9aed7b6a6c7dd9bab0showard
57835444864c7b6f49865a7e17aa0052987b72e4728showard    public void onSelectAll(boolean ignored) {
57935444864c7b6f49865a7e17aa0052987b72e4728showard        selectionManager.selectAll();
58035444864c7b6f49865a7e17aa0052987b72e4728showard    }
58135444864c7b6f49865a7e17aa0052987b72e4728showard
58235444864c7b6f49865a7e17aa0052987b72e4728showard    public void onSelectNone() {
58335444864c7b6f49865a7e17aa0052987b72e4728showard        selectionManager.clearSelection();
58435444864c7b6f49865a7e17aa0052987b72e4728showard    }
58535444864c7b6f49865a7e17aa0052987b72e4728showard
58635444864c7b6f49865a7e17aa0052987b72e4728showard    @Override
58735444864c7b6f49865a7e17aa0052987b72e4728showard    protected boolean hasFirstQueryOccurred() {
58835444864c7b6f49865a7e17aa0052987b72e4728showard        return !notYetQueried;
58935444864c7b6f49865a7e17aa0052987b72e4728showard    }
59035444864c7b6f49865a7e17aa0052987b72e4728showard
59135444864c7b6f49865a7e17aa0052987b72e4728showard    private void setLoading(boolean loading) {
59235444864c7b6f49865a7e17aa0052987b72e4728showard        queryButton.setEnabled(!loading);
59335444864c7b6f49865a7e17aa0052987b72e4728showard        NotifyManager.getInstance().setLoading(loading);
59435444864c7b6f49865a7e17aa0052987b72e4728showard    }
5950c31bc5ef2ecdf8edf19468e1a373520110f5bc6showard
5960c31bc5ef2ecdf8edf19468e1a373520110f5bc6showard    public void onSetControlsVisible(boolean visible) {
5970c31bc5ef2ecdf8edf19468e1a373520110f5bc6showard        TkoUtils.setElementVisible("ss_all_controls", visible);
5980c31bc5ef2ecdf8edf19468e1a373520110f5bc6showard        if (isTabVisible()) {
5990c31bc5ef2ecdf8edf19468e1a373520110f5bc6showard            spreadsheet.fillWindow(true);
6000c31bc5ef2ecdf8edf19468e1a373520110f5bc6showard        }
6010c31bc5ef2ecdf8edf19468e1a373520110f5bc6showard    }
60235444864c7b6f49865a7e17aa0052987b72e4728showard}
603