From 5b4a95f59be82c02d594488963e7698686d0720a Mon Sep 17 00:00:00 2001 From: jwollert Date: Thu, 7 Apr 2011 15:51:21 +0200 Subject: [PATCH] animated progress bar to trick the user into thinking that we know what we're doing when actually, we DON'T HAVE ANY CLUE GUYS --- assets/javascripts/reporting.js | 2 + assets/javascripts/reporting/group_bys.js | 16 ++- assets/javascripts/reporting/progressbar.js | 17 +++ .../reporting/prototype_progress_bar.js | 102 ++++++++++++++++++ assets/stylesheets/reporting.css | 14 +++ lib/widget/table/progressbar.rb | 1 + 6 files changed, 148 insertions(+), 4 deletions(-) create mode 100644 assets/javascripts/reporting/prototype_progress_bar.js diff --git a/assets/javascripts/reporting.js b/assets/javascripts/reporting.js index f0f2b7e519..bb801a37d8 100644 --- a/assets/javascripts/reporting.js +++ b/assets/javascripts/reporting.js @@ -62,4 +62,6 @@ Reporting.require("filters"); Reporting.require("group_bys"); Reporting.require("restore_query"); Reporting.require("controls"); +Reporting.require("prototype_progress_bar"); Reporting.require("progressbar"); + diff --git a/assets/javascripts/reporting/group_bys.js b/assets/javascripts/reporting/group_bys.js index f079eefeb4..9e57e3b543 100644 --- a/assets/javascripts/reporting/group_bys.js +++ b/assets/javascripts/reporting/group_bys.js @@ -59,17 +59,17 @@ Reporting.GroupBys = { 'data-group-by': field }); group_by.identify(); // give it a unique id - + left_arrow = Reporting.GroupBys.create_arrow(group_by, 'left'); group_by.appendChild(left_arrow); - + label = Reporting.GroupBys.create_label(group_by, caption); Reporting.GroupBys.init_group_by_hover_effects([group_by, label]); group_by.appendChild(label); - + remove_button = Reporting.GroupBys.create_remove_button(group_by); group_by.appendChild(remove_button); - + right_arrow = Reporting.GroupBys.create_arrow(group_by, 'right'); group_by.appendChild(right_arrow); return group_by; @@ -136,6 +136,14 @@ Reporting.GroupBys = { add_groups_select_box.insert({ before: group_by }); Reporting.GroupBys.adding_group_by_enabled(field, false); Reporting.GroupBys.recreate_sortables(); + }, + + clear: function() { + Reporting.GroupBys.group_by_container_ids().each(function (container) { + $(container).select('[data-group-by]').each(function (group_by) { + Reporting.GroupBys.remove_group_by(group_by); + }); + }); } }; diff --git a/assets/javascripts/reporting/progressbar.js b/assets/javascripts/reporting/progressbar.js index 51165a2f64..9ea88fde65 100644 --- a/assets/javascripts/reporting/progressbar.js +++ b/assets/javascripts/reporting/progressbar.js @@ -3,11 +3,28 @@ Reporting.Progress = { + replace_with_bar: function (element) { + var parent = $('progressbar'); + var size = parseInt(element.getAttribute('data-size'), 10) || 500; + parent.descendants().each(function (elem) { + elem.remove(); + }); + parent.appendChild(new Element('div', { + 'id': 'progressbar_container', + 'class': 'progressbar_container' + })); + new Control.ProgressBar('progressbar_container', { + // Speed determined through laborous experimentation! + interval: (size * (Math.log(size)^3)) / 80000 + }).start(); + }, + attach_listeners: function () { if ($('progressbar') !== null && $('progressbar') !== undefined) { $('progressbar').select('span[data-load]').each(function (element) { element.observe("click", function (e) { if (this.getAttribute("data-load") === "true") { + Reporting.Progress.replace_with_bar(this); Reporting.Controls.send_settings_data(this.getAttribute("data-target"), Reporting.Controls.update_result_table); } else { $('progressbar').toggle(); diff --git a/assets/javascripts/reporting/prototype_progress_bar.js b/assets/javascripts/reporting/prototype_progress_bar.js new file mode 100644 index 0000000000..d039a69557 --- /dev/null +++ b/assets/javascripts/reporting/prototype_progress_bar.js @@ -0,0 +1,102 @@ +/** + * @author Ryan Johnson + * @copyright 2008 PersonalGrid Corporation + * @package LivePipe UI + * @license MIT + * @url http://livepipe.net/control/progressbar + * @require prototype.js, livepipe.js + */ + +/*global document, Prototype, Ajax, Class, PeriodicalExecuter, $, $A, Control */ + +if(typeof(Prototype) == "undefined") { + throw "Control.ProgressBar requires Prototype to be loaded."; } +if(typeof(Event) == "undefined") { + throw "Control.ProgressBar requires Event to be loaded."; } + +Control.ProgressBar = Class.create({ + initialize: function(container,options){ + this.progress = 0; + this.executer = false; + this.active = false; + this.poller = false; + this.container = $(container); + this.containerWidth = this.container.getDimensions().width - (parseInt(this.container.getStyle('border-right-width').replace(/px/,''), 10) + parseInt(this.container.getStyle('border-left-width').replace(/px/,''), 10)); + this.progressContainer = $(document.createElement('div')); + this.progressContainer.setStyle({ + width: this.containerWidth + 'px', + height: '100%', + position: 'absolute', + top: '0px', + right: '0px' + }); + this.container.appendChild(this.progressContainer); + this.options = { + afterChange: Prototype.emptyFunction, + interval: 0.25, + step: 1, + classNames: { + active: 'progress_bar_active', + inactive: 'progress_bar_inactive' + } + }; + Object.extend(this.options,options || {}); + this.container.addClassName(this.options.classNames.inactive); + this.active = false; + }, + setProgress: function(value){ + this.progress = value; + this.draw(); + if(this.progress >= 100) { + this.stop(false); } + this.notify('afterChange',this.progress,this.active); + }, + poll: function (url, interval, ajaxOptions){ + // Extend the passed ajax options and success callback with our own. + ajaxOptions = ajaxOptions || {}; + var success = ajaxOptions.onSuccess || Prototype.emptyFunction; + ajaxOptions.onSuccess = success.wrap(function (callOriginal, request) { + this.setProgress(parseInt(request.responseText, 10)); + if(!this.active) { this.poller.stop(); } + callOriginal(request); + }).bind(this); + + this.active = true; + this.poller = new PeriodicalExecuter(function(){ + var a = new Ajax.Request(url, ajaxOptions); + }.bind(this),interval || 3); + }, + start: function(){ + this.active = true; + this.container.removeClassName(this.options.classNames.inactive); + this.container.addClassName(this.options.classNames.active); + this.executer = new PeriodicalExecuter(this.step.bind(this,this.options.step),this.options.interval); + }, + stop: function(reset){ + this.active = false; + if(this.executer) { + this.executer.stop(); } + this.container.removeClassName(this.options.classNames.active); + this.container.addClassName(this.options.classNames.inactive); + if (typeof reset === 'undefined' || reset === true) { + this.reset(); } + }, + step: function(amount){ + this.active = true; + this.setProgress(Math.min(100,this.progress + amount)); + }, + reset: function(){ + this.active = false; + this.setProgress(0); + }, + draw: function(){ + this.progressContainer.setStyle({ + width: (this.containerWidth - Math.floor((parseInt(this.progress, 10) / 100) * this.containerWidth)) + 'px' + }); + }, + notify: function(event_name){ + if(this.options[event_name]) { + return [this.options[event_name].apply(this.options[event_name],$A(arguments).slice(1))]; } + } +}); +Event.extend(Control.ProgressBar); \ No newline at end of file diff --git a/assets/stylesheets/reporting.css b/assets/stylesheets/reporting.css index 99c62ebc31..47e3f9f4f8 100644 --- a/assets/stylesheets/reporting.css +++ b/assets/stylesheets/reporting.css @@ -480,6 +480,20 @@ div.button_form p * { background-color: #ededed; } +#progressbar_container { + height: 16px; + border: 1px solid #ccc; + padding: 0; + margin: 0; + position: relative; + background-color: #9A9A9A; + background-repeat: repeat-x; +} + +#progressbar_container div { + background-color:#fff; +} + /***** Ajax indicator ******/ #ajax-indicator { font-family: Verdana, sans-serif; diff --git a/lib/widget/table/progressbar.rb b/lib/widget/table/progressbar.rb index b5679beb1c..9ecfe3c575 100644 --- a/lib/widget/table/progressbar.rb +++ b/lib/widget/table/progressbar.rb @@ -20,6 +20,7 @@ class Widget::Table::Progressbar < Widget::Base :id => "progressbar-yes", :'data-load' => 'true', :class => "form_controls", + :'data-size' => size, :'data-target' => url_for(:action => 'index', :set_filter => '1', :immediately => true) do content_tag :em do ::I18n.t(:label_yes)