From 15c6bde390b7de65f6cf3d950d4de296f9aa9310 Mon Sep 17 00:00:00 2001 From: Dan Vanderkam Date: Thu, 4 Dec 2014 16:07:08 -0500 Subject: [PATCH] Add spinner while queries are executing --- cycledash/static/css/examine.css | 6 ++ cycledash/static/img/loader.gif | Bin 34411 -> 500 bytes cycledash/static/js/examine/RecordActions.js | 27 +------- cycledash/static/js/examine/RecordStore.js | 60 ++++++------------ .../js/examine/components/ExaminePage.js | 1 + .../static/js/examine/components/QueryBox.js | 3 +- 6 files changed, 30 insertions(+), 67 deletions(-) diff --git a/cycledash/static/css/examine.css b/cycledash/static/css/examine.css index 2989886..32a25fe 100644 --- a/cycledash/static/css/examine.css +++ b/cycledash/static/css/examine.css @@ -273,6 +273,12 @@ dt { font-size: 1.5em; color: white; } +.query-status.loading { + background: url(/static/img/loader.gif) no-repeat; +} +.query-status.loading:before { + content: ""; +} .tt-hint { color: gray; } diff --git a/cycledash/static/img/loader.gif b/cycledash/static/img/loader.gif index ab4871214b14361e4491cd549bb05a7e49a190ac..a4b5178f8d33cdb79f251f801500e88f1e5ff156 100644 GIT binary patch literal 500 zcmZ?wbhEHb6krfw_{6~Q|NsB;^72QI9<5%zx}l)~$YuZo#sA!Xt|7tBjsdPldIrpl zKtaWSQqD!Gi6yBi3gww4848J6i4{5di79%Sd1?6!ia%L6xqzy4K-xiuGce0>tTHl5 z^0e%dH5QKcn0NK7=UL(2j8*G$UhgZ=In9Ypi#*4!JLi%nD9TBz^6&Q0V_BXsi^C;2 z6{6+59}_k`vOqom3{H8jlt}5Y?2;FLD9U2qbZKgCDA1ZcD)@A)-fPkA*fzsikxy7r zjHP1IrE9g4(|{hu^a{)lppIa}69Sh5dJenvunI0(dZco}HbQoEq1h4n2Ct5(So{&A nip^DWK%Z+h^E|wzQ4!)+pm@6|^`WqDDl~x2IT@@$aRCMZsZWy6 literal 34411 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 diff --git a/cycledash/static/js/examine/RecordActions.js b/cycledash/static/js/examine/RecordActions.js index 412a421..0da0e69 100644 --- a/cycledash/static/js/examine/RecordActions.js +++ b/cycledash/static/js/examine/RecordActions.js @@ -5,10 +5,7 @@ var ACTION_TYPES = { REQUEST_PAGE: 'REQUEST_PAGE', SELECT_RECORD: 'SELECT_RECORD', SET_QUERY: 'SET_QUERY', - SORT_BY: 'SORT_BY', - UPDATE_FILTER: 'UPDATE_FILTER', - UPDATE_RANGE: 'UPDATE_RANGE', - UPDATE_VARIANT_TYPE: 'UPDATE_VARIANT_TYPE', + SORT_BY: 'SORT_BY' }; function getRecordActions(dispatcher) { @@ -20,28 +17,6 @@ function getRecordActions(dispatcher) { order }); }, - updateFilters: function({columnName, type, filterValue}) { - dispatcher.dispatch({ - actionType: ACTION_TYPES.UPDATE_FILTER, - columnName, - type, - filterValue - }); - }, - updateRange: function({contig, start, end}) { - dispatcher.dispatch({ - actionType: ACTION_TYPES.UPDATE_RANGE, - start, - end, - contig - }); - }, - updateVariantType: function(variantType) { - dispatcher.dispatch({ - actionType: ACTION_TYPES.UPDATE_VARIANT_TYPE, - variantType - }); - }, setQuery: function(query) { dispatcher.dispatch({ actionType: ACTION_TYPES.SET_QUERY, diff --git a/cycledash/static/js/examine/RecordStore.js b/cycledash/static/js/examine/RecordStore.js index db8a58a..eb7a85c 100644 --- a/cycledash/static/js/examine/RecordStore.js +++ b/cycledash/static/js/examine/RecordStore.js @@ -30,6 +30,7 @@ var ENTIRE_GENOME = {start: null, end: null, contig: types.ALL_CHROMOSOMES}; function createRecordStore(run, dispatcher, opt_testDataSource) { // Initial state of the store. This is mutable. There be monsters. var vcfId = run.id, + hasPendingRequest = false, hasLoaded = false, loadError = null, @@ -58,18 +59,13 @@ function createRecordStore(run, dispatcher, opt_testDataSource) { var dataSource = opt_testDataSource || networkDataSource; + var currentPendingRequest = null; + function receiver(action) { switch(action.actionType) { case ACTION_TYPES.SORT_BY: updateSortBys(action.columnName, action.order); - updateGenotypes({append: false}); - break; - case ACTION_TYPES.UPDATE_FILTER: - updateFilters(action.columnName, action.filterValue, action.type); - updateGenotypes({append: false}); - break; - case ACTION_TYPES.UPDATE_RANGE: - updateRange(action.contig, action.start, action.end); + clearPendingRequests(); updateGenotypes({append: false}); break; case ACTION_TYPES.REQUEST_PAGE: @@ -81,6 +77,7 @@ function createRecordStore(run, dispatcher, opt_testDataSource) { break; case ACTION_TYPES.SET_QUERY: setQuery(action.query); + clearPendingRequests(); updateGenotypes({append: false}); break; } @@ -119,23 +116,34 @@ function createRecordStore(run, dispatcher, opt_testDataSource) { // table is now invalidated). if (!append) selectedRecord = null; + currentPendingRequest = query; + hasPendingRequest = true; + notifyChange(); // notify of pending request $.when(deferredGenotypes(vcfId, query)) .done(response => { - hasLoaded = true; + if (!_.isEqual(currentPendingRequest, query)) { + return; // A subsequent request has superceded this one. + } if (append) { - // TODO: BUG: This can result in a out-of-order records, if a later - // XHR returns before an earlier XHR. records = records.concat(response.records); } else { stats = response.stats; records = response.records; } + hasLoaded = true; + hasPendingRequest = false; notifyChange(); }); } var updateGenotypes = _.debounce(_.throttle(_updateGenotypes, 500 /* ms */), 500 /* ms */); + // All pending requests are obsolete. Ignore them for purposes of the UI. + function clearPendingRequests() { + hasPendingRequest = false; + currentPendingRequest = null; + } + // Returns a JS object query for sending to the backend. function queryFrom(range, filters, sortBy, page, limit) { if (sortBy[0].columnName == 'position') { @@ -169,26 +177,6 @@ function createRecordStore(run, dispatcher, opt_testDataSource) { if (val) return decodeURIComponent(val.split('=')[1]); } - /** - * Updates the filters by columnName and filterValue. Removes previous any - * previous filter which applies to the columnName, and then appends the new - * filter. - * - * NB: mutates store state! - */ - function updateFilters(columnName, filterValue, type) { - // TODO(ihodes): be careful with how we remove filters: we could have two+ - // filters applied to a given columnName, e.g. selection a - // range of interesting sample:DP - var filter = _.find(filters, f => _.isEqual(columnName, f.columnName)); - if (filter) { - filters = _.without(filters, filter); - } - if (filterValue.length > 0) { - filters.push({columnName, filterValue, type}); - } - } - /** * Updates the sortBys by columnName and order. * @@ -200,15 +188,6 @@ function createRecordStore(run, dispatcher, opt_testDataSource) { sortBys = [{columnName, order}]; } - /** - * Updates the range. - * - * NB: mutates store state! - */ - function updateRange(contig, start, end) { - range = {contig, start, end}; - } - /** * Sets sortBy, range and filters all in one go. * Unlike the update* methods, this clobbers whatever was there before. @@ -250,6 +229,7 @@ function createRecordStore(run, dispatcher, opt_testDataSource) { var query = queryFrom(range, filters, sortBys, page, limit); return { hasLoaded, + hasPendingRequest, loadError, records, stats, diff --git a/cycledash/static/js/examine/components/ExaminePage.js b/cycledash/static/js/examine/components/ExaminePage.js index 643e47c..c987549 100644 --- a/cycledash/static/js/examine/components/ExaminePage.js +++ b/cycledash/static/js/examine/components/ExaminePage.js @@ -63,6 +63,7 @@ var ExaminePage = React.createClass({ stats={state.stats} />