Ver código fonte

HPCC-8582 Add Back/Forward Support

Add better back/forward button handling with Tabbed Widgets.

Fixes HPCC-8582

Signed-off-by: Gordon Smith <gordon.smith@lexisnexis.com>
Gordon Smith 12 anos atrás
pai
commit
f91bbbfbd5

+ 4 - 0
esp/files/css/hpcc.css

@@ -169,6 +169,10 @@ form h2{
     display: none !important;
 }
 
+.hpccApp {
+    height: 100%;
+}
+
 .toolTip{
 width:500px;
 }

+ 4 - 0
esp/files/scripts/DFUSearchWidget.js

@@ -158,6 +158,10 @@ define([
 
         //  Implementation  ---
         init: function (params) {
+            if (this.initalized)
+                return;
+            this.initalized = true;
+
             //dom.byId("showWuid").innerHTML = params.Wuid;
             if (params.Wuid) {
                 //dom.byId(this.id + "Wuid").innerHTML = params.Wuid;

+ 4 - 0
esp/files/scripts/DFUWUDetailsWidget.js

@@ -148,6 +148,10 @@ define([
 
         //  Implementation  ---
         init: function (params) {
+            if (this.initalized)
+                return;
+            this.initalized = true;
+
             //dom.byId("showWuid").innerHTML = params.Wuid;
             if (params.Wuid) {
                 registry.byId(this.id + "Summary").set("title", params.Wuid);

+ 49 - 51
esp/files/scripts/DFUWUQueryWidget.js

@@ -20,7 +20,6 @@ define([
     "dojo/date",
     "dojo/on",
 
-    "dijit/layout/_LayoutWidget",
     "dijit/_TemplatedMixin",
     "dijit/_WidgetsInTemplateMixin",
     "dijit/registry",
@@ -29,6 +28,7 @@ define([
     "dojox/grid/enhanced/plugins/Pagination",
     "dojox/grid/enhanced/plugins/IndirectSelection",
 
+    "hpcc/_TabContainerWidget",
     "hpcc/WsDfu",
     "hpcc/LFDetailsWidget",
 
@@ -45,50 +45,25 @@ define([
     "dijit/Toolbar",
     "dijit/TooltipDialog"
 ], function (declare, dom, ObjectStore, date, on,
-                _LayoutWidget, _TemplatedMixin, _WidgetsInTemplateMixin, registry,
+                _TemplatedMixin, _WidgetsInTemplateMixin, registry,
                 EnhancedGrid, Pagination, IndirectSelection,
-                WsDfu, LFDetailsWidget,
+                _TabContainerWidget, WsDfu, LFDetailsWidget,
                 template) {
-    return declare("DFUWUQueryWidget", [_LayoutWidget, _TemplatedMixin, _WidgetsInTemplateMixin], {
+    return declare("DFUWUQueryWidget", [_TabContainerWidget, _TemplatedMixin, _WidgetsInTemplateMixin], {
         templateString: template,
         baseClass: "DFUWUQueryWidget",
-        borderContainer: null,
-        tabContainer: null,
+        workunitsTab: null,
         workunitsGrid: null,
         legacyPane: null,
         legacyPaneLoaded: false,
 
         tabMap: [],
 
-        buildRendering: function (args) {
-            this.inherited(arguments);
-        },
-
         postCreate: function (args) {
             this.inherited(arguments);
-            this.borderContainer = registry.byId(this.id + "BorderContainer");
-            this.tabContainer = registry.byId(this.id + "TabContainer");
+            this.workunitsTab = registry.byId(this.id + "_Workunits");
             this.workunitsGrid = registry.byId(this.id + "WorkunitsGrid");
-            this.legacyPane = registry.byId(this.id + "Legacy");
-
-            var context = this;
-            this.tabContainer.watch("selectedChildWidget", function (name, oval, nval) {
-                if (nval.id == context.id + "Workunits") {
-                } else if (nval.id == context.id + "Legacy") {
-                    if (!context.legacyPaneLoaded) {
-                        context.legacyPaneLoaded = true;
-                        context.legacyPane.set("content", dojo.create("iframe", {
-                            src: "/WsDfu/DFUQuery",
-                            style: "border: 0; width: 100%; height: 100%"
-                        }));
-                    }
-                } else {
-                    if (!nval.initalized) {
-                        nval.init(nval.params);
-                    }
-                }
-                context.selectedTab = nval;
-            });
+            this.legacyPane = registry.byId(this.id + "_Legacy");
         },
 
         startup: function (args) {
@@ -97,26 +72,20 @@ define([
             this.initWorkunitsGrid();
         },
 
-        resize: function (args) {
-            this.inherited(arguments);
-            this.borderContainer.resize();
-        },
-
-        layout: function (args) {
-            this.inherited(arguments);
-        },
-
-        destroy: function (args) {
-            this.inherited(arguments);
-        },
-
         //  Hitched actions  ---
         _onOpen: function (event) {
             var selections = this.workunitsGrid.selection.getSelected();
+            var firstTab = null;
             for (var i = selections.length - 1; i >= 0; --i) {
-                this.ensurePane(selections[i].Name, {
+                var tab = this.ensurePane(this.id + "_" + selections[i].Name, {
                     Name: selections[i].Name
                 });
+                if (i == 0) {
+                    firstTab = tab;
+                }
+            }
+            if (firstTab) {
+                this.selectChild(firstTab, true);
             }
         },
         _onDelete: function (event) {
@@ -191,6 +160,31 @@ define([
 
         //  Implementation  ---
         init: function (params) {
+            if (this.initalized)
+                return;
+            this.initalized = true;
+
+            this.selectChild(this.workunitsTab, true);
+        },
+
+        initTab: function() {
+            var currSel = this.getSelectedChild();
+            if (currSel && !currSel.initalized) {
+                if (currSel.id == this.workunitsTab.id) {
+                } else if (currSel.id == this.legacyPane.id) {
+                    if (!this.legacyPaneLoaded) {
+                        this.legacyPaneLoaded = true;
+                        this.legacyPane.set("content", dojo.create("iframe", {
+                            src: "/WsDfu/DFUQuery",
+                            style: "border: 0; width: 100%; height: 100%"
+                        }));
+                    }
+                } else {
+                    if (!currSel.initalized) {
+                        currSel.init(currSel.params);
+                    }
+                }
+            }
         },
 
         initWorkunitsGrid: function() {
@@ -283,12 +277,16 @@ define([
         },
 
         ensurePane: function (id, params) {
+            var obj = id.split("::");
+            id = obj.join("");
+            obj = id.split(".");
+            id = obj.join("");
             var retVal = this.tabMap[id];
             if (!retVal) {
                 var context = this;
                 retVal = new LFDetailsWidget({
-                    Name: id,
-                    title: id,
+                    id: id,
+                    title: params.Name,
                     closable: true,
                     onClose: function () {
                         delete context.tabMap[id];
@@ -297,16 +295,16 @@ define([
                     params: params
                 });
                 this.tabMap[id] = retVal;
-                this.tabContainer.addChild(retVal, 2);
+                this.addChild(retVal, 2);
             }
             return retVal;
         },
 
         onRowDblClick: function (name) {
-            var wuTab = this.ensurePane(name, {
+            var wuTab = this.ensurePane(this.id + "_" + name, {
                 Name: name
             });
-            this.tabContainer.selectChild(wuTab);
+            this.selectChild(wuTab);
         }
     });
 });

+ 5 - 1
esp/files/scripts/ECLPlaygroundWidget.js

@@ -75,7 +75,7 @@ define([
             var context = this;
             this.borderContainer = registry.byId(this.id + "BorderContainer");
             this.targetSelectWidget = registry.byId(this.id + "TargetSelect");
-            this.resultsWidget = registry.byId(this.id + "Results");
+            this.resultsWidget = registry.byId(this.id + "_Results");
             this.resultsWidget.onErrorClick = function (line, col) {
                 context.editorControl.setCursor(line, col);
             };
@@ -88,6 +88,10 @@ define([
         },
 
         init: function (params) {
+            if (this.initalized)
+                return;
+            this.initalized = true;
+
             if (params.Wuid) {
                 this.hideTitle();
             }

+ 4 - 0
esp/files/scripts/ECLSourceWidget.js

@@ -68,6 +68,10 @@ define([
 
             //  Plugin wrapper  ---
             init: function (params) {
+                if (this.initalized)
+                    return;
+                this.initalized = true;
+
                 this.editor = CodeMirror.fromTextArea(document.getElementById(this.id + "EclCode"), {
                     tabMode: "indent",
                     matchBrackets: true,

+ 4 - 0
esp/files/scripts/FilePartsWidget.js

@@ -74,6 +74,10 @@ define([
 
             //  Plugin wrapper  ---
             init: function (params) {
+                if (this.initalized)
+                    return;
+                this.initalized = true;
+
                 var memory = new Memory({ data: params.fileParts });
                 this.store = new ObjectStore({ objectStore: memory });
                 this.filePartsGrid.setStore(this.store);

+ 3 - 0
esp/files/scripts/GetDFUWorkunitsWidget.js

@@ -214,6 +214,9 @@ define([
 
         //  Implementation  ---
         init: function (params) {
+            if (this.initalized)
+                return;
+            this.initalized = true;
         },
 
         initWorkunitsGrid: function() {

+ 18 - 43
esp/files/scripts/GraphsWidget.js

@@ -18,11 +18,11 @@ define([
     "dojo/_base/lang",
     "dojo/dom",
 
-    "dijit/layout/_LayoutWidget",
     "dijit/_TemplatedMixin",
     "dijit/_WidgetsInTemplateMixin",
     "dijit/registry",
 
+    "hpcc/_TabContainerWidget",
     "hpcc/ESPWorkunit",
     "hpcc/GraphPageWidget",
 
@@ -30,55 +30,23 @@ define([
 
     "dijit/layout/TabContainer"
 ], function (declare, lang, dom, 
-                _LayoutWidget, _TemplatedMixin, _WidgetsInTemplateMixin, registry,
-                ESPWorkunit, GraphPageWidget,
+                _TemplatedMixin, _WidgetsInTemplateMixin, registry,
+                _TabContainerWidget, ESPWorkunit, GraphPageWidget,
                 template) {
-    return declare("GraphsWidget", [_LayoutWidget, _TemplatedMixin, _WidgetsInTemplateMixin], {
+    return declare("GraphsWidget", [_TabContainerWidget, _TemplatedMixin, _WidgetsInTemplateMixin], {
         templateString: template,
         baseClass: "GraphsWidget",
 
-        //borderContainer: null,
-        tabContainer: null,
         tabMap: [],
-        selectedTab: null,
 
-        buildRendering: function (args) {
-            this.inherited(arguments);
-        },
-
-        postCreate: function (args) {
-            this.inherited(arguments);
-            this._initControls();
-        },
-
-        startup: function (args) {
-            this.inherited(arguments);
-        },
-
-        resize: function (args) {
-            this.inherited(arguments);
-            this.tabContainer.resize();
-        },
-
-        layout: function (args) {
-            this.inherited(arguments);
-        },
-
-        //  Implementation  ---
         onErrorClick: function (line, col) {
         },
 
-        _initControls: function () {
-            var context = this;
-            this.tabContainer = registry.byId(this.id + "TabContainer");
-
-            var context = this;
-            this.tabContainer.watch("selectedChildWidget", function (name, oval, nval) {
-                if (!nval.initalized) {
-                    nval.init(nval.params);
-                }
-                context.selectedTab = nval;
-            });
+        initTab: function () {
+            var currSel = this.getSelectedChild();
+            if (currSel && !currSel.initalized) {
+                currSel.init(currSel.params);
+            }
         },
 
         ensurePane: function (id, params) {
@@ -93,11 +61,15 @@ define([
                     });
                 }
                 this.tabMap[id] = retVal;
-                this.tabContainer.addChild(retVal);
+                this.addChild(retVal);
             }
         },
 
         init: function (params) {
+            if (this.initalized)
+                return;
+            this.initalized = true;
+
             if (params.Wuid) {
                 this.wu = new ESPWorkunit({
                     Wuid: params.Wuid
@@ -109,9 +81,12 @@ define([
                         context.wu.getInfo({
                             onGetGraphs: function (graphs) {
                                 for (var i = 0; i < graphs.length; ++i) {
-                                    context.ensurePane(context.id + "graph_" + i, {
+                                    context.ensurePane(context.id + "_graph" + i, {
                                         graph: graphs[i]
                                     });
+                                    if (i == 0) {
+                                        context.initTab();
+                                    }
                                 }
                             }
                         });

+ 4 - 0
esp/files/scripts/InfoGridWidget.js

@@ -141,6 +141,10 @@ define([
             },
 
             init: function (params) {
+                if (this.initalized)
+                    return;
+                this.initalized = true;
+
                 if (params.onErrorClick) {
                     this.onErrorClick = params.onErrorClick;
                 }

+ 84 - 100
esp/files/scripts/LFDetailsWidget.js

@@ -19,7 +19,6 @@ define([
     "dojo/dom",
     "dojo/dom-class",
 
-    "dijit/layout/_LayoutWidget",
     "dijit/_TemplatedMixin",
     "dijit/_WidgetsInTemplateMixin",
     "dijit/layout/BorderContainer",
@@ -32,6 +31,7 @@ define([
     "dijit/TitlePane",
     "dijit/registry",
 
+    "hpcc/_TabContainerWidget",
     "hpcc/ResultWidget",
     "hpcc/ECLSourceWidget",
     "hpcc/FilePartsWidget",
@@ -42,17 +42,17 @@ define([
 
     "dojo/text!../templates/LFDetailsWidget.html"
 ], function (declare, lang, dom, domClass, 
-                _LayoutWidget, _TemplatedMixin, _WidgetsInTemplateMixin, BorderContainer, TabContainer, ContentPane, Toolbar, TooltipDialog, SimpleTextarea, Button, TitlePane, registry,
-                ResultWidget, EclSourceWidget, FilePartsWidget, WUDetailsWidget, DFUWUDetailsWidget,
+                _TemplatedMixin, _WidgetsInTemplateMixin, BorderContainer, TabContainer, ContentPane, Toolbar, TooltipDialog, SimpleTextarea, Button, TitlePane, registry,
+                _TabContainerWidget, ResultWidget, EclSourceWidget, FilePartsWidget, WUDetailsWidget, DFUWUDetailsWidget,
                 ESPLogicalFile,
                 template) {
-    return declare("LFDetailsWidget", [_LayoutWidget, _TemplatedMixin, _WidgetsInTemplateMixin], {
+    return declare("LFDetailsWidget", [_TabContainerWidget, _TemplatedMixin, _WidgetsInTemplateMixin], {
         templateString: template,
         baseClass: "LFDetailsWidget",
         borderContainer: null,
         tabContainer: null,
-        resultWidget: null,
-        resultWidgetLoaded: false,
+        contentWidget: null,
+        contentWidgetLoaded: false,
         sourceWidget: null,
         sourceWidgetLoaded: false,
         defWidget: null,
@@ -70,87 +70,19 @@ define([
 
         logicalFile: null,
         prevState: "",
-        initiated: false,
-
-        buildRendering: function (args) {
-            this.inherited(arguments);
-        },
+        initalized: false,
 
         postCreate: function (args) {
             this.inherited(arguments);
-            this.borderContainer = registry.byId(this.id + "BorderContainer");
-            this.tabContainer = registry.byId(this.id + "TabContainer");
-            this.resultWidget = registry.byId(this.id + "Content");
-            this.sourceWidget = registry.byId(this.id + "Source");
-            this.defWidget = registry.byId(this.id + "DEF");
-            this.xmlWidget = registry.byId(this.id + "XML");
-            this.filePartsWidget = registry.byId(this.id + "FileParts");
-            this.workunitWidget = registry.byId(this.id + "Workunit");
-            this.dfuWorkunitWidget = registry.byId(this.id + "DFUWorkunit");
-            this.legacyPane = registry.byId(this.id + "Legacy");
-
-            var context = this;
-            this.tabContainer.watch("selectedChildWidget", function (name, oval, nval) {
-                if (nval.id == context.id + "Content" && !context.resultWidgetLoaded) {
-                    context.resultWidgetLoaded = true;
-                    context.resultWidget.init({
-                        result: context.logicalFile.result
-                    });
-                } else if (nval.id == context.id + "Source" && !context.sourceWidgetLoaded) {
-                    context.sourceWidgetLoaded = true;
-                    context.sourceWidget.init({
-                        ECL: context.logicalFile.DFUInfoResponse.Ecl
-                    });
-                } else if (nval.id == context.id + "DEF" && !context.defWidgetLoaded) {
-                    context.logicalFile.fetchDEF(function (response) {
-                        context.defWidgetLoaded = true;
-                        context.defWidget.init({
-                            ECL: response
-                        });
-                    });
-                } else if (nval.id == context.id + "XML" && !context.xmlWidgetLoaded) {
-                    context.logicalFile.fetchXML(function (response) {
-                        context.xmlWidgetLoaded = true;
-                        context.xmlWidget.init({
-                            ECL: response
-                        });
-                    });
-                } else if (nval.id == context.id + "FileParts" && !context.filePartsWidgetLoaded) {
-                    context.filePartsWidgetLoaded = true;
-                    context.filePartsWidget.init({
-                        fileParts: lang.exists("logicalFile.DFUInfoResponse.DFUFileParts.DFUPart", context) ? context.logicalFile.DFUInfoResponse.DFUFileParts.DFUPart : []
-                    });
-                } else if (nval.id == context.id + "Workunit" && !context.workunitWidgetLoaded) {
-                    context.workunitWidgetLoaded = true;
-                    context.workunitWidget.init({
-                        Wuid: context.logicalFile.DFUInfoResponse.Wuid
-                    });
-                } else if (nval.id == context.id + "DFUWorkunit" && !context.workunitWidgetLoaded) {
-                    context.dfuWorkunitWidgetLoaded = true;
-                    context.dfuWorkunitWidget.init({
-                        Wuid: context.logicalFile.DFUInfoResponse.Wuid
-                    });
-                } else if (nval.id == context.id + "Legacy" && !context.legacyPaneLoaded) {
-                    context.legacyPaneLoaded = true;
-                    context.legacyPane.set("content", dojo.create("iframe", {
-                        src: "/WsDfu/DFUInfo?Name=" + context.logicalFile.logicalName,//+ "&Cluster=" + context.logicalFile.cluster,
-                        style: "border: 0; width: 100%; height: 100%"
-                    }));
-                }
-            });
-        },
-
-        startup: function (args) {
-            this.inherited(arguments);
-        },
-
-        resize: function (args) {
-            this.inherited(arguments);
-            this.borderContainer.resize();
-        },
-
-        layout: function (args) {
-            this.inherited(arguments);
+            this.summaryWidget = registry.byId(this.id + "_Summary");
+            this.contentWidget = registry.byId(this.id + "_Content");
+            this.sourceWidget = registry.byId(this.id + "_Source");
+            this.defWidget = registry.byId(this.id + "_DEF");
+            this.xmlWidget = registry.byId(this.id + "_XML");
+            this.filePartsWidget = registry.byId(this.id + "_FileParts");
+            this.workunitWidget = registry.byId(this.id + "_Workunit");
+            this.dfuWorkunitWidget = registry.byId(this.id + "_DFUWorkunit");
+            this.legacyPane = registry.byId(this.id + "_Legacy");
         },
 
         //  Hitched actions  ---
@@ -194,17 +126,71 @@ define([
 
         //  Implementation  ---
         init: function (params) {
-            if (!this.initiated) {
-                this.initiated = true;
-                if (params.Name) {
-                    dom.byId(this.id + "LogicalFileName").innerHTML = params.Name;
-                    //dom.byId(this.id + "LogicalFileName2").value = params.Name;
-                    this.logicalFile = new ESPLogicalFile({
-                        cluster: params.Cluster,
-                        logicalName: params.Name
+            if (this.initalized)
+                return;
+            this.initalized = true;
+
+            if (params.Name) {
+                dom.byId(this.id + "LogicalFileName").innerHTML = params.Name;
+                //dom.byId(this.id + "LogicalFileName2").value = params.Name;
+                this.logicalFile = new ESPLogicalFile({
+                    cluster: params.Cluster,
+                    logicalName: params.Name
+                });
+                this.refreshPage();
+            }
+            this.selectChild(this.summaryWidget, true);
+        },
+
+        initTab: function() {
+            var currSel = this.getSelectedChild();
+            if (currSel.id == this.contentWidget.id && !this.contentWidgetLoaded) {
+                this.contentWidgetLoaded = true;
+                this.contentWidget.init({
+                    result: this.logicalFile.result
+                });
+            } else if (currSel.id == this.sourceWidget.id && !this.sourceWidgetLoaded) {
+                this.sourceWidgetLoaded = true;
+                this.sourceWidget.init({
+                    ECL: this.logicalFile.DFUInfoResponse.Ecl
+                });
+            } else if (currSel.id == this.defWidget.id && !this.defWidgetLoaded) {
+                var context = this;
+                this.logicalFile.fetchDEF(function (response) {
+                    context.defWidgetLoaded = true;
+                    context.defWidget.init({
+                        ECL: response
                     });
-                    this.refreshPage();
-                }
+                });
+            } else if (currSel.id == this.xmlWidget.id && !this.xmlWidgetLoaded) {
+                var context = this;
+                this.logicalFile.fetchXML(function (response) {
+                    context.xmlWidgetLoaded = true;
+                    context.xmlWidget.init({
+                        ECL: response
+                    });
+                });
+            } else if (currSel.id == this.filePartsWidget.id && !this.filePartsWidgetLoaded) {
+                this.filePartsWidgetLoaded = true;
+                this.filePartsWidget.init({
+                    fileParts: lang.exists("logicalFile.DFUInfoResponse.DFUFileParts.DFUPart", this) ? this.logicalFile.DFUInfoResponse.DFUFileParts.DFUPart : []
+                });
+            } else if (this.workunitWidget && currSel.id == this.workunitWidget.id && !this.workunitWidgetLoaded) {
+                this.workunitWidgetLoaded = true;
+                this.workunitWidget.init({
+                    Wuid: this.logicalFile.DFUInfoResponse.Wuid
+                });
+            } else if (this.dfuWorkunitWidget && currSel.id == this.dfuWorkunitWidget.id && !this.workunitWidgetLoaded) {
+                this.dfuWorkunitWidgetLoaded = true;
+                this.dfuWorkunitWidget.init({
+                    Wuid: this.logicalFile.DFUInfoResponse.Wuid
+                });
+            } else if (currSel.id == this.legacyPane.id && !this.legacyPaneLoaded) {
+                this.legacyPaneLoaded = true;
+                this.legacyPane.set("content", dojo.create("iframe", {
+                    src: "/WsDfu/DFUInfo?Name=" + this.logicalFile.logicalName,//+ "&Cluster=" + this.logicalFile.cluster,
+                    style: "border: 0; width: 100%; height: 100%"
+                }));
             }
         },
 
@@ -225,15 +211,13 @@ define([
         },
         refreshFileDetails: function (fileDetails) {
             if (fileDetails.Wuid && fileDetails.Wuid[0] == "D" && this.workunitWidget) {
-                this.tabContainer.removeChild(this.workunitWidget);
-                this.workunitWidget.destroyRecursive();
+                this.removeChild(this.workunitWidget);
                 this.workunitWidget = null;
             } else if (this.dfuWorkunitWidget) {
-                this.tabContainer.removeChild(this.dfuWorkunitWidget);
-                this.dfuWorkunitWidget.destroyRecursive();
+                this.removeChild(this.dfuWorkunitWidget);
                 this.dfuWorkunitWidget = null;
             }
-            registry.byId(this.id + "Summary").set("title", fileDetails.Filename);
+            registry.byId(this.id + "_Summary").set("title", fileDetails.Filename);
             //registry.byId(this.id + "Summary").set("iconClass", "iconRefresh");
             //domClass.remove(this.id + "Test");
             //domClass.add(this.id + "Test", "iconRefresh");
@@ -245,7 +229,7 @@ define([
             dom.byId(this.id + "Directory").innerHTML = fileDetails.Dir;
             dom.byId(this.id + "RecordSize").innerHTML = fileDetails.RecordSize;
             dom.byId(this.id + "Count").innerHTML = fileDetails.RecordCount;
-            this.resultWidget.set("title", "Content " + "(" + fileDetails.RecordCount + ")");
+            this.contentWidget.set("title", "Content " + "(" + fileDetails.RecordCount + ")");
             dom.byId(this.id + "Filesize").innerHTML = fileDetails.Filesize;
             dom.byId(this.id + "Pathmask").innerHTML = fileDetails.PathMask;
         }

+ 4 - 0
esp/files/scripts/LogsWidget.js

@@ -139,6 +139,10 @@ define([
             },
             //  Plugin wrapper  ---
             init: function (params) {
+                if (this.initalized)
+                    return;
+                this.initalized = true;
+
                 this.wu = new ESPWorkunit({
                     Wuid: params.Wuid
                 });

+ 1 - 0
esp/files/scripts/ResultWidget.js

@@ -120,6 +120,7 @@ define([
                 return;
             }
             this.initalized = true;
+
             this.result = params.result;
             //TODO:  Encapsulate this IF into ESPResult.js
             if (params.result && params.result.canShowResults()) {

+ 29 - 51
esp/files/scripts/ResultsWidget.js

@@ -18,21 +18,21 @@ define([
     "dojo/_base/lang",
     "dojo/dom",
 
-    "dijit/layout/_LayoutWidget",
     "dijit/_TemplatedMixin",
     "dijit/_WidgetsInTemplateMixin",
     "dijit/registry",
 
+    "hpcc/_TabContainerWidget",
     "hpcc/ESPWorkunit",
 
     "dojo/text!../templates/ResultsWidget.html",
 
     "dijit/layout/TabContainer"
 ], function (declare, lang, dom, 
-                _LayoutWidget, _TemplatedMixin, _WidgetsInTemplateMixin, registry,
-                ESPWorkunit, 
+                _TemplatedMixin, _WidgetsInTemplateMixin, registry,
+                _TabContainerWidget, ESPWorkunit,
                 template) {
-    return declare("ResultsWidget", [_LayoutWidget, _TemplatedMixin, _WidgetsInTemplateMixin], {
+    return declare("ResultsWidget", [_TabContainerWidget, _TemplatedMixin, _WidgetsInTemplateMixin], {
         templateString: template,
         baseClass: "ResultsWidget",
 
@@ -41,45 +41,14 @@ define([
         tabMap: [],
         selectedTab: null,
 
-        buildRendering: function (args) {
-            this.inherited(arguments);
-        },
-
-        postCreate: function (args) {
-            this.inherited(arguments);
-            this._initControls();
-        },
-
-        startup: function (args) {
-            this.inherited(arguments);
-        },
-
-        resize: function (args) {
-            this.inherited(arguments);
-            //this.borderContainer.resize();
-            this.tabContainer.resize();
-        },
-
-        layout: function (args) {
-            this.inherited(arguments);
-        },
-
-        //  Implementation  ---
         onErrorClick: function (line, col) {
         },
 
-        _initControls: function () {
-            var context = this;
-            //this.borderContainer = registry.byId(this.id + "BorderContainer");
-            this.tabContainer = registry.byId(this.id + "TabContainer");
-
-            var context = this;
-            this.tabContainer.watch("selectedChildWidget", function (name, oval, nval) {
-                if (!nval.initalized) {
-                    nval.init(nval.params);
-                }
-                context.selectedTab = nval;
-            });
+        initTab: function () {
+            var currSel = this.getSelectedChild();
+            if (currSel && !currSel.initalized) {
+                currSel.init(currSel.params);
+            }
         },
 
         ensurePane: function (id, params) {
@@ -105,11 +74,16 @@ define([
                     });
                 }
                 this.tabMap[id] = retVal;
-                this.tabContainer.addChild(retVal);
+                this.addChild(retVal);
             }
+            return retVal;
         },
 
         init: function (params) {
+            if (this.initalized)
+                return;
+            this.initalized = true;
+
             if (params.Wuid) {
                 this.wu = new ESPWorkunit({
                     Wuid: params.Wuid
@@ -121,35 +95,43 @@ define([
                         context.wu.getInfo({
                             onGetWUExceptions: function (exceptions) {
                                 if (params.ShowErrors && exceptions.length) {
-                                    context.ensurePane(context.id + "exceptions", {
+                                    context.ensurePane(context.id + "_exceptions", {
                                         Wuid: params.Wuid,
                                         onErrorClick: context.onErrorClick,
                                         exceptions: exceptions
                                     });
+                                    context.initTab();
                                 }
                             },
                             onGetSourceFiles: function (sourceFiles) {
                                 if (params.SourceFiles) {
                                     for (var i = 0; i < sourceFiles.length; ++i) {
-                                        context.ensurePane(context.id + "logicalFile_" + i, {
+                                        var tab = context.ensurePane(context.id + "_logicalFile" + i, {
                                             Name: sourceFiles[i].Name,
                                             Cluster: sourceFiles[i].FileCluster
                                         });
+                                        if (i == 0) {
+                                            context.initTab();
+                                        }
                                     }
                                 }
                             },
                             onGetResults: function (results) {
                                 if (!params.SourceFiles) {
                                     for (var i = 0; i < results.length; ++i) {
-                                        context.ensurePane(context.id + "result_" + i, {
+                                        var tab = context.ensurePane(context.id + "_result" + i, {
                                             result: results[i]
                                         });
+                                        if (i == 0) {
+                                            context.initTab();
+                                        }
                                     }
                                 }
                             }
                         });
-                        if (context.selectedTab) {
-                            context.selectedTab.refresh();
+                        var currSel = context.getSelectedChild();
+                        if (currSel) {
+                            currSel.refresh();
                         }
                     }
                 });
@@ -157,11 +139,7 @@ define([
         },
 
         clear: function () {
-            var tabs = this.tabContainer.getChildren();
-            for (var i = 0; i < tabs.length; ++i) {
-                this.tabContainer.removeChild(tabs[i]);
-                tabs[i].destroyRecursive();
-            }
+            this.removeAllChildren();
             this.tabMap = [];
             this.selectedTab = null;
         },

+ 4 - 0
esp/files/scripts/TargetSelectWidget.js

@@ -59,6 +59,10 @@ require([
         },
 
         init: function (params) {
+            if (this.initalized)
+                return;
+            this.initalized = true;
+
             if (params.Target) {
                 this._value = params.Target;
             }

+ 4 - 0
esp/files/scripts/TimingGridWidget.js

@@ -89,6 +89,10 @@ define([
             },
 
             init: function (params) {
+                if (this.initalized)
+                    return;
+                this.initalized = true;
+
                 this.defaultQuery = "*";
                 if (params.query) {
                     this.defaultQuery = params.query;

+ 4 - 0
esp/files/scripts/TimingPageWidget.js

@@ -65,6 +65,10 @@ define([
 
             //  Plugin wrapper  ---
             init: function (params) {
+                if (this.initalized)
+                    return;
+                this.initalized = true;
+
                 var context = this;
                 this.timingGrid.init(params);
                 this.timingGrid.onClick = function (items) {

+ 4 - 0
esp/files/scripts/TimingTreeMapWidget.js

@@ -81,6 +81,10 @@ define([
             },
 
             init: function (params) {
+                if (this.initalized)
+                    return;
+                this.initalized = true;
+
                 this.defaultQuery = "*";
                 if (params.query) {
                     this.defaultQuery = params.query;

+ 76 - 94
esp/files/scripts/WUDetailsWidget.js

@@ -20,11 +20,11 @@ define([
     "dojo/store/Memory",
     "dojo/data/ObjectStore",
 
-    "dijit/layout/_LayoutWidget",
     "dijit/_TemplatedMixin",
     "dijit/_WidgetsInTemplateMixin",
     "dijit/registry",
 
+    "hpcc/_TabContainerWidget",
     "hpcc/ECLSourceWidget",
     "hpcc/TargetSelectWidget",
     "hpcc/SampleSelectWidget",
@@ -45,14 +45,13 @@ define([
     "dijit/TooltipDialog",
     "dijit/TitlePane"
 ], function (declare, dom, domClass, Memory, ObjectStore,
-                _LayoutWidget, _TemplatedMixin, _WidgetsInTemplateMixin, registry,
-                EclSourceWidget, TargetSelectWidget, SampleSelectWidget, GraphsWidget, ResultsWidget, InfoGridWidget, LogsWidget, Workunit,
+                _TemplatedMixin, _WidgetsInTemplateMixin, registry,
+                _TabContainerWidget, EclSourceWidget, TargetSelectWidget, SampleSelectWidget, GraphsWidget, ResultsWidget, InfoGridWidget, LogsWidget, Workunit,
                 template) {
-    return declare("WUDetailsWidget", [_LayoutWidget, _TemplatedMixin, _WidgetsInTemplateMixin], {
+    return declare("WUDetailsWidget", [_TabContainerWidget, _TemplatedMixin, _WidgetsInTemplateMixin], {
         templateString: template,
         baseClass: "WUDetailsWidget",
-        borderContainer: null,
-        tabContainer: null,
+        summaryWidget: null,
         resultsWidget: null,
         resultsWidgetLoaded: false,
         filesWidget: null,
@@ -76,94 +75,20 @@ define([
         wu: null,
         prevState: "",
 
-        buildRendering: function (args) {
-            this.inherited(arguments);
-        },
-
         postCreate: function (args) {
             this.inherited(arguments);
-            this.borderContainer = registry.byId(this.id + "BorderContainer");
-            this.tabContainer = registry.byId(this.id + "TabContainer");
-            this.resultsWidget = registry.byId(this.id + "Results");
-            this.filesWidget = registry.byId(this.id + "Files");
-            this.timersWidget = registry.byId(this.id + "Timers");
-            this.graphsWidget = registry.byId(this.id + "Graphs");
-            this.sourceWidget = registry.byId(this.id + "Source");
-            this.logsWidget = registry.byId(this.id + "Logs");
-            this.playgroundWidget = registry.byId(this.id + "Playground");
-            this.xmlWidget = registry.byId(this.id + "XML");
-            this.infoGridWidget = registry.byId(this.id + "InfoContainer");
-            this.legacyPane = registry.byId(this.id + "Legacy");
-
-            var context = this;
-            this.tabContainer.watch("selectedChildWidget", function (name, oval, nval) {
-                if (nval.id == context.id + "Results" && !context.resultsWidgetLoaded) {
-                    context.resultsWidgetLoaded = true;
-                    context.resultsWidget.init({
-                        Wuid: context.wu.Wuid
-                    });
-                } else if (nval.id == context.id + "Files" && !context.filesWidgetLoaded) {
-                    context.filesWidgetLoaded = true;
-                    context.filesWidget.init({
-                        Wuid: context.wu.Wuid,
-                        SourceFiles: true
-                    });
-                } else if (nval.id == context.id + "Timers" && !context.timersWidgetLoaded) {
-                    context.timersWidgetLoaded = true;
-                    context.timersWidget.init({
-                        Wuid: context.wu.Wuid
-                    });
-                } else if (nval.id == context.id + "Graphs" && !context.graphsWidgetLoaded) {
-                    context.graphsWidgetLoaded = true;
-                    context.graphsWidget.init({
-                        Wuid: context.wu.Wuid
-                    });
-                } else if (nval.id == context.id + "Source" && !context.sourceWidgetLoaded) {
-                    context.sourceWidgetLoaded = true;
-                    context.sourceWidget.init({
-                        Wuid: context.wu.Wuid
-                    });
-                } else if (nval.id == context.id + "Logs" && !context.logsWidgetLoaded) {
-                    context.logsWidgetLoaded = true;
-                    context.logsWidget.init({
-                        Wuid: context.wu.Wuid
-                    });
-                } else if (nval.id == context.id + "Playground" && !context.playgroundWidgetLoaded) {
-                    context.playgroundWidgetLoaded = true;
-                    context.playgroundWidget.init({
-                        Wuid: context.wu.Wuid,
-                        Target: context.wu.WUInfoResponse.Cluster
-                    });
-                } else if (nval.id == context.id + "XML" && !context.xmlWidgetLoaded) {
-                    context.xmlWidgetLoaded = true;
-                    context.xmlWidget.init({
-                        Wuid: context.wu.Wuid
-                    });
-                } else if (nval.id == context.id + "Legacy" && !context.legacyPaneLoaded) {
-                    context.legacyPaneLoaded = true;
-                    context.legacyPane.set("content", dojo.create("iframe", {
-                        src: "/WsWorkunits/WUInfo?Wuid=" + context.wu.Wuid + "&IncludeExceptions=0&IncludeGraphs=0&IncludeSourceFiles=0&IncludeResults=0&IncludeVariables=0&IncludeTimers=0&IncludeDebugValues=0&IncludeApplicationValues=0&IncludeWorkflows&SuppressResultSchemas=1",
-                        style: "border: 0; width: 100%; height: 100%"
-                    }));
-                }
-            });
-        },
-
-        startup: function (args) {
-            this.inherited(arguments);
-        },
-
-        resize: function (args) {
-            this.inherited(arguments);
-            this.borderContainer.resize();
-        },
-
-        layout: function (args) {
-            this.inherited(arguments);
-        },
+            this.summaryWidget = registry.byId(this.id + "_Summary");
+            this.resultsWidget = registry.byId(this.id + "_Results");
+            this.filesWidget = registry.byId(this.id + "_Files");
+            this.timersWidget = registry.byId(this.id + "_Timers");
+            this.graphsWidget = registry.byId(this.id + "_Graphs");
+            this.sourceWidget = registry.byId(this.id + "_Source");
+            this.logsWidget = registry.byId(this.id + "_Logs");
+            this.playgroundWidget = registry.byId(this.id + "_Playground");
+            this.xmlWidget = registry.byId(this.id + "_XML");
+            this.legacyPane = registry.byId(this.id + "_Legacy");
 
-        destroy: function (args) {
-            this.inherited(arguments);
+            this.infoGridWidget = registry.byId(this.id + "InfoContainer");
         },
 
         //  Hitched actions  ---
@@ -229,10 +154,10 @@ define([
         init: function (params) {
             if (this.initalized)
                 return;
-
             this.initalized = true;
+
             if (params.Wuid) {
-                registry.byId(this.id + "Summary").set("title", params.Wuid);
+                this.summaryWidget.set("title", params.Wuid);
 
                 dom.byId(this.id + "Wuid").innerHTML = params.Wuid;
                 this.wu = new Workunit({
@@ -241,6 +166,63 @@ define([
                 this.monitor();
             }
             this.infoGridWidget.init(params);
+            this.selectChild(this.summaryWidget, true);
+        },
+
+        initTab: function () {
+            if (!this.wu) {
+                return
+            }
+            var currSel = this.getSelectedChild();
+            if (currSel.id == this.resultsWidget.id && !this.resultsWidgetLoaded) {
+                this.resultsWidgetLoaded = true;
+                this.resultsWidget.init({
+                    Wuid: this.wu.Wuid
+                });
+            } else if (currSel.id == this.filesWidget.id && !this.filesWidgetLoaded) {
+                this.filesWidgetLoaded = true;
+                this.filesWidget.init({
+                    Wuid: this.wu.Wuid,
+                    SourceFiles: true
+                });
+            } else if (currSel.id == this.timersWidget.id && !this.timersWidgetLoaded) {
+                this.timersWidgetLoaded = true;
+                this.timersWidget.init({
+                    Wuid: this.wu.Wuid
+                });
+            } else if (currSel.id == this.graphsWidget.id && !this.graphsWidgetLoaded) {
+                this.graphsWidgetLoaded = true;
+                this.graphsWidget.init({
+                    Wuid: this.wu.Wuid
+                });
+            } else if (currSel.id == this.sourceWidget.id && !this.sourceWidgetLoaded) {
+                this.sourceWidgetLoaded = true;
+                this.sourceWidget.init({
+                    Wuid: this.wu.Wuid
+                });
+            } else if (currSel.id == this.logsWidget.id && !this.logsWidgetLoaded) {
+                this.logsWidgetLoaded = true;
+                this.logsWidget.init({
+                    Wuid: this.wu.Wuid
+                });
+            } else if (currSel.id == this.playgroundWidget.id && !this.playgroundWidgetLoaded) {
+                this.playgroundWidgetLoaded = true;
+                this.playgroundWidget.init({
+                    Wuid: this.wu.Wuid,
+                    Target: this.wu.WUInfoResponse.Cluster
+                });
+            } else if (currSel.id == this.xmlWidget.id && !this.xmlWidgetLoaded) {
+                this.xmlWidgetLoaded = true;
+                this.xmlWidget.init({
+                    Wuid: this.wu.Wuid
+                });
+            } else if (currSel.id == this.legacyPane.id && !this.legacyPaneLoaded) {
+                this.legacyPaneLoaded = true;
+                this.legacyPane.set("content", dojo.create("iframe", {
+                    src: "/WsWorkunits/WUInfo?Wuid=" + this.wu.Wuid + "&IncludeExceptions=0&IncludeGraphs=0&IncludeSourceFiles=0&IncludeResults=0&IncludeVariables=0&IncludeTimers=0&IncludeDebugValues=0&IncludeApplicationValues=0&IncludeWorkflows&SuppressResultSchemas=1",
+                    style: "border: 0; width: 100%; height: 100%"
+                }));
+            }
         },
 
         monitor: function () {
@@ -286,7 +268,7 @@ define([
             registry.byId(this.id + "Description").set("readOnly", !this.wu.isComplete());
             registry.byId(this.id + "Protected").set("readOnly", !this.wu.isComplete());
 
-            registry.byId(this.id + "Summary").set("iconClass",this.wu.getStateIconClass());
+            this.summaryWidget.set("iconClass",this.wu.getStateIconClass());
             domClass.remove(this.id + "StateIdImage");
             domClass.add(this.id + "StateIdImage", this.wu.getStateIconClass());
 

+ 43 - 51
esp/files/scripts/WUQueryWidget.js

@@ -20,7 +20,6 @@ define([
     "dojo/date",
     "dojo/on",
 
-    "dijit/layout/_LayoutWidget",
     "dijit/_TemplatedMixin",
     "dijit/_WidgetsInTemplateMixin",
     "dijit/registry",
@@ -29,6 +28,7 @@ define([
     "dojox/grid/enhanced/plugins/Pagination",
     "dojox/grid/enhanced/plugins/IndirectSelection",
 
+    "hpcc/_TabContainerWidget",
     "hpcc/WsWorkunits",
     "hpcc/WUDetailsWidget",
 
@@ -45,50 +45,25 @@ define([
     "dijit/Toolbar",
     "dijit/TooltipDialog"
 ], function (declare, dom, ObjectStore, date, on,
-                _LayoutWidget, _TemplatedMixin, _WidgetsInTemplateMixin, registry,
+                _TemplatedMixin, _WidgetsInTemplateMixin, registry,
                 EnhancedGrid, Pagination, IndirectSelection,
-                WsWorkunits, WUDetailsWidget,
+                _TabContainerWidget, WsWorkunits, WUDetailsWidget,
                 template) {
-    return declare("WUQueryWidget", [_LayoutWidget, _TemplatedMixin, _WidgetsInTemplateMixin], {
+    return declare("WUQueryWidget", [_TabContainerWidget, _TemplatedMixin, _WidgetsInTemplateMixin], {
         templateString: template,
         baseClass: "WUQueryWidget",
-        borderContainer: null,
-        tabContainer: null,
+        workunitsTab: null,
         workunitsGrid: null,
         legacyPane: null,
         legacyPaneLoaded: false,
 
         tabMap: [],
 
-        buildRendering: function (args) {
-            this.inherited(arguments);
-        },
-
         postCreate: function (args) {
             this.inherited(arguments);
-            this.borderContainer = registry.byId(this.id + "BorderContainer");
-            this.tabContainer = registry.byId(this.id + "TabContainer");
+            this.workunitsTab = registry.byId(this.id + "_Workunits");
             this.workunitsGrid = registry.byId(this.id + "WorkunitsGrid");
-            this.legacyPane = registry.byId(this.id + "Legacy");
-
-            var context = this;
-            this.tabContainer.watch("selectedChildWidget", function (name, oval, nval) {
-                if (nval.id == context.id + "Workunits") {
-                } else if (nval.id == context.id + "Legacy") {
-                    if (!context.legacyPaneLoaded) {
-                        context.legacyPaneLoaded = true;
-                        context.legacyPane.set("content", dojo.create("iframe", {
-                            src: "/WsWorkunits/WUQuery",
-                            style: "border: 0; width: 100%; height: 100%"
-                        }));
-                    }
-                } else {
-                    if (!nval.initalized) {
-                        nval.init(nval.params);
-                    }
-                }
-                context.selectedTab = nval;
-            });
+            this.legacyPane = registry.byId(this.id + "_Legacy");
         },
 
         startup: function (args) {
@@ -97,26 +72,20 @@ define([
             this.initWorkunitsGrid();
         },
 
-        resize: function (args) {
-            this.inherited(arguments);
-            this.borderContainer.resize();
-        },
-
-        layout: function (args) {
-            this.inherited(arguments);
-        },
-
-        destroy: function (args) {
-            this.inherited(arguments);
-        },
-
         //  Hitched actions  ---
         _onOpen: function (event) {
             var selections = this.workunitsGrid.selection.getSelected();
+            var firstTab = null;
             for (var i = selections.length - 1; i >= 0; --i) {
-                this.ensurePane(selections[i].Wuid, {
+                var tab = this.ensurePane(this.id + "_" + selections[i].Wuid, {
                     Wuid: selections[i].Wuid
                 });
+                if (i == 0) {
+                    firstTab = tab;
+                }
+            }
+            if (firstTab) {
+                this.selectChild(firstTab);
             }
         },
         _onDelete: function (event) {
@@ -218,7 +187,30 @@ define([
 
         //  Implementation  ---
         init: function (params) {
-            if (params.Wuid) {
+            if (this.initalized)
+                return;
+            this.initalized = true;
+
+            this.selectChild(this.workunitsTab, true);
+        },
+
+        initTab: function () {
+            var currSel = this.getSelectedChild();
+            if (currSel && !currSel.initalized) {
+                if (currSel.id == this.workunitsTab.id) {
+                } else if (currSel.id == this.legacyPane.id) {
+                    if (!this.legacyPaneLoaded) {
+                        this.legacyPaneLoaded = true;
+                        this.legacyPane.set("content", dojo.create("iframe", {
+                            src: "/WsWorkunits/WUQuery",
+                            style: "border: 0; width: 100%; height: 100%"
+                        }));
+                    }
+                } else {
+                    if (!currSel.initalized) {
+                        currSel.init(currSel.params);
+                    }
+                }
             }
         },
 
@@ -312,7 +304,7 @@ define([
                 var context = this;
                 retVal = new WUDetailsWidget({
                     id: id,
-                    title: id,
+                    title: params.Wuid,
                     closable: true,
                     onClose: function () {
                         delete context.tabMap[id];
@@ -321,16 +313,16 @@ define([
                     params: params
                 });
                 this.tabMap[id] = retVal;
-                this.tabContainer.addChild(retVal, 2);
+                this.addChild(retVal, 2);
             }
             return retVal;
         },
 
         onRowDblClick: function (wuid) {
-            var wuTab = this.ensurePane(wuid, {
+            var wuTab = this.ensurePane(this.id + "_" + wuid, {
                 Wuid: wuid
             });
-            this.tabContainer.selectChild(wuTab);
+            this.selectChild(wuTab);
         }
     });
 });

+ 197 - 0
esp/files/scripts/_TabContainerWidget.js

@@ -0,0 +1,197 @@
+define([
+	"dojo/_base/declare", // declare
+	"dojo/_base/lang", // lang.mixin
+    "dojo/hash",
+    "dojo/router",
+
+    "dijit/registry",
+    "dijit/layout/_LayoutWidget"
+], function (declare, lang, hash, router,
+    registry, _LayoutWidget) {
+
+    return declare("_TabContainerWidget", [_LayoutWidget], {
+        //  Assumptions:
+        //    this.id + "BorderContainer" may exist.
+        //    this.id + "TabContainer" exits.
+        //    Child Tab Widgets ID have an underbar after the parent ID -> "${ID}_thisid" (this id for automatic back/forward button support.
+
+        baseClass: "_TabContainerWidget",
+        borderContainer: null,
+        _tabContainer: null,
+
+        disableHashing: 0,
+
+        //  String helpers  ---
+        idToPath: function (id) {
+            var obj = id.split("_");
+            return "/" + obj.join("/");
+        },
+
+        pathToId: function (path) {
+            var obj = path.split("/");
+            obj.splice(0, 1);
+            return obj.join("_");
+        },
+
+        startsWith: function (tst, str) {
+            if (tst.length > str.length) {
+                return false;
+            }
+            for (var i = 0; i < tst.length; ++i) {
+                if (tst.charAt(i) !== str.charAt(i)) {
+                    return false;
+                }
+            }
+            return true;
+        },
+
+        buildRendering: function () {
+            this.inherited(arguments);
+        },
+
+        postCreate: function (args) {
+            this.inherited(arguments);
+            this.borderContainer = registry.byId(this.id + "BorderContainer");
+            this._tabContainer = registry.byId(this.id + "TabContainer");
+
+            var context = this;
+            this._tabContainer.watch("selectedChildWidget", function (name, oval, nval) {
+                context.onNewTabSelection({
+                    oldWidget: oval,
+                    newWidget: nval
+                });
+            });
+        },
+
+        startup: function () {
+            if (this._started) {
+                return;
+            }
+            this.inherited(arguments);
+
+            var context = this;
+            var obj = router.register(this.getPath() + "/:sel", function (evt) {
+                context.routerCallback(evt, true);
+            });
+            router.registerBefore(this.getPath() + "/:sel/*other", function (evt) {
+                context.routerCallback(evt, false);
+            });
+            router.startup();
+        },
+
+        resize: function (args) {
+            this.inherited(arguments);
+            if (this.borderContainer) {
+                this.borderContainer.resize();
+            } else {
+                this._tabContainer.resize();
+            }
+        },
+
+        layout: function (args) {
+            this.inherited(arguments);
+        },
+
+        destroy: function (args) {
+            this.inherited(arguments);
+        },
+
+        //  Hash Helpers  ---
+        onNewTabSelection: function (notification) {
+            var currHash = hash();
+            var newHash = this.getSelectedPath();
+            if (newHash != this.idToPath(notification.newWidget.id)) {
+                var d = 0;
+            }
+            if (this.disableHashing) {
+                this.go(this.getSelectedPath(), false, true);
+            } else {
+                var overwrite = this.startsWith(currHash, newHash);
+                this.go(this.getSelectedPath(), overwrite);
+            }
+        },
+
+        go: function (path, replace, noHash) {
+            console.log(this.id + ".go(" + path + ", " + replace + ", " + noHash + ")");
+            if (noHash) {
+                var d = 0;
+            } else {
+                hash(path, replace);
+            }
+            router._handlePathChange(path);
+        },
+
+        routerCallback: function (evt) {
+            var currSel = this.getSelectedChild();
+            var newSel = this.id + "_" + evt.params.sel;
+            if (currSel.id != newSel) {
+                this.selectChild(newSel, null);
+            }
+            if (this.initTab) {
+                this.initTab();
+            }
+        },
+
+        getPath: function () {
+            return this.idToPath(this.id);
+        },
+
+        getSelectedPath: function () {
+            var selWidget = this._tabContainer.get("selectedChildWidget");
+            if (!selWidget || selWidget == this._tabContainer) {
+                return null;
+            }
+            if (selWidget.getPath) {
+                return selWidget.getPath();
+            }
+            return this.idToPath(selWidget.id);
+        },
+
+        //  Tab Helpers ---
+        getSelectedChild: function () {
+            return this._tabContainer.get("selectedChildWidget");
+        },
+
+        getChildren: function () {
+            return this._tabContainer.getChildren();
+        },
+
+        addChild: function (child, pos) {
+            //this.disableHashing++;
+            var retVal = this._tabContainer.addChild(child, pos);
+            //this.disableHashing--;
+            return retVal;
+        },
+
+        removeChild: function (child) {
+            this._tabContainer.removeChild(child);
+            child.destroyRecursive();
+        },
+
+        removeAllChildren: function() {
+            var tabs = this._tabContainer.getChildren();
+            for (var i = 0; i < tabs.length; ++i) {
+                this._tabContainer.removeChild(tabs[i]);
+                tabs[i].destroyRecursive();
+            }
+        },
+
+        selectChild: function (child, doHash) {
+            if (!doHash) {
+                this.disableHashing++;
+            }
+            var currSel = this.getSelectedChild();
+            if (currSel != child) {
+                this._tabContainer.selectChild(child);
+            } else {
+                this.onNewTabSelection({
+                    oldWidget: null,
+                    newWidget: child
+                })
+            }
+            if (!doHash) {
+                this.disableHashing--;
+            }
+        }
+    });
+});

+ 2 - 1
esp/files/stub.htm

@@ -34,7 +34,8 @@
     <!-- load dojo and provide config via dojoConfig global -->
     <script>
         var dojoConfig = (function () {
-            var base = location.href.split("/");
+            var baseLHS = location.href.split("#");
+            var base = baseLHS[0].split("/");
             base.pop();
             base = base.join("/");
 

+ 4 - 2
esp/files/stub.js

@@ -14,8 +14,10 @@
 #    limitations under the License.
 ############################################################################## */
 define([
+    "dojo/_base/lang",
     "dojo/_base/fx",
     "dojo/_base/window",
+    "dojo/_base/connect",
     "dojo/dom",
     "dojo/dom-style",
     "dojo/dom-geometry",
@@ -35,7 +37,7 @@ define([
     "hpcc/DFUWUDetailsWidget",
     "hpcc/DFUWUQueryWidget",
     "hpcc/LFDetailsWidget"
-], function (fx, baseWindow, dom, domStyle, domGeometry, ioQuery, ready,
+], function (lang, fx, baseWindow, connect, dom, domStyle, domGeometry, ioQuery, ready,
         ECLPlaygroundWidget, GraphPageWidget, ResultsWidget, TimingPageWidget, TimingTreeMapWidget, ECLSourceWidget, InfoGridWidget, WUQueryWidget, WUDetailsWidget, GetDFUWorkunitsWidget, DFUWUDetailsWidget, DFUWUQueryWidget, LFDetailsWidget
         ) {
 
@@ -44,7 +46,7 @@ define([
 
         //TODO:  Can we get rid of the required dependency above?
         var widget = new (eval(params.Widget))({
-            id: "appLayout",
+            id: "app",
             "class": "hpccApp"
         });
 

+ 2 - 2
esp/files/templates/DFUWUQueryWidget.html

@@ -1,7 +1,7 @@
 <div class="${baseClass}">
     <div id="${id}BorderContainer" class="${baseClass}BorderContainer" style="width: 100%; height: 100%;" data-dojo-type="dijit.layout.BorderContainer">
         <div id="${id}TabContainer" data-dojo-props="region: 'center', tabPosition: 'top'" style="width: 100%; height: 100%" data-dojo-type="dijit.layout.TabContainer">
-            <div id="${id}Workunits" style="width: 100%; height: 100%" data-dojo-props='title:"Logical Files"' data-dojo-type="dijit.layout.BorderContainer">
+            <div id="${id}_Workunits" style="width: 100%; height: 100%" data-dojo-props='title:"Logical Files"' data-dojo-type="dijit.layout.BorderContainer">
                 <div id="${id}Toolbar" class="topPanel" data-dojo-props="region: 'top'" data-dojo-type="dijit.Toolbar">
                     <div id="${id}Open" data-dojo-attach-event="onClick:_onOpen" data-dojo-type="dijit.form.Button">Open</div>
                     <div id="${id}Delete" data-dojo-attach-event="onClick:_onDelete" data-dojo-type="dijit.form.Button">Delete</div>
@@ -69,7 +69,7 @@
                 }" data-dojo-type="dojox.grid.EnhancedGrid">
                 </div>
             </div>
-            <div id="${id}Legacy" title="Legacy Web Page" data-dojo-type="dijit.layout.ContentPane">
+            <div id="${id}_Legacy" title="Legacy Web Page" data-dojo-type="dijit.layout.ContentPane">
             </div>
         </div>
     </div>

+ 1 - 1
esp/files/templates/ECLPlaygroundWidget.html

@@ -13,7 +13,7 @@
         </div>
         <div id="${id}Graphs" style="width: 240px;" data-dojo-props="minSize:120, region: 'right', splitter:true" data-dojo-type="GraphWidget">
         </div>
-        <div id="${id}Results" style="height: 240px;" data-dojo-props="minSize:120, region: 'bottom', splitter:true" data-dojo-type="ResultsWidget">
+        <div id="${id}_Results" style="height: 240px;" data-dojo-props="minSize:120, region: 'bottom', splitter:true" data-dojo-type="ResultsWidget">
         </div>
         <div id="${id}SubmitPane" class="edgePanel" data-dojo-props="region: 'bottom'" data-dojo-type="dijit.layout.ContentPane">
             <div style="display: inline-block; vertical-align: middle">

+ 9 - 9
esp/files/templates/LFDetailsWidget.html

@@ -1,7 +1,7 @@
 <div class="${baseClass}">
     <div id="${id}BorderContainer" class="${baseClass}BorderContainer" style="width: 100%; height: 100%" data-dojo-type="dijit.layout.BorderContainer">
         <div id="${id}TabContainer" data-dojo-props="region: 'center', tabPosition: 'top'" style="width: 100%; height: 100%" data-dojo-type="dijit.layout.TabContainer">
-            <div id="${id}Summary" style="width: 100%; height: 100%" data-dojo-props='title:"Summary", iconClass:"iconLogicalFile"' data-dojo-type="dijit.layout.BorderContainer">
+            <div id="${id}_Summary" style="width: 100%; height: 100%" data-dojo-props='title:"Summary", iconClass:"iconLogicalFile"' data-dojo-type="dijit.layout.BorderContainer">
                 <div id="${id}Toolbar" class="topPanel" data-dojo-props="region: 'top'" data-dojo-type="dijit.Toolbar">
                     <div id="${id}Save" data-dojo-attach-event="onClick:_onSave" data-dojo-type="dijit.form.Button">Save</div>
                     <div id="${id}Delete" data-dojo-attach-event="onClick:_onDelete" data-dojo-type="dijit.form.Button">Delete</div>
@@ -63,21 +63,21 @@
                     </form>                                   
                 </div>
             </div>
-            <div id="${id}Content" title="Contents" data-dojo-type="ResultWidget">
+            <div id="${id}_Content" title="Contents" data-dojo-type="ResultWidget">
             </div>
-            <div id="${id}Source" title="ECL" data-dojo-type="ECLSourceWidget">
+            <div id="${id}_Source" title="ECL" data-dojo-type="ECLSourceWidget">
             </div>
-            <div id="${id}DEF" title="DEF" data-dojo-type="ECLSourceWidget">
+            <div id="${id}_DEF" title="DEF" data-dojo-type="ECLSourceWidget">
             </div>
-            <div id="${id}XML" title="XML" data-dojo-props="WUXml: true" data-dojo-type="ECLSourceWidget">
+            <div id="${id}_XML" title="XML" data-dojo-props="WUXml: true" data-dojo-type="ECLSourceWidget">
             </div>
-            <div id="${id}FileParts" title="File Parts" data-dojo-type="FilePartsWidget">
+            <div id="${id}_FileParts" title="File Parts" data-dojo-type="FilePartsWidget">
             </div>
-            <div id="${id}Workunit" title="Workunit" data-dojo-type="WUDetailsWidget">
+            <div id="${id}_Workunit" title="Workunit" data-dojo-type="WUDetailsWidget">
             </div>
-            <div id="${id}DFUWorkunit" title="Workunit" data-dojo-type="DFUWUDetailsWidget">
+            <div id="${id}_DFUWorkunit" title="Workunit" data-dojo-type="DFUWUDetailsWidget">
             </div>
-            <div id="${id}Legacy" title="Legacy Web Page" data-dojo-type="dijit.layout.ContentPane">
+            <div id="${id}_Legacy" title="Legacy Web Page" data-dojo-type="dijit.layout.ContentPane">
             </div>
         </div>
     </div>

+ 11 - 11
esp/files/templates/WUDetailsWidget.html

@@ -1,7 +1,7 @@
 <div class="${baseClass}">
     <div id="${id}BorderContainer" class="${baseClass}BorderContainer" style="width: 100%; height: 100%;" data-dojo-type="dijit.layout.BorderContainer">
         <div id="${id}TabContainer" data-dojo-props="region: 'center', tabPosition: 'top'" style="width: 100%; height: 100%" data-dojo-type="dijit.layout.TabContainer">
-            <div id="${id}Summary" style="width: 100%; height: 100%" data-dojo-props='title:"Summary", iconClass:"iconWorkunit"' data-dojo-type="dijit.layout.BorderContainer">
+            <div id="${id}_Summary" style="width: 100%; height: 100%" data-dojo-props='title:"Summary", iconClass:"iconWorkunit"' data-dojo-type="dijit.layout.BorderContainer">
                 <div id="${id}Toolbar" class="topPanel" data-dojo-props="region: 'top'" data-dojo-type="dijit.Toolbar">
                     <div id="${id}Save" data-dojo-attach-event="onClick:_onSave" data-dojo-type="dijit.form.Button">Save</div>
                     <div id="${id}Delete" data-dojo-attach-event="onClick:_onDelete" data-dojo-type="dijit.form.Button">Delete</div>
@@ -72,27 +72,27 @@
                 <div id="${id}InfoContainer" style="height: 33%" data-dojo-props="region: 'bottom', splitter: true, minSize: 120" data-dojo-type="InfoGridWidget">
                 </div>
             </div>
-            <div id="${id}Variables" title="Variables" data-dojo-type="dijit.layout.ContentPane">
+            <div id="${id}_Variables" title="Variables" data-dojo-type="dijit.layout.ContentPane">
                 <div id="${id}VariablesGrid" data-dojo-type="dojox.grid.DataGrid">
                 </div>
             </div>
-            <div id="${id}Results" title="Outputs" data-dojo-type="ResultsWidget">
+            <div id="${id}_Results" title="Outputs" data-dojo-type="ResultsWidget">
             </div>
-            <div id="${id}Files" title="Inputs" data-dojo-type="ResultsWidget">
+            <div id="${id}_Files" title="Inputs" data-dojo-type="ResultsWidget">
             </div>
-            <div id="${id}Timers" title="Timings" data-dojo-type="TimingPageWidget">
+            <div id="${id}_Timers" title="Timings" data-dojo-type="TimingPageWidget">
             </div>
-            <div id="${id}Graphs" title="Graphs" data-dojo-type="GraphsWidget">
+            <div id="${id}_Graphs" title="Graphs" data-dojo-type="GraphsWidget">
             </div>
-            <div id="${id}Source" title="ECL" data-dojo-type="ECLSourceWidget">
+            <div id="${id}_Source" title="ECL" data-dojo-type="ECLSourceWidget">
             </div>
-            <div id="${id}Logs" title="Helpers" data-dojo-type="LogsWidget">
+            <div id="${id}_Logs" title="Helpers" data-dojo-type="LogsWidget">
             </div>
-            <div id="${id}Playground" title="Playground" data-dojo-type="ECLPlaygroundWidget">
+            <div id="${id}_Playground" title="Playground" data-dojo-type="ECLPlaygroundWidget">
             </div>
-            <div id="${id}XML" title="XML" data-dojo-props="WUXml: true" data-dojo-type="ECLSourceWidget">
+            <div id="${id}_XML" title="XML" data-dojo-props="WUXml: true" data-dojo-type="ECLSourceWidget">
             </div>
-            <div id="${id}Legacy" title="Legacy Web Page" data-dojo-type="dijit.layout.ContentPane">
+            <div id="${id}_Legacy" title="Legacy Web Page" data-dojo-type="dijit.layout.ContentPane">
             </div>
         </div>
     </div>

+ 2 - 2
esp/files/templates/WUQueryWidget.html

@@ -1,7 +1,7 @@
 <div class="${baseClass}">
     <div id="${id}BorderContainer" class="${baseClass}BorderContainer" style="width: 100%; height: 100%;" data-dojo-type="dijit.layout.BorderContainer">
         <div id="${id}TabContainer" data-dojo-props="region: 'center', tabPosition: 'top'" style="width: 100%; height: 100%" data-dojo-type="dijit.layout.TabContainer">
-            <div id="${id}Workunits" style="width: 100%; height: 100%" data-dojo-props='title:"Workunits"' data-dojo-type="dijit.layout.BorderContainer">
+            <div id="${id}_Workunits" style="width: 100%; height: 100%" data-dojo-props='title:"Workunits"' data-dojo-type="dijit.layout.BorderContainer">
                 <div id="${id}Toolbar" class="topPanel" data-dojo-props="region: 'top'" data-dojo-type="dijit.Toolbar">
                     <div id="${id}Open" data-dojo-attach-event="onClick:_onOpen" data-dojo-type="dijit.form.Button">Open</div>
                     <div id="${id}Delete" data-dojo-attach-event="onClick:_onDelete" data-dojo-type="dijit.form.Button">Delete</div>
@@ -79,7 +79,7 @@
                 }" data-dojo-type="dojox.grid.EnhancedGrid">
                 </div>
             </div>
-            <div id="${id}Legacy" title="Legacy Web Page" data-dojo-type="dijit.layout.ContentPane">
+            <div id="${id}_Legacy" title="Legacy Web Page" data-dojo-type="dijit.layout.ContentPane">
             </div>
         </div>
     </div>