jenkins-bot has submitted this change and it was merged.
Change subject: Add header buttons to Totals Earned, share data
......................................................................
Add header buttons to Totals Earned, share data
Shares data in a shared context for other widgets to use. Uses
widget base to save configuration. Restores configuration on
reload. Save widget instance title.
Change-Id: I6a88ddff9165ec5145c335e7fe63d7428d4a6472
---
M src/app/widgetBase.js
M src/components/boards/generic-board/generic-board.html
M src/components/boards/generic-board/generic-board.js
M src/components/widgets/totals-earned-chart/totals-earned-chart.html
M src/components/widgets/totals-earned-chart/totals-earned-chart.js
5 files changed, 168 insertions(+), 126 deletions(-)
Approvals:
Ssmith: Looks good to me, approved
jenkins-bot: Verified
diff --git a/src/app/widgetBase.js b/src/app/widgetBase.js
index 92b46b7..bae190e 100644
--- a/src/app/widgetBase.js
+++ b/src/app/widgetBase.js
@@ -27,6 +27,7 @@
self.chartWidth = ko.observable('900');
self.chartHeight = ko.observable('550');
self.chartLoaded = ko.observable(false);
+ self.title =
ko.observable(params.title);
self.getChartData = function( qs ){
self.dataLoading(true);
@@ -40,16 +41,18 @@
};
self.saveWidgetConfig = function(){
+ var data = JSON.stringify( {
+ configuration: self.config,
+ isShared: false,
+ displayName: self.title()
+ } );
if( self.instanceID ){
$.ajax({
method: 'PUT',
url: '/widget-instance/' +
self.instanceID,
contentType: 'application/json;
charset=UTF-8',
- data: JSON.stringify({
- configuration: self.config,
- isShared: false
- }),
+ data: data,
success: function( data ) {
self.chartSaved(true);
self.logStateChange(false);
@@ -60,10 +63,7 @@
method: 'POST',
url: '/widget-instance/',
contentType: 'application/json;
charset=UTF-8',
- data: JSON.stringify({
- configuration: self.config,
- isShared: false
- }),
+ data: data,
success: function( data ) {
self.instanceID = data.id;
self.chartSaved(true);
@@ -169,7 +169,9 @@
self.logStateChange = function(n){
self.optionStateChanged(n);
- self.chartSaved(false);
+ if ( n !== false ) {
+ self.chartSaved(false);
+ }
};
return this;
diff --git a/src/components/boards/generic-board/generic-board.html
b/src/components/boards/generic-board/generic-board.html
index 7797fae..9dd8d2f 100644
--- a/src/components/boards/generic-board/generic-board.html
+++ b/src/components/boards/generic-board/generic-board.html
@@ -20,7 +20,7 @@
</span>
<div class="row" data-bind="foreach: displayedBoard().widgets">
- <div data-bind="component: { name: widgetCode, params: { title:
displayName, description: description, configuration: configuration,
widgetInstance: id, widgetCode: widgetCode } }"><span data-bind="text:
display_name"></span></div>
+ <div data-bind="component: { name: widgetCode, params: { title:
displayName, description: description, configuration: configuration,
widgetInstance: id, widgetCode: widgetCode, sharedContext:
$parent.sharedContext } }"><span data-bind="text: display_name"></span></div>
</div>
</div>
\ No newline at end of file
diff --git a/src/components/boards/generic-board/generic-board.js
b/src/components/boards/generic-board/generic-board.js
index 60f593a..fb3fa04 100644
--- a/src/components/boards/generic-board/generic-board.js
+++ b/src/components/boards/generic-board/generic-board.js
@@ -11,6 +11,8 @@
var self = this,
timeFormat = 'dddd, MMMM Do YYYY, h:mm:ss a';
+ self.sharedContext = {};
+
self.displayedBoard = params.displayedBoard;
//make this false until data loading has been written
diff --git
a/src/components/widgets/totals-earned-chart/totals-earned-chart.html
b/src/components/widgets/totals-earned-chart/totals-earned-chart.html
index 3ea4b2b..d7a3a52 100644
--- a/src/components/widgets/totals-earned-chart/totals-earned-chart.html
+++ b/src/components/widgets/totals-earned-chart/totals-earned-chart.html
@@ -1,83 +1,112 @@
<div class="row">
- <div class="panel panel-transparent">
- <div class="panel-body">
- <!--Main updates: Goal, Total so far, Remaining to raise-->
- <div class="row-fluid bigEnglish-updates">
- <div class="col-md-4 col-sm-4 col-lg-4">
- <div class="row factbox factbox-blue">
- <div class="col-md-3">
- <div class="factbox-icon">
- <i class='fa fa-soccer-ball-o'></i>
- </div>
- </div>
- <div class="col-md-9">
- <p class='factbox-header'>2014 Big English Goal</p>
- <h3 data-bind="text: bigEnglishGoal"></h3>
- </div>
- </div>
- </div>
- <div class="col-md-4 col-sm-4 col-lg-4">
- <div class="row factbox factbox-yellow">
- <div class="col-md-3">
- <div class="factbox-icon">
- <i class='fa fa-gift'></i>
- </div>
- </div>
- <div class="col-md-9">
- <p class='factbox-header'>Total To Date</p>
- <h3 data-bind="text: totalRaisedToDate"></h3>
- </div>
- </div>
- </div>
- <div class="col-md-4 col-sm-4 col-lg-4">
- <div class="row factbox factbox-red">
- <div class="col-md-3">
- <div class="factbox-icon">
- <i class='fa fa-calculator'></i>
- </div>
- </div>
- <div class="col-md-9">
- <p class='factbox-header'>Remaining To Raise</p>
- <h3 data-bind="text: totalRemainingToDate"></h3>
- </div>
- </div>
- </div>
- </div>
- </div>
- </div>
+ <div class="col-md-4 titleCol">
+ <h3 style="display:inline" data-bind="text:title"></h2>
+ <p>As of <span data-bind="text: displayDate"></span></p>
+ </div>
+ <div class="col-md-8 titleCol">
+ <div class="btn-group btn-group-xs pull-right">
+ <button type="button" class="btn btn-default
dropdown-toggle" data-toggle="modal" data-target="#bigEsqlModal"><i class="fa
fa-database"></i></button>
+ <button type="button" class="btn btn-default
dropdown-toggle" data-toggle="modal" data-target="#BEsettingsModal"><i
class="fa fa-gear"></i></button>
+ <button type="button" class="btn btn-default"
data-bind="click: reloadData"><i class="fa fa-refresh"></i></button>
+ <button type="button" class="btn btn-danger"
data-bind="visible: !chartSaved(), click: saveWidgetConfig"><i class="fa
fa-save"></i></button>
+ <button type="button" class="btn btn-success"
data-bind="visible: chartSaved"><i class="fa fa-save"></i> Saved</button>
+ </div>
+ </div>
+</div>
+
+<div class="row">
+ <div class="panel panel-transparent">
+ <div class="panel-body">
+ <!--Main updates: Goal, Total so far, Remaining to
raise-->
+ <div class="row-fluid bigEnglish-updates">
+ <div class="col-md-4 col-sm-4 col-lg-4">
+ <div class="row factbox factbox-blue">
+ <div class="col-md-3">
+ <div
class="factbox-icon">
+ <i class='fa
fa-soccer-ball-o'></i>
+ </div>
+ </div>
+ <div class="col-md-9">
+ <p
class='factbox-header'>Goal</p>
+ <h3 data-bind="text:
formattedGoal"></h3>
+ </div>
+ </div>
+ </div>
+ <div class="col-md-4 col-sm-4 col-lg-4">
+ <div class="row factbox factbox-yellow">
+ <div class="col-md-3">
+ <div
class="factbox-icon">
+ <i class='fa
fa-gift'></i>
+ </div>
+ </div>
+ <div class="col-md-9">
+ <p
class='factbox-header'>Total To Date</p>
+ <h3 data-bind="text:
totalRaisedToDate"></h3>
+ </div>
+ </div>
+ </div>
+ <div class="col-md-4 col-sm-4 col-lg-4">
+ <div class="row factbox factbox-red">
+ <div class="col-md-3">
+ <div
class="factbox-icon">
+ <i class='fa
fa-calculator'></i>
+ </div>
+ </div>
+ <div class="col-md-9">
+ <p
class='factbox-header'>Remaining To Raise</p>
+ <h3 data-bind="text:
totalRemainingToDate"></h3>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
+ </div>
</div>
<div class="row">
<div class="panel panel-purple">
- <div class="panel-heading">
- <p data-bind="text: title"></p>
- </div>
- <div class="panel-body">
- <!--Daily, Hourly, etc Totals Earned-->
- <div id='totalsEarnedChart'></div>
- </div>
- </div>
+ <div class="panel-heading">
+ <p data-bind="text: title"></p>
+ </div>
+ <div class="panel-body">
+ <!--Daily, Hourly, etc Totals Earned-->
+ <div id='totalsEarnedChart'></div>
+ </div>
+</div>
</div>
<div class="modal fade" id="BEsettingsModal">
- <div class="modal-dialog">
- <div class="modal-content">
- <div class="modal-header">
- <button type="button" class="close" data-dismiss="modal"><span
aria-hidden="true">×</span><span class="sr-only">Close</span></button>
- <h4 class="modal-title">Options</h4>
- </div>
- <div class="modal-body">
- <label>Change Big English goal</label>
- <div class="input-group">
- <span class="input-group-addon">$</span>
- <input type="text" class="form-control"
data-bind="textInput: goal">
- <span class="input-group-addon">.00</span>
- </div>
- </div>
- <div class="modal-footer">
- <button type="button" class="btn btn-default"
data-dismiss="modal">Cancel</button>
- <button type="button" class="btn btn-success pull-right"
data-dismiss="modal">Submit</button>
- </div>
- </div><!-- /.modal-content -->
- </div><!-- /.modal-dialog -->
-</div><!-- /.modal -->
\ No newline at end of file
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close"
data-dismiss="modal"><span aria-hidden="true">×</span><span
class="sr-only">Close</span></button>
+ <h4 class="modal-title">Options</h4>
+ </div>
+ <div class="modal-body">
+ <label>Change Big English goal</label>
+ <div class="input-group">
+ <span class="input-group-addon">$</span>
+ <input type="text" class="form-control"
data-bind="textInput: goal">
+ <span class="input-group-addon">.00</span>
+ </div>
+ </div>
+ <div class="modal-footer">
+ <button type="button" class="btn btn-default"
data-dismiss="modal">Cancel</button>
+ <button type="button" class="btn btn-success
pull-right" data-dismiss="modal">Submit</button>
+ </div>
+ </div><!-- /.modal-content -->
+ </div><!-- /.modal-dialog -->
+</div><!-- /.modal -->
+<div class="modal fade" id="bigEsqlModal">
+ <div class="modal-dialog">
+ <div class="modal-content">
+ <div class="modal-header">
+ <button type="button" class="close"
data-dismiss="modal"><span aria-hidden="true">×</span><span
class="sr-only">Close</span></button>
+ <h4 class="modal-title">Totals Earned SQL:</h4>
+ </div>
+ <div class="modal-body">
+ <p data-bind="text:queryStringSQL"></p>
+ </div>
+ </div><!-- /.modal-content -->
+ </div><!-- /.modal-dialog -->
+</div><!-- /.modal -->
diff --git a/src/components/widgets/totals-earned-chart/totals-earned-chart.js
b/src/components/widgets/totals-earned-chart/totals-earned-chart.js
index ae3257f..d37ffe8 100644
--- a/src/components/widgets/totals-earned-chart/totals-earned-chart.js
+++ b/src/components/widgets/totals-earned-chart/totals-earned-chart.js
@@ -3,8 +3,9 @@
'text!components/widgets/totals-earned-chart/totals-earned-chart.html',
'c3',
'numeraljs',
- 'momentjs'
-], function( ko, template, c3, numeral, moment ){
+ 'momentjs',
+ 'WidgetBase'
+], function( ko, template, c3, numeral, moment, WidgetBase ){
function TotalsEarnedChartViewModel( params ){
@@ -12,27 +13,34 @@
var self = this,
timeFormat = 'dddd, MMMM Do YYYY, h:mm:ss a';
- self.title = ko.observable(params.title);
-
- //self.title = ko.observable(params.title);
- self.widgetWidth = ko.observable(params.configuration.width);
- self.dataLoading = ko.observable(true);
+ WidgetBase.call( this, params );
//initialize day/hour data
- self.dayObj = [];
- self.dailyDataArray = ['Daily Total'];
- self.dailyCountArray = ['Daily Count'];
- self.lastDataPoint = { day: 1, hour: 0 };
- self.secondsByHourDonationData = ['Donations Per Second'];
+ //sharing these for other widgets
+ params.sharedContext.dayObj = [];
+ params.sharedContext.dailyDataArray = ['Daily Total'];
+ params.sharedContext.dailyCountArray = ['Daily Count'];
+ params.sharedContext.lastDataPoint = { day: 1, hour: 0 };
+ params.sharedContext.secondsByHourDonationData = ['Donations
Per Second'];
// Get the date
self.displayDate = ko.observable( moment().format( timeFormat )
);
- self.goal = ko.observable(20000000);
+ self.goal = params.sharedContext.goal = ko.observable(
self.config.goal || 20000000 );
+ params.sharedContext.goal.subscribe( function() {
+ self.config.goal = params.sharedContext.goal();
+ self.logStateChange();
+ } );
+
self.raised = ko.observable(0);
- self.bigEnglishGoal = ko.computed(function(){
- return numeral(self.goal()).format('$0,0');
+ // Let other widgets subscribe to changes in the goal or the
totals
+ params.sharedContext.totalsChanged = ko.computed( function() {
+ return self.raised() - params.sharedContext.goal();
+ } );
+
+ self.formattedGoal = ko.computed(function(){
+ return
numeral(params.sharedContext.goal()).format('$0,0');
});
self.totalRaisedToDate = ko.computed(function(){
@@ -40,49 +48,45 @@
});
self.totalRemainingToDate = ko.computed( function(){
- var trtd = self.goal() - self.raised();
+ var trtd = params.sharedContext.goal() - self.raised();
return numeral(trtd >= 0 ? trtd : 0).format('$0,0');
});
- // params.dataChanged.subscribe(function() {
- // self.makeCharts();
- // });
-
//get the data needed for this chart
- self.loadData = function ( decemberData, timestamp ) {
+ self.loadData = function ( data, timestamp ) {
var runningTotal = 0,
currentDate = new Date();
currentDate.setTime( timestamp );
self.displayDate( moment( currentDate ).format(
timeFormat ) );
- self.lastDataPoint.day = currentDate.getUTCDate();
- self.lastDataPoint.hour = currentDate.getUTCHours();
+ params.sharedContext.lastDataPoint.day =
currentDate.getUTCDate();
+ params.sharedContext.lastDataPoint.hour =
currentDate.getUTCHours();
for (var d = 1; d < 32; d++) {
- self.dailyDataArray[d] = 0;
- self.dailyCountArray[d] = 0;
- if (!self.dayObj[d]) {
- self.dayObj[d] = new Array(25);
- self.dayObj[d][0] = 'Hourly Totals';
+ params.sharedContext.dailyDataArray[d] = 0;
+ params.sharedContext.dailyCountArray[d] = 0;
+ if (!params.sharedContext.dayObj[d]) {
+ params.sharedContext.dayObj[d] = new
Array(25);
+ params.sharedContext.dayObj[d][0] =
'Hourly Totals';
for (var h = 0; h < 24; h++) {
- self.dayObj[d][h + 1] = {
total: 0, count: 0 };
-
self.secondsByHourDonationData[(d - 1) * 24 + h + 1] = 0;
+
params.sharedContext.dayObj[d][h + 1] = { total: 0, count: 0 };
+
params.sharedContext.secondsByHourDonationData[(d - 1) * 24 + h + 1] = 0;
}
}
}
- var dataCount = decemberData.length;
+ var dataCount = data.length;
for (var i = 0; i < dataCount; i++ ) {
- var el = decemberData[i],
+ var el = data[i],
day = el.day,
hour = el.hour,
total = el.usd_total;
- self.dayObj[day][hour + 1] = { total: total,
count: el.donations };
+ params.sharedContext.dayObj[day][hour + 1] = {
total: total, count: el.donations };
- self.secondsByHourDonationData[(day - 1) * 24 +
hour + 1] = el.usd_per_second;
+
params.sharedContext.secondsByHourDonationData[(day - 1) * 24 + hour + 1] =
el.usd_per_second;
runningTotal += total;
- self.dailyDataArray[day] += total;
- self.dailyCountArray[day] += el.donations;
+ params.sharedContext.dailyDataArray[day] +=
total;
+ params.sharedContext.dailyCountArray[day] +=
el.donations;
}
self.makeCharts();
@@ -100,7 +104,8 @@
}
$.get( url , function ( dataget ) {
self.loadData( dataget.results,
dataget.timestamp );
- self.dataLoading(false);
+ self.dataLoading( false );
+ self.queryStringSQL( dataget.sqlQuery );
});
// Do it every 5 minutes as well
setTimeout( function () {
@@ -111,11 +116,11 @@
self.reloadData( true );
self.makeCharts = function() {
- if (self.dailyDataArray.length < 2) {
+ if (params.sharedContext.dailyDataArray.length < 2) {
return;
}
self.hourlyChart = function(d,i){
- var hourlyData = self.dayObj[d.x + 1 ],
+ var hourlyData =
params.sharedContext.dayObj[d.x + 1 ],
hourlyCountArray = ['Hourly Count'],
hourlyTotalArray = ['Hourly Total'];
for(var j=1; j<25; j++){
@@ -133,7 +138,10 @@
columns: [ hourlyTotalArray,
hourlyCountArray ],
type: 'bar',
colors: { 'Hourly Total':
'rgb(92,184,92)', 'Hourly Count': '#f0ad4e' },
- onclick: function (d, i) {
c3.generate(self.dailyChart()); },
+ onclick: function (d, i) {
+
self.totalsEarnedChart.destroy();
+ self.totalsEarnedChart
= c3.generate(self.dailyChart());
+ },
axes: {
'Hourly Total': 'y',
'Hourly Count': 'y2'
@@ -200,10 +208,11 @@
},
zoom: { enabled: true },
data: {
- columns: [ self.dailyDataArray,
self.dailyCountArray ],
+ columns: [
params.sharedContext.dailyDataArray, params.sharedContext.dailyCountArray ],
type: 'bar',
colors: { 'Daily Total':
'rgb(49,176,213)', 'Daily Count': '#f0ad4e' },
onclick: function (d, i) {
+
self.totalsEarnedChart.destroy();
self.totalsEarnedChart
= c3.generate(self.hourlyChart(d,i));
},
axes: {
--
To view, visit https://gerrit.wikimedia.org/r/197841
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: merged
Gerrit-Change-Id: I6a88ddff9165ec5145c335e7fe63d7428d4a6472
Gerrit-PatchSet: 5
Gerrit-Project: wikimedia/fundraising/dash
Gerrit-Branch: master
Gerrit-Owner: Ejegg <[email protected]>
Gerrit-Reviewer: Ssmith <[email protected]>
Gerrit-Reviewer: jenkins-bot <>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits