| Sync research changes - warvox - VoIP based wardialing tool, forked from rapid7… | |
| Log | |
| Files | |
| Refs | |
| README | |
| --- | |
| commit 3e3fbfb5bd9f1295c66868ae3a94b3d41040a98d | |
| parent 93b2de6b613e819c4123fa15eccf878a5adb4949 | |
| Author: HD Moore <[email protected]> | |
| Date: Sun, 13 Jan 2013 11:12:14 -0600 | |
| Sync research changes | |
| Diffstat: | |
| M app/assets/stylesheets/bootstrap_a… | 93 +++++++++++++++++++++++++++… | |
| M app/controllers/application_contro… | 2 +- | |
| M app/controllers/jobs_controller.rb | 2 +- | |
| M app/controllers/projects_controlle… | 196 +++++++++++++++++++--------… | |
| M app/helpers/application_helper.rb | 4 ++++ | |
| M app/models/call.rb | 31 +++++++++++++++++++++++------… | |
| M app/models/job.rb | 20 +++++++++++++++++--- | |
| M app/views/jobs/index.html.erb | 14 +++++++++----- | |
| M app/views/jobs/results.html.erb | 6 +++--- | |
| M app/views/layouts/application.html… | 2 +- | |
| M app/views/projects/index.html.erb | 4 ++-- | |
| M app/views/projects/show.html.erb | 240 +++++++++++++++++++++++++----… | |
| M app/views/shared/graphs/_sparkline… | 4 ++-- | |
| M db/migrate/20121228171549_initial_… | 2 +- | |
| M db/schema.rb | 2 +- | |
| 15 files changed, 467 insertions(+), 155 deletions(-) | |
| --- | |
| diff --git a/app/assets/stylesheets/bootstrap_and_overrides.css.less b/app/asse… | |
| @@ -86,8 +86,13 @@ | |
| .sparkline { | |
| - width: 100px; | |
| - height: 20px; | |
| + width: 100%; | |
| + height: 30px; | |
| +} | |
| + | |
| +.sparkline-title { | |
| + text-align: center; | |
| + font-size: 11px; | |
| } | |
| .call-detail { | |
| @@ -99,17 +104,89 @@ | |
| border-bottom: 1px solid #eeeeee; | |
| } | |
| +.zoom { | |
| + background-color: @orange; | |
| + height: 40px; | |
| +} | |
| + | |
| + | |
| .stat-box { | |
| padding: 10px; | |
| - | |
| - background-color: #eeeeee; | |
| - border: 1px solid #bbbbbb; | |
| - font-size: 18px; | |
| + background-color: white; | |
| + border: 2px solid @darkGray; | |
| + font-size: 16px; | |
| font-weight: bold; | |
| color: @darkGray; | |
| - width: 65px; | |
| + width: 55px; | |
| margin: auto auto; | |
| text-align: center; | |
| + | |
| + border-top-left-radius: 20px; | |
| + border-top-right-radius: 20px; | |
| + border-bottom-right-radius: 20px; | |
| + border-bottom-left-radius: 20px; | |
| +} | |
| + | |
| +.stat-modem { | |
| + background-color: white; | |
| + border: 2px solid @red; | |
| + color: @red; | |
| +} | |
| + | |
| + | |
| +.stat-nodata { | |
| + background-color: #f4f4f4; | |
| + border: 2px solid @darkGray; | |
| + color: @darkGray; | |
| + font-size: 24px; | |
| +} | |
| + | |
| +.stat-completed { | |
| + background-color: white; | |
| + border: 2px solid @orange; | |
| + color: @darkGray; | |
| +} | |
| + | |
| +.stat-voice { | |
| + background-color: white; | |
| + border: 2px solid @green; | |
| + color: @darkGray; | |
| +} | |
| + | |
| +.stat-voicemail { | |
| + background-color: white; | |
| + border: 2px solid @blue; | |
| + color: @darkGray; | |
| +} | |
| + | |
| +.stat-fax { | |
| + background-color: white; | |
| + border: 2px solid @darkGray; | |
| + color: @darkGray; | |
| +} | |
| + | |
| +.stat-modem { | |
| + background-color: white; | |
| + border: 2px solid @red; | |
| + color: @darkGray; | |
| +} | |
| + | |
| + | |
| +.arrow-down { | |
| + font-size: 18px; | |
| + text-align: center; | |
| + margin: auto auto; | |
| + padding-top: 10px; | |
| + padding-bottom: 10px; | |
| + color: @darkOrange; | |
| +} | |
| + | |
| +.arrow-right { | |
| + font-size: 22px; | |
| + text-align: center; | |
| + margin: auto auto; | |
| + padding-top: 10px; | |
| + padding-bottom: 10px; | |
| } | |
| .stat-subtitle { | |
| @@ -170,7 +247,7 @@ | |
| } | |
| .progress_pct { | |
| - color: @red; | |
| + color: @darkGray; | |
| margin-left: 10px; | |
| font-weight: bold; | |
| } | |
| diff --git a/app/controllers/application_controller.rb b/app/controllers/applic… | |
| @@ -6,7 +6,7 @@ class ApplicationController < ActionController::Base | |
| before_filter :require_user, :load_project | |
| add_breadcrumb :projects, :root_path | |
| - | |
| + include ActionView::Helpers::NumberHelper | |
| private | |
| diff --git a/app/controllers/jobs_controller.rb b/app/controllers/jobs_controll… | |
| @@ -7,7 +7,7 @@ class JobsController < ApplicationController | |
| @submitted_jobs = Job.where(:status => ['submitted', 'schedule… | |
| @active_jobs = Job.where(:status => 'running', :completed_a… | |
| - @inactive_jobs = Job.where('status NOT IN (?) OR completed_at… | |
| + @inactive_jobs = Job.where('status NOT IN (?)', ['submitted',… | |
| :page => params[:page], | |
| :order => 'id DESC', | |
| :per_page => 30 | |
| diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_… | |
| @@ -1,7 +1,7 @@ | |
| class ProjectsController < ApplicationController | |
| def index | |
| - @projects = Project.paginate( | |
| + @projects = Project.paginate( | |
| :page => params[:page], | |
| :order => 'id DESC', | |
| :per_page => 10 | |
| @@ -10,83 +10,129 @@ class ProjectsController < ApplicationController | |
| @new_project = Project.new | |
| respond_to do |format| | |
| - format.html # index.html.erb | |
| - format.xml { render :xml => @projects } | |
| + format.html | |
| + format.xml { render :xml => @projects } | |
| end | |
| end | |
| - # GET /projects/1 | |
| - # GET /projects/1.xml | |
| - def show | |
| - @project = Project.find(params[:id]) | |
| - respond_to do |format| | |
| - format.html # show.html.erb | |
| - format.xml { render :xml => @project } | |
| - end | |
| - | |
| - end | |
| - | |
| - # GET /projects/new | |
| - # GET /projects/new.xml | |
| - def new | |
| - @new_project = Project.new | |
| - respond_to do |format| | |
| - format.html # new.html.erb | |
| - format.xml { render :xml => @new_project } | |
| - end | |
| - end | |
| - | |
| - # GET /projects/1/edit | |
| - def edit | |
| - @project = Project.find(params[:id]) | |
| - end | |
| - | |
| - # POST /projects | |
| - # POST /projects.xml | |
| - def create | |
| - @new_project = Project.new(params[:project]) | |
| - @new_project.created_by = current_user.login | |
| - | |
| - respond_to do |format| | |
| - if @new_project.save | |
| - flash[:notice] = 'Project was successfully created.' | |
| - format.html { redirect_to(project_path(@new_project)) } | |
| - format.xml { render :xml => @project, :status => :created, :location … | |
| - else | |
| - format.html { render :action => "new" } | |
| - format.xml { render :xml => @new_project.errors, :status => :unproces… | |
| - end | |
| - end | |
| - end | |
| - | |
| - # PUT /projects/1 | |
| - # PUT /projects/1.xml | |
| - def update | |
| - @project = Project.find(params[:id]) | |
| - | |
| - respond_to do |format| | |
| - if @project.update_attributes(params[:project]) | |
| - flash[:notice] = 'Project was successfully updated.' | |
| - format.html { redirect_to projects_path } | |
| - format.xml { head :ok } | |
| - else | |
| - format.html { render :action => "edit" } | |
| - format.xml { render :xml => @project.errors, :status => :unprocessabl… | |
| - end | |
| - end | |
| - end | |
| - | |
| - # DELETE /projects/1 | |
| - # DELETE /projects/1.xml | |
| - def destroy | |
| - @project = Project.find(params[:id]) | |
| - @project.destroy | |
| - | |
| - respond_to do |format| | |
| - format.html { redirect_to(projects_url) } | |
| - format.xml { head :ok } | |
| - end | |
| - end | |
| + def show | |
| + @project = Project.find(params[:id]) | |
| + @active_jobs = @project.jobs.where(:status => 'running', :comp… | |
| + @inactive_jobs = @project.jobs.where('status NOT IN (?)… | |
| + :page => params[:page], | |
| + :order => 'id DESC', | |
| + :per_page => 30 | |
| + ) | |
| + | |
| + @boxes = { | |
| + :called => { :cnt => @project.calls.count }, | |
| + :answered => { :cnt => @project.calls.where(:answered… | |
| + :analyzed => { :cnt => @project.calls.where('analysis… | |
| + :voice => { :cnt => @project.lines.where(:line_typ… | |
| + :voicemail => { :cnt => @project.lines.where(:line_typ… | |
| + :fax => { :cnt => @project.lines.where(:line_typ… | |
| + :modem => { :cnt => @project.lines.where(:line_typ… | |
| + } | |
| + | |
| + if @boxes[:called][:cnt] == 0 | |
| + @boxes[:called][:txt] = '0' | |
| + @boxes[:called][:cls] = 'nodata' | |
| + | |
| + # No calls, so everything else is unknown | |
| + [ :answered, :analyzed, :voice, :voicemail, :fax, :mod… | |
| + @boxes[t][:txt] = '?' | |
| + @boxes[t][:cls] = 'nodata' | |
| + end | |
| + | |
| + else | |
| + | |
| + [ :called, :answered, :analyzed].each do |t| | |
| + @boxes[t][:txt] = number_with_delimiter(@boxes… | |
| + @boxes[t][:cls] = 'completed' | |
| + end | |
| + | |
| + if @boxes[:answered][:cnt] == 0 | |
| + @boxes[:answered][:txt] = '0' | |
| + @boxes[:answered][:cls] = 'nodata' | |
| + end | |
| + | |
| + if @boxes[:analyzed][:cnt] == 0 | |
| + [ :voice, :voicemail, :fax, :modem ].each do |… | |
| + @boxes[t][:txt] = '?' | |
| + @boxes[t][:cls] = 'nodata' | |
| + end | |
| + @boxes[:analyzed][:cls] = 'nodata' | |
| + else | |
| + | |
| + @boxes[:voice][:txt] = number_with_delimiter(@… | |
| + @boxes[:voice][:cls] = 'voice' | |
| + | |
| + @boxes[:voicemail][:txt] = number_with_delimit… | |
| + @boxes[:voicemail][:cls] = 'voicemail' | |
| + | |
| + @boxes[:fax][:txt] = number_with_delimiter(@bo… | |
| + @boxes[:fax][:cls] = 'fax' | |
| + | |
| + @boxes[:modem][:txt] = number_with_delimiter(@… | |
| + @boxes[:modem][:cls] = 'modem' | |
| + end | |
| + end | |
| + | |
| + respond_to do |format| | |
| + format.html | |
| + format.xml { render :xml => @project } | |
| + end | |
| + end | |
| + | |
| + def new | |
| + @new_project = Project.new | |
| + respond_to do |format| | |
| + format.html | |
| + format.xml { render :xml => @new_project } | |
| + end | |
| + end | |
| + | |
| + | |
| + def edit | |
| + @project = Project.find(params[:id]) | |
| + end | |
| + | |
| + def create | |
| + @new_project = Project.new(params[:project]) | |
| + @new_project.created_by = current_user.login | |
| + | |
| + respond_to do |format| | |
| + if @new_project.save | |
| + format.html { redirect_to(project_path(@new_pr… | |
| + format.xml { render :xml => @project, :… | |
| + else | |
| + format.html { render :action => "new" } | |
| + format.xml { render :xml => @new_projec… | |
| + end | |
| + end | |
| + end | |
| + | |
| + def update | |
| + @project = Project.find(params[:id]) | |
| + | |
| + respond_to do |format| | |
| + if @project.update_attributes(params[:project]) | |
| + format.html { redirect_to projects_path } | |
| + format.xml { head :ok } | |
| + else | |
| + format.html { render :action => "edit" } | |
| + format.xml { render :xml => @project.er… | |
| + end | |
| + end | |
| + end | |
| + def destroy | |
| + @project = Project.find(params[:id]) | |
| + @project.destroy | |
| + respond_to do |format| | |
| + format.html { redirect_to(projects_url) } | |
| + format.xml { head :ok } | |
| + end | |
| + end | |
| end | |
| diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper… | |
| @@ -67,6 +67,10 @@ module ApplicationHelper | |
| end | |
| end | |
| + def format_job_rate(job) | |
| + pluralize(job.rate.to_i, "call") + "/s" | |
| + end | |
| + | |
| # | |
| # Includes any javascripts specific to this view. The hosts/show view | |
| # will automatically include any javascripts at public/javascripts/hos… | |
| diff --git a/app/models/call.rb b/app/models/call.rb | |
| @@ -1,14 +1,14 @@ | |
| class Call < ActiveRecord::Base | |
| - reportable :hourly, :aggregation => :count, :grouping => :hour, :live_… | |
| - reportable :daily, :aggregation => :count, :grouping => :day, :live_da… | |
| - reportable :weekly, :aggregation => :count, :grouping => :week, :live_… | |
| - reportable :monthly, :aggregation => :count, :grouping => :month, :liv… | |
| + reportable :hourly, :aggregation => :count, :grouping => :hour, :live_… | |
| + reportable :daily, :aggregation => :count, :grouping => :day, :live_da… | |
| + reportable :weekly, :aggregation => :count, :grouping => :week, :live_… | |
| + reportable :monthly, :aggregation => :count, :grouping => :month, :liv… | |
| - reportable :analyzed_hourly, :aggregation => :count, :grouping => :hou… | |
| - reportable :analyzed_daily, :aggregation => :count, :grouping => :day,… | |
| - reportable :analyzed_weekly, :aggregation => :count, :grouping => :wee… | |
| - reportable :analyzed_monthly, :aggregation => :count, :grouping => :mo… | |
| + reportable :analyzed_hourly, :aggregation => :count, :grouping => :hou… | |
| + reportable :analyzed_daily, :aggregation => :count, :grouping => :day,… | |
| + reportable :analyzed_weekly, :aggregation => :count, :grouping => :wee… | |
| + reportable :analyzed_monthly, :aggregation => :count, :grouping => :mo… | |
| belongs_to :project | |
| belongs_to :provider | |
| @@ -37,6 +37,8 @@ class Call < ActiveRecord::Base | |
| } | |
| + after_save :update_linked_line | |
| + | |
| def paginate_matches(scope, min_match, page, per_page) | |
| scope_limit = "" | |
| @@ -68,4 +70,17 @@ class Call < ActiveRecord::Base | |
| CallMedium.columns_hash.keys.reject{|x| x =~ /^id|_id$/} | |
| end | |
| + def linked_line | |
| + Line.find_or_create_by_number_and_project_id(self[:number], se… | |
| + end | |
| + | |
| + def update_linked_line | |
| + line = linked_line | |
| + | |
| + if self[:line_type] | |
| + line.line_type = self[:line_type] | |
| + line.save | |
| + end | |
| + end | |
| + | |
| end | |
| diff --git a/app/models/job.rb b/app/models/job.rb | |
| @@ -47,7 +47,6 @@ class Job < ActiveRecord::Base | |
| end | |
| end | |
| - | |
| # XXX: Purging a single job will be slow, but deleting the project is … | |
| has_many :calls, :dependent => :destroy | |
| @@ -105,9 +104,8 @@ class Job < ActiveRecord::Base | |
| :seconds => self.seconds.to_i, | |
| :cid_mask => self.cid_mask | |
| }) | |
| - $stderr.puts self.inspect | |
| - | |
| return self.save | |
| + | |
| when 'analysis' | |
| self.status = 'submitted' | |
| self.args = Marshal.dump({ | |
| @@ -122,4 +120,20 @@ class Job < ActiveRecord::Base | |
| end | |
| end | |
| + def rate | |
| + tend = (self.completed_at || Time.now) | |
| + tlen = tend.to_f - self.started_at.to_f | |
| + | |
| + case self.task | |
| + when 'dialer' | |
| + Call.where('job_id = ?', self.id).count() / tlen | |
| + when 'analysis' | |
| + Call.where('job_id = ? AND analysis_completed_at > ? A… | |
| + when 'import' | |
| + Call.where('job_id = ?', self.id).count() / tlen | |
| + else | |
| + 0 | |
| + end | |
| + end | |
| + | |
| end | |
| diff --git a/app/views/jobs/index.html.erb b/app/views/jobs/index.html.erb | |
| @@ -17,7 +17,7 @@ | |
| <td><%= job.id %></td> | |
| <td><%= format_job_details(job) %></td> | |
| <td><%= format_job_status(job) %></td> | |
| - <td><%= job.created_at.localtime.strftime("%Y-%m-%d %H:%M:%S %Z") %></td> | |
| + <td><%= time_ago_in_words(job.created_at) %> ago</td> | |
| <td> | |
| <a class="btn" href="<%= job_path(job) %>" data-confirm="Remov… | |
| @@ -38,6 +38,7 @@ | |
| <th>ID</th> | |
| <th>Task</th> | |
| <th>Progress</th> | |
| + <th>Rate</th> | |
| <th>Launched</th> | |
| <th>Actions</th> | |
| <th>Project</th> | |
| @@ -48,13 +49,14 @@ | |
| <td><%= job.id %></td> | |
| <td><%= format_job_details(job) %></td> | |
| <td> | |
| - <div class="progress progress-success progress-striped progres… | |
| + <div class="progress progress-warning progress-striped progres… | |
| <div class="bar" style="width: <%= job.progress %>%"> | |
| <span class='progress_pct'><%= job.progress %>… | |
| </div> | |
| </div> | |
| </td> | |
| - <td><%= job.created_at.localtime.strftime("%Y-%m-%d %H:%M:%S %Z") %></td> | |
| + <td><%= format_job_rate(job) %></td> | |
| + <td><%= time_ago_in_words(job.created_at) %> ago</td> | |
| <td> | |
| <% if job.task == "dialer" %> | |
| <a class="btn" href="<%= view_results_path(job.project,job… | |
| @@ -88,6 +90,7 @@ | |
| <th>ID</th> | |
| <th>Task</th> | |
| <th>Status</th> | |
| + <th>Rate</th> | |
| <th>Created</th> | |
| <th>Completed</th> | |
| <th>Project</th> | |
| @@ -106,8 +109,9 @@ | |
| <td><%= job.id %></td> | |
| <td><%= format_job_details(job) %></td> | |
| <td><%= format_job_status(job) %></td> | |
| - <td><%= job.created_at.localtime.strftime("%Y-%m-%d %H:%M:%S %Z") %></td> | |
| - <td><%= job.completed_at ? job.completed_at.localtime.strftime("%Y-%m-%d %… | |
| + <td><%= format_job_rate(job) %></td> | |
| + <td><%= time_ago_in_words(job.created_at) %> ago</td> | |
| + <td><%= job.completed_at ? "after " + time_ago_in_words(Time.at(Time.now.t… | |
| <td><%= link_to( h(truncate(job.project.name, :length => 25)), project_pat… | |
| </tr> | |
| <% end %> | |
| diff --git a/app/views/jobs/results.html.erb b/app/views/jobs/results.html.erb | |
| @@ -49,7 +49,7 @@ | |
| <td><span rel="tooltip" class="xtooltip" title="<%= pct_analyzed %>% analy… | |
| - <td><%= job.created_at.strftime("%Y-%m-%d %H:%M:%S") %></td> | |
| + <td><%= time_ago_in_words(job.created_at) %> ago</td> | |
| <td><%= job.created_by %></td> | |
| <td> | |
| <a class="btn" href="<%= view_results_path(@project,job) %>" rel="tool… | |
| @@ -59,11 +59,11 @@ | |
| <% if pct_analyzed == 100 %> | |
| <a class="btn" href="<%= reanalyze_job_path(@p… | |
| <% else %> | |
| - <a class="btn" href="<%= analyze_job_path(@pro… | |
| + <a class="btn" href="<%= analyze_job_path(@pro… | |
| <% end %> | |
| <% else %> | |
| <% if cnt_answered > 0 %> | |
| - <a class="btn" href="<%= analyze_job_path(@project,job… | |
| + <a class="btn" href="<%= analyze_job_path(@project,job… | |
| <% end %> | |
| <% end %> | |
| diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/applica… | |
| @@ -77,7 +77,7 @@ | |
| <%= menu_item raw('<i class="icon-info… | |
| <% end %> | |
| - <%= menu_item raw('<div class="help-icon"><i c… | |
| + <%= menu_item raw('<div class="help-icon"><i c… | |
| <%= menu_item raw('<div class="help-icon"><i c… | |
| <% end %> | |
| diff --git a/app/views/projects/index.html.erb b/app/views/projects/index.html.… | |
| @@ -10,7 +10,7 @@ | |
| <th>Jobs</th> | |
| <th>Calls</th> | |
| <th>Analyzed</th> | |
| - <th>Date</th> | |
| + <th>Created</th> | |
| <th>Actions</th> | |
| </tr> | |
| </thead> | |
| @@ -23,7 +23,7 @@ | |
| <td><%= number_with_delimiter(project.jobs.count) %></td> | |
| <td><%= number_with_delimiter(project.calls.count) %></td> | |
| <td><%= number_with_delimiter(project.calls.where('analysis_completed_at I… | |
| - <td><%= project.updated_at.localtime.strftime("%Y-%m-%d %H:%M:%S") %></td> | |
| + <td><%= time_ago_in_words(project.created_at) %> ago</td> | |
| <td> | |
| <a class="btn" href="<%= edit_project_path(project) %>"rel="tool… | |
| <a class="btn" href="<%= project_path(project) %>" data-confirm="D… | |
| diff --git a/app/views/projects/show.html.erb b/app/views/projects/show.html.erb | |
| @@ -1,6 +1,3 @@ | |
| - | |
| - | |
| - | |
| <div class="row-fluid"> | |
| <div class="span12"> | |
| <a class="btn btn-small pull-right" href="<%= edit_project_pat… | |
| @@ -9,72 +6,227 @@ | |
| </div> | |
| </div> | |
| - | |
| <div class="row-fluid"> | |
| - <div class="span2"> | |
| - <div class="stat-box"> | |
| - <div><%= number_with_delimiter( @project.calls.count )… | |
| + <div class="span3"> | |
| + <div class="stat-box stat-<%= @boxes[:called][:cls]%>"> | |
| + <div><%= @boxes[:called][:txt] %></div> | |
| <span class="stat-subtitle">Calls</span> | |
| </div> | |
| </div> | |
| - <div class="span2"> | |
| - <div class="stat-box"> | |
| - <div><%= number_with_delimiter( @project.calls.where(:… | |
| - <span class="stat-subtitle">Answered</span> | |
| - </div> | |
| - </div> | |
| - <div class="span2"> | |
| - <div class="stat-box"> | |
| - <div><%= number_with_delimiter( @project.calls.where('… | |
| - <span class="stat-subtitle">Analyzed</span> | |
| + <div class="span9"> | |
| + <div class="row-fluid"> | |
| + <div class="span2"> </div> | |
| + <div class="span2"><a href="<%= new_dialer_job_path %>… | |
| + <% if @boxes[:answered][:cnt] > 0 %> | |
| + <div class="span2"><a href="#" class="btn" rel="toolti… | |
| + <div class="span2"><a href="#" class="btn" rel="toolti… | |
| + <div class="span2"><a href="#" class="btn" rel="toolti… | |
| + <% else %> | |
| + <div class="span2"><a href="#" class="btn disabled" re… | |
| + <div class="span2"><a href="#" class="btn" rel="toolti… | |
| + <div class="span2"><a href="#" class="btn disabled" re… | |
| + <% end %> | |
| + <div class="span2"> </div> | |
| </div> | |
| </div> | |
| +</div> | |
| - <div class="span2"> | |
| - <div class="stat-box"> | |
| - <div><%= number_with_delimiter( @project.calls.where(:… | |
| - <span class="stat-subtitle">Voice</span> | |
| - </div> | |
| - </div> | |
| - <div class="span2"> | |
| - <div class="stat-box"> | |
| - <div><%= number_with_delimiter( @project.calls.where(:… | |
| - <span class="stat-subtitle">Fax</span> | |
| +<div class="row-fluid"> | |
| + <div class="span3 arrow-down"><i class="icon-arrow-down"></i></div> | |
| + <div class="span9"> </div> | |
| +</div> | |
| + | |
| +<div class="row-fluid"> | |
| + <div class="span3"> | |
| + <div class="stat-box stat-<%= @boxes[:answered][:cls]%>"> | |
| + <div><%= @boxes[:answered][:txt] %></div> | |
| + <span class="stat-subtitle">Answered</span> | |
| </div> | |
| </div> | |
| - <div class="span2"> | |
| - <div class="stat-box"> | |
| - <div><%= number_with_delimiter( @project.calls.where(:… | |
| - <span class="stat-subtitle">Modem</span> | |
| + <div class="span9"></div> | |
| +</div> | |
| + | |
| +<div class="row-fluid"> | |
| + <div class="span3 arrow-down"><i class="icon-arrow-down"></i></div> | |
| + <div class="span9"> </div> | |
| +</div> | |
| + | |
| +<div class="row-fluid"> | |
| + <div class="span3"> | |
| + <div class="stat-box stat-<%= @boxes[:analyzed][:cls]%>"> | |
| + <div><%= @boxes[:analyzed][:txt] %></div> | |
| + <span class="stat-subtitle">Analyzed</span> | |
| </div> | |
| </div> | |
| + <div class="span9"> </div> | |
| </div> | |
| - | |
| +<div class="row-fluid"> | |
| + <div class="span3 arrow-down"><i class="icon-arrow-down"></i></div> | |
| + <div class="span9"> </div> | |
| +</div> | |
| <div class="row-fluid"> | |
| - <div class="span2"> | |
| + <div class="span3"> | |
| + <div class="row-fluid"> | |
| + <div class="span6"> | |
| + <div class="stat-box stat-<%= @boxes[:voice][:… | |
| + <div><%= @boxes[:voice][:txt] %></div> | |
| + <span class="stat-subtitle">Voice</spa… | |
| + </div> | |
| + </div> | |
| + <div class="span6"> | |
| + <div class="stat-box stat-<%= @boxes[:voicemai… | |
| + <div><%= @boxes[:voicemail][:txt] %></… | |
| + <span class="stat-subtitle">VoiceMail<… | |
| + </div> | |
| + </div> | |
| + </div> | |
| + </div> | |
| + <div class="span3 sparkline-cell"> | |
| <%= render :partial => 'shared/graphs/sparkline', :locals => {… | |
| - Calls/Hour | |
| + <span class='sparkline-title'>Phone Calls / Hour (Last Day)</a> | |
| </div> | |
| - <div class="span2"> | |
| + <div class="span3 sparkline-cell"> | |
| <%= render :partial => 'shared/graphs/sparkline', :locals => {… | |
| - Calls/Day | |
| + <span class='sparkline-title'>Phone Calls / Day (Last Week)</a> | |
| </div> | |
| - <div class="span2"> | |
| + <div class="span3 sparkline-cell"> | |
| <%= render :partial => 'shared/graphs/sparkline', :locals => {… | |
| - Calls/Week | |
| + <span class='sparkline-title'>Phone Calls / Week (Last Month)<… | |
| + </div> | |
| +</div> | |
| + | |
| +<div class="row-fluid"> | |
| + <div class="span12"> </div> | |
| +</div> | |
| + | |
| +<div class="row-fluid"> | |
| + <div class="span3"> | |
| + <div class="row-fluid"> | |
| + <div class="span6"> | |
| + <div class="stat-box stat-<%= @boxes[:fax][:cl… | |
| + <div><%= @boxes[:fax][:txt] %></div> | |
| + <span class="stat-subtitle">Fax</span> | |
| + </div> | |
| + </div> | |
| + <div class="span6"> | |
| + <div class="stat-box stat-<%= @boxes[:modem][:… | |
| + <div><%= @boxes[:modem][:txt] %></div> | |
| + <span class="stat-subtitle">Modems</sp… | |
| + </div> | |
| + </div> | |
| + </div> | |
| </div> | |
| - <div class="span2"> | |
| + <div class="span3 sparkline-cell"> | |
| <%= render :partial => 'shared/graphs/sparkline', :locals => {… | |
| - Analysis/Hour | |
| + <span class='sparkline-title'>Analyzed Calls / Hour (Last Day)… | |
| </div> | |
| - <div class="span2"> | |
| + <div class="span3 sparkline-cell"> | |
| <%= render :partial => 'shared/graphs/sparkline', :locals => {… | |
| - Analysis/Day | |
| + <span class='sparkline-title'>Analyzed Calls / Day (Last Week)… | |
| </div> | |
| - <div class="span2"> | |
| + <div class="span3 sparkline-cell"> | |
| <%= render :partial => 'shared/graphs/sparkline', :locals => {… | |
| - Analysis/Week | |
| + <span class='sparkline-title'>Analyzed Calls / Week (Last Mont… | |
| + </div> | |
| + <div class="span6"> </div> | |
| +</div> | |
| + | |
| +<div class="row-fluid"> | |
| + <div class="span12"> </div> | |
| +</div> | |
| + | |
| +<div class="row-fluid"> | |
| + <div class="span12"> | |
| + <p class='project-header'><%= @project.description %></p> | |
| + </div> | |
| +</div> | |
| + | |
| +<% if @active_jobs.count > 0 %> | |
| + | |
| +<div class="row-fluid"> | |
| + <div class="span12"> | |
| + | |
| + <h2 class='title'>Active Jobs</h1> | |
| + | |
| + <table class='table table-striped table-condensed' width='90%'> | |
| + <tr> | |
| + <th>ID</th> | |
| + <th>Task</th> | |
| + <th>Progress</th> | |
| + <th>Rate</th> | |
| + <th>Launched</th> | |
| + <th>Actions</th> | |
| + </tr> | |
| + | |
| +<% @active_jobs.each do |job| %> | |
| + <tr class='active_job_row'> | |
| + <td><%= job.id %></td> | |
| + <td><%= format_job_details(job) %></td> | |
| + <td> | |
| + <div class="progress progress-warning progress-striped… | |
| + <div class="bar" style="width: <%= job.progres… | |
| + <span class='progress_pct'><%= job.pro… | |
| + </div> | |
| + </div> | |
| + </td> | |
| + <td><%= format_job_rate(job) %></td> | |
| + <td><%= time_ago_in_words(job.created_at) %> ago</td> | |
| + <td> | |
| + <% if job.task == "dialer" %> | |
| + <a class="btn" href="<%= view_results_path(job.pro… | |
| + <% end %> | |
| + <% if job.task == "analysis" and job.details[:scope].to_s … | |
| + <a class="btn" href="<%= view_analyze_path(job.pro… | |
| + <% end %> | |
| + <a class="btn" href="<%= stop_job_path(job) %>" data-c… | |
| + </td> | |
| + </tr> | |
| +<% end %> | |
| + </table> | |
| + </div> | |
| +</div> | |
| +<% end %> | |
| + | |
| + | |
| +<% if(@inactive_jobs.length > 0) %> | |
| + | |
| +<div class="row-fluid"> | |
| + <div class="span12"> | |
| + <h2 class='title'>Completed Jobs</h2> | |
| + | |
| + <%= will_paginate @inactive_jobs, :renderer => BootstrapPagination::Ra… | |
| + <table class='table table-striped table-condensed' width='90%'> | |
| + <tr> | |
| + <th>ID</th> | |
| + <th>Task</th> | |
| + <th>Status</th> | |
| + <th>Rate</th> | |
| + <th>Started</th> | |
| + <th>Completed</th> | |
| + </tr> | |
| + | |
| + <% @inactive_jobs.each do |job| | |
| + special = "" | |
| + case job.status | |
| + when "error" | |
| + special = "error" | |
| + when "stopped" | |
| + special = "warning" | |
| + end | |
| + %> | |
| + <tr class='<%= special %>'> | |
| + <td><%= job.id %></td> | |
| + <td><%= format_job_details(job) %></td> | |
| + <td><%= format_job_status(job) %></td> | |
| + <td><%= format_job_rate(job) %></td> | |
| + <td><%= time_ago_in_words(job.created_at) %> ago</td> | |
| + <td><%= job.completed_at ? "after " + time_ago_in_words(Time.at(Ti… | |
| + </tr> | |
| + <% end %> | |
| + </table> | |
| + <%= will_paginate @inactive_jobs, :renderer => BootstrapPagination::Ra… | |
| </div> | |
| </div> | |
| +<% end %> | |
| diff --git a/app/views/shared/graphs/_sparkline.html.erb b/app/views/shared/gra… | |
| @@ -57,8 +57,8 @@ | |
| } | |
| }, | |
| series: [{ | |
| - color:'#666', | |
| - fillColor:'rgba(204,204,204,.25)', | |
| + color:'#BB4607', | |
| + fillColor:'#fcfcfc', | |
| data: [ <%= raw(points.join(", ")) %> ] | |
| }] | |
| }); | |
| diff --git a/db/migrate/20121228171549_initial_schema.rb b/db/migrate/201212281… | |
| @@ -65,7 +65,7 @@ class InitialSchema < ActiveRecord::Migration | |
| t.timestamps | |
| t.text "number", :null => false | |
| t.integer "project_id", :null => false | |
| - t.text "type" | |
| + t.text "line_type" | |
| t.text "notes" | |
| end | |
| diff --git a/db/schema.rb b/db/schema.rb | |
| @@ -92,7 +92,7 @@ ActiveRecord::Schema.define(:version => 20130113004653) do | |
| t.datetime "updated_at", :null => false | |
| t.text "number", :null => false | |
| t.integer "project_id", :null => false | |
| - t.text "type" | |
| + t.text "line_type" | |
| t.text "notes" | |
| end | |