浏览代码

HPCC-10588 Improve File Spray Multi Selection

Fixes HPCC-10588

Signed-off-by: Gordon Smith <gordon.smith@lexisnexis.com>
Gordon Smith 11 年之前
父节点
当前提交
40f2688fc4

+ 17 - 16
esp/files/css/hpcc.css

@@ -68,21 +68,8 @@ form {
 }
 
 form label{
-    float: left;
-    width: 14%;
-    margin: 0 15px 0 0;
-    text-align: left;
-    padding-top: 4px;
+    margin: 0 8px 0 0;
     font-weight:bold;
-    height:20px;
-}
-
-form textarea{
-    font-size: 13px;
-    font-family: Arial;
-    width:auto;
-    height:auto;
-    float:left;
 }
 
 form ul{
@@ -99,13 +86,27 @@ form li{
     height:20px;
 }
 
-form div{
-    margin:4px 0 0 0;
+form li label{
+    float: left;
+    width: 14%;
+    margin: 0 15px 0 0;
+    text-align: left;
+    padding-top: 4px;
 }
+
+form li textarea{
+    font-size: 13px;
+    font-family: Arial;
+    width:auto;
+    height:auto;
+    float:left;
+}
+
 form h1{
     font-size: 1.5em;
     margin-left:15px;
 }
+
 form h2{
     padding:5px 0;
     color:rgb(22, 22, 22);

+ 144 - 88
esp/files/scripts/DFUQueryWidget.js

@@ -35,10 +35,12 @@ define([
     "dijit/MenuSeparator",
     "dijit/PopupMenuItem",
     "dijit/form/Textarea",
+    "dijit/form/ValidationTextBox",
 
     "dgrid/Grid",
     "dgrid/Keyboard",
     "dgrid/Selection",
+    "dgrid/editor",
     "dgrid/selector",
     "dgrid/extensions/ColumnResizer",
     "dgrid/extensions/DijitRegistry",
@@ -55,6 +57,7 @@ define([
     "hpcc/DFUWUDetailsWidget",
     "hpcc/TargetSelectWidget",
     "hpcc/FilterDropDownWidget",
+    "hpcc/SelectionGridWidget",
 
     "dojo/text!../templates/DFUQueryWidget.html",
 
@@ -68,44 +71,35 @@ define([
     "dijit/form/Select",
     "dijit/Toolbar",
     "dijit/TooltipDialog",
+    "dijit/Fieldset",
 
     "hpcc/TableContainer"
 
 ], function (declare, lang, i18n, nlsCommon, nlsSpecific, arrayUtil, dom, domAttr, domConstruct, domClass, domForm, date, on,
-                registry, Dialog, Menu, MenuItem, MenuSeparator, PopupMenuItem, Textarea,
-                Grid, Keyboard, Selection, selector, ColumnResizer, DijitRegistry, Pagination,
-                _TabContainerWidget, WsDfu, FileSpray, ESPUtil, ESPLogicalFile, ESPDFUWorkunit, LFDetailsWidget, SFDetailsWidget, DFUWUDetailsWidget, TargetSelectWidget, FilterDropDownWidget,
+                registry, Dialog, Menu, MenuItem, MenuSeparator, PopupMenuItem, Textarea, ValidationTextBox,
+                Grid, Keyboard, Selection, editor, selector, ColumnResizer, DijitRegistry, Pagination,
+                _TabContainerWidget, WsDfu, FileSpray, ESPUtil, ESPLogicalFile, ESPDFUWorkunit, LFDetailsWidget, SFDetailsWidget, DFUWUDetailsWidget, TargetSelectWidget, FilterDropDownWidget, SelectionGridWidget,
                 template) {
     return declare("DFUQueryWidget", [_TabContainerWidget, ESPUtil.FormHelper], {
         templateString: template,
         baseClass: "DFUQueryWidget",
         i18n: lang.mixin(nlsCommon, nlsSpecific),
 
-        addToSuperFileForm: null,
-        desprayDialog: null,
-        sprayFixedDialog: null,
-        sprayVariableDialog: null,
-        sprayXmlDialog: null,
-
-        workunitsTab: null,
-        workunitsGrid: null,
-
-        filter: null,
-
         postCreate: function (args) {
             this.inherited(arguments);
-            this.addToSuperFileForm = registry.byId(this.id + "AddToSuperfileForm");
-            this.desprayDialog = registry.byId(this.id + "DesprayDialog");
-            this.sprayFixedDialog = registry.byId(this.id + "SprayFixedDialog");
-            this.sprayVariableDialog = registry.byId(this.id + "SprayVariableDialog");
-            this.sprayXmlDialog = registry.byId(this.id + "SprayXmlDialog");
             this.workunitsTab = registry.byId(this.id + "_Workunits");
             this.filter = registry.byId(this.id + "Filter");
             this.clusterTargetSelect = registry.byId(this.id + "ClusterTargetSelect");
+            this.copyForm = registry.byId(this.id + "CopyForm");
+            this.copyTargetSelect = registry.byId(this.id + "CopyTargetSelect");
+            this.copyGrid = registry.byId(this.id + "CopyGrid");
+            this.renameForm = registry.byId(this.id + "RenameForm");
+            this.renameGrid = registry.byId(this.id + "RenameGrid");
+            this.addToSuperFileForm = registry.byId(this.id + "AddToSuperfileForm");
+            this.addToSuperfileGrid = registry.byId(this.id + "AddToSuperfileGrid");
+            this.desprayForm = registry.byId(this.id + "DesprayForm");
             this.desprayTargetSelect = registry.byId(this.id + "DesprayTargetSelect");
-            this.sprayFixedDestinationSelect = registry.byId(this.id + "SprayFixedDestination");
-            this.sprayVariableDestinationSelect = registry.byId(this.id + "SprayVariableDestination");
-            this.sprayXmlDestinationSelect = registry.byId(this.id + "SprayXmlDestinationSelect");
+            this.desprayGrid = registry.byId(this.id + "DesprayGrid");
         },
 
         startup: function (args) {
@@ -148,20 +142,6 @@ define([
             }
         },
 
-        _onAddToSuperfileOk: function (event) {
-            if (this.addToSuperFileForm.validate()) {
-                var context = this;
-                var formData = domForm.toObject(this.id + "AddToSuperfileForm");
-                WsDfu.AddtoSuperfile(this.workunitsGrid.getSelected(), formData.Superfile, formData.ExistingFile, {
-                    load: function (response) {
-                        context.refreshGrid(response);
-                    }
-                });
-                var d = registry.byId(this.id + "AddtoDropDown");
-                registry.byId(this.id + "AddtoDropDown").closeDropDown();
-            }
-        },
-
         _handleResponse: function (wuidQualifier, response) {
             if (lang.exists(wuidQualifier, response)) {
                 var wu = ESPDFUWorkunit.Get(lang.getObject(wuidQualifier, false, response));
@@ -175,60 +155,71 @@ define([
             }
         },
 
-        _onDesprayOk: function (event) {
-            if (this.desprayDialog.validate()) {
+        _onCopyOk: function (event) {
+            if (this.copyForm.validate()) {
                 var context = this;
-                arrayUtil.forEach(this.workunitsGrid.getSelected(), function (item, idx) {
-                    item.refresh().then(function (response) {
-                        var request = domForm.toObject(context.id + "DesprayDialog");
-                        request.destPath += item.Filename;
-                        item.despray({
-                            request: request
-                        }).then(function (response) {
-                            context._handleResponse("DesprayResponse.wuid", response);
-                        });
+                arrayUtil.forEach(this.copyGrid.store.data, function (item, idx) {
+                    var logicalFile = ESPLogicalFile.Get(item.Name);
+                    var request = domForm.toObject(context.id + "CopyForm");
+                    request.RenameSourceName = item.Name;
+                    request.destLogicalName = item.targetCopyName;
+                    logicalFile.copy({
+                        request: request
+                    }).then(function (response) {
+                        context._handleResponse("CopyResponse.result", response);
                     });
                 });
-                registry.byId(this.id + "DesprayDropDown").closeDropDown();
+                registry.byId(this.id + "CopyDropDown").closeDropDown();
             }
         },
 
-        _onSprayFixed: function (event) {
-            if (this.sprayFixedDialog.validate()) {
-                var formData = domForm.toObject(this.id + "SprayFixedDialog");
+        _onRenameOk: function (event) {
+            if (this.renameForm.validate()) {
                 var context = this;
-                FileSpray.SprayFixed({
-                    request: formData
-                }).then(function (response) {
-                    context._handleResponse("SprayFixedResponse.wuid", response);
-                })
-                registry.byId(this.id + "SprayFixedDropDown").closeDropDown();
+                arrayUtil.forEach(this.renameGrid.store.data, function (item, idx) {
+                    var logicalFile = ESPLogicalFile.Get(item.Name);
+                    var request = domForm.toObject(context.id + "RenameForm");
+                    request.RenameSourceName = item.Name;
+                    request.dstname = item.targetRenameName;
+                    logicalFile.rename({
+                        request: request
+                    }).then(function (response) {
+                        context._handleResponse("RenameResponse.wuid", response);
+                    });
+                });
+                registry.byId(this.id + "RenameDropDown").closeDropDown();
             }
         },
 
-        _onSprayVariable: function (event) {
-            if (this.sprayVariableDialog.validate()) {
+        _onAddToSuperfileOk: function (event) {
+            if (this.addToSuperFileForm.validate()) {
                 var context = this;
-                var formData = domForm.toObject(this.id + "SprayVariableDialog");
-                FileSpray.SprayVariable({
-                    request: formData
-                }).then(function (response) {
-                    context._handleResponse("SprayResponse.wuid", response);
+                var formData = domForm.toObject(this.id + "AddToSuperfileForm");
+                WsDfu.AddtoSuperfile(this.workunitsGrid.getSelected(), formData.Superfile, formData.ExistingFile, {
+                    load: function (response) {
+                        context.refreshGrid(response);
+                    }
                 });
-                registry.byId(this.id + "SprayVariableDropDown").closeDropDown();
+                registry.byId(this.id + "AddtoDropDown").closeDropDown();
             }
         },
 
-        _onSprayXml: function (event) {
-            if (this.sprayXmlDialog.validate()) {
+        _onDesprayOk: function (event) {
+            if (this.desprayForm.validate()) {
                 var context = this;
-                var formData = domForm.toObject(this.id + "SprayXmlDialog");
-                FileSpray.SprayVariable({
-                    request: formData
-                }).then(function (response) {
-                    context._handleResponse("SprayResponse.wuid", response);
+                arrayUtil.forEach(this.desprayGrid.store.data, function (item, idx) {
+                    var request = domForm.toObject(context.id + "DesprayForm");
+                    if (!context.endsWith(request.destPath, "/")) {
+                        request.destPath += "/";
+                    }
+                    request.destPath += item.targetName;
+                    item.despray({
+                        request: request
+                    }).then(function (response) {
+                        context._handleResponse("DesprayResponse.wuid", response);
+                    });
                 });
-                registry.byId(this.id + "SprayXmlDropDown").closeDropDown();
+                registry.byId(this.id + "DesprayDropDown").closeDropDown();
             }
         },
 
@@ -283,6 +274,9 @@ define([
                 includeBlank: true
             });
             var context = this;
+            this.copyTargetSelect.init({
+                Groups: true
+            });
             this.desprayTargetSelect.init({
                 DropZones: true,
                 callback: function (value, item) {
@@ -290,15 +284,6 @@ define([
                     registry.byId(context.id + "DesprayTargetPath").set("value", item.machine.Directory + "/");
                 }
             });
-            this.sprayFixedDestinationSelect.init({
-                Groups: true
-            });
-            this.sprayVariableDestinationSelect.init({
-                Groups: true
-            });
-            this.sprayXmlDestinationSelect.init({
-                Groups: true
-            });
             this.initWorkunitsGrid();
             this.selectChild(this.workunitsTab, true);
 
@@ -363,7 +348,7 @@ define([
                 this.menuFilterCluster = this.addMenuItem(pSubMenu, {
                     onClick: function (args) {
                         context.filter.clear();
-                        context.filter.setValue(context.id + "ClusterTargetSelect", context.menuFilterOwner.get("hpcc_value"));
+                        context.filter.setValue(context.id + "ClusterTargetSelect", context.menuFilterCluster.get("hpcc_value"));
                         context.refreshGrid();
                     }
                 });
@@ -473,6 +458,54 @@ define([
                 context.refreshActionState();
             });
             this.workunitsGrid.startup();
+
+            this.copyGrid.createGrid({
+                idProperty: "Name",
+                columns: {
+                    targetCopyName: editor({
+                        label: this.i18n.TargetName,
+                        width: 144,
+                        autoSave: true,
+                        editor: "text"
+                    })
+                }
+            });
+
+            this.renameGrid.createGrid({
+                idProperty: "Name",
+                columns: {
+                    targetRenameName: editor({
+                        label: this.i18n.TargetName,
+                        width: 144,
+                        autoSave: true,
+                        editor: "text"
+                    })
+                }
+            });
+
+            this.addToSuperfileGrid.createGrid({
+                idProperty: "Name",
+                columns: {
+                    Name: {
+                        label: this.i18n.LogicalName
+                    }
+                }
+            });
+
+            this.desprayGrid.createGrid({
+                idProperty: "Name",
+                columns: {
+                    Name: {
+                        label: this.i18n.LogicalName
+                    },
+                    targetName: editor({
+                        label: this.i18n.TargetName,
+                        width: 144,
+                        autoSave: true,
+                        editor: "text"
+                    })
+                }
+            });
         },
 
         initFilter: function () {
@@ -495,18 +528,41 @@ define([
 
             registry.byId(this.id + "Open").set("disabled", !hasSelection);
             registry.byId(this.id + "Delete").set("disabled", !hasSelection);
+            registry.byId(this.id + "CopyDropDown").set("disabled", !hasSelection);
+            registry.byId(this.id + "RenameDropDown").set("disabled", !hasSelection);
+            registry.byId(this.id + "AddtoDropDown").set("disabled", !hasSelection);
             registry.byId(this.id + "AddtoDropDown").set("disabled", !hasSelection);
             registry.byId(this.id + "DesprayDropDown").set("disabled", !hasSelection);
 
             if (hasSelection) {
-                var sourceDiv = dom.byId(this.id + "DesprayDialogSource");
-                domConstruct.empty(sourceDiv);
                 var context = this;
+                var data = [];
+                var matchedPrefix = [];
                 arrayUtil.forEach(selection, function (item, idx) {
-                    domConstruct.create("div", {
-                        innerHTML: item.Name
-                    }, sourceDiv);
+                    var nameParts = item.Name.split("::");
+                    if (idx === 0) {
+                        matchedPrefix = nameParts.slice(0, nameParts.length - 1);
+                    } else {
+                        var i = 0;
+                        for (var i = 0; i < matchedPrefix.length && i < nameParts.length - 1; ++i) {
+                            if (matchedPrefix[i] !== nameParts[i]) {
+                                break;
+                            }
+                        }
+                        matchedPrefix = matchedPrefix.slice(0, i);
+                    }
+                    lang.mixin(item, {
+                        targetName:  nameParts[nameParts.length - 1],
+                        targetCopyName: item.Name + "_copy",
+                        targetRenameName: item.Name + "_rename"
+                });
+                    data.push(item);
                 });
+                registry.byId(this.id + "AddToSuperfileTargetName").set("value", matchedPrefix.join("::") + "::superfile");
+                this.copyGrid.setData(data);
+                this.renameGrid.setData(data);
+                this.addToSuperfileGrid.setData(data);
+                this.desprayGrid.setData(data);
             }
         },
 

+ 1 - 10
esp/files/scripts/ESPDFUWorkunit.js

@@ -21,15 +21,13 @@ define([
     "dojo/i18n!./nls/GetDFUWorkunitsWidget",
     "dojo/_base/array",
     "dojo/_base/Deferred",
-    "dojo/data/ObjectStore",
-    "dojo/store/util/QueryResults",
     "dojo/store/Observable",
 
     "hpcc/FileSpray",
     "hpcc/ESPUtil",
     "hpcc/ESPRequest",
     "hpcc/ESPResult"
-], function (declare, lang, i18n, nlsCommon, nlsSpecific, arrayUtil, Deferred, ObjectStore, QueryResults, Observable,
+], function (declare, lang, i18n, nlsCommon, nlsSpecific, arrayUtil, Deferred, Observable,
     FileSpray, ESPUtil, ESPRequest, ESPResult) {
 
     var i18n = lang.mixin(nlsCommon, nlsSpecific);
@@ -298,13 +296,6 @@ define([
             var store = new Store(options);
             store = Observable(store);
             return store;
-        },
-
-        CreateWUQueryObjectStore: function (options) {
-            var objStore = new ObjectStore({
-                objectStore: this.CreateWUQueryStore()
-            });
-            return objStore;
         }
     };
 });

+ 5 - 10
esp/files/scripts/ESPLogicalFile.js

@@ -18,8 +18,6 @@ define([
     "dojo/_base/array",
     "dojo/_base/lang",
     "dojo/_base/Deferred",
-    "dojo/data/ObjectStore",
-    "dojo/store/util/QueryResults",
     "dojo/store/Observable",
     "dojo/Stateful",
 
@@ -28,7 +26,7 @@ define([
     "hpcc/ESPRequest",
     "hpcc/ESPUtil",
     "hpcc/ESPResult"
-], function (declare, arrayUtil, lang, Deferred, ObjectStore, QueryResults, Observable, Stateful,
+], function (declare, arrayUtil, lang, Deferred, Observable, Stateful,
         WsDfu, FileSpray, ESPRequest, ESPUtil, ESPResult) {
 
     var _logicalFiles = {};
@@ -158,6 +156,10 @@ define([
                 }
             });
         },
+        getLeaf: function () {
+            var nameParts = this.Name.split("::");
+            return nameParts.length ? nameParts[nameParts.length - 1] : "";
+        },
         updateData: function (data) {
             this.inherited(arguments);
             if (!this.result) {
@@ -198,13 +200,6 @@ define([
         CreateLFQueryStore: function (options) {
             var store = new Store(options);
             return Observable(store);
-        },
-
-        CreateLFQueryObjectStore: function (options) {
-            var objStore = new ObjectStore({
-                objectStore: this.CreateLFQueryStore()
-            });
-            return objStore;
         }
     };
 });

+ 1 - 3
esp/files/scripts/ESPQuery.js

@@ -18,8 +18,6 @@ define([
     "dojo/_base/array",
     "dojo/_base/lang",
     "dojo/_base/Deferred",
-    "dojo/data/ObjectStore",
-    "dojo/store/util/QueryResults",
     "dojo/store/Observable",
     "dojo/Stateful",
 
@@ -30,7 +28,7 @@ define([
     "hpcc/ESPRequest",
     "hpcc/ESPUtil",
     "hpcc/ESPWorkunit"
-], function (declare, arrayUtil, lang, Deferred, ObjectStore, QueryResults, Observable, Stateful,
+], function (declare, arrayUtil, lang, Deferred, Observable, Stateful,
         parser,
         WsWorkunits, WsEcl, ESPRequest, ESPUtil, ESPWorkunit) {
 

+ 1 - 16
esp/files/scripts/ESPResult.js

@@ -19,8 +19,6 @@ define([
     "dojo/_base/Deferred",
     "dojo/_base/lang",
     "dojo/NodeList-manipulate",
-    "dojo/data/ObjectStore",
-    "dojo/store/util/QueryResults",
     "dojo/store/Observable",
     "dojo/dom-construct",
 
@@ -31,7 +29,7 @@ define([
     "hpcc/ESPBase",
     "hpcc/ESPRequest",
     "hpcc/WsWorkunits"
-], function (declare, arrayUtil, Deferred, lang, NodeListManipulate, ObjectStore, QueryResults, Observable, domConstruct,
+], function (declare, arrayUtil, Deferred, lang, NodeListManipulate, Observable, domConstruct,
             parser, DomParser, entities,
             ESPBase, ESPRequest, WsWorkunits) {
 
@@ -474,12 +472,6 @@ define([
             return deferred.promise;
         },
 
-        getObjectStore: function () {
-            return new ObjectStore({
-                objectStore: this.store
-            });
-        },
-
         getLoadingMessage: function () {
             if (lang.exists("wu.state", this)) {
                 return "<span class=\'dojoxGridWating\'>[" + this.wu.state + "]</span>";
@@ -498,13 +490,6 @@ define([
     });
 
     return {
-        CreateWUResultObjectStore: function (options) {
-            var store = new Store(options);
-            store = Observable(store);
-            var objStore = new ObjectStore({ objectStore: store });
-            return objStore;
-        },
-
         Get: function (params) {
             return new Result(params);
         }

+ 1 - 7
esp/files/scripts/ESPWorkunit.js

@@ -19,8 +19,6 @@ define([
     "dojo/_base/lang",
     "dojo/_base/Deferred",
     "dojo/promise/all",
-    "dojo/data/ObjectStore",
-    "dojo/store/util/QueryResults",
     "dojo/store/Observable",
 
     "hpcc/WsWorkunits",
@@ -28,7 +26,7 @@ define([
     "hpcc/ESPUtil",
     "hpcc/ESPRequest",
     "hpcc/ESPResult"
-], function (declare, arrayUtil, lang, Deferred, all, ObjectStore, QueryResults, Observable,
+], function (declare, arrayUtil, lang, Deferred, all, Observable,
     WsWorkunits, WsTopology, ESPUtil, ESPRequest, ESPResult) {
 
     var _workunits = {};
@@ -650,10 +648,6 @@ define([
         CreateWUQueryStore: function (options) {
             var store = new Store(options);
             return Observable(store);
-        },
-
-        CreateWUQueryObjectStore: function (options) {
-            return new ObjectStore({ objectStore: this.CreateWUQueryStore(options) });
         }
     };
 });

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

@@ -266,21 +266,21 @@ define([
                 this.menuFilterJobname = this.addMenuItem(pSubMenu, {
                     onClick: function (args) {
                         context.filter.clear();
-                        context.filter.setValue(context.id + "Jobname", context.menuFilterOwner.get("hpcc_value"));
+                        context.filter.setValue(context.id + "Jobname", context.menuFilterJobname.get("hpcc_value"));
                         context.refreshGrid();
                     }
                 });
                 this.menuFilterCluster = this.addMenuItem(pSubMenu, {
                     onClick: function (args) {
                         context.filter.clear();
-                        context.filter.setValue(context.id + "ClusterTargetSelect", context.menuFilterOwner.get("hpcc_value"));
+                        context.filter.setValue(context.id + "ClusterTargetSelect", context.menuFilterCluster.get("hpcc_value"));
                         context.refreshGrid();
                     }
                 });
                 this.menuFilterState = this.addMenuItem(pSubMenu, {
                     onClick: function (args) {
                         context.filter.clear();
-                        context.filter.setValue(context.id + "StateSelect", context.menuFilterOwner.get("hpcc_value"));
+                        context.filter.setValue(context.id + "StateSelect", context.menuFilterState.get("hpcc_value"));
                         context.refreshGrid();
                     }
                 });

+ 1 - 2
esp/files/scripts/HPCCPlatformWidget.js

@@ -47,13 +47,12 @@ define([
     "dijit/Dialog",
     "dijit/MenuSeparator",
 
-    "dojox/layout/TableContainer",
-
     "hpcc/HPCCPlatformMainWidget",
     "hpcc/HPCCPlatformECLWidget",
     "hpcc/HPCCPlatformFilesWidget",
     "hpcc/HPCCPlatformRoxieWidget",
     "hpcc/HPCCPlatformOpsWidget",
+    "hpcc/TableContainer",
     "hpcc/InfoGridWidget"
 
 ], function (declare, lang, i18n, nlsCommon, nlsSpecific, arrayUtil, dom, domStyle,

+ 13 - 13
esp/files/scripts/LFDetailsWidget.js

@@ -64,9 +64,9 @@ define([
 
         borderContainer: null,
 
-        copyDialog: null,
-        renameDialog: null,
-        desprayDialog: null,
+        copyForm: null,
+        renameForm: null,
+        desprayForm: null,
         summaryWidget: null,
         contentWidget: null,
         sourceWidget: null,
@@ -81,9 +81,9 @@ define([
 
         postCreate: function (args) {
             this.inherited(arguments);
-            this.copyDialog = registry.byId(this.id + "CopyDialog");
-            this.renameDialog = registry.byId(this.id + "RenameDialog");
-            this.desprayDialog = registry.byId(this.id + "DesprayDialog");
+            this.copyForm = registry.byId(this.id + "CopyForm");
+            this.renameForm = registry.byId(this.id + "RenameForm");
+            this.desprayForm = registry.byId(this.id + "DesprayForm");
             this.summaryWidget = registry.byId(this.id + "_Summary");
             this.contentWidget = registry.byId(this.id + "_Content");
             this.sourceWidget = registry.byId(this.id + "_Source");
@@ -128,10 +128,10 @@ define([
             }
         },
         _onCopyOk: function (event) {
-            if (this.copyDialog.validate()) {
+            if (this.copyForm.validate()) {
                 var context = this;
                 this.logicalFile.copy({
-                    request: domForm.toObject(this.id + "CopyDialog")
+                    request: domForm.toObject(this.id + "CopyForm")
                 }).then(function (response) {
                     context._handleResponse("CopyResponse.result", response);
                 });
@@ -139,10 +139,10 @@ define([
             }
         },
         _onRenameOk: function (event) {
-            if (this.renameDialog.validate()) {
+            if (this.renameForm.validate()) {
                 var context = this;
                 this.logicalFile.rename({
-                    request: domForm.toObject(this.id + "RenameDialog")
+                    request: domForm.toObject(this.id + "RenameForm")
                 }).then(function (response) {
                     context._handleResponse("RenameResponse.wuid", response);
                 });
@@ -150,10 +150,10 @@ define([
             }
         },
         _onDesprayOk: function (event) {
-            if (this.desprayDialog.validate()) {
+            if (this.desprayForm.validate()) {
                 var context = this;
                 this.logicalFile.despray({
-                    request: domForm.toObject(this.id + "DesprayDialog")
+                    request: domForm.toObject(this.id + "DesprayForm")
                 }).then(function (response) {
                     context._handleResponse("DesprayResponse.wuid", response);
                 });
@@ -186,7 +186,7 @@ define([
                 DropZones: true,
                 callback: function (value, item) {
                     context.updateInput("DesprayTargetIPAddress", null, item.machine.Netaddress);
-                    context.updateInput("DesprayTargetPath", null, item.machine.Directory + "/" + context.logicalFile.Filename);
+                    context.updateInput("DesprayTargetPath", null, item.machine.Directory + "/" + context.logicalFile.getLeaf());
                 }
             });
         },

+ 207 - 92
esp/files/scripts/LZBrowseWidget.js

@@ -39,6 +39,7 @@ define([
     "dgrid/tree",
     "dgrid/Keyboard",
     "dgrid/Selection",
+    "dgrid/editor",
     "dgrid/selector",
     "dgrid/extensions/ColumnResizer",
     "dgrid/extensions/DijitRegistry",
@@ -52,6 +53,7 @@ define([
     "hpcc/HexViewWidget",
     "hpcc/DFUWUDetailsWidget",
     "hpcc/TargetSelectWidget",
+    "hpcc/SelectionGridWidget",
 
     "dojo/text!../templates/LZBrowseWidget.html",
 
@@ -69,6 +71,7 @@ define([
     "dijit/ToolbarSeparator",
     "dijit/TooltipDialog",
     "dijit/form/DropDownButton",
+    "dijit/Fieldset",
 
     "dojox/form/Uploader",
     "dojox/form/uploader/FileList",
@@ -76,37 +79,34 @@ define([
     "hpcc/TableContainer"
 ], function (declare, lang, i18n, nlsCommon, nlsSpecific, arrayUtil, dom, domAttr, domClass, domForm, iframe, date, on,
                 registry, Dialog, Menu, MenuItem, MenuSeparator, PopupMenuItem,
-                OnDemandGrid, tree, Keyboard, Selection, selector, ColumnResizer, DijitRegistry, Pagination,
-                _TabContainerWidget, FileSpray, ESPUtil, ESPRequest, ESPDFUWorkunit, HexViewWidget, DFUWUDetailsWidget, TargetSelectWidget,
+                OnDemandGrid, tree, Keyboard, Selection, editor, selector, ColumnResizer, DijitRegistry, Pagination,
+                _TabContainerWidget, FileSpray, ESPUtil, ESPRequest, ESPDFUWorkunit, HexViewWidget, DFUWUDetailsWidget, TargetSelectWidget, SelectionGridWidget,
                 template) {
     return declare("LZBrowseWidget", [_TabContainerWidget, ESPUtil.FormHelper], {
         templateString: template,
         baseClass: "LZBrowseWidget",
         i18n: lang.mixin(nlsCommon, nlsSpecific),
 
-        sprayFixedDialog: null,
-        sprayVariableDialog: null,
-        sprayXmlDialog: null,
-
-        landingZonesTab: null,
-        landingZonesGrid: null,
-
-        tabMap: [],
-
-        validateDialog: null,
-
         postCreate: function (args) {
             this.inherited(arguments);
-            this.sprayFixedDialog = registry.byId(this.id + "SprayFixedDialog");
-            this.sprayVariableDialog = registry.byId(this.id + "SprayVariableDialog");
-            this.sprayXmlDialog = registry.byId(this.id + "SprayXmlDialog");
+            this.sprayFixedForm = registry.byId(this.id + "SprayFixedForm");
+            this.sprayFixedDestinationSelect = registry.byId(this.id + "SprayFixedDestination");
+            this.sprayFixedGrid = registry.byId(this.id + "SprayFixedGrid");
+            this.sprayDelimitedForm = registry.byId(this.id + "SprayDelimitedForm");
+            this.sprayDelimitedDestinationSelect = registry.byId(this.id + "SprayDelimitedDestination");
+            this.sprayDelimitedGrid = registry.byId(this.id + "SprayDelimitedGrid");
+            this.sprayXmlForm = registry.byId(this.id + "SprayXmlForm");
+            this.sprayXmlDestinationSelect = registry.byId(this.id + "SprayXmlDestinationSelect");
+            this.sprayXmlGrid = registry.byId(this.id + "SprayXmlGrid");
+            this.sprayVariableForm = registry.byId(this.id + "SprayVariableForm");
+            this.sprayVariableDestinationSelect = registry.byId(this.id + "SprayVariableDestination");
+            this.sprayVariableGrid = registry.byId(this.id + "SprayVariableGrid");
+            this.sprayBlobForm = registry.byId(this.id + "SprayBlobForm");
+            this.sprayBlobDestinationSelect = registry.byId(this.id + "SprayBlobDestination");
+            this.sprayBlobGrid = registry.byId(this.id + "SprayBlobGrid");
             this.landingZonesTab = registry.byId(this.id + "_LandingZones");
             this.uploader = registry.byId(this.id + "Upload");
             this.uploadFileList = registry.byId(this.id + "UploadFileList");
-            this.spraySourceSelect = registry.byId(this.id + "SpraySourceSelect");
-            this.sprayFixedDestinationSelect = registry.byId(this.id + "SprayFixedDestination");
-            this.sprayVariableDestinationSelect = registry.byId(this.id + "SprayVariableDestination");
-            this.sprayXmlDestinationSelect = registry.byId(this.id + "SprayXmlDestinationSelect");
             this.dropZoneSelect = registry.byId(this.id + "DropZoneTargetSelect");
             this.fileListDialog = registry.byId(this.id + "FileListDialog");
 
@@ -167,7 +167,7 @@ define([
         },
 
         _onDelete: function (event) {
-            if (confirm(this.i18n.Deleteselectedfiles)) {
+            if (confirm(this.i18n.DeleteSelectedFiles)) {
                 var context = this;
                 arrayUtil.forEach(this.landingZonesGrid.getSelected(), function(item, idx) {
                     FileSpray.DeleteDropZoneFile({
@@ -212,72 +212,111 @@ define([
             registry.byId(this.id + "FileListDialog").hide();
         },
 
-        _onSprayFixed: function (event) {
-            if (this.sprayFixedDialog.validate()) {
+        _spraySelectedOneAtATime: function (dropDownID, formID, doSpray) {
+            if (registry.byId(this.id + formID).validate()) {
                 var selections = this.landingZonesGrid.getSelected();
                 var context = this;
                 arrayUtil.forEach(selections, function (item, idx) {
-                    var formData = domForm.toObject(context.id + "SprayFixedDialog");
-                    lang.mixin(formData, {
+                    var request = domForm.toObject(context.id + formID);
+                    if (request.namePrefix && !context.endsWith(request.namePrefix, "::")) {
+                        request.namePrefix += "::";
+                    }
+                    lang.mixin(request, {
                         sourceIP: item.DropZone.NetAddress,
-                        sourcePath: item.fullPath
+                        sourcePath: item.fullPath,
+                        sourceRowTag: item.targetRowTag,
+                        destLogicalName: request.namePrefix + item.targetName
                     });
-
-                    FileSpray.SprayFixed({
-                        request: formData
-                    }).then(function (response) {
-                        context._handleResponse("SprayFixedResponse.wuid", response);
-                    })
+                    doSpray(request, item);
                 });
-                registry.byId(this.id + "SprayFixedDropDown").closeDropDown();
+                registry.byId(this.id + dropDownID).closeDropDown();
             }
         },
 
-        _onSprayVariable: function(event) {
-            if (this.sprayVariableDialog.validate()) {
+        _spraySelected: function (dropDownID, formID, doSpray) {
+            if (registry.byId(this.id + formID).validate()) {
                 var selections = this.landingZonesGrid.getSelected();
-                var context = this;
-                arrayUtil.forEach(selections, function (item, idx) {
-                    var formData = domForm.toObject(context.id + "SprayVariableDialog");
-                    lang.mixin(formData, {
-                        sourceIP: item.DropZone.NetAddress,
-                        sourcePath: item.fullPath
+                if (selections.length) {
+                    var request = domForm.toObject(this.id + formID);
+                    var item = selections[0];
+                    lang.mixin(request, {
+                        sourceIP: selections[0].DropZone.NetAddress,
+                        nosplit: true
                     });
-                    FileSpray.SprayVariable({
-                        request: formData
-                    }).then(function (response) {
-                        context._handleResponse("SprayResponse.wuid", response);
+                    var sourcePath = "";
+                    arrayUtil.forEach(selections, function (item, idx) {
+                        if (sourcePath.length)
+                            sourcePath += ",";
+                        sourcePath += item.fullPath;
                     });
-                });
-                registry.byId(this.id + "SprayVariableDropDown").closeDropDown();
+                    lang.mixin(request, {
+                        sourcePath: sourcePath
+                    });
+                    doSpray(request, item);
+                    registry.byId(this.id + dropDownID).closeDropDown();
+                }
             }
         },
 
+        _onSprayFixed: function (event) {
+            var context = this;
+            this._spraySelectedOneAtATime("SprayFixedDropDown", "SprayFixedForm", function (request, item) {
+                lang.mixin(request, {
+                    sourceRecordSize: item.targetRecordLength
+                });
+                FileSpray.SprayFixed({
+                    request: request
+                }).then(function (response) {
+                    context._handleResponse("SprayFixedResponse.wuid", response);
+                });
+            });
+        },
+
+        _onSprayDelimited: function(event) {
+            var context = this;
+            this._spraySelectedOneAtATime("SprayDelimitedDropDown", "SprayDelimitedForm", function (request, item) {
+                FileSpray.SprayVariable({
+                    request: request
+                }).then(function (response) {
+                    context._handleResponse("SprayResponse.wuid", response);
+                });
+            });
+        },
+
         _onSprayXml: function(event) {
-            if (this.sprayXmlDialog.validate()) {
-                var selections = this.landingZonesGrid.getSelected();
-                var context = this;
-                arrayUtil.forEach(selections, function (item, idx) {
-                    var formData = domForm.toObject(context.id + "SprayXmlDialog");
-                    lang.mixin(formData, {
-                        sourceIP: item.DropZone.NetAddress,
-                        sourcePath: item.DropZone.fullPath
-                    });
-                    FileSpray.SprayVariable({
-                        request: formData
-                    }).then(function (response) {
-                        context._handleResponse("SprayResponse.wuid", response);
-                    });
+            var context = this;
+            this._spraySelectedOneAtATime("SprayXmlDropDown", "SprayXmlForm", function (request, item) {
+                lang.mixin(request, {
+                    sourceRowTag: item.targetRowTag
                 });
-                registry.byId(this.id + "SprayXmlDropDown").closeDropDown();
-            }
+                FileSpray.SprayVariable({
+                    request: request
+                }).then(function (response) {
+                    context._handleResponse("SprayResponse.wuid", response);
+                });
+            });
+        },
+
+        _onSprayVariable: function (event) {
+            var context = this;
+            this._spraySelectedOneAtATime("SprayVariableDropDown", "SprayVariableForm", function (request, item) {
+                FileSpray.SprayFixed({
+                    request: request
+                }).then(function (response) {
+                    context._handleResponse("SprayFixedResponse.wuid", response);
+                });
+            });
         },
 
-        _onRowDblClick: function (wuid) {
-            var wuTab = this.ensurePane(this.id + "_" + wuid, {
-                Wuid: wuid
+        _onSprayBlob: function (event) {
+            var context = this;
+            this._spraySelected("SprayBlobDropDown", "SprayBlobForm", function (request, item) {
+                FileSpray.SprayFixed({
+                    request: request
+                }).then(function (response) {
+                    context._handleResponse("SprayFixedResponse.wuid", response);
+                });
             });
-            this.selectChild(wuTab);
         },
 
         _onRowContextMenu: function (item, colField, mystring) {
@@ -293,26 +332,21 @@ define([
             this.sprayFixedDestinationSelect.init({
                 Groups: true
             });
-            this.sprayVariableDestinationSelect.init({
+            this.sprayDelimitedDestinationSelect.init({
                 Groups: true
             });
             this.sprayXmlDestinationSelect.init({
                 Groups: true
             });
+            this.sprayVariableDestinationSelect.init({
+                Groups: true
+            });
+            this.sprayBlobDestinationSelect.init({
+                Groups: true
+            });
             this.dropZoneSelect.init({
                 DropZones: true
             });
-            var context = this;
-            this.spraySourceSelect.set("value", "Fixed");
-            this.spraySourceSelect.on("change", function (evt) {
-                var source = this.get("value");
-                if(source == "Fixed"){
-                    registry.byId(context.id + "SprayFixedRecordLength").set('readOnly', false);
-                }else{
-                    registry.byId(context.id + "SprayFixedRecordLength").set('readOnly', true);
-                    registry.byId(context.id + "SprayFixedRecordLength").set('value', "");
-                }
-            });
         },
 
         initTab: function () {
@@ -386,18 +420,6 @@ define([
             this.landingZonesGrid.set("noDataMessage", "<span class='dojoxGridNoData'>" + this.i18n.noDataMessage + "</span>");
 
             var context = this;
-            on(document, ".WuidClick:click", function (evt) {
-                if (context._onRowDblClick) {
-                    var item = context.landingZonesGrid.row(evt).data;
-                    context._onRowDblClick(item.Wuid);
-                }
-            });
-            this.landingZonesGrid.on(".dgrid-row:dblclick", function (evt) {
-                if (context._onRowDblClick) {
-                    var item = context.landingZonesGrid.row(evt).data;
-                    context._onRowDblClick(item.Wuid);
-                }
-            });
             this.landingZonesGrid.on(".dgrid-row:contextmenu", function (evt) {
                 if (context._onRowContextMenu) {
                     var item = context.landingZonesGrid.row(evt).data;
@@ -414,6 +436,79 @@ define([
                 context.refreshActionState();
             });
             this.landingZonesGrid.startup();
+
+            this.sprayFixedGrid.createGrid({
+                idProperty: "calculatedID",
+                columns: {
+                    targetName: editor({
+                        label: this.i18n.TargetName,
+                        width: 144,
+                        autoSave: true,
+                        editor: "text"
+                    }),
+                    targetRecordLength: editor({
+                        label: this.i18n.RecordLength,
+                        width: 72,
+                        autoSave: true,
+                        editor: "text"
+                    })
+                }
+            });
+
+            this.sprayDelimitedGrid.createGrid({
+                idProperty: "calculatedID",
+                columns: {
+                    targetName: editor({
+                        label: this.i18n.TargetName,
+                        width: 144,
+                        autoSave: true,
+                        editor: "text"
+                    })
+                }
+            });
+
+            this.sprayXmlGrid.createGrid({
+                idProperty: "calculatedID",
+                columns: {
+                    targetName: editor({
+                        label: this.i18n.TargetName,
+                        width: 144,
+                        autoSave: true,
+                        editor: "text"
+                    }),
+                    targetRowTag: editor({
+                        label: this.i18n.RowTag,
+                        width: 72,
+                        autoSave: true,
+                        editor: "text"
+                    })
+                }
+            });
+
+            this.sprayVariableGrid.createGrid({
+                idProperty: "calculatedID",
+                columns: {
+                    targetName: editor({
+                        label: this.i18n.TargetName,
+                        width: 144,
+                        autoSave: true,
+                        editor: "text"
+                    })
+                }
+            });
+
+            this.sprayBlobGrid.createGrid({
+                idProperty: "calculatedID",
+                columns: {
+                    fullPath: editor({
+                        label: this.i18n.SourcePath,
+                        width: 144,
+                        autoSave: true,
+                        editor: "text"
+                    })
+                }
+            });
+
             this.refreshActionState();
         },
 
@@ -430,8 +525,28 @@ define([
             registry.byId(this.id + "Download").set("disabled", !hasSelection);
             registry.byId(this.id + "Delete").set("disabled", !hasSelection);
             registry.byId(this.id + "SprayFixedDropDown").set("disabled", !hasSelection);
-            registry.byId(this.id + "SprayVariableDropDown").set("disabled", !hasSelection);
+            registry.byId(this.id + "SprayDelimitedDropDown").set("disabled", !hasSelection);
             registry.byId(this.id + "SprayXmlDropDown").set("disabled", !hasSelection);
+            registry.byId(this.id + "SprayVariableDropDown").set("disabled", !hasSelection);
+            registry.byId(this.id + "SprayBlobDropDown").set("disabled", !hasSelection);
+
+            if (hasSelection) {
+                var context = this;
+                var data = [];
+                arrayUtil.forEach(selection, function (item, idx) {
+                    lang.mixin(item, lang.mixin({
+                        targetName: item.displayName,
+                        targetRecordLength: 1,
+                        targetRowTag: context.i18n.tag
+                    }, item));
+                    data.push(item);
+                });
+                this.sprayFixedGrid.setData(data);
+                this.sprayDelimitedGrid.setData(data);
+                this.sprayXmlGrid.setData(data);
+                this.sprayVariableGrid.setData(data);
+                this.sprayBlobGrid.setData(data);
+            }
         },
 
         ensurePane: function (type, id, title, params) {

+ 1 - 2
esp/files/scripts/PackageMapQueryWidget.js

@@ -30,7 +30,6 @@ define([
     "dijit/registry",
     "dojox/form/Uploader",
     "dojox/form/uploader/FileList",
-    "dojox/form/uploader/plugins/Flash",
     "dojox/grid/EnhancedGrid",
     "dojox/grid/enhanced/plugins/Pagination",
     "dojox/grid/enhanced/plugins/IndirectSelection",
@@ -54,7 +53,7 @@ define([
     "dijit/TooltipDialog"
 ], function (declare, lang, arrayUtil, dom, domConstruct, domForm, ObjectStore, on, topic,
     _LayoutWidget, _TemplatedMixin, _WidgetsInTemplateMixin, registry,
-    Uploader, FileUploader, Flash, EnhancedGrid, Pagination, IndirectSelection, ItemFileWriteStore,
+    Uploader, FileUploader, EnhancedGrid, Pagination, IndirectSelection, ItemFileWriteStore,
     PackageMapDetailsWidget, PackageMapValidateWidget,
     WsPackageMaps, ESPPackageProcess, SFDetailsWidget,
     template) {

+ 1 - 1
esp/files/scripts/SFDetailsWidget.js

@@ -101,7 +101,7 @@ define([
         },
         _onDelete: function (event) {
             if (confirm(this.i18n.DeleteSuperfile)) {
-                this.logicalFile.removeSubfiles(this.subfilesGrid.store.objectStore.data, true);
+                this.logicalFile.removeSubfiles(this.subfilesGrid.store.data, true);
             }
         },
         _onRemove: function (event) {

+ 86 - 0
esp/files/scripts/SelectionGridWidget.js

@@ -0,0 +1,86 @@
+/*##############################################################################
+#    HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License");
+#    you may not use this file except in compliance with the License.
+#    You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+############################################################################## */
+define([
+    "dojo/_base/declare",
+    "dojo/_base/lang",
+    "dojo/store/Memory",
+    "dojo/store/Observable",
+
+    "dijit/registry",
+
+    "dgrid/OnDemandGrid",
+    "dgrid/Keyboard",
+    "dgrid/Selection",
+    "dgrid/editor",
+    "dgrid/selector",
+    "dgrid/extensions/ColumnResizer",
+    "dgrid/extensions/DijitRegistry",
+
+    "hpcc/_Widget",
+
+    "dojo/text!../templates/SelectionGridWidget.html",
+
+    "dijit/layout/BorderContainer",
+    "dijit/layout/ContentPane"
+], function (declare, lang, Memory, Observable,
+        registry,
+        OnDemandGrid, Keyboard, Selection, editor, selector, ColumnResizer, DijitRegistry,
+        _Widget,
+        template) {
+    return declare("SelectionGridWidget", [_Widget], {
+        templateString: template,
+        store: null,
+        idProperty: "Change Me",
+
+        constructor: function (args) {
+            this.inherited(arguments);
+        },
+
+        postCreate: function (args) {
+            this.inherited(arguments);
+            this.borderContainer = registry.byId(this.id + "BorderContainer");
+        },
+
+        resize: function (args) {
+            this.inherited(arguments);
+            this.borderContainer.resize();
+        },
+
+        startup: function (args) {
+            this.inherited(arguments);
+        },
+
+        //  Implementation ---
+        createGrid: function (args) {
+            this.idProperty = args.idProperty;
+            var store = new Memory({
+                idProperty: this.idProperty,
+                data: []
+            });
+            this.store = Observable(store);
+
+            this.grid = new declare([OnDemandGrid, Keyboard, Selection, ColumnResizer, DijitRegistry])({
+                store: this.store,
+                columns: args.columns
+            }, this.id + "Grid");
+        },
+
+        setData: function (data) {
+            this.store.setData(data);
+            this.grid.refresh();
+        }
+    });
+});

+ 2 - 2
esp/files/scripts/WsDfu.js

@@ -75,11 +75,11 @@ define([
             return ESPRequest.send("WsDfu", "SuperfileAction", {
                 request: request,
                 load: function (response) {
-                    if (lang.exists("SuperfileActionResponse", response)) {
+                    if (lang.exists("SuperfileActionResponse", response) && response.SuperfileActionResponse.retcode) {
                         dojo.publish("hpcc/brToaster", {
                             Severity: "Error",
                             Source: "WsDfu.SuperfileAction",
-                            Exceptions: [{ Message: response.AddtoSuperfileResponse.Subfiles }]
+                            Exceptions: [{ Message: dojo.toJson(response.SuperfileActionResponse) }]
                         });
                     }
 

+ 1 - 1
esp/files/scripts/_TabContainerWidget.js

@@ -115,7 +115,7 @@ define([
         },
 
         go: function (path, replace, noHash) {
-            console.log(this.id + ".go(" + path + ", " + replace + ", " + noHash + ")");
+            //console.log(this.id + ".go(" + path + ", " + replace + ", " + noHash + ")");
             if (noHash) {
                 var d = 0;
             } else {

+ 5 - 0
esp/files/scripts/_Widget.js

@@ -30,6 +30,11 @@ define([
             }
             
             return false;
+        },
+
+        //  Usefull functions  ---
+        endsWith: function (str, suffix) {
+            return str.indexOf(suffix, str.length - suffix.length) !== -1;
         }
     });
 });

+ 6 - 0
esp/files/scripts/nls/DFUQueryWidget.js

@@ -7,6 +7,7 @@ define({ root:
     AddToSuperfile: "Add To Superfile",
     Append: "Append",
     Cluster: "Cluster",
+    Copy: "Copy",
     Compress: "Compress",
     DeleteSelectedFiles: "Delete Selected Files?",
     Delimited: "Delimited",
@@ -45,6 +46,8 @@ define({ root:
     Quote: "Quote",
     RecordLength: "Record Length",
     Records: "Records",
+    Rename: "Rename",
+    RetainSuperfileStructure: "Retain Superfile Structure",
     RowTag: "Row Tag",
     Seperators: "Seperators",
     Size: "Size",
@@ -53,11 +56,14 @@ define({ root:
     Source: "Source",
     SplitPrefix: "Split Prefix",
     Spray: "Spray",
+    SuperFile: "Super File",
     tag: "tag",
     Target: "Target",
+    TargetName: "Target Name",
     ToDate: "To Date",
     ToSizes: "To Sizes",
     UseSingleConnection: "Use Single Connection",
+    Wrap: "Wrap",
     XML: "XML",
     ZeroLogicalFilesCheckFilter: "Zero Logical Files(check filter)"
 })

+ 1 - 0
esp/files/scripts/nls/LFDetailsWidget.js

@@ -34,6 +34,7 @@ define({ root:
     SplitPrefix: "Split Prefix",
     Summary: "Summary",
     Target: "Target",
+    TargetName: "Target Name",
     UseSingleConnection: "Use Single Connection",
     Workunit: "Workunit",
     Wrap: "Wrap",

+ 14 - 2
esp/files/scripts/nls/LZBrowseWidget.js

@@ -3,6 +3,8 @@ define({ root:
 ({
     title: "Landing Zones",
 
+    Blob: "BLOB",
+    BlobPrefix: "BLOB Prefix",
     Compress: "Compress",
     Date: "Date",
     DeleteSelectedFiles: "Delete Selected Files?",
@@ -14,30 +16,40 @@ define({ root:
     Fixed: "Fixed",
     Format: "Format",
     Group: "Group",
-    HexPreview: "Hex Preview",
+    Hex: "Hex",
+    Variable: "Variable",
+    VariableSourceType: "Source Type",
     Label: "Label",
     LandingZone: "Landing Zone",
     LineTerminators: "Line Terminators",
     Mask: "Mask",
     MaxRecordLength: "Max Record Length",
     Name: "Name",
+    NamePrefix: "Name Prefix",
+    NamePrefixPlaceholder: "some::prefix",
     NoSplit: "No Split",
     OmitSeparator: "Omit Separator",
     Options: "Options",
     Overwrite: "Overwrite",
     Prefix: "Prefix",
+    PrefixPlaceholder: "filename{:length}, filesize{:[B|L][1-8]}",
+    Preview: "Preview",
     Quote: "Quote",
     RecordLength: "Record Length",
     RowTag: "Row Tag",
     Seperators: "Seperators",
     Size: "Size",
     Source: "Source",
+    SourcePath: "Source Path (Wildcard Enabled)",
     Spray: "Spray",
-    SpraySourceType: "Spray Source Type",
     Start: "Start",
     tag: "tag",
     Target: "Target",
+    TargetName: "Target Name",
+    TargetNamePlaceholder: "some::logical::name",
     Upload: "Upload",
+    Variable: "Variable",
+    VariableBigendian: "Variable Big-endian",
     XML: "XML"
 })
 //end v1.x content

+ 74 - 124
esp/files/templates/DFUQueryWidget.html

@@ -7,154 +7,104 @@
                     <span data-dojo-type="dijit.ToolbarSeparator"></span>
                     <div id="${id}Open" data-dojo-attach-event="onClick:_onOpen" data-dojo-type="dijit.form.Button">${i18n.Open}</div>
                     <div id="${id}Delete" data-dojo-attach-event="onClick:_onDelete" data-dojo-type="dijit.form.Button">${i18n.Delete}</div>
-                    <div id="${id}AddtoDropDown" data-dojo-type="dijit.form.DropDownButton">
-                        <span>${i18n.AddToSuperfile}</span>
-                        <div data-dojo-type="dijit.TooltipDialog">
-                            <div id="${id}AddToSuperfileForm" style="width:480px" onsubmit="return false;" data-dojo-type="dijit.form.Form" >
-                                <div class="dijitDialogPaneContentArea" data-dojo-props="cols:1" data-dojo-type="dojox.layout.TableContainer">
-                                    <input id="${id}AddToSuperfileTargetName" name="Superfile" title="${i18n.LogicalFile}:" style="width:100%;" required="true" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
-                                    <input id="${id}AddToSuperfileTargetAppend" name="ExistingFile" title="${i18n.Append}:" data-dojo-type="dijit/form/CheckBox" />
-                                </div>
-                                <div class="dijitDialogPaneActionBar">
-                                    <button type="submit" data-dojo-attach-event="onClick:_onAddToSuperfileOk" data-dojo-type="dijit.form.Button">${i18n.Add}</button>
-                                </div>
-                            </div>
-                        </div>
-                    </div>
-                    <div id="${id}DesprayDropDown" data-dojo-type="dijit.form.DropDownButton">
-                        <span>${i18n.Despray}</span>
+                    <span data-dojo-type="dijit.ToolbarSeparator"></span>
+                    <div id="${id}CopyDropDown" data-dojo-type="dijit.form.DropDownButton">
+                        <span>${i18n.Copy}</span>
                         <div data-dojo-type="dijit.TooltipDialog">
-                            <div id="${id}DesprayDialog" style="width: 460px;" onsubmit="return false;" data-dojo-type="dijit.form.Form">
-                                <h2>${i18n.Target}</h2>
-                                <div data-dojo-props="cols:2" data-dojo-type="dojox.layout.TableContainer">
-                                    <input id="${id}DesprayTargetSelect" title="${i18n.DropZone}:" name="destGroup" colspan="2" style="width: 100%;" data-dojo-type="TargetSelectWidget" />
-                                    <input id="${id}DesprayTargetIPAddress" title="${i18n.IPAddress}:" name="destIP" colspan="2" style="width: 100%;" required="true" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
-                                    <input id="${id}DesprayTargetPath" title="${i18n.Path}:" name="destPath" colspan="2" style="width: 100%;" required="true" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
-                                    <input id="${id}DesprayTargetSplitPrefix" title="${i18n.SplitPrefix}:" name="splitprefix" colspan="2" style="width: 100%;" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
-                                    <input id="${id}DesprayTargetUseSingleConnection" title="${i18n.UseSingleConnection}:" name="SingleConnection" colspan="2" data-dojo-type="dijit.form.CheckBox" />
-                                    <input id="${id}DesprayTargetOverwrite" title="${i18n.Overwrite}:" name="overwrite" colspan="2" data-dojo-type="dijit.form.CheckBox" />
-                                </div>
-                                <h2>${i18n.Source}</h2>
-                                <div id="${id}DesprayDialogSource" data-dojo-props="cols:1" data-dojo-type="dojox.layout.TableContainer">
+                            <div id="${id}CopyForm" style="width: 460px;" onsubmit="return false;" data-dojo-props="region: 'bottom'" data-dojo-type="dijit.form.Form">
+                                <div data-dojo-type="dijit.Fieldset">
+                                    <legend>Target</legend>
+                                    <div data-dojo-type="hpcc.TableContainer">
+                                        <input id="${id}CopyTargetSelect" title="${i18n.Group}:" name="destGroup" style="width:100%;" data-dojo-type="TargetSelectWidget" style="display: inline-block; vertical-align: middle" />
+                                    </div>
+                                    <div id="${id}CopyGrid" data-dojo-type="SelectionGridWidget">
+                                    </div>
+                                </div>
+                                <div data-dojo-type="dijit.Fieldset">
+                                    <legend>Options</legend>
+                                    <div data-dojo-props="cols:2" data-dojo-type="hpcc.TableContainer">
+                                        <input id="${id}CopyTargetOverwrite" title="${i18n.Overwrite}:" name="overwrite" data-dojo-type="dijit/form/CheckBox" />
+                                        <input id="${id}CopyTargetNoSplit" title="${i18n.NoSplit}:" name="nosplit" data-dojo-type="dijit/form/CheckBox" />
+                                        <input id="${id}CopyTargetCompress" title="${i18n.Compress}:" name="compress" data-dojo-type="dijit/form/CheckBox" />
+                                        <input id="${id}CopyTargetWrap" title="${i18n.Wrap}:" name="Wrap" data-dojo-type="dijit/form/CheckBox" />
+                                        <input id="${id}CopyTargetRetainSuperfileStructure" title="${i18n.RetainSuperfileStructure}:" name="superCopy" data-dojo-type="dijit/form/CheckBox" />
+                                    </div>
                                 </div>
                                 <div class="dijitDialogPaneActionBar">
-                                    <button type="submit" data-dojo-attach-event="onClick:_onDesprayOk" data-dojo-type="dijit.form.Button">${i18n.Despray}</button>
+                                    <button type="submit" data-dojo-attach-event="onClick:_onCopyOk" data-dojo-type="dijit.form.Button">${i18n.Copy}</button>
                                 </div>
                             </div>
                         </div>
                     </div>
-                    <span data-dojo-type="dijit.ToolbarSeparator"></span>
-                    <b>${i18n.Spray}:</b>
-                    <div id="${id}SprayFixedDropDown" data-dojo-type="dijit.form.DropDownButton">
-                        <span>${i18n.Fixed}</span>
+                    <div id="${id}RenameDropDown" data-dojo-type="dijit.form.DropDownButton">
+                        <span>${i18n.Rename}</span>
                         <div data-dojo-type="dijit.TooltipDialog">
-                            <div id="${id}SprayFixedDialog" style="width: 530px;" onsubmit="return false;" data-dojo-type="dijit.form.Form">
-                                <h2>${i18n.Source}</h2>
-                                <div data-dojo-props="cols:2" data-dojo-type="dojox.layout.TableContainer">
-                                    <input id="${id}SprayFixedIP" title="${i18n.IP}:" style="width: 95%;" name="sourceIP" colspan="2" required="true" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
-                                    <input id="${id}SprayFixedPath" title="${i18n.Path}:" style="width: 95%;" name="sourcePath" colspan="2" required="true" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
-                                    <input id="${id}SprayFixedRecordLength" title="${i18n.RecordLength}:" style="width: 95%;" name="sourceRecordSize" colspan="2" required="true" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
-                                </div>
-                                <h2>${i18n.Target}</h2>
-                                <div data-dojo-props="cols:2" data-dojo-type="dojox.layout.TableContainer">
-                                    <input id="${id}SprayFixedDestination" title="${i18n.Group}:" style="width: 95%;" name="destGroup" colspan="2" data-dojo-type="TargetSelectWidget" />
-                                    <input title="${i18n.Label}:" style="width: 95%;" name="destLogicalName" colspan="2" required="true" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
-                                    <input title="${i18n.Mask}:" style="width: 95%;" colspan="2" data-dojo-props="trim: true, readonly: true"  data-dojo-type="dijit.form.TextBox" />
-                                    <input title="${i18n.Prefix}:" style="width: 95%;" name="prefix" colspan="2" data-dojo-type="dijit.form.TextBox" />
-                                </div>
-                                <h2>${i18n.Options}</h2>
-                                <div data-dojo-props="cols:2" data-dojo-type="dojox.layout.TableContainer">
-                                    <input title="${i18n.Overwrite}:" name="overwrite" colspan="2" data-dojo-type="dijit.form.CheckBox" />
-                                    <input title="${i18n.NoSplit}:" name="nosplit" colspan="2" data-dojo-type="dijit.form.CheckBox" />
-                                    <input title="${i18n.Compress}:" name="compress" colspan="2" data-dojo-type="dijit.form.CheckBox" />
+                            <div id="${id}RenameForm" style="width: 460px;" onsubmit="return false;" data-dojo-type="dijit.form.Form">
+                                <div data-dojo-type="dijit.Fieldset">
+                                    <legend>Target</legend>
+                                    <div id="${id}RenameGrid" data-dojo-type="SelectionGridWidget">
+                                    </div>
+                                </div>
+                                <div data-dojo-type="dijit.Fieldset">
+                                    <legend>Options</legend>
+                                    <div data-dojo-props="cols:1" data-dojo-type="hpcc.TableContainer">
+                                        <input id="${id}RenameTargetOverwrite" title="${i18n.Overwrite}:" name="overwrite" data-dojo-type="dijit.form.CheckBox" />
+                                    </div>
                                 </div>
                                 <div class="dijitDialogPaneActionBar">
-                                    <button type="submit" data-dojo-attach-event="onClick:_onSprayFixed" data-dojo-type="dijit.form.Button">${i18n.Spray}</button>
+                                    <button type="submit" data-dojo-attach-event="onClick:_onRenameOk" data-dojo-type="dijit.form.Button">${i18n.Rename}</button>
                                 </div>
                             </div>
                         </div>
                     </div>
-                    <div id="${id}SprayVariableDropDown" data-dojo-type="dijit.form.DropDownButton">
-                        <span>${i18n.Delimited}</span>
+                    <div id="${id}AddtoDropDown" data-dojo-type="dijit.form.DropDownButton">
+                        <span>${i18n.AddToSuperfile}</span>
                         <div data-dojo-type="dijit.TooltipDialog">
-                            <div id="${id}SprayVariableDialog" style="width: 530px;" onsubmit="return false;" data-dojo-type="dijit.form.Form">
-                                <h2>${i18n.Source}</h2>
-                                <div data-dojo-props="cols:2" data-dojo-type="dojox.layout.TableContainer">
-                                    <input id="${id}SprayVariableIP" title="${i18n.IP}:" style="width: 95%;" name="sourceIP" colspan="2" required="true" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
-                                    <input id="${id}SprayVariablePath" title="${i18n.Path}:" style="width: 95%;" name="sourcePath" colspan="2" required="true" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
-                                    <select id="${id}sourceFormat" title="${i18n.Format}:" name="sourceFormat" data-dojo-type="dijit/form/Select">
-                                        <option value="1">ASCII</option>
-                                        <option value="2">UTF-8</option>
-                                        <option value="3">UTF-8N</option>
-                                        <option value="4">UTF-16</option>
-                                        <option value="5">UTF-16LE</option>
-                                        <option value="6">UTF-16BE</option>
-                                        <option value="7">UTF-32</option>
-                                        <option value="8">UTF-32LE</option>
-                                        <option value="9">UTF-32BE</option>
-                                    </select>
-                                    <input id="${id}SprayVariableMaxRecordLength" title="${i18n.MaxRecordLength}:" style="width: 95%;" name="sourceMaxRecordSize" value="8192" colspan="2" required="true" data-dojo-props="trim: true, placeHolder:'8192'" data-dojo-type="dijit.form.ValidationTextBox" />
-                                    <input id="${id}SprayVariableSeperators" title="${i18n.Seperators}:" style="width: 95%;" name="sourceCsvSeparate" value="," colspan="2" data-dojo-props="trim: true, placeHolder:'\,'" data-dojo-type="dijit.form.ValidationTextBox" />
-                                    <input title="${i18n.OmitSeparator}:" name="NoSourceCsvSeparator" colspan="2" data-dojo-type="dijit.form.CheckBox" />
-                                    <input id="${id}SprayVariableEscape" title="${i18n.Escape}:" style="width: 95%;" name="sourceCsvEscape" colspan="2" data-dojo-props="trim: true" data-dojo-type="dijit.form.TextBox" />
-                                    <input id="${id}SprayVariableTerminators" title="${i18n.LineTerminators}:" name="sourceCsvTerminate"  style="width: 95%;" value="\n,\r\n" colspan="2" required="true" data-dojo-props="trim: true, placeHolder:'\\n,\\r\\n'" data-dojo-type="dijit.form.ValidationTextBox" />
-                                    <input id="${id}SprayVariableQuote" title="${i18n.Quote}:" style="width: 95%;" name="sourceCsvQuote" value="'" colspan="2" data-data-dojo-props="trim: true, placeHolder:'\''" data-dojo-type="dijit.form.TextBox" />
-                                </div>
-                                <h2>${i18n.Target}</h2>
-                                <div data-dojo-props="cols:2" data-dojo-type="dojox.layout.TableContainer">
-                                    <input id="${id}SprayVariableDestination" title="${i18n.Group}:" style="width: 95%;" name="destGroup" colspan="2" data-dojo-type="TargetSelectWidget" />
-                                    <input title="${i18n.Label}:" style="width: 95%;" name="destLogicalName" colspan="2" data-dojo-props="trim: true" required="true" data-dojo-type="dijit.form.ValidationTextBox" />
-                                    <input title="${i18n.Prefix}:" style="width: 95%;" name="prefix" colspan="2" data-dojo-type="dijit.form.TextBox" />
-                                </div>
-                                <h2>${i18n.Options}</h2>
-                                <div data-dojo-props="cols:2" data-dojo-type="dojox.layout.TableContainer">
-                                    <input title="${i18n.Overwrite}:" name="overwrite" colspan="2" data-dojo-type="dijit.form.CheckBox" />
-                                    <input title="${i18n.NoSplit}:" name="nosplit" colspan="2" data-dojo-type="dijit.form.CheckBox" />
-                                    <input title="${i18n.Compress}:" name="compress" colspan="2" data-dojo-type="dijit.form.CheckBox" />
+                            <div id="${id}AddToSuperfileForm" style="width:480px" onsubmit="return false;" data-dojo-type="dijit.form.Form" >
+                                <div data-dojo-type="dijit.Fieldset">
+                                    <legend>Target</legend>
+                                    <div class="dijitDialogPaneContentArea" data-dojo-props="cols:1" data-dojo-type="hpcc.TableContainer">
+                                        <input id="${id}AddToSuperfileTargetName" name="Superfile" title="${i18n.SuperFile}:" style="width:100%;" required="true" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
+                                    </div>
+                                    <div id="${id}AddToSuperfileGrid" data-dojo-type="SelectionGridWidget">
+                                    </div>
+                                </div>
+                                <div data-dojo-type="dijit.Fieldset">
+                                    <legend>Options</legend>
+                                    <div class="dijitDialogPaneContentArea" data-dojo-props="cols:1" data-dojo-type="hpcc.TableContainer">
+                                        <input id="${id}AddToSuperfileTargetAppend" name="ExistingFile" title="${i18n.Append}:" data-dojo-type="dijit/form/CheckBox" />
+                                    </div>
                                 </div>
                                 <div class="dijitDialogPaneActionBar">
-                                    <button type="submit" data-dojo-attach-event="onClick:_onSprayVariable" data-dojo-type="dijit.form.Button">${i18n.Spray}</button>
+                                    <button type="submit" data-dojo-attach-event="onClick:_onAddToSuperfileOk" data-dojo-type="dijit.form.Button">${i18n.Add}</button>
                                 </div>
                             </div>
                         </div>
                     </div>
-                    <div id="${id}SprayXmlDropDown" data-dojo-type="dijit.form.DropDownButton">
-                        <span>${i18n.XML}</span>
+                    <div id="${id}DesprayDropDown" data-dojo-type="dijit.form.DropDownButton">
+                        <span>${i18n.Despray}</span>
                         <div data-dojo-type="dijit.TooltipDialog">
-                            <div id="${id}SprayXmlDialog" style="width: 530px;" data-dojo-type="dijit.form.Form">
-                                <h2>${i18n.Source}</h2>
-                                <div data-dojo-props="cols:2" data-dojo-type="dojox.layout.TableContainer">
-                                    <input id="${id}SprayXmlIP" title="${i18n.IP}:" style="width: 95%;" name="sourceIP" colspan="2" required="true" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
-                                    <input id="${id}SprayXmlPath" title="${i18n.Path}:" style="width: 95%;" name="sourcePath" colspan="2" required="true" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
-                                    <select id="${id}xmlsourceFormat" title="${i18n.Format}:" name="sourceFormat" data-dojo-type="dijit/form/Select">
-                                        <option value="1">ASCII</option>
-                                        <option value="2">UTF-8</option>
-                                        <option value="3">UTF-8N</option>
-                                        <option value="4">UTF-16</option>
-                                        <option value="5">UTF-16LE</option>
-                                        <option value="6">UTF-16BE</option>
-                                        <option value="7">UTF-32</option>
-                                        <option value="8">UTF-32LE</option>
-                                        <option value="9">UTF-32BE</option>
-                                    </select>
-                                    <input id="${id}SprayXmlMaxRecordLength" title="${i18n.MaxRecordLength}:" value="8192" style="width: 95%;" name="sourceMaxRecordSize" colspan="2" required="true" data-dojo-props="trim: true, placeHolder:'8192'" data-dojo-type="dijit.form.ValidationTextBox" />
-                                    <input id="${id}SprayXmlRowTag" title="${i18n.RowTag}:" style="width: 95%;" name="sourceRowTag" colspan="2" required="true" data-dojo-props="trim: true, placeHolder:'${i18n.tag}'" data-dojo-type="dijit.form.ValidationTextBox" />
-                                </div>
-                                <h2>${i18n.Spray}Destination</h2>
-                                <div data-dojo-props="cols:2" data-dojo-type="dojox.layout.TableContainer">
-                                    <input id="${id}SprayXmlDestinationSelect" title="${i18n.Group}:" style="width: 95%;" name="destGroup" colspan="2" data-dojo-type="TargetSelectWidget" />
-                                    <input title="${i18n.Label}:" style="width: 95%;" name="destLogicalName" colspan="2" data-dojo-props="trim: true" required="true" data-dojo-type="dijit.form.ValidationTextBox" />
-                                    <input title="${i18n.Mask}:" style="width: 95%;" colspan="2" data-dojo-type="dijit.form.TextBox" />
-                                    <input title="${i18n.Prefix}:" style="width: 95%;" name="prefix" colspan="2" data-dojo-type="dijit.form.TextBox" />
-                                </div>
-                                <h2>${i18n.Options}</h2>
-                                <div data-dojo-props="cols:2" data-dojo-type="dojox.layout.TableContainer">
-                                    <input title="${i18n.Overwrite}:" name="overwrite" colspan="2" data-dojo-type="dijit.form.CheckBox" />
-                                    <input title="${i18n.NoSplit}:" name="nosplit" colspan="2" data-dojo-type="dijit.form.CheckBox" />
-                                    <input title="${i18n.Compress}:" name="compress" colspan="2" data-dojo-type="dijit.form.CheckBox" />
+                            <div id="${id}DesprayForm" style="width: 460px;" onsubmit="return false;" data-dojo-type="dijit.form.Form">
+                                <div data-dojo-type="dijit.Fieldset">
+                                    <legend>Target</legend>
+                                    <div data-dojo-type="hpcc.TableContainer">
+                                        <input id="${id}DesprayTargetSelect" title="${i18n.DropZone}:" name="destGroup" style="width: 100%;" data-dojo-type="TargetSelectWidget" />
+                                        <input id="${id}DesprayTargetIPAddress" title="${i18n.IPAddress}:" name="destIP" style="width: 100%;" required="true" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
+                                        <input id="${id}DesprayTargetPath" title="${i18n.Path}:" name="destPath" style="width: 100%;" required="true" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
+                                        <input id="${id}DesprayTargetSplitPrefix" title="${i18n.SplitPrefix}:" name="splitprefix" style="width: 100%;" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
+                                    </div>
+                                    <div id="${id}DesprayGrid" data-dojo-type="SelectionGridWidget">
+                                    </div>
+                                </div>
+                                <div data-dojo-type="dijit.Fieldset">
+                                    <legend>Options</legend>
+                                    <div data-dojo-props="cols:2" data-dojo-type="hpcc.TableContainer">
+                                        <input id="${id}DesprayTargetOverwrite" title="${i18n.Overwrite}:" name="overwrite" data-dojo-type="dijit.form.CheckBox" />
+                                        <input id="${id}DesprayTargetUseSingleConnection" title="${i18n.UseSingleConnection}:" name="SingleConnection" data-dojo-type="dijit.form.CheckBox" />
+                                    </div>
                                 </div>
                                 <div class="dijitDialogPaneActionBar">
-                                    <button data-dojo-attach-event="onClick:_onSprayXml" data-dojo-type="dijit.form.Button">${i18n.Spray}</button>
+                                    <button type="submit" data-dojo-attach-event="onClick:_onDesprayOk" data-dojo-type="dijit.form.Button">${i18n.Despray}</button>
                                 </div>
                             </div>
                         </div>

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

@@ -47,7 +47,7 @@
     </div>
     <div id="${id}AboutDialog" title="About HPCC Platform" style="width: 480px;" data-dojo-type="dijit/Dialog">
         <div class="dijitDialogPaneContentArea">
-            <div data-dojo-props="cols:2" data-dojo-type="dojox.layout.TableContainer">
+            <div data-dojo-props="cols:2" data-dojo-type="hpcc.TableContainer">
                 <input id="${id}ServerVersion" title="Server:" name="ServerVersion" colspan="2" style="width:100%;" data-dojo-props="trim: true, readonly: true" data-dojo-type="dijit.form.Textarea" />
                 <input id="${id}GraphControlVersion" title="Graph&nbsp;Control:" name="GraphControlVersion" colspan="2" style="width:100%;" data-dojo-props="trim: true, readonly: true" data-dojo-type="dijit.form.Textarea" />
             </div>
@@ -60,7 +60,7 @@
     </div>
     <div id="${id}SetBannerDialog" title="Set Banner" style="width: 480px;" data-dojo-type="dijit/Dialog">
         <div class="dijitDialogPaneContentArea">
-            <div data-dojo-props="cols:2" data-dojo-type="dojox.layout.TableContainer">
+            <div data-dojo-props="cols:2" data-dojo-type="hpcc.TableContainer">
                 <input id="${id}BannerText" title="Banner&nbsp;Message:" name="ServerVersion" colspan="2" style="width:100%;" data-dojo-props="trim: true" data-dojo-type="dijit.form.Textarea" />
             </div>
         </div>

+ 17 - 32
esp/files/templates/LFDetailsWidget.html

@@ -11,20 +11,15 @@
                     <div id="${id}CopyDropDown" data-dojo-type="dijit.form.DropDownButton">
                         <span>${i18n.Copy}</span>
                         <div data-dojo-type="dijit.TooltipDialog">
-                            <div id="${id}CopyDialog" style="width: 460px;" onsubmit="return false;" data-dojo-type="dijit.form.Form">
-                                <h2>${i18n.Source}</h2>
-                                <div data-dojo-props="cols:2" data-dojo-type="dojox.layout.TableContainer">
-                                    <input id="${id}CopySourceName" title="${i18n.LogicalFile}:" style="width: 100%;" name="sourceLogicalName" colspan="2" data-dojo-props="trim: true, readonly: true" data-dojo-type="dijit.form.Textarea" />
-                                </div>
-                                <h2>${i18n.Target}</h2>
-                                <div data-dojo-props="cols:2" data-dojo-type="dojox.layout.TableContainer">
+                            <div id="${id}CopyForm" style="width: 460px;" onsubmit="return false;" data-dojo-type="dijit.form.Form">
+                                <div data-dojo-props="cols:2" data-dojo-type="hpcc.TableContainer">
                                     <input id="${id}CopyTargetSelect" title="${i18n.Group}:" name="destGroup" colspan="2" style="width:100%;" data-dojo-type="TargetSelectWidget" style="display: inline-block; vertical-align: middle" />
-                                    <input id="${id}CopyTargetName"  title="${i18n.LogicalFile}:" name="destLogicalName" colspan="2" style="width:100%;" required="true" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
-                                    <input id="${id}CopyTargetWrap" title="${i18n.Wrap}:" name="Wrap" data-dojo-type="dijit/form/CheckBox" />
-                                    <input id="${id}CopyTargetNoSplit" title="${i18n.NoSplit}:" name="nosplit" data-dojo-type="dijit/form/CheckBox" />
+                                    <input id="${id}CopyTargetName"  title="${i18n.TargetName}:" name="destLogicalName" colspan="2" style="width:100%;" required="true" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
                                     <input id="${id}CopyTargetOverwrite" title="${i18n.Overwrite}:" name="overwrite" data-dojo-type="dijit/form/CheckBox" />
+                                    <input id="${id}CopyTargetNoSplit" title="${i18n.NoSplit}:" name="nosplit" data-dojo-type="dijit/form/CheckBox" />
                                     <input id="${id}CopyTargetCompress" title="${i18n.Compress}:" name="compress" data-dojo-type="dijit/form/CheckBox" />
-                                    <input id="${id}CopyTargetRetainSuperfileStructure" title="${i18n.RetainSuperfileStructure}:" name="superCopy" colspan="2" data-dojo-type="dijit/form/CheckBox" />
+                                    <input id="${id}CopyTargetWrap" title="${i18n.Wrap}:" name="Wrap" data-dojo-type="dijit/form/CheckBox" />
+                                    <input id="${id}CopyTargetRetainSuperfileStructure" title="${i18n.RetainSuperfileStructure}:" name="superCopy" data-dojo-type="dijit/form/CheckBox" />
                                 </div>
                                 <div class="dijitDialogPaneActionBar">
                                     <button type="submit" data-dojo-attach-event="onClick:_onCopyOk" data-dojo-type="dijit.form.Button">${i18n.Copy}</button>
@@ -35,15 +30,10 @@
                     <div id="${id}RenameDropDown" data-dojo-type="dijit.form.DropDownButton">
                         <span>${i18n.Rename}</span>
                         <div data-dojo-type="dijit.TooltipDialog">
-                            <div id="${id}RenameDialog" style="width: 460px;" onsubmit="return false;" data-dojo-type="dijit.form.Form">
-                                <h2>${i18n.Source}</h2>
-                                <div data-dojo-props="cols:2" data-dojo-type="dojox.layout.TableContainer">
-                                    <input id="${id}RenameSourceName" title="${i18n.LogicalFile}:" style="width: 100%;" name="RenameSourceName" colspan="2" data-dojo-props="trim: true, readonly: true" data-dojo-type="dijit.form.Textarea" />
-                                </div>
-                                <h2>${i18n.Target}</h2>
-                                <div data-dojo-props="cols:2" data-dojo-type="dojox.layout.TableContainer">
-                                    <input id="${id}RenameTargetName" title="${i18n.LogicalFile}:" style="width: 100%;" name="dstname" colspan="2" required="true" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
-                                    <input id="${id}RenameTargetOverwrite" title="${i18n.Overwrite}:" name="overwrite" colspan="2" data-dojo-type="dijit.form.CheckBox" />
+                            <div id="${id}RenameForm" style="width: 460px;" onsubmit="return false;" data-dojo-type="dijit.form.Form">
+                                <div data-dojo-props="cols:2" data-dojo-type="hpcc.TableContainer">
+                                    <input id="${id}RenameTargetName" title="${i18n.TargetName}:" style="width: 100%;" name="dstname" colspan="2" required="true" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
+                                    <input id="${id}RenameTargetOverwrite" title="${i18n.Overwrite}:" name="overwrite" data-dojo-type="dijit.form.CheckBox" />
                                 </div>
                                 <div class="dijitDialogPaneActionBar">
                                     <button type="submit" data-dojo-attach-event="onClick:_onRenameOk" data-dojo-type="dijit.form.Button">${i18n.Rename}</button>
@@ -54,19 +44,14 @@
                     <div id="${id}DesprayDropDown" data-dojo-type="dijit.form.DropDownButton">
                         <span>${i18n.Despray}</span>
                         <div data-dojo-type="dijit.TooltipDialog">
-                            <div id="${id}DesprayDialog" style="width: 460px;" onsubmit="return false;" data-dojo-type="dijit.form.Form">
-                                <h2>${i18n.Source}</h2>
-                                <div data-dojo-props="cols:2" data-dojo-type="dojox.layout.TableContainer">
-                                    <input id="${id}DespraySourceName" title="${i18n.LogicalFile}:" style="width: 100%;" name="DespraySourceName" colspan="2" data-dojo-props="trim: true, readonly: true" data-dojo-type="dijit.form.Textarea" />
-                                </div>
-                                <h2>${i18n.Target}</h2>
-                                <div data-dojo-props="cols:2" data-dojo-type="dojox.layout.TableContainer">
+                            <div id="${id}DesprayForm" style="width: 460px;" onsubmit="return false;" data-dojo-type="dijit.form.Form">
+                                <div data-dojo-props="cols:2" data-dojo-type="hpcc.TableContainer">
                                     <input id="${id}DesprayTargetSelect" title="${i18n.DropZone}:" name="destGroup" colspan="2" style="width: 100%;" data-dojo-type="TargetSelectWidget" />
-                                    <input id="${id}DesprayTargetIPAddress" title="${i18n.IPAddress}:" name="destIP" colspan="2" required="true" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
-                                    <input id="${id}DesprayTargetPath" title="${i18n.Path}:" name="destPath" colspan="2" required="true" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
-                                    <input id="${id}DesprayTargetSplitPrefix" title="${i18n.SplitPrefix}:" name="splitprefix" colspan="2" data-dojo-props="trim: true" data-dojo-type="dijit.form.TextBox" />
-                                    <input id="${id}DesprayTargetUseSingleConnection" title="${i18n.UseSingleConnection}:" name="SingleConnection" colspan="2" data-dojo-type="dijit.form.CheckBox" />
-                                    <input id="${id}DesprayTargetOverwrite" title="${i18n.Overwrite}:" name="overwrite" colspan="2" data-dojo-type="dijit.form.CheckBox" />
+                                    <input id="${id}DesprayTargetIPAddress" title="${i18n.IPAddress}:" name="destIP" colspan="2" required="true" style="width: 100%;" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
+                                    <input id="${id}DesprayTargetPath" title="${i18n.Path}:" name="destPath" colspan="2" required="true" style="width: 100%;" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
+                                    <input id="${id}DesprayTargetSplitPrefix" title="${i18n.SplitPrefix}:" name="splitprefix" colspan="2" style="width: 100%;" data-dojo-props="trim: true" data-dojo-type="dijit.form.TextBox" />
+                                    <input id="${id}DesprayTargetOverwrite" title="${i18n.Overwrite}:" name="overwrite" data-dojo-type="dijit.form.CheckBox" />
+                                    <input id="${id}DesprayTargetUseSingleConnection" title="${i18n.UseSingleConnection}:" name="SingleConnection" data-dojo-type="dijit.form.CheckBox" />
                                 </div>
                                 <div class="dijitDialogPaneActionBar">
                                     <button type="submit" data-dojo-attach-event="onClick:_onDesprayOk" data-dojo-type="dijit.form.Button">${i18n.Despray}</button>

+ 139 - 86
esp/files/templates/LZBrowseWidget.html

@@ -5,7 +5,8 @@
                 <div id="${id}Toolbar" class="topPanel" data-dojo-props="region: 'top'" data-dojo-type="dijit.Toolbar">
                     <div id="${id}Refresh" data-dojo-attach-event="onClick:_onRefresh" data-dojo-props="iconClass:'iconRefresh'" data-dojo-type="dijit.form.Button">${i18n.Refresh}</div>
                     <span data-dojo-type="dijit.ToolbarSeparator"></span>
-                    <div id="${id}HexPreview" data-dojo-attach-event="onClick:_onHexPreview" data-dojo-type="dijit.form.Button">${i18n.HexPreview}</div>
+                    <b>${i18n.Preview}:</b>
+                    <div id="${id}HexPreview" data-dojo-attach-event="onClick:_onHexPreview" data-dojo-type="dijit.form.Button">${i18n.Hex}</div>
                     <span data-dojo-type="dijit.ToolbarSeparator"></span>
                     <input id="${id}Upload" label="${i18n.Upload}" type="file" data-dojo-attach-event="onChange:_onUpload" data-dojo-props='multiple: true' data-dojo-type="dojox.form.Uploader"/>
                     <div id="${id}Download" data-dojo-attach-event="onClick:_onDownload" data-dojo-type="dijit.form.Button">${i18n.Download}</div>
@@ -15,29 +16,22 @@
                     <div id="${id}SprayFixedDropDown" data-dojo-type="dijit.form.DropDownButton">
                         <span>${i18n.Fixed}</span>
                         <div data-dojo-type="dijit.TooltipDialog">
-                            <div id="${id}SprayFixedDialog" style="width: 530px;" onsubmit="return false;" data-dojo-type="dijit.form.Form">
-                                <h2>${i18n.Source}</h2>
-                                <div data-dojo-props="cols:2" data-dojo-type="hpcc.TableContainer">
-                                    <select id="${id}SpraySourceSelect" title="${i18n.SpraySourceType}:" name="sourceFormat" data-dojo-type="dijit/form/Select">
-                                        <option value="Fixed" selected="true">Fixed</option>
-                                        <option value="Recfmv">Recfmv</option>
-                                        <option value="Recfmvb">Recfmvb</option>
-                                        <option value="Variable">Variable</option>
-                                    </select>
-                                    <input id="${id}SprayFixedRecordLength" title="${i18n.RecordLength}:" style="width: 95%;" name="sourceRecordSize" colspan="2" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
+                            <div id="${id}SprayFixedForm" style="width: 530px;" onsubmit="return false;" data-dojo-type="dijit.form.Form">
+                                <div data-dojo-type="dijit.Fieldset">
+                                    <legend>Target</legend>
+                                    <div data-dojo-type="hpcc.TableContainer">
+                                        <input id="${id}SprayFixedDestination" title="${i18n.Group}:" style="width: 95%;" name="destGroup" data-dojo-type="TargetSelectWidget" />
+                                        <input id="${id}SprayFixedDestinationNamePrefix" title="${i18n.NamePrefix}:" style="width: 95%;" name="namePrefix" data-dojo-props="trim: true, placeHolder:'${i18n.NamePrefixPlaceholder}'" data-dojo-type="dijit.form.TextBox" />
+                                    </div>
+                                    <div id="${id}SprayFixedGrid" data-dojo-type="SelectionGridWidget">
+                                    </div>
                                 </div>
-                                <h2>${i18n.Target}</h2>
-                                <div data-dojo-props="cols:2" data-dojo-type="hpcc.TableContainer">
-                                    <input id="${id}SprayFixedDestination" title="${i18n.Group}:" style="width: 95%;" name="destGroup" colspan="2" data-dojo-type="TargetSelectWidget" />
-                                    <input id="${id}SprayFixedDestinationLabel" title="${i18n.Label}:" style="width: 95%;" name="destLogicalName" colspan="2" required="true" data-dojo-props="trim: true" data-dojo-type="dijit.form.ValidationTextBox" />
-                                    <input id="${id}SprayFixedDestinationMask" title="${i18n.Mask}:" style="width: 95%;" colspan="2" data-dojo-props="trim: true, readonly: true"  data-dojo-type="dijit.form.TextBox" />
-                                    <input id="${id}SprayFixedDestinationPrefix" title="${i18n.Prefix}:" style="width: 95%;" name="prefix" colspan="2" data-dojo-type="dijit.form.TextBox" />
-                                </div>
-                                <h2>${i18n.Options}</h2>
-                                <div data-dojo-props="cols:2" data-dojo-type="hpcc.TableContainer">
-                                    <input title="${i18n.Overwrite}:" name="overwrite" colspan="2" data-dojo-type="dijit.form.CheckBox" />
-                                    <input title="${i18n.NoSplit}:" name="nosplit" colspan="2" data-dojo-type="dijit.form.CheckBox" />
-                                    <input title="${i18n.Compress}:" name="compress" colspan="2" data-dojo-type="dijit.form.CheckBox" />
+                                <div data-dojo-type="dijit.Fieldset">
+                                    <legend>Options</legend>
+                                    <div data-dojo-props="cols:2" data-dojo-type="hpcc.TableContainer">
+                                        <input title="${i18n.Overwrite}:" name="overwrite" data-dojo-type="dijit.form.CheckBox" />
+                                        <input title="${i18n.Compress}:" name="compress" data-dojo-type="dijit.form.CheckBox" />
+                                    </div>
                                 </div>
                                 <div class="dijitDialogPaneActionBar">
                                     <button type="submit" data-dojo-attach-event="onClick:_onSprayFixed" data-dojo-type="dijit.form.Button">${i18n.Spray}</button>
@@ -45,44 +39,45 @@
                             </div>
                         </div>
                     </div>
-                    <div id="${id}SprayVariableDropDown" data-dojo-type="dijit.form.DropDownButton">
+                    <div id="${id}SprayDelimitedDropDown" data-dojo-type="dijit.form.DropDownButton">
                         <span>${i18n.Delimited}</span>
                         <div data-dojo-type="dijit.TooltipDialog">
-                            <div id="${id}SprayVariableDialog" style="width: 530px;" onsubmit="return false;" data-dojo-type="dijit.form.Form">
-                                <h2>${i18n.Source}</h2>
-                                <div data-dojo-props="cols:2" data-dojo-type="hpcc.TableContainer">
-                                    <select id="${id}sourceFormat" title="${i18n.Format}:" name="sourceFormat" data-dojo-type="dijit/form/Select">
-                                        <option value="1">ASCII</option>
-                                        <option value="2">UTF-8</option>
-                                        <option value="3">UTF-8N</option>
-                                        <option value="4">UTF-16</option>
-                                        <option value="5">UTF-16LE</option>
-                                        <option value="6">UTF-16BE</option>
-                                        <option value="7">UTF-32</option>
-                                        <option value="8">UTF-32LE</option>
-                                        <option value="9">UTF-32BE</option>
-                                    </select>
-                                    <input id="${id}SprayVariableMaxRecordLength" title="${i18n.MaxRecordLength}:" style="width: 95%;" name="sourceMaxRecordSize" value="8192" colspan="2" required="true" data-dojo-props="trim: true, placeHolder:'8192'" data-dojo-type="dijit.form.ValidationTextBox" />
-                                    <input id="${id}SprayVariableSeperators" title="${i18n.Seperators}:" style="width: 95%;" name="sourceCsvSeparate" value="," colspan="2" data-dojo-props="trim: true, placeHolder:'\,'" data-dojo-type="dijit.form.ValidationTextBox" />
-                                    <input title="${i18n.OmitSeparator}:" name="NoSourceCsvSeparator" colspan="2" data-dojo-type="dijit.form.CheckBox" />
-                                    <input id="${id}SprayVariableEscape" title="${i18n.Escape}:" style="width: 95%;" name="sourceCsvEscape" colspan="2" data-dojo-props="trim: true" data-dojo-type="dijit.form.TextBox" />
-                                    <input id="${id}SprayVariableTerminators" title="${i18n.LineTerminators}:" name="sourceCsvTerminate"  style="width: 95%;" value="\n,\r\n" colspan="2" required="true" data-dojo-props="trim: true, placeHolder:'\\n,\\r\\n'" data-dojo-type="dijit.form.ValidationTextBox" />
-                                    <input id="${id}SprayVariableQuote" title="${i18n.Quote}:" style="width: 95%;" name="sourceCsvQuote" value="'" colspan="2" data-data-dojo-props="trim: true, placeHolder:'\''" data-dojo-type="dijit.form.TextBox" />
-                                </div>
-                                <h2>${i18n.Target}</h2>
-                                <div data-dojo-props="cols:2" data-dojo-type="hpcc.TableContainer">
-                                    <input id="${id}SprayVariableDestination" title="${i18n.Group}:" style="width: 95%;" name="destGroup" colspan="2" data-dojo-type="TargetSelectWidget" />
-                                    <input title="${i18n.Label}:" style="width: 95%;" name="destLogicalName" colspan="2" data-dojo-props="trim: true" required="true" data-dojo-type="dijit.form.ValidationTextBox" />
-                                    <input title="${i18n.Prefix}:" style="width: 95%;" name="prefix" colspan="2" data-dojo-type="dijit.form.TextBox" />
+                            <div id="${id}SprayDelimitedForm" style="width: 530px;" onsubmit="return false;" data-dojo-type="dijit.form.Form">
+                                <div data-dojo-type="dijit.Fieldset">
+                                    <legend>Target</legend>
+                                    <div data-dojo-type="hpcc.TableContainer">
+                                        <input id="${id}SprayDelimitedDestination" title="${i18n.Group}:" style="width: 95%;" name="destGroup" data-dojo-type="TargetSelectWidget" />
+                                        <input title="${i18n.NamePrefix}:" style="width: 95%;" name="namePrefix" data-dojo-props="trim: true, placeHolder:'${i18n.NamePrefixPlaceholder}'" data-dojo-type="dijit.form.TextBox" />
+                                    </div>
+                                    <div id="${id}SprayDelimitedGrid" data-dojo-type="SelectionGridWidget">
+                                    </div>
                                 </div>
-                                <h2>${i18n.Options}</h2>
-                                <div data-dojo-props="cols:2" data-dojo-type="hpcc.TableContainer">
-                                    <input title="${i18n.Overwrite}:" name="overwrite" colspan="2" data-dojo-type="dijit.form.CheckBox" />
-                                    <input title="${i18n.NoSplit}:" name="nosplit" colspan="2" data-dojo-type="dijit.form.CheckBox" />
-                                    <input title="${i18n.Compress}:" name="compress" colspan="2" data-dojo-type="dijit.form.CheckBox" />
+                                <div data-dojo-type="dijit.Fieldset">
+                                    <legend>Options</legend>
+                                    <div data-dojo-props="cols:2" data-dojo-type="hpcc.TableContainer">
+                                        <select id="${id}sourceFormat" title="${i18n.Format}:" name="sourceFormat" colspan="2" data-dojo-type="dijit/form/Select">
+                                            <option value="1">ASCII</option>
+                                            <option value="2">UTF-8</option>
+                                            <option value="3">UTF-8N</option>
+                                            <option value="4">UTF-16</option>
+                                            <option value="5">UTF-16LE</option>
+                                            <option value="6">UTF-16BE</option>
+                                            <option value="7">UTF-32</option>
+                                            <option value="8">UTF-32LE</option>
+                                            <option value="9">UTF-32BE</option>
+                                        </select>
+                                        <input id="${id}SprayDelimitedMaxRecordLength" title="${i18n.MaxRecordLength}:" style="width: 95%;" name="sourceMaxRecordSize" value="8192" required="true" colspan="2" data-dojo-props="trim: true, placeHolder:'8192'" data-dojo-type="dijit.form.ValidationTextBox" />
+                                        <input id="${id}SprayDelimitedSeperators" title="${i18n.Seperators}:" style="width: 95%;" name="sourceCsvSeparate" value="," data-dojo-props="trim: true, placeHolder:'\,'" colspan="2" data-dojo-type="dijit.form.ValidationTextBox" />
+                                        <input title="${i18n.OmitSeparator}:" name="NoSourceCsvSeparator" colspan="2" data-dojo-type="dijit.form.CheckBox" />
+                                        <input id="${id}SprayDelimitedEscape" title="${i18n.Escape}:" style="width: 95%;" name="sourceCsvEscape" data-dojo-props="trim: true" colspan="2" data-dojo-type="dijit.form.TextBox" />
+                                        <input id="${id}SprayDelimitedTerminators" title="${i18n.LineTerminators}:" name="sourceCsvTerminate" style="width: 95%;" value="\n,\r\n" required="true" colspan="2" data-dojo-props="trim: true, placeHolder:'\\n,\\r\\n'" data-dojo-type="dijit.form.ValidationTextBox" />
+                                        <input id="${id}SprayDelimitedQuote" title="${i18n.Quote}:" style="width: 95%;" name="sourceCsvQuote" value="'" data-data-dojo-props="trim: true, placeHolder:'\''" colspan="2" data-dojo-type="dijit.form.TextBox" />
+                                        <input title="${i18n.Overwrite}:" name="overwrite" data-dojo-type="dijit.form.CheckBox" />
+                                        <input title="${i18n.Compress}:" name="compress" data-dojo-type="dijit.form.CheckBox" />
+                                    </div>
                                 </div>
                                 <div class="dijitDialogPaneActionBar">
-                                    <button type="submit" data-dojo-attach-event="onClick:_onSprayVariable" data-dojo-type="dijit.form.Button">${i18n.Spray}</button>
+                                    <button type="submit" data-dojo-attach-event="onClick:_onSprayDelimited" data-dojo-type="dijit.form.Button">${i18n.Spray}</button>
                                 </div>
                             </div>
                         </div>
@@ -90,35 +85,34 @@
                     <div id="${id}SprayXmlDropDown" data-dojo-type="dijit.form.DropDownButton">
                         <span>${i18n.XML}</span>
                         <div data-dojo-type="dijit.TooltipDialog">
-                            <div id="${id}SprayXmlDialog" style="width: 530px;" data-dojo-type="dijit.form.Form">
-                                <h2>${i18n.Source}</h2>
-                                <div data-dojo-props="cols:2" data-dojo-type="hpcc.TableContainer">
-                                    <select id="${id}xmlsourceFormat" title="${i18n.Format}:" name="sourceFormat" data-dojo-type="dijit/form/Select">
-                                        <option value="1">ASCII</option>
-                                        <option value="2">UTF-8</option>
-                                        <option value="3">UTF-8N</option>
-                                        <option value="4">UTF-16</option>
-                                        <option value="5">UTF-16LE</option>
-                                        <option value="6">UTF-16BE</option>
-                                        <option value="7">UTF-32</option>
-                                        <option value="8">UTF-32LE</option>
-                                        <option value="9">UTF-32BE</option>
-                                    </select>
-                                    <input id="${id}SprayXmlMaxRecordLength" title="${i18n.MaxRecordLength}:" value="8192" style="width: 95%;" name="sourceMaxRecordSize" colspan="2" required="true" data-dojo-props="trim: true, placeHolder:'8192'" data-dojo-type="dijit.form.ValidationTextBox" />
-                                    <input id="${id}SprayXmlRowTag" title="${i18n.RowTag}:" style="width: 95%;" name="sourceRowTag" colspan="2" required="true" data-dojo-props="trim: true, placeHolder:'${i18n.tag}'" data-dojo-type="dijit.form.ValidationTextBox" />
-                                </div>
-                                <h2>${i18n.Target}</h2>
-                                <div data-dojo-props="cols:2" data-dojo-type="hpcc.TableContainer">
-                                    <input id="${id}SprayXmlDestinationSelect" title="${i18n.Group}:" style="width: 95%;" name="destGroup" colspan="2" data-dojo-type="TargetSelectWidget" />
-                                    <input title="${i18n.Label}:" style="width: 95%;" name="destLogicalName" colspan="2" data-dojo-props="trim: true" required="true" data-dojo-type="dijit.form.ValidationTextBox" />
-                                    <input title="${i18n.Mask}:" style="width: 95%;" colspan="2" data-dojo-type="dijit.form.TextBox" />
-                                    <input title="${i18n.Prefix}:" style="width: 95%;" name="prefix" colspan="2" data-dojo-type="dijit.form.TextBox" />
+                            <div id="${id}SprayXmlForm" style="width: 530px;" data-dojo-type="dijit.form.Form">
+                                <div data-dojo-type="dijit.Fieldset">
+                                    <legend>Target</legend>
+                                    <div data-dojo-type="hpcc.TableContainer">
+                                        <input id="${id}SprayXmlDestinationSelect" title="${i18n.Group}:" style="width: 95%;" name="destGroup" data-dojo-type="TargetSelectWidget" />
+                                        <input title="${i18n.NamePrefix}:" style="width: 95%;" name="namePrefix" data-dojo-props="trim: true, placeHolder:'${i18n.NamePrefixPlaceholder}'" data-dojo-type="dijit.form.TextBox" />
+                                    </div>
+                                    <div id="${id}SprayXmlGrid" data-dojo-type="SelectionGridWidget">
+                                    </div>
                                 </div>
-                                <h2>${i18n.Options}</h2>
-                                <div data-dojo-props="cols:2" data-dojo-type="hpcc.TableContainer">
-                                    <input title="${i18n.Overwrite}:" name="overwrite" colspan="2" data-dojo-type="dijit.form.CheckBox" />
-                                    <input title="${i18n.NoSplit}:" name="nosplit" colspan="2" data-dojo-type="dijit.form.CheckBox" />
-                                    <input title="${i18n.Compress}:" name="compress" colspan="2" data-dojo-type="dijit.form.CheckBox" />
+                                <div data-dojo-type="dijit.Fieldset">
+                                    <legend>Options</legend>
+                                    <div data-dojo-props="cols:2" data-dojo-type="hpcc.TableContainer">
+                                        <select id="${id}xmlsourceFormat" title="${i18n.Format}:" name="sourceFormat" colspan="2" data-dojo-type="dijit/form/Select">
+                                            <option value="1">ASCII</option>
+                                            <option value="2">UTF-8</option>
+                                            <option value="3">UTF-8N</option>
+                                            <option value="4">UTF-16</option>
+                                            <option value="5">UTF-16LE</option>
+                                            <option value="6">UTF-16BE</option>
+                                            <option value="7">UTF-32</option>
+                                            <option value="8">UTF-32LE</option>
+                                            <option value="9">UTF-32BE</option>
+                                        </select>
+                                        <input id="${id}SprayXmlMaxRecordLength" title="${i18n.MaxRecordLength}:" value="8192" style="width: 95%;" name="sourceMaxRecordSize" required="true" colspan="2" data-dojo-props="trim: true, placeHolder:'8192'" data-dojo-type="dijit.form.ValidationTextBox" />
+                                        <input title="${i18n.Overwrite}:" name="overwrite" data-dojo-type="dijit.form.CheckBox" />
+                                        <input title="${i18n.Compress}:" name="compress" data-dojo-type="dijit.form.CheckBox" />
+                                    </div>
                                 </div>
                                 <div class="dijitDialogPaneActionBar">
                                     <button data-dojo-attach-event="onClick:_onSprayXml" data-dojo-type="dijit.form.Button">${i18n.Spray}</button>
@@ -126,6 +120,65 @@
                             </div>
                         </div>
                     </div>
+                    <div id="${id}SprayVariableDropDown" data-dojo-type="dijit.form.DropDownButton">
+                        <span>${i18n.Variable}</span>
+                        <div data-dojo-type="dijit.TooltipDialog">
+                            <div id="${id}SprayVariableForm" style="width: 530px;" onsubmit="return false;" data-dojo-type="dijit.form.Form">
+                                <div data-dojo-type="dijit.Fieldset">
+                                    <legend>Target</legend>
+                                    <div data-dojo-type="hpcc.TableContainer">
+                                        <input id="${id}SprayVariableDestination" title="${i18n.Group}:" style="width: 95%;" name="destGroup" data-dojo-type="TargetSelectWidget" />
+                                        <input title="${i18n.NamePrefix}:" style="width: 95%;" name="namePrefix" data-dojo-props="trim: true, placeHolder:'${i18n.NamePrefixPlaceholder}'" data-dojo-type="dijit.form.TextBox" />
+                                    </div>
+                                    <div id="${id}SprayVariableGrid" data-dojo-type="SelectionGridWidget">
+                                    </div>
+                                </div>
+                                <div data-dojo-type="dijit.Fieldset">
+                                    <legend>Options</legend>
+                                    <div data-dojo-props="cols:2" data-dojo-type="hpcc.TableContainer">
+                                        <select title="${i18n.VariableSourceType}:" name="sourceFormat" colspan="2" data-dojo-type="dijit/form/Select">
+                                            <option value="recfmv" selected="true">recfmv</option>
+                                            <option value="recfmvb">recfmvb</option>
+                                            <option value="variable">${i18n.Variable}</option>
+                                            <option value="variablebigendian">${i18n.VariableBigendian}</option>
+                                        </select>
+                                        <input title="${i18n.Overwrite}:" name="overwrite" data-dojo-type="dijit.form.CheckBox" />
+                                        <input title="${i18n.Compress}:" name="compress" data-dojo-type="dijit.form.CheckBox" />
+                                    </div>
+                                </div>
+                                <div class="dijitDialogPaneActionBar">
+                                    <button type="submit" data-dojo-attach-event="onClick:_onSprayVariable" data-dojo-type="dijit.form.Button">${i18n.Spray}</button>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                    <div id="${id}SprayBlobDropDown" data-dojo-type="dijit.form.DropDownButton">
+                        <span>${i18n.Blob}</span>
+                        <div data-dojo-type="dijit.TooltipDialog">
+                            <div id="${id}SprayBlobForm" style="width: 530px;" onsubmit="return false;" data-dojo-type="dijit.form.Form">
+                                <div data-dojo-type="dijit.Fieldset">
+                                    <legend>Target</legend>
+                                    <div data-dojo-type="hpcc.TableContainer">
+                                        <input id="${id}SprayBlobDestination" title="${i18n.Group}:" style="width: 95%;" name="destGroup" data-dojo-type="TargetSelectWidget" />
+                                        <input title="${i18n.TargetName}:" style="width: 95%;" name="destLogicalName" data-dojo-props="trim: true, placeHolder:'${i18n.TargetNamePlaceholder}'" required="true" data-dojo-type="dijit.form.ValidationTextBox" />
+                                    </div>
+                                    <div id="${id}SprayBlobGrid" data-dojo-type="SelectionGridWidget">
+                                    </div>
+                                </div>
+                                <div data-dojo-type="dijit.Fieldset">
+                                    <legend>Options</legend>
+                                    <div data-dojo-props="cols:2" data-dojo-type="hpcc.TableContainer">
+                                        <input title="${i18n.BlobPrefix}:" style="width: 95%;" name="prefix" data-dojo-props="trim: true, placeHolder:'${i18n.PrefixPlaceholder}'" colspan="2" data-dojo-type="dijit.form.TextBox" />
+                                        <input title="${i18n.Overwrite}:" name="overwrite" data-dojo-type="dijit.form.CheckBox" />
+                                        <input title="${i18n.Compress}:" name="compress" data-dojo-type="dijit.form.CheckBox" />
+                                    </div>
+                                </div>
+                                <div class="dijitDialogPaneActionBar">
+                                    <button type="submit" data-dojo-attach-event="onClick:_onSprayBlob" data-dojo-type="dijit.form.Button">${i18n.Spray}</button>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
                     <span data-dojo-type="dijit.ToolbarSeparator"></span>
                     <div id="${id}NewPage" class="right" data-dojo-attach-event="onClick:_onNewPage" data-dojo-props="iconClass:'iconNewPage', showLabel:false" data-dojo-type="dijit.form.Button">${i18n.OpenInNewPage}</div>
                 </div>
@@ -138,8 +191,8 @@
     </div>
     <div id="${id}FileListDialog" title="${i18n.FileUploader}" data-dojo-type="dijit.Dialog">
         <div class="dijitDialogPaneContentArea">
-            <div data-dojo-props="cols:2" data-dojo-type="hpcc.TableContainer">
-                <input id="${id}DropZoneTargetSelect" title="${i18n.LandingZone}:" style="width: 95%;" colspan="2" data-dojo-type="TargetSelectWidget" />
+            <div data-dojo-props="cols:1" data-dojo-type="hpcc.TableContainer">
+                <input id="${id}DropZoneTargetSelect" title="${i18n.LandingZone}:" style="width: 95%;" data-dojo-type="TargetSelectWidget" />
             </div>
             <p>
             <div id="${id}UploadFileList" class="dijitDialogPaneContentArea" data-dojo-props="uploaderId: '${id}Upload'" data-dojo-type="dojox.form.uploader.FileList"></div>

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

@@ -1,7 +1,7 @@
 <div class="${baseClass}">
     <div id="${id}BorderContainer" class="${baseClass}BorderContainer" style="width: 100%; height: 100%" data-dojo-props="splitter: false" data-dojo-type="dijit.layout.BorderContainer">
-        <div id="${id}Toolbar" class="topPanel" style="padding: 0px; overflow: hidden" data-dojo-props="region: 'top'" data-dojo-type="dijit.Toolbar">
-            <span class="bold">${i18n.Download}:</span>
+        <div id="${id}Toolbar" class="topPanel" data-dojo-props="region: 'top'" data-dojo-type="dijit.Toolbar">
+            <b>${i18n.Download}:</b>
             <div data-dojo-attach-event="onClick:_onDownloadZip" data-dojo-type="dijit.form.Button">${i18n.Zip}</div>
             <div data-dojo-attach-event="onClick:_onDownloadGZip" data-dojo-type="dijit.form.Button">${i18n.GZip}</div>
             <div data-dojo-attach-event="onClick:_onDownloadXLS" data-dojo-type="dijit.form.Button">${i18n.XLS}</div>

+ 8 - 0
esp/files/templates/SelectionGridWidget.html

@@ -0,0 +1,8 @@
+<div class="${baseClass}">
+    <div id="${id}BorderContainer" style="width: 100%; height: 280px" data-dojo-props="splitter: false, gutters: false" data-dojo-type="dijit.layout.BorderContainer">
+        <div id="${id}ContentPane" style="padding: 0px" data-dojo-props="region: 'center'" data-dojo-type="dijit.layout.ContentPane">
+            <div id="${id}Grid" style="margin: 1px">
+            </div>
+        </div>
+    </div>
+</div>