Skip to content

Commit

Permalink
Introduce new Homepage that Summarizes Your Progress (+ new nav?) (#684)
Browse files Browse the repository at this point in the history
Brand new amazing awesome way better than before so needed and with a UX designed by an engineer ;-).
  • Loading branch information
epugh authored Aug 16, 2023
1 parent a9cdcaa commit 1be60d6
Show file tree
Hide file tree
Showing 36 changed files with 1,056 additions and 127 deletions.
4 changes: 3 additions & 1 deletion .rubocop.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
require: rubocop-rails
require:
- rubocop-rails
- rubocop-capybara


AllCops:
Expand Down
2 changes: 2 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,5 @@ group :test do
gem 'selenium-webdriver'
gem 'webdrivers'
end

gem 'prophet-rb', '~> 0.4.2'
9 changes: 9 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ GEM
regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2)
choice (0.2.0)
cmdstan (0.2.2)
colorize (0.8.1)
concurrent-ruby (1.2.2)
connection_pool (2.4.0)
Expand Down Expand Up @@ -231,6 +232,7 @@ GEM
racc (~> 1.4)
nokogiri (1.15.2-x86_64-linux)
racc (~> 1.4)
numo-narray (0.9.2.1)
oauth2 (2.0.9)
faraday (>= 0.17.3, < 3.0)
jwt (>= 1.0, < 3.0)
Expand Down Expand Up @@ -267,6 +269,10 @@ GEM
postmark-rails (0.22.1)
actionmailer (>= 3.0.0)
postmark (>= 1.21.3, < 2.0)
prophet-rb (0.4.2)
cmdstan (>= 0.2)
numo-narray (>= 0.9.1.7)
rover-df
public_suffix (5.0.1)
puma (6.3.0)
nio4r (~> 2.0)
Expand Down Expand Up @@ -335,6 +341,8 @@ GEM
actionpack (>= 5.2)
railties (>= 5.2)
rexml (3.2.5)
rover-df (0.3.4)
numo-narray (>= 0.9.1.9)
rubocop (1.54.1)
json (~> 2.3)
language_server-protocol (>= 3.17.0)
Expand Down Expand Up @@ -472,6 +480,7 @@ DEPENDENCIES
omniauth-keycloak
omniauth-rails_csrf_protection (~> 1.0)
postmark-rails
prophet-rb (~> 0.4.2)
puma
pundit
rack-cors (~> 2.0)
Expand Down
4 changes: 2 additions & 2 deletions app/assets/javascripts/controllers/mainCtrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ angular.module('QuepidApp')
// there's a lot of dependencies here, but this guy
// is responsible for bootstrapping everyone so...
.controller('MainCtrl', [
'$scope', '$routeParams', '$location', '$rootScope', '$log',
'$scope', '$routeParams', '$rootScope', '$log',
'flash',
'caseSvc', 'settingsSvc', 'querySnapshotSvc', 'caseTryNavSvc',
'queryViewSvc', 'queriesSvc', 'docCacheSvc', 'diffResultsSvc', 'scorerSvc',
'paneSvc',
function (
$scope, $routeParams, $location, $rootScope, $log,
$scope, $routeParams, $rootScope, $log,
flash,
caseSvc, settingsSvc, querySnapshotSvc, caseTryNavSvc,
queryViewSvc, queriesSvc, docCacheSvc, diffResultsSvc, scorerSvc,
Expand Down
8 changes: 0 additions & 8 deletions app/assets/javascripts/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@ angular.module('QuepidApp')
$locationProvider.html5Mode(true);

$routeProvider
.when('/', {
controller: 'BootstrapCtrl',
template: ''
})
.when('/case/:caseNo/try/:tryNo', {
templateUrl: 'views/queriesLayout.html',
controller: 'MainCtrl',
Expand All @@ -37,10 +33,6 @@ angular.module('QuepidApp')
controller: 'MainCtrl',
reloadOnSearch: false
})
.when('/case', {
templateUrl: 'views/cases/index.html',
controller: 'CasesCtrl'
})
.when('/cases', {
templateUrl: 'views/cases/index.html',
controller: 'CasesCtrl'
Expand Down
20 changes: 2 additions & 18 deletions app/assets/javascripts/services/caseTryNavSvc.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,18 @@
// What did I do here, like implement a router on top of my router!?!?
angular.module('QuepidApp')
.service('caseTryNavSvc', [
'$location', '$timeout', '$window',
function caseTryNavSvc($location, $timeout, $window) {
'$location', '$timeout',
function caseTryNavSvc($location, $timeout) {
var caseNo = 0;
var tryNo = 0;
var bootstrapPath = null;

var currNavDelay = 1000;
var isLoading = false;


this.pathRequested = function(caseTryObj) {
bootstrapPath = caseTryObj;
};

this.isLoading = function() {
return isLoading;
};


this.bootstrap = function() {
if (bootstrapPath) {
this.navigateTo(bootstrapPath);
bootstrapPath = null;
} else {
$window.location.reload();
}
};

this.navigateTo = function(caseTryObj, navDelay) {
if (navDelay === undefined) {
navDelay = 1000;
Expand Down
6 changes: 3 additions & 3 deletions app/assets/stylesheets/_admin2.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@
}

// push the Admin Panel down from the top a bit since it's got plenty of room
main > .container {
padding: 60px 15px 0;
}
//main > .container {
// padding: 60px 15px 0;
//}
18 changes: 18 additions & 0 deletions app/controllers/analytics/sparkline_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

require 'csv'
module Analytics
class SparklineController < ApplicationController
layout 'analytics'

def show
end

def vega_specification
end

def vega_data
@scores = Score.where(case_id: @current_user.cases.not_archived.select(:id)).includes([ :case ])
end
end
end
12 changes: 9 additions & 3 deletions app/controllers/core_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,17 @@

# This hosts the main Angular 1 application that runs in the client.
class CoreController < ApplicationController
before_action :set_case_or_bootstrap
before_action :populate_from_params
before_action :set_case_or_bootstrap, except: :new
before_action :populate_from_params, except: :new

def index
# return unless current_user
end

def new
@case = current_user.cases.build case_name: "Case #{current_user.cases.size}"
@case.save!

redirect_to case_core_path(@case, @case.tries.first.try_number, params: { showWizard: true })
end

private
Expand Down
68 changes: 68 additions & 0 deletions app/controllers/home_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
# frozen_string_literal: true

class HomeController < ApplicationController
# rubocop:disable Metrics/AbcSize
def show
# @cases = @current_user.cases.not_archived.includes([ :scores ])
@cases = @current_user.cases.not_archived

# copied from dropdown_contoller.rb
@most_recent_cases = lookup_most_recent_cases

@most_recent_books = []
@lookup_for_books = {}
@current_user.books_involved_with.order(:updated_at).each do |book|
@most_recent_books << book
judged_by_current_user = book.judgements.where(user: @current_user).count
if judged_by_current_user.positive? && judged_by_current_user < book.query_doc_pairs.count
@lookup_for_books[book] = book.query_doc_pairs.count - judged_by_current_user

end
break if 4 == @most_recent_books.count
end

candidate_cases = @cases.select { |kase| kase.scores.scored.count.positive? }
@grouped_cases = candidate_cases.group_by { |kase| kase.case_name.split(':').first }
@grouped_cases = @grouped_cases.select { |_key, value| value.count > 1 }
end
# rubocop:enable Metrics/AbcSize

private

# rubocop:disable Metrics/MethodLength
def lookup_most_recent_cases
# Using joins/includes will not return the proper list in the
# correct order because rails refuses to include the
# `case_metadata`.`last_viewed_at` column in the SELECT statement
# which will then cause the ordering not to work properly.
# So instead, we have this beauty!
sql = "
SELECT DISTINCT `cases`.`id`, `case_metadata`.`last_viewed_at`
FROM `cases`
LEFT OUTER JOIN `case_metadata` ON `case_metadata`.`case_id` = `cases`.`id`
LEFT OUTER JOIN `teams_cases` ON `teams_cases`.`case_id` = `cases`.`id`
LEFT OUTER JOIN `teams` ON `teams`.`id` = `teams_cases`.`team_id`
LEFT OUTER JOIN `teams_members` ON `teams_members`.`team_id` = `teams`.`id`
LEFT OUTER JOIN `users` ON `users`.`id` = `teams_members`.`member_id`
WHERE (`teams_members`.`member_id` = #{current_user.id} OR `cases`.`owner_id` = #{current_user.id})
AND (`cases`.`archived` = false OR `cases`.`archived` IS NULL)
ORDER BY `case_metadata`.`last_viewed_at` DESC, `cases`.`id` DESC
LIMIT 4
"

results = ActiveRecord::Base.connection.execute(sql)

case_ids = []
results.each do |row|
case_ids << row.first.to_i
end

# map to objects
most_recent_cases = Case.includes([ :scorer, :scores ]).where(id: [ case_ids ])
most_recent_cases = most_recent_cases.select { |kase| kase.last_score.present? }
# rubocop:enable
most_recent_cases = most_recent_cases.sort_by(&:case_name)
most_recent_cases
end
# rubocop:enable Metrics/MethodLength
end
3 changes: 0 additions & 3 deletions app/controllers/users/signups_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ def create
@user.assign_attributes(user_params_to_save)
else
@user = User.new user_params_to_save
# in this flow, we have a new user joining, so we create a empty case for them, which
# on the core_controller.rb triggers the bootstrap and the new case wizard.
@user.cases.build case_name: "Case #{@user.cases.size}"
end
end

Expand Down
18 changes: 8 additions & 10 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
# frozen_string_literal: true

module ApplicationHelper
def make_active? options
if options.key?(:path)
request.fullpath.include?(options[:path])
elsif options.key?(:controller)
controller_name == options[:controller]
end
end

def bootstrap_class_for flash_type
{
success: 'alert-success',
Expand Down Expand Up @@ -85,14 +93,4 @@ def document_fields_parses_as_json document_fields

document_fields
end

def document_fields_except_title document_fields
document_fields_json = JSON.parse(document_fields)
special_field_name = 'title'
if special_field_name in document_fields_json
document_fields_json.except(special_field_name)
else
document_fields_json
end
end
end
62 changes: 62 additions & 0 deletions app/helpers/home_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# frozen_string_literal: true

module HomeHelper
def greeting
greetings = [
'Good Day',
'Hello',
"How's your day",
"How's your day going",
'Good to see you',
'So good to see you',
'Hiya!',
'Bonjour',
'Hola!'
]
greetings.sample
end

# rubocop:disable Metrics/AbcSize
# rubocop:disable Metrics/MethodLength
def greeting2
current_time = DateTime.current.seconds_since_midnight
midnight = DateTime.now.beginning_of_day.seconds_since_midnight
noon = DateTime.now.middle_of_day.seconds_since_midnight
five_pm = DateTime.now.change(:hour => 17 ).seconds_since_midnight
eight_pm = DateTime.now.change(:hour => 20 ).seconds_since_midnight

puts "DateTime.current #{DateTime.current}"
puts "midnight: #{midnight}"
puts "noon: #{noon}"
puts "current_time: #{current_time}"

if midnight.upto(noon).include?(current_time)
greeting = 'Good Morning'
elsif noon.upto(five_pm).include?(current_time)
greeting = 'Good Afternoon'
elsif five_pm.upto(eight_pm).include?(current_time)
greeting = 'Good Evening'
elsif eight_pm.upto(midnight + 1.day).include?(current_time)
greeting = 'Good Night'
end
greeting
end
# rubocop:enable Metrics/AbcSize
# rubocop:enable Metrics/MethodLength

def book_title book
if book.name.downcase.starts_with?('book')
book.name
else
"Book #{book.name}"
end
end

def case_title kase
if kase.case_name.downcase.starts_with?('case')
kase.case_name
else
"Case #{kase.case_name}"
end
end
end
4 changes: 3 additions & 1 deletion app/models/score.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,12 @@ class Score < ApplicationRecord
# Scores
scope :last_one, -> {
where(annotation_id: nil)
.order(updated_at: :desc)
.order(updated_at: :desc)
.order(created_at: :desc)
.order(id: :desc)
.limit(1)
.first
}

scope :scored, -> { where('score > ?', 0) }
end
6 changes: 6 additions & 0 deletions app/views/analytics/sparkline/_event.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# frozen_string_literal: true

json.case_id score.case_id
json.date score.created_at
json.y score.score
json.symbol score.case.case_name
2 changes: 2 additions & 0 deletions app/views/analytics/sparkline/vega_data.csv.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
"date","state","positive","positiveIncrease"
<% @scores.each do |score| %><%= ::CSV.generate_line([score.created_at.to_date.to_fs(:number), score.case.case_name, 100, (score.score * 100).to_i]).html_safe %><% end %>
3 changes: 3 additions & 0 deletions app/views/analytics/sparkline/vega_data.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# frozen_string_literal: true

json.array! @scores, partial: 'event', as: :score
Loading

0 comments on commit 1be60d6

Please sign in to comment.