Skip to content

Commit

Permalink
parameter query
Browse files Browse the repository at this point in the history
  • Loading branch information
dufoli committed Oct 22, 2024
1 parent 0c85169 commit 87223a5
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 32 deletions.
27 changes: 17 additions & 10 deletions addon/data-export.css
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ textarea[hidden], div[hidden] {
display: none !important;
}

.help-text {
.help-text, .variable-block {
background: #fff;
border: 1px solid #DDDBDA;
padding: 0 15px;
Expand Down Expand Up @@ -160,11 +160,23 @@ textarea[hidden], div[hidden] {
}

.result-text {
outline: none;
border-radius: 0;
border: none;
border-top: 1px solid #DDDBDA;
flex: 1 1 0;
resize: none;
white-space: pre;
}

.conf-error {
color: #a00;
margin-left: 12px;
display: flex;
align-items: center;
}
.confError {
box-shadow: 0 0 3px 1px #a00;
}
.area {
background-color: #F8F8F8;
padding: 8px 12px;
Expand Down Expand Up @@ -321,13 +333,6 @@ option[value="null"][disabled] {
display: none;
}

textarea[readonly] {
outline: none;
border-radius: 0;
border: none;
border-top: 1px solid #DDDBDA;
}

.top-btn {
margin-left: auto;
text-decoration: none;
Expand Down Expand Up @@ -360,7 +365,9 @@ textarea[readonly] {
#options-btn .icon {
-webkit-mask-image: url('chrome-extension://__MSG_@@extension_id__/images/settings.svg');
}

#variable-btn .icon {
-webkit-mask-image: url('chrome-extension://__MSG_@@extension_id__/images/variable.svg');
}

#spinner {
left: -15px;
Expand Down
137 changes: 115 additions & 22 deletions addon/data-export.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import {sfConn, apiVersion} from "./inspector.js";
/* global initButton */
import {Enumerable, DescribeInfo, copyToClipboard, ScrollTable, TableModel, s, Editor} from "./data-load.js";
import {csvParse} from "./csv-parse.js";

class QueryHistory {
constructor(storageKey, max) {
Expand Down Expand Up @@ -79,6 +80,10 @@ class Model {
this.sfLink = "https://" + sfHost;
this.spinnerCount = 0;
this.showHelp = false;
this.showVariable = false;
this.variableData = [];
this.variableDataError = "";
this.batchSize = 1;
this.userInfo = "...";
this.winInnerHeight = 0;
this.queryAll = false;
Expand Down Expand Up @@ -180,6 +185,27 @@ class Model {
toggleHelp() {
this.showHelp = !this.showHelp;
}
toggleVariable() {
this.showVariable = !this.showVariable;
}
variableMessage() {
return "Paste 1 variable by line here";
}
setVariableData(text) {
try {
//only get first column for cell
this.variableData = csvParse(text, "\t").map(c => c[0]);
} catch (e) {
this.variableDataError = "Error: " + e.message;
return;
}
}
batchSizeError() {
if (!(+this.batchSize > 0)) { // This also handles NaN
return "Error: Must be a positive number";
}
return "";
}
toggleExpand() {
this.expandAutocomplete = !this.expandAutocomplete;
}
Expand Down Expand Up @@ -1530,7 +1556,15 @@ class Model {
finalQuery += remaining;
return finalQuery;
}

sliceArrayIntoGroups(arr, size) {
let step = 0;
let sliceArr = [];
let len = arr.length;
while (step < len) {
sliceArr.push(arr.slice(step, step += size));
}
return sliceArr;
}
doExport() {
let vm = this; // eslint-disable-line consistent-this
let exportedData = new RecordTable(vm);
Expand Down Expand Up @@ -1633,24 +1667,52 @@ class Model {
return null;
});
}
vm.spinFor(batchHandler(vm.callRest(query))
.catch(error => {
console.error(error);
if (error && error.name == "Unauthorized") {
let rootEl = document.getElementById("insext");
let popupEl = document.getElementsByClassName("insext-popup-iframe")[0];
popupEl.contentWindow.postMessage({
showInvalidTokenBanner: true
}, "*");
rootEl.classList.add("insext-active");
}
vm.isWorking = false;
vm.exportStatus = "Error";
vm.exportError = "UNEXPECTED EXCEPTION:" + error;
vm.exportedData = null;
vm.markPerf();
vm.updatedExportedData();
}));
if (vm.variableData && vm.variableData.length > 0) {
vm.spinFor(Promise.all(vm.sliceArrayIntoGroups(vm.variableData, vm.batchSize).map(range => {
let subquery = query.replace("$1", range.join(","));
//TODO parametter type (string, number )
//TODO move batchHandler in sub mthod to avoid boilerplate
return batchHandler(vm.callRest(subquery))
.catch(error => {
console.error(error);
if (error && error.name == "Unauthorized") {
let rootEl = document.getElementById("insext");
let popupEl = document.getElementsByClassName("insext-popup-iframe")[0];
popupEl.contentWindow.postMessage({
showInvalidTokenBanner: true
}, "*");
rootEl.classList.add("insext-active");
}
vm.isWorking = false;
vm.exportStatus = "Error";
vm.exportError = "UNEXPECTED EXCEPTION:" + error;
vm.exportedData = null;
vm.markPerf();
vm.updatedExportedData();
});
}
)));
} else {
vm.spinFor(batchHandler(vm.callRest(query))
.catch(error => {
console.error(error);
if (error && error.name == "Unauthorized") {
let rootEl = document.getElementById("insext");
let popupEl = document.getElementsByClassName("insext-popup-iframe")[0];
popupEl.contentWindow.postMessage({
showInvalidTokenBanner: true
}, "*");
rootEl.classList.add("insext-active");
}
vm.isWorking = false;
vm.exportStatus = "Error";
vm.exportError = "UNEXPECTED EXCEPTION:" + error;
vm.exportedData = null;
vm.markPerf();
vm.updatedExportedData();
}));
}

vm.setResultsFilter("");
vm.isWorking = true;
vm.exportStatus = "Exporting...";
Expand Down Expand Up @@ -1953,6 +2015,9 @@ class App extends React.Component {
this.onStopExport = this.onStopExport.bind(this);
this.onClick = this.onClick.bind(this);
this.onSaveAll = this.onSaveAll.bind(this);
this.onToggleVariable = this.onToggleVariable.bind(this);
this.onDataPaste = this.onDataPaste.bind(this);
this.onBatchSizeChange = this.onBatchSizeChange.bind(this);
}
onSaveAll() {
let {model} = this.props;
Expand Down Expand Up @@ -2113,6 +2178,22 @@ class App extends React.Component {
model.stopExport();
model.didUpdate();
}
onToggleVariable() {
let {model} = this.props;
model.toggleVariable();
model.didUpdate();
}
onDataPaste(e) {
let {model} = this.props;
let text = e.clipboardData.getData("text/plain");
model.setVariableData(text);
model.didUpdate();
}
onBatchSizeChange(e){
let {model} = this.props;
model.batchSize = e.target.value;
model.didUpdate();
}
componentDidMount() {
let {model} = this.props;
model.autocompleteResultBox = this.refs.autocompleteResultBox;
Expand Down Expand Up @@ -2183,6 +2264,9 @@ class App extends React.Component {
h("div", {className: "slds-spinner__dot-a"}),
h("div", {className: "slds-spinner__dot-b"}),
),
h("a", {href: "#", className: "top-btn", id: "variable-btn", title: "Variable-btn", onClick: this.onToggleVariable},
h("div", {className: "icon"})
),
h("a", {href: "options.html?" + hostArg, className: "top-btn", id: "options-btn", title: "Option", target: "_blank"},
h("div", {className: "icon"})
),
Expand Down Expand Up @@ -2258,11 +2342,20 @@ class App extends React.Component {
),
h("div", {hidden: !model.showHelp, className: "help-text"},
h("h3", {}, "Export Help"),
h("p", {}, "Use for quick one-off data exports. Enter a ", h("a", {href: "http://www.salesforce.com/us/developer/docs/soql_sosl/", target: "_blank"}, "SOQL query"), " in the box above and press Export."),
h("p", {}, "Use for quick one-off data exports. Enter a ", h("a", {href: "http://www.salesforce.com/us/developer/docs/soql_sosl/", target: "_blank"}, "SOQL or SOSL query"), " in the box above and press Export."),
h("p", {}, "Press Ctrl+Space to insert all field name autosuggestions or to load suggestions for field values."),
h("p", {}, "Press Ctrl+Enter or F5 to execute the export."),
h("p", {}, "Supports the full SOQL language. The columns in the CSV output depend on the returned data. Using subqueries may cause the output to grow rapidly. Bulk API is not supported. Large data volumes may freeze or crash your browser.")
)
h("p", {}, "Supports the full SOQL/SOSL language. The columns in the CSV output depend on the returned data. Using subqueries may cause the output to grow rapidly. Bulk API is not supported. Large data volumes may freeze or crash your browser.")
),
h("div", {hidden: !model.showVariable, className: "variable-block"},
h("h3", {}, "batch Parameters"),
h("p", {}, "Paste Parameter data of SOQL then use it with $1 in SOQL query"),
h("span", {className: "conf-label"}, "Batch size"),
h("input", {type: "number", value: model.batchSize, onChange: this.onBatchSizeChange, className: (model.batchSizeError() ? "confError" : "") + " batch-size"}),
h("textarea", {id: "data", value: model.variableMessage(), onPaste: this.onDataPaste, className: model.dataError ? "confError" : "", readOnly: true, rows: 1}),
h("div", {className: "conf-error", hidden: !model.variableDataError}, model.variableDataError),
model.variableData.length > 0 ? model.variableData.slice(0, 4).concat(["..."]).map(c => h("div", {}, c)) : ""
),
),
h("div", {className: "area", id: "result-area"},
h("div", {className: "result-bar"},
Expand Down

0 comments on commit 87223a5

Please sign in to comment.