Skip to content

Commit

Permalink
Add a dropdown for recent books (#986)
Browse files Browse the repository at this point in the history
* leverage our recent book tracking and expose in ui as a drop down
  • Loading branch information
epugh authored Mar 27, 2024
1 parent 3d2b2d7 commit 61de70a
Show file tree
Hide file tree
Showing 14 changed files with 181 additions and 16 deletions.
46 changes: 37 additions & 9 deletions app/assets/javascripts/controllers/headerCtrl.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,30 +7,44 @@ angular.module('QuepidApp')
'$rootScope',
'$scope',
'$route',
'$uibModal',
'caseSvc', 'caseTryNavSvc',
'caseSvc',
'bookSvc',
'caseTryNavSvc',
function(
$rootScope,
$scope,
$route,
$uibModal,
caseSvc,
bookSvc,
caseTryNavSvc
) {
$rootScope.isRailsGoingToAngular = isRailsGoingToAngular;

$scope.headerScope = {};
$scope.headerScope.dropdownCases = [];
$scope.headerScope.dropdownBooks = [];
$scope.headerScope.casesCount = 0;
$scope.headerScope.booksCount = 0;
$scope.theCase = null;

$scope.headerScope.goToCase = goToCase;
$scope.headerScope.createBookLink = createBookLink;

angular.forEach(['fetchedDropdownCasesList'], function (eventName) {
$scope.$on(eventName, function() {
$scope.headerScope.dropdownCases = caseSvc.dropdownCases;
$scope.headerScope.casesCount = caseSvc.casesCount;
});

$scope.$on('fetchedDropdownCasesList', function() {
$scope.headerScope.dropdownCases = caseSvc.dropdownCases;
$scope.headerScope.casesCount = caseSvc.casesCount;
});

$scope.$on('fetchedDropdownBooksList', function() {
$scope.headerScope.dropdownBooks = bookSvc.dropdownBooks;
$scope.headerScope.booksCount = bookSvc.booksCount;
});

$scope.$on('associateBook', function() {
bookSvc.fetchDropdownBooks();
});


angular.forEach(['updatedCasesList', 'caseRenamed'], function (eventName) {
$scope.$on(eventName, function() {
Expand All @@ -40,14 +54,28 @@ angular.module('QuepidApp')

// Necessary when the first page isn't the main case page
caseSvc.fetchDropdownCases();
bookSvc.fetchDropdownBooks();

function goToCase($event, aCase) {
$event.preventDefault();
caseTryNavSvc.navigateTo({'caseNo': aCase.caseNo, 'tryNo': aCase.lastTry});
}
}

function isRailsGoingToAngular() {
return !( angular.isDefined($route.current) && angular.isDefined($route.current.$$route) );
}

$scope.$on('caseSelected', function() {
$scope.theCase = caseSvc.getSelectedCase();
});

function createBookLink() {
if ($scope.theCase){
const teamIds = $scope.theCase.teams.map(function(team) {
return `&team_ids[]=${team.id}`;
});
return `books/new?book[scorer_id]=${$scope.theCase.scorerId}${teamIds}&origin_case_id=${$scope.theCase.caseNo}`;
}
}
}
]);
21 changes: 20 additions & 1 deletion app/assets/javascripts/services/bookSvc.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ angular.module('QuepidApp')
'$http',
'broadcastSvc',
function bookSvc($http, broadcastSvc) {
this.books = [];
this.books = [];
this.dropdownBooks = [];

var Book = function(id, name) {
this.id = id;
Expand Down Expand Up @@ -132,5 +133,23 @@ angular.module('QuepidApp')
console.log('refreshed ratings' + response.data);
});
};

this.fetchDropdownBooks = function() {
this.dropdownBooks.length = 0;
return $http.get('api/dropdown/books')
.then(function(response) {
this.booksCount = response.data.books_count;

angular.forEach(response.data.books, function(dataBook) {
let book = this.constructFromData(dataBook);

if(!contains(this.dropdownBooks, book)) {
this.dropdownBooks.push(book);
}
});

broadcastSvc.send('fetchedDropdownBooksList', this.dropdownBooks);
});
};
}
]);
1 change: 1 addition & 0 deletions app/assets/javascripts/services/caseSvc.js
Original file line number Diff line number Diff line change
Expand Up @@ -461,6 +461,7 @@ angular.module('QuepidApp')

theCase.bookId = bookId;
theCase.bookName = response.book_name;
broadcastSvc.send('associateBook', svc.dropdownBooks);
}, function() {
caseTryNavSvc.notFound();
});
Expand Down
15 changes: 15 additions & 0 deletions app/controllers/api/v1/books/dropdown_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

module Api
module V1
module Books
class DropdownController < Api::ApiController
def index
@books = recent_books 3

respond_with @books
end
end
end
end
end
4 changes: 4 additions & 0 deletions app/controllers/api/v1/cases_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ def update
Analytics::Tracker.track_case_archived_event current_user, @case
respond_with @case
elsif @case.update update_params
if update_params[:book_id]
@book = Book.find(update_params[:book_id])
TrackBookViewedJob.perform_now @book, current_user
end
Analytics::Tracker.track_case_updated_event current_user, @case
respond_with @case
else
Expand Down
1 change: 1 addition & 0 deletions app/controllers/application_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ class ApplicationController < ActionController::Base
before_action :require_login
before_action :check_current_user_locked!
before_action :set_recent_cases
before_action :set_recent_books
before_action :check_for_announcement

# Prevent CSRF attacks by raising an exception.
Expand Down
16 changes: 13 additions & 3 deletions app/controllers/books_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ def new
else
Book.new
end

@origin_case = current_user.cases_involved_with.where(id: params[:origin_case_id]).first if params[:origin_case_id]

respond_with(@book)
end

Expand All @@ -70,6 +73,13 @@ def create
@book = Book.new(book_params)
@book.owner = current_user
if @book.save

if params[:book][:link_the_case]
@origin_case = current_user.cases_involved_with.where(id: params[:book][:origin_case_id]).first
@origin_case.book = @book
@origin_case.save
end

redirect_to @book, notice: 'Book was successfully created.'
else
render :new
Expand All @@ -89,7 +99,7 @@ def update

@book.teams.replace(teams)

@book.update(book_params.except(:team_ids))
@book.update(book_params.except(:team_ids, :link_the_case, :origin_case_id))

respond_with(@book)
end
Expand Down Expand Up @@ -260,13 +270,13 @@ def find_user

def book_params
params_to_use = params.require(:book).permit(:scorer_id, :selection_strategy_id, :name,
:support_implicit_judgements,
:support_implicit_judgements, :link_the_case, :origin_case_id,
:show_rank, team_ids: [])

# Crafting a book[team_ids] parameter from the AngularJS side didn't work, so using top level parameter
params_to_use[:team_ids] = params[:team_ids] if params[:team_ids]
params_to_use[:team_ids]&.compact_blank!
params_to_use
params_to_use.except(:link_the_case, :origin_case_id)
end
end

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ def check_book
render json: { message: 'Book not found!' }, status: :not_found unless @book
end

def set_recent_books
@recent_books = recent_books(3)
end

# rubocop:disable Metrics/MethodLength
def recent_books count
if current_user
Expand Down
10 changes: 10 additions & 0 deletions app/views/api/v1/books/dropdown/index.json.jbuilder
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true

json.books do
json.array! @books do |book|
json.name book.name
json.id book.id
end
end

json.books_count current_user.books_involved_with.count
12 changes: 12 additions & 0 deletions app/views/books/_form.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,18 @@
<% end %>
<div class="form-text">Books are meant to be shared with human raters and relevance engineers, and you do this by picking which teams can use them.</div>
</div>

<% if @origin_case %>
<div class="mb-3">
<div class="form-check form-switch">
<%= form.label :link_the_case, class:'form-check-label' %>
<%= form.check_box :link_the_case, class:'form-check-input' %>
<%= @origin_case.case_name %> to this book?
</div>
<%= form.hidden_field :origin_case_id, :value => @origin_case.id %>
<div class="form-text">A book can be used by none, one, or more Cases. </div>
</div>
<% end %>

<div class="mb-3">
<%= form.label :scorer_id, class: 'form-label' %>
Expand Down
2 changes: 1 addition & 1 deletion app/views/judgements/_moar_judgements_needed.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
</div>
<% elsif book.query_doc_pairs.empty? %>
<div class="alert alert-warning" role="alert">
You don't have any query/doc pairs.
You don't have any query/doc pairs created yet.
<% if book.cases.empty? %>
You can populate this Book with query/doc pairs for judging by <%= link_to 'picking a Case', cases_path, class: 'alert-link' %> and using the <b><i class="bi bi-book-half"></i> Judgements</b> tool to populate this book with query/doc pairs from your search engine.
<% else %>
Expand Down
26 changes: 25 additions & 1 deletion app/views/layouts/_header.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
</li>
<li><hr class="dropdown-divider"></li>
<% @recent_cases.each do |kase| %>
<li><%= link_to kase.case_name, case_core_path(kase, kase.last_try_number), class: 'cases-nav-listing' %></li>
<li><%= link_to kase.case_name, case_core_path(kase, kase.last_try_number) %></li>
<li><hr class="dropdown-divider"></li>
<% end %>

Expand All @@ -33,6 +33,30 @@

</ul>
</li>
<li class="nav-item dropdown">

<a class="nav-link dropdown-toggle" href="#" id="dropdownBooks" role="button" data-bs-toggle="dropdown">
<span class="nav-label">Books</span>
</a>
<ul class="dropdown-menu p-2" style="left: auto; width:250px;" aria-labelledby="navbarDropdownBooks">
<li class="text-muted">
RECENT BOOKS
</li>
<li><hr class="dropdown-divider"></li>
<% @recent_books.each do |book| %>
<li><%= link_to book.name, book_path(book) %></li>
<li><hr class="dropdown-divider"></li>
<% end %>

<li class="actions">
<div class="d-grid gap-2">
<%= link_to "View all books", books_path, class: "btn btn-outline-secondary" %>
<%= link_to 'Create a book', new_book_path, class: 'btn btn-success' %>
</div>
</li>

</ul>
</li>
<li class="nav-item">
<%= link_to "Teams", teams_core_path, class: "nav-link" %>
</li>
Expand Down
38 changes: 37 additions & 1 deletion app/views/layouts/_header_core_app.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
<strong>RECENT CASES</strong>
</li>

<li ng-repeat="case in headerScope.dropdownCases | limitTo:5 track by $index" class="cases-nav-listing">
<li ng-repeat="case in headerScope.dropdownCases | limitTo:5 track by $index">
<a href="#" class="dropdown-link" ng-click="headerScope.goToCase($event, case)" ng-if="!isRailsGoingToAngular()">{{ case.caseName }}</a>

<a ng-href="{{'/case/' + case.caseNo + '/try/' + case.lastTry}}" class="dropdown-link" ng-if="isRailsGoingToAngular()" target="_self">{{ case.caseName }}</a>
Expand All @@ -40,6 +40,42 @@
</ul>
</li>
<!-- End case selector -->
<!-- Begin book selector -->
<li class="dropdown" uib-dropdown>
<a href class="dropdown-toggle" uib-dropdown-toggle>
<span class="nav-label">Books</span>
<i class="fa fa-chevron-down"></i>
</a>

<ul class="dropdown-menu dropdown-content" ng-model="headerScope.dropdownBooks" uib-dropdown-menu>
<li class="text-muted">
<strong>RECENT BOOKS</strong>
</li>

<li ng-repeat="book in headerScope.dropdownBooks | limitTo:5 track by $index">
<a ng-href="books/{{book.id}}" target="_self" class="dropdown-link">{{ book.name }}</a>
</li>

<li class="actions">
<a href="books" class="btn btn-default btn-block" target="_self">
View all books
<small class="text-muted">
({{ headerScope.booksCount }} active)
</small>
</a>

<a
class="btn btn-success btn-block"
ng-href="{{headerScope.createBookLink()}}"
target="_self"
>
<i class="fa fa-plus"></i>
Create a book
</a>
</li>
</ul>
</li>
<!-- End book selector -->

<li><a ng-attr-target="{{ isRailsGoingToAngular() ? '_self' : undefined }}" href="teams">Teams</a></li>
<li><a ng-attr-target="{{ isRailsGoingToAngular() ? '_self' : undefined }}" href="scorers">Scorers</a></li>
Expand Down
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@
resources :signups, only: [ :create ] if Rails.application.config.signup_enabled

get '/dropdown/cases' => 'cases/dropdown#index'
get '/dropdown/books' => 'books/dropdown#index'

# Cases routes.
# In order to be consistent and always user :case_id as the param for the
Expand Down

0 comments on commit 61de70a

Please sign in to comment.