[#13,transforms][l]: re-enable column transforms (bulk editing).
* TODO: only operates on documents in current view atm -- to do this properly want a transform function on Backend.
This commit is contained in:
parent
b934307a2a
commit
e23354eb4e
@ -25,6 +25,7 @@ var costco = function() {
|
||||
preview.push({before: JSON.stringify(before), after: JSON.stringify(after)});
|
||||
}
|
||||
}
|
||||
// TODO: 2012-01-05 Move this out of this function and up into (view) functions that call this
|
||||
util.render('editPreview', 'expression-preview-container', {rows: preview});
|
||||
}
|
||||
|
||||
@ -166,4 +167,4 @@ var costco = function() {
|
||||
ensureCommit: ensureCommit,
|
||||
uploadCSV: uploadCSV
|
||||
};
|
||||
}();
|
||||
}();
|
||||
|
||||
234
src/view.js
234
src/view.js
@ -147,8 +147,8 @@ my.DataTable = Backbone.View.extend({
|
||||
var self = this;
|
||||
e.preventDefault();
|
||||
var actions = {
|
||||
bulkEdit: function() { self.showDialog('bulkEdit', {name: self.state.currentColumn}) },
|
||||
transform: function() { showDialog('transform') },
|
||||
bulkEdit: function() { self.showTransformColumnDialog('bulkEdit', {name: self.state.currentColumn}) },
|
||||
transform: function() { self.showTransformDialog('transform') },
|
||||
csv: function() { window.location.href = app.csvUrl },
|
||||
json: function() { window.location.href = "_rewrite/api/json" },
|
||||
urlImport: function() { showDialog('urlImport') },
|
||||
@ -180,6 +180,37 @@ my.DataTable = Backbone.View.extend({
|
||||
actions[$(e.target).attr('data-action')]();
|
||||
},
|
||||
|
||||
showTransformColumnDialog: function() {
|
||||
var $el = $('.dialog-content');
|
||||
util.show('dialog');
|
||||
var view = new my.ColumnTransform({
|
||||
model: this.model
|
||||
});
|
||||
view.state = this.state;
|
||||
view.render();
|
||||
$el.empty();
|
||||
$el.append(view.el);
|
||||
util.observeExit($el, function() {
|
||||
util.hide('dialog');
|
||||
})
|
||||
$('.dialog').draggable({ handle: '.dialog-header', cursor: 'move' });
|
||||
},
|
||||
|
||||
showTransformDialog: function() {
|
||||
var $el = $('.dialog-content');
|
||||
util.show('dialog');
|
||||
var view = new my.DataTransform({
|
||||
});
|
||||
view.render();
|
||||
$el.empty();
|
||||
$el.append(view.el);
|
||||
util.observeExit($el, function() {
|
||||
util.hide('dialog');
|
||||
})
|
||||
$('.dialog').draggable({ handle: '.dialog-header', cursor: 'move' });
|
||||
},
|
||||
|
||||
|
||||
// ======================================================
|
||||
// Core Templating
|
||||
template: ' \
|
||||
@ -308,6 +339,205 @@ my.DataTableRow = Backbone.View.extend({
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// View (Dialog) for doing data transformations (on columns of data).
|
||||
my.ColumnTransform = Backbone.View.extend({
|
||||
className: 'transform-column-view',
|
||||
template: ' \
|
||||
<div class="dialog-header"> \
|
||||
Functional transform on column {{name}} \
|
||||
</div> \
|
||||
<div class="dialog-body"> \
|
||||
<div class="grid-layout layout-tight layout-full"> \
|
||||
<table> \
|
||||
<tbody> \
|
||||
<tr> \
|
||||
<td colspan="4"> \
|
||||
<div class="grid-layout layout-tight layout-full"> \
|
||||
<table rows="4" cols="4"> \
|
||||
<tbody> \
|
||||
<tr style="vertical-align: bottom;"> \
|
||||
<td colspan="4"> \
|
||||
Expression \
|
||||
</td> \
|
||||
</tr> \
|
||||
<tr> \
|
||||
<td colspan="3"> \
|
||||
<div class="input-container"> \
|
||||
<textarea class="expression-preview-code"></textarea> \
|
||||
</div> \
|
||||
</td> \
|
||||
<td class="expression-preview-parsing-status" width="150" style="vertical-align: top;"> \
|
||||
No syntax error. \
|
||||
</td> \
|
||||
</tr> \
|
||||
<tr> \
|
||||
<td colspan="4"> \
|
||||
<div id="expression-preview-tabs" class="refine-tabs ui-tabs ui-widget ui-widget-content ui-corner-all"> \
|
||||
<span>Preview</span> \
|
||||
<div id="expression-preview-tabs-preview" class="ui-tabs-panel ui-widget-content ui-corner-bottom"> \
|
||||
<div class="expression-preview-container" style="width: 652px; "> \
|
||||
</div> \
|
||||
</div> \
|
||||
</div> \
|
||||
</td> \
|
||||
</tr> \
|
||||
</tbody> \
|
||||
</table> \
|
||||
</div> \
|
||||
</td> \
|
||||
</tr> \
|
||||
</tbody> \
|
||||
</table> \
|
||||
</div> \
|
||||
</div> \
|
||||
<div class="dialog-footer"> \
|
||||
<button class="okButton button"> Update All </button> \
|
||||
<button class="cancelButton button">Cancel</button> \
|
||||
</div> \
|
||||
',
|
||||
|
||||
events: {
|
||||
'click .okButton': 'onSubmit'
|
||||
, 'keydown .expression-preview-code': 'onEditorKeydown'
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
this.el = $(this.el);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
var htmls = $.mustache(this.template,
|
||||
{name: this.state.currentColumn}
|
||||
)
|
||||
this.el.html(htmls);
|
||||
// Put in the basic (identity) transform script
|
||||
// TODO: put this into the template?
|
||||
var editor = this.el.find('.expression-preview-code');
|
||||
editor.val("function(doc) {\n doc['"+ this.state.currentColumn+"'] = doc['"+ this.state.currentColumn+"'];\n return doc;\n}");
|
||||
editor.focus().get(0).setSelectionRange(18, 18);
|
||||
editor.keydown();
|
||||
},
|
||||
|
||||
onSubmit: function(e) {
|
||||
var self = this;
|
||||
var funcText = this.el.find('.expression-preview-code').val();
|
||||
var editFunc = costco.evalFunction(funcText);
|
||||
if (editFunc.errorMessage) {
|
||||
util.notify("Error with function! " + editFunc.errorMessage);
|
||||
return;
|
||||
}
|
||||
util.hide('dialog');
|
||||
util.notify("Updating all visible docs. This could take a while...", {persist: true, loader: true});
|
||||
var docs = self.model.currentDocuments.map(function(doc) {
|
||||
return doc.toJSON();
|
||||
});
|
||||
// TODO: notify about failed docs?
|
||||
var toUpdate = costco.mapDocs(docs, editFunc).edited;
|
||||
var totalToUpdate = toUpdate.length;
|
||||
function onCompletedUpdate() {
|
||||
totalToUpdate += -1;
|
||||
if (totalToUpdate === 0) {
|
||||
util.notify(toUpdate.length + " documents updated successfully");
|
||||
alert('WARNING: We have only updated the docs in this view. (Updating of all docs not yet implemented!)');
|
||||
self.remove();
|
||||
}
|
||||
}
|
||||
// TODO: Very inefficient as we search through all docs every time!
|
||||
_.each(toUpdate, function(editedDoc) {
|
||||
var realDoc = self.model.currentDocuments.get(editedDoc.id);
|
||||
realDoc.set(editedDoc);
|
||||
realDoc.save().then(onCompletedUpdate).fail(onCompletedUpdate)
|
||||
});
|
||||
},
|
||||
|
||||
onEditorKeydown: function(e) {
|
||||
var self = this;
|
||||
// if you don't setTimeout it won't grab the latest character if you call e.target.value
|
||||
window.setTimeout( function() {
|
||||
var errors = self.el.find('.expression-preview-parsing-status');
|
||||
var editFunc = costco.evalFunction(e.target.value);
|
||||
if (!editFunc.errorMessage) {
|
||||
errors.text('No syntax error.');
|
||||
var docs = self.model.currentDocuments.map(function(doc) {
|
||||
return doc.toJSON();
|
||||
});
|
||||
costco.previewTransform(docs, editFunc, self.state.currentColumn);
|
||||
} else {
|
||||
errors.text(editFunc.errorMessage);
|
||||
}
|
||||
}, 1, true);
|
||||
}
|
||||
});
|
||||
|
||||
// View (Dialog) for doing data transformations on whole dataset.
|
||||
my.DataTransform = Backbone.View.extend({
|
||||
className: 'transform-view',
|
||||
template: ' \
|
||||
<div class="dialog-header"> \
|
||||
Recursive transform on all rows \
|
||||
</div> \
|
||||
<div class="dialog-body"> \
|
||||
<div class="grid-layout layout-full"> \
|
||||
<p class="info">Traverse and transform objects by visiting every node on a recursive walk using <a href="https://github.com/substack/js-traverse">js-traverse</a>.</p> \
|
||||
<table> \
|
||||
<tbody> \
|
||||
<tr> \
|
||||
<td colspan="4"> \
|
||||
<div class="grid-layout layout-tight layout-full"> \
|
||||
<table rows="4" cols="4"> \
|
||||
<tbody> \
|
||||
<tr style="vertical-align: bottom;"> \
|
||||
<td colspan="4"> \
|
||||
Expression \
|
||||
</td> \
|
||||
</tr> \
|
||||
<tr> \
|
||||
<td colspan="3"> \
|
||||
<div class="input-container"> \
|
||||
<textarea class="expression-preview-code"></textarea> \
|
||||
</div> \
|
||||
</td> \
|
||||
<td class="expression-preview-parsing-status" width="150" style="vertical-align: top;"> \
|
||||
No syntax error. \
|
||||
</td> \
|
||||
</tr> \
|
||||
<tr> \
|
||||
<td colspan="4"> \
|
||||
<div id="expression-preview-tabs" class="refine-tabs ui-tabs ui-widget ui-widget-content ui-corner-all"> \
|
||||
<span>Preview</span> \
|
||||
<div id="expression-preview-tabs-preview" class="ui-tabs-panel ui-widget-content ui-corner-bottom"> \
|
||||
<div class="expression-preview-container" style="width: 652px; "> \
|
||||
</div> \
|
||||
</div> \
|
||||
</div> \
|
||||
</td> \
|
||||
</tr> \
|
||||
</tbody> \
|
||||
</table> \
|
||||
</div> \
|
||||
</td> \
|
||||
</tr> \
|
||||
</tbody> \
|
||||
</table> \
|
||||
</div> \
|
||||
</div> \
|
||||
<div class="dialog-footer"> \
|
||||
<button class="okButton button"> Update All </button> \
|
||||
<button class="cancelButton button">Cancel</button> \
|
||||
</div> \
|
||||
',
|
||||
|
||||
initialize: function() {
|
||||
this.el = $(this.el);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
this.el.html(this.template);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
my.FlotGraph = Backbone.View.extend({
|
||||
|
||||
tagName: "div",
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user