Permalink
Browse files

better error messages, more robust csv uploading

  • Loading branch information...
maxogden committed Sep 17, 2011
1 parent 935e0d1 commit fe8df046daa72d033f5e1f673a9a33eb84e0b0f1
View
6 app.js
@@ -115,12 +115,6 @@ ddoc.lists = {
}
}
-ddoc.validate_doc_update = function (newDoc, oldDoc, userCtx) {
- if (newDoc._deleted === true && userCtx.roles.indexOf('_admin') === -1) {
- throw "Only admin can delete documents on this database.";
- }
-};
-
couchapp.loadAttachments(ddoc, path.join(__dirname, 'attachments'));
module.exports = ddoc;
@@ -6,16 +6,8 @@
<link rel="stylesheet" href="style/reset.css" media="screen">
<link rel="stylesheet" href="style/data-table.css" media="screen">
<link rel="stylesheet" href="style/style.css" media="screen">
- <script type="text/javascript" src="script/lib/jquery-1.6.1.min.js"></script>
<!-- only using jqueryui for draggable -- a lighter solution would be nice -->
- <script type="text/javascript" src="script/lib/jquery-ui-1.8.14.custom.min.js"></script>
- <script type="text/javascript" src="script/lib/jquery.mustache.js"></script>
- <script type="text/javascript" src="script/lib/jquery.couch2.js"></script>
- <script type="text/javascript" src="script/lib/jquery.hotkeys.js"></script>
- <script type="text/javascript" src="script/lib/sammy-0.6.3.min.js"></script>
- <script type="text/javascript" src="script/lib/underscore.js"></script>
- <script type="text/javascript" src="script/lib/microevent.js"></script>
- <script type="text/javascript" src="script/lib/traverse.js"></script>
+ <script type="text/javascript" src="script/deps-min.js"></script>
<script type="text/javascript" src="script/util.js"></script>
<script type="text/javascript" src="script/costco.js"></script>
<script type="text/javascript" src="script/recline.js"></script>
@@ -32,7 +24,10 @@
<div class="project-actions"></div>
<div class="project-controls"></div>
</div>
- <div class="main_content"></div>
+ <div class="main_content">
+ <div class="left-panel"></div>
+ <div class="right-panel"></div>
+ </div>
</div>
<div id="notification-container">
@@ -94,43 +89,40 @@
<script type='text/mustache' class="generatingTemplate"><div class="loading">Loading...</div></script>
<script type='text/mustache' class="tableContainerTemplate">
- <div id="right-panel">
- <div id="tool-panel">
- <div id="summary-bar">
- <span id="docCount"></span>
- </div>
- <div id="download">
- </div>
+ <div id="tool-panel">
+ <div id="summary-bar">
+ <span id="docCount"></span>
+ </div>
+ <div id="download">
</div>
- <div id="view-panel">
- <div class="viewpanel-header">
- <div class="viewpanel-pagesize">
- <span>
- Show:
- </span>
- <a href="javascript:{}" class="viewPanel-pagingControls-page action">5</a>
- <a href="javascript:{}" class="viewPanel-pagingControls-page selected">10</a>
- <a href="javascript:{}" class="viewPanel-pagingControls-page action">25</a>
- <a href="javascript:{}" class="viewPanel-pagingControls-page action">50</a>
- <span>
- rows
- </span>
- </div>
- <div class="viewpanel-sorting">
- </div>
- <div class="viewpanel-paging">
- <a href="javascript:{}" class="first inaction">« first</a>
- <a href="javascript:{}" class="previous inaction">‹ previous</a>
- <span class="viewpanel-pagingcount">
- 1 - 10
- </span>
- <a href="javascript:{}" class="next action">next ›</a>
- <a href="javascript:{}" class="last action">last »</a>
- </div>
+ </div>
+ <div id="view-panel">
+ <div class="viewpanel-header">
+ <div class="viewpanel-pagesize">
+ <span>
+ Show:
+ </span>
+ <a href="javascript:{}" class="viewPanel-pagingControls-page action">5</a>
+ <a href="javascript:{}" class="viewPanel-pagingControls-page selected">10</a>
+ <a href="javascript:{}" class="viewPanel-pagingControls-page action">25</a>
+ <a href="javascript:{}" class="viewPanel-pagingControls-page action">50</a>
+ <span>
+ rows
+ </span>
</div>
- <div class="data-table-container">
-
+ <div class="viewpanel-sorting">
</div>
+ <div class="viewpanel-paging">
+ <a href="javascript:{}" class="first inaction">« first</a>
+ <a href="javascript:{}" class="previous inaction">‹ previous</a>
+ <span class="viewpanel-pagingcount">
+ 1 - 10
+ </span>
+ <a href="javascript:{}" class="next action">next ›</a>
+ <a href="javascript:{}" class="last action">last »</a>
+ </div>
+ </div>
+ <div class="data-table-container">
</div>
</div>
</script>
@@ -304,7 +296,7 @@
Paste in an array of JSON objects representing the documents that you would like to insert into the database.
</p>
<p class="info">
- <code>[{woo: "pizza"}, {tasty: "muffins"}]</code>
+ <code>[{"woo": "pizza"}, {"tasty": "muffins"}]</code>
</p>
<div class="menu-container data-table-cell-editor">
<textarea class="data-table-cell-copypaste-editor" bind="textarea">{{value}}</textarea>
@@ -45,12 +45,12 @@ onmessage = function(message) {
var docs = parseCSV(message.data.data);
var req = new XMLHttpRequest();
-
+
req.onprogress = req.upload.onprogress = function(e) {
- if(e.lengthComputable) postMessage(JSON.stringify({ percent: (e.loaded / e.total) * 100 }));
+ if(e.lengthComputable) postMessage({ percent: (e.loaded / e.total) * 100 });
};
- req.onreadystatechange = function() { if (req.readyState == 4) postMessage(JSON.stringify( {done: true} )) };
+ req.onreadystatechange = function() { if (req.readyState == 4) postMessage({done: true, response: req.responseText}) };
req.open('POST', message.data.url);
req.setRequestHeader('Content-Type', 'application/json');
req.send(JSON.stringify({docs: docs}));
@@ -90,7 +90,14 @@ var costco = function() {
if(!docs.length) dfd.resolve("Failed: No docs specified");
couch.request({url: app.baseURL + "api/_bulk_docs", type: "POST", data: JSON.stringify({docs: docs})})
.then(
- function(resp) {ensureCommit().then(function() { dfd.resolve(resp) })},
+ function(resp) {ensureCommit().then(function() {
+ var error = couch.responseError(resp);
+ if (error) {
+ dfd.reject(error);
+ } else {
+ dfd.resolve(resp);
+ }
+ })},
function(err) { dfd.reject(err.responseText) }
);
return dfd.promise();
@@ -119,25 +126,29 @@ var costco = function() {
data: event.target.result
};
var worker = new Worker('script/costco-csv-worker.js');
- worker.onmessage = function(message) {
- message = JSON.parse(message.data);
- console.log(message)
-
- if (message.done) {
- util.hide('dialog');
- util.notify("Data uploaded successfully!");
- recline.initializeTable(app.offset);
- } else if (message.percent) {
- if (message.percent === 100) {
- util.notify("Waiting for CouchDB...", {persist: true, loader: true})
- } else {
- util.notify("Uploading... " + message.percent + "%");
- }
- } else {
- util.notify(JSON.stringify(message));
- }
- };
- worker.postMessage(payload);
+ worker.onmessage = function(event) {
+ var message = event.data;
+ if (message.done) {
+ var error = couch.responseError(JSON.parse(message.response))
+ console.log('e',error)
+ if (error) {
+ app.emitter.emit(error, 'error');
+ } else {
+ util.notify("Data uploaded successfully!");
+ recline.initializeTable(app.offset);
+ }
+ util.hide('dialog');
+ } else if (message.percent) {
+ if (message.percent === 100) {
+ util.notify("Waiting for CouchDB...", {persist: true, loader: true})
+ } else {
+ util.notify("Uploading... " + message.percent + "%");
+ }
+ } else {
+ util.notify(JSON.stringify(message));
+ }
+ };
+ worker.postMessage(payload);
};
} else {
util.notify('File not selected. Please try again');

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -10,9 +10,32 @@
url: "/"
};
+ couch.errors = {
+ forbidden: "You aren't allowed to do that."
+ }
+
+ couch.responseError = function(response) {
+ if(_.isArray(response) && (response.length > 0) ) response = response[0];
+ if (response.error) return couch.errors[response.error];
+ }
+
couch.request = function(opts) {
- var ajaxOpts = $.extend({}, defaults, opts);
- return $.ajax(ajaxOpts).promise();
+ var ajaxOpts = $.extend({}, defaults, opts)
+ , dfd = $.Deferred()
+ ;
+
+ $.ajax(ajaxOpts).then(
+ function(successResponse) {
+ var error = couch.responseError(successResponse);
+ if (error) app.emitter.emit(error, 'error');
+ dfd.resolve(successResponse);
+ },
+ function(errorResponse) {
+ app.emitter.emit("Fatal XHR Error", 'error');
+ }
+ )
+
+ return dfd.promise();
}
couch.get = function(url) {
@@ -122,7 +122,12 @@ var recline = function() {
}
function getPageSize() {
- return parseInt($(".viewpanel-pagesize .selected").text());
+ var pagination = $(".viewpanel-pagesize .selected");
+ if (pagination.length > 0) {
+ return parseInt(pagination.text())
+ } else {
+ return 10;
+ }
}
function fetchRows(id, skip) {
@@ -158,9 +163,9 @@ var recline = function() {
)
}
- function getDbInfo() {
+ function getDbInfo(url) {
var dfd = $.Deferred();
- return couch.request({url: app.baseURL + "api"}).then(function(dbInfo) {
+ return couch.request({url: url}).then(function(dbInfo) {
app.dbInfo = dbInfo;
$.extend(app.dbInfo, {
@@ -176,18 +181,15 @@ var recline = function() {
}
- function bootstrap() {
- util.registerEmitter();
+ function bootstrap(id) {
+ app.dbPath = app.baseURL + "api/";
+
util.listenFor(['esc', 'return']);
- getDbInfo().then(function( dbInfo ) {
-
- util.render('tableContainer', app.container);
- util.render('title', 'project-title', app.dbInfo);
+ getDbInfo(app.dbPath).then(function( dbInfo ) {
+ util.render('title', 'project-title', dbInfo);
util.render( 'generating', 'project-actions' );
-
- updateDocCount(app.dbInfo.doc_count);
-
+
couch.session().then(function(session) {
if ( session.userCtx.name ) {
var text = "Sign out";
@@ -196,24 +198,26 @@ var recline = function() {
}
util.render('controls', 'project-controls', {text: text});
})
-
+
initializeTable();
})
}
function initializeTable(offset) {
+ util.render( 'tableContainer', 'right-panel' );
showDialog('busy');
- couch.request({url: app.baseURL + 'api/headers'}).then(function ( headers ) {
+ couch.request({url: app.dbPath + 'headers'}).then(function ( headers ) {
util.hide('dialog');
- getDbInfo().then(function(dbInfo) {
+ getDbInfo(app.dbPath).then(function(dbInfo) {
updateDocCount(dbInfo.doc_count);
});
app.headers = headers;
- app.csvUrl = app.baseURL + 'api/csv?headers=' + escape(JSON.stringify(headers));
+ app.csvUrl = app.dbPath + 'csv?headers=' + escape(JSON.stringify(headers));
util.render( 'actions', 'project-actions', $.extend({}, app.dbInfo, {url: app.csvUrl}) );
fetchRows(false, offset);
})
}
+
return {
formatDiskSize: formatDiskSize,
@@ -1,6 +1,7 @@
var app = {
baseURL: util.getBaseURL(document.location.pathname),
- container: 'main_content'
+ container: 'main_content',
+ emitter: util.registerEmitter()
};
app.handler = function(route) {
@@ -227,7 +228,6 @@ app.after = {
},
function (err) {
util.hide('dialog');
- util.notify("Error uploading: " + err.responseText);
}
);
} else {
@@ -246,6 +246,10 @@ app.sammy = $.sammy(function () {
});
$(function() {
+ app.emitter.on('error', function(error) {
+ util.notify("Server error: " + error);
+ })
+
util.traverse = require('traverse');
app.sammy.run();
})
@@ -32,7 +32,7 @@ var util = function() {
};
};
MicroEvent.mixin(Emitter);
- app.emitter = new Emitter();
+ return new Emitter();
}
function listenFor(keys) {
@@ -450,7 +450,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
font-size: 11px;
}
-#left-panel {
+.left-panel {
position: fixed;
overflow: hidden;
padding: 0px;
@@ -459,14 +459,14 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
background: #e3e9ff;
}
-#left-panel .ui-tabs .ui-tabs-panel {
+.left-panel .ui-tabs .ui-tabs-panel {
border-left: none;
border-right: none;
border-bottom: none;
padding: 0;
}
-#right-panel {
+.right-panel {
position: fixed;
top: 40px;
left: 0px;

0 comments on commit fe8df04

Please sign in to comment.