Skip to content

Commit

Permalink
LTI-410: implement pagination to improve performance (#364)
Browse files Browse the repository at this point in the history
This feature was implemented by calling all recordings first and counting them, then only displaying a portion at a time.
It will have to be updated once the LB/BBB start sending back the totalElements field.
  • Loading branch information
Mariam05 authored Nov 13, 2024
1 parent b39927b commit 16a8c4b
Show file tree
Hide file tree
Showing 5 changed files with 167 additions and 15 deletions.
32 changes: 30 additions & 2 deletions app/controllers/concerns/bbb_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ module BbbHelper
attr_writer :cache, :cache_enabled # Rails.cache store is assumed. # Enabled by default.

RECORDINGS_KEY = :recordings
RECORDINGS_PER_PAGE = 8

include RoomsError
include BrokerHelper
Expand Down Expand Up @@ -123,12 +124,39 @@ def meeting_running?
end

# Fetches all recordings for a room.
def recordings
def recordings(page = 1)
res = Rails.cache.fetch("rooms/#{@chosen_room.handler}/#{RECORDINGS_KEY}", expires_in: Rails.configuration.cache_expires_in_minutes.minutes) if Rails.configuration.cache_enabled
res ||= bbb.get_recordings(meetingID: @chosen_room.handler)
offset = (page.to_i - 1) * RECORDINGS_PER_PAGE # The offset is an index that starts at 0.
res ||= bbb.get_recordings(meetingID: @chosen_room.handler, offset: offset, limit: RECORDINGS_PER_PAGE) # offset and limit are for pagination purposes
recordings_formatted(res)
end

def recordings_count
res = Rails.cache.fetch("rooms/#{@chosen_room.handler}/#{RECORDINGS_KEY}", expires_in: Rails.configuration.cache_expires_in_minutes.minutes) if Rails.configuration.cache_enabled
res ||= bbb.get_recordings(meetingID: @chosen_room.handler)
res[:recordings].length
end

def paginate?
recordings_count > RECORDINGS_PER_PAGE
end

# returns the amount of pages for recordings
def pages_count
(recordings_count.to_f / RECORDINGS_PER_PAGE).ceil
end

# on the last page, we don't want recordings that were in the second-to-last page to show
def recordings_limit(page)
page_int = page.to_i
num_of_recs = recordings_count
recordings_overflow = num_of_recs - page_int * RECORDINGS_PER_PAGE
# if offset is > 0 and there are less recordings than the current page * recordings per page, then we'll need to pass a limit that's less than what's defined in RECORDINGS_PER_PAGE
return recordings_overflow if page_int.positive? && recordings_overflow < RECORDINGS_PER_PAGE

RECORDINGS_PER_PAGE
end

# Fetch an individual recording
def recording(record_id)
r = bbb.get_recordings(meetingID: @chosen_room.handler, recordID: record_id)
Expand Down
22 changes: 15 additions & 7 deletions app/controllers/rooms_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,13 @@ class RoomsController < ApplicationController
# GET /rooms/1
# GET /rooms/1.json
def show
# page offset is equal to the page number minus 1
@page = params[:page] || 1
session[:page] = @page
respond_to do |format|
if @room && @chosen_room
begin
@recordings = recordings
@recordings = recordings(@page)
@meeting_info = meeting_info
@meeting_running = @meeting_info[:returncode] == true
rescue BigBlueButton::BigBlueButtonException => e
Expand Down Expand Up @@ -185,25 +188,29 @@ def meeting_close
# POST /rooms/:id/recording/:record_id/unpublish
def recording_unpublish
unpublish_recording(params[:record_id])
redirect_to(room_path(params[:id], launch_nonce: params[:launch_nonce]))
@page_num = session[:page] || 1
redirect_to(room_path(params[:id], launch_nonce: params[:launch_nonce], page: @page_num))
end

# POST /rooms/:id/recording/:record_id/publish
def recording_publish
publish_recording(params[:record_id])
redirect_to(room_path(params[:id], launch_nonce: params[:launch_nonce]))
@page_num = session[:page] || 1
redirect_to(room_path(params[:id], launch_nonce: params[:launch_nonce], page: @page_num))
end

# POST /rooms/:id/recording/:record_id/protect
def recording_protect
update_recording(params[:record_id], protect: true)
redirect_to(room_path(params[:id], launch_nonce: params[:launch_nonce]))
@page_num = session[:page] || 1
redirect_to(room_path(params[:id], launch_nonce: params[:launch_nonce], page: @page_num))
end

# POST /rooms/:id/recording/:record_id/unprotect
def recording_unprotect
update_recording(params[:record_id], protect: false)
redirect_to(room_path(params[:id], launch_nonce: params[:launch_nonce]))
@page_num = session[:page] || 1
redirect_to(room_path(params[:id], launch_nonce: params[:launch_nonce], page: @page_num))
end

# POST /rooms/:id/recording/:record_id/update
Expand All @@ -219,7 +226,8 @@ def recording_update
# POST /rooms/:id/recording/:record_id/delete
def recording_delete
delete_recording(params[:record_id])
redirect_to(room_path(params[:id], launch_nonce: params[:launch_nonce]))
@page_num = session[:page] || 1
redirect_to(room_path(params[:id], launch_nonce: params[:launch_nonce], page: @page_num))
end

# POST /rooms/:id/recording/:record_id/:format/recording
Expand All @@ -237,7 +245,7 @@ def individual_recording
redirect_to(errors_path(401))
end

helper_method :recording_date, :recording_length, :meeting_running?, :bigbluebutton_moderator_roles,
helper_method :recording_date, :recording_length, :meeting_running?, :bigbluebutton_moderator_roles, :paginate?, :recordings_count, :pages_count,
:bigbluebutton_recording_public_formats, :meeting_info, :bigbluebutton_recording_enabled, :server_running?

private
Expand Down
6 changes: 2 additions & 4 deletions app/javascript/packs/rename.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
* with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
*/

function func() {
$(document).on('turbolinks:load', function () {
var controller = $("body").data('controller');
var action = $("body").data('action');

Expand Down Expand Up @@ -135,6 +135,4 @@ function func() {
configure_recording_row(recording_description, 'recording-description-text');
});
}
};

$(func) // run when the DOM is ready
});
46 changes: 46 additions & 0 deletions app/javascript/packs/rooms.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,50 @@ $(document).on('turbolinks:load', function () {
}
});
}

/** PAGINATION STUFF */
/** disable previous or next buttons if user is on first or last page */
const $paginationContainer = $("#pagination-container");

if ($paginationContainer.length) {
const currentPage = parseInt($paginationContainer.data("current-page"));
const totalPages = parseInt($paginationContainer.data("total-pages"));

const $previousButton = $("#backbtn");
const $nextButton = $("#nextbtn");

// Disable Previous button if on the first page
if (currentPage <= 1) {
$previousButton.addClass("cursor-not-allowed opacity-50")
.attr("aria-disabled", "true")
.attr("href", "javascript:void(0)");
} else {
$previousButton.removeClass("cursor-not-allowed opacity-50")
.removeAttr("aria-disabled")
.attr("href", $previousButton.data("pageNum"));
}

// Disable Next button if on the last page
if (currentPage >= totalPages) {
$nextButton.addClass("cursor-not-allowed opacity-50")
.attr("aria-disabled", "true")
.attr("href", "javascript:void(0)");
} else {
$nextButton.removeClass("cursor-not-allowed opacity-50")
.removeAttr("aria-disabled")
.attr("href", $nextButton.data("pageNum"));
}
}

/** change the colour of the page buttons */
// Get the current page number from the container
const currentPage = $("#pagination-container").data("current-page");

// Define the classes
const activeClasses = "text-blue-600 border border-blue-300 bg-blue-50 hover:bg-blue-100 hover:text-blue-700";
const nonActiveClasses = "text-gray-500 bg-white border border-gray-300 hover:bg-gray-100 hover:text-gray-700";

// Remove active styling from all buttons, then apply to the current button
$("[id^='pg-']").removeClass(activeClasses).addClass(nonActiveClasses);
$(`#pg-${currentPage}-btn`).removeClass(nonActiveClasses).addClass(activeClasses);
});
76 changes: 74 additions & 2 deletions app/views/shared/_room.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,10 @@

<!-- recordings -->
<% if bigbluebutton_recording_enabled %>
<div class= "">
<div>
<%= render "shared/components/search_bar", subtitle: t("default.room.recordings")%>

<div class = "flex justify-between items-center rounded-lg border mb-10">
<div class = "flex justify-between items-center rounded-lg border mb-2">
<table class="w-full max-w-full rounded-lg text-left border-collapse text-sm" >
<thead class="text-left uppercase border-b rounded-lg bg-gray-100 text-sm text-gray-500 font-sans py-4" >
<tr>
Expand Down Expand Up @@ -194,5 +194,77 @@
</tbody>
</table>
</div>


<% numOfPages = pages_count %>
<% if paginate? %>
<div class="flex justify-center items-center mb-5" id="pagination-container" data-current-page="<%= @page %>" data-total-pages="<%= numOfPages %>">
<nav aria-label="Page navigation example">
<ul class="flex items-center -space-x-px h-8 text-sm">
<!-- Previous Button (disabled if on first page) -->
<li>
<% if @page == 1 %>
<%= link_to 'javascript:void(0)',
class: "flex items-center justify-center px-3 h-8 ms-0 leading-tight text-gray-500 bg-white border border-e-0 border-gray-300 rounded-s-lg hover:bg-gray-100 hover:text-gray-700 opacity-50 cursor-not-allowed", aria_disabled: "true",
disabled: true do %>
<span class="sr-only">Previous</span>
<svg class="w-2.5 h-2.5 rtl:rotate-180" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 1 1 5l4 4"/>
</svg>
<% end %>
<% else %>
<%= link_to room_path(@room, page: @page.to_i - 1, :launch_nonce => @launch_nonce),
class: "flex items-center justify-center px-3 h-8 ms-0 leading-tight text-gray-500 bg-white border border-e-0 border-gray-300 rounded-s-lg hover:bg-gray-100 hover:text-gray-700 dark:bg-gray-800 dark:border-gray-700 dark:text-gray-400 dark:hover:bg-gray-700 dark:hover:text-white",
id: 'backbtn',
data: { turbolinks: false, pageNum: @page.to_i - 1 } do %>
<span class="sr-only">Previous</span>
<svg class="w-2.5 h-2.5 rtl:rotate-180" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M5 1 1 5l4 4"/>
</svg>
<% end %>
<% end %>
</li>

<!-- Page Buttons -->
<% (1..numOfPages).each do |i| %>
<% if @page == i %>
<% classes = "z-10 flex items-center justify-center px-3 h-8 leading-tight border" %>
<% else %>
<% classes = "flex items-center justify-center px-3 h-8 leading-tight border"%>
<% end %>
<li>
<%= link_to i.to_s, room_path(@room, page: i, :launch_nonce => @launch_nonce), class: classes, id: "pg-#{i}-btn", data: { turbolinks: false, pageNum: i, currPage: @page } %>
</li>
<% end %>

<!-- Next Button (disabled if on last page) -->
<li>
<% if @page == numOfPages %>
<%= link_to 'javascript:void(0)',
class: "flex items-center justify-center px-3 h-8 leading-tight text-gray-400 bg-gray-200 border border-gray-300 rounded-e-lg opacity-50 cursor-not-allowed",
id: 'nextbtndisabled',
aria_disabled: "true" ,
disabled: true do %>
<span class="sr-only">Next</span>
<svg class="w-2.5 h-2.5 rtl:rotate-180" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 9 4-4-4-4"/>
</svg>
<% end %>
<% else %>
<%= link_to room_path(@room, page: @page.to_i + 1, launch_nonce: @launch_nonce),
class: "flex items-center justify-center px-3 h-8 leading-tight text-gray-500 bg-white border border-gray-300 rounded-e-lg hover:bg-gray-100 hover:text-gray-700",
id: 'nextbtn',
data: { turbolinks: false, pageNum: @page.to_i + 1 } do %>
<span class="sr-only">Next</span>
<svg class="w-2.5 h-2.5 rtl:rotate-180" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 6 10">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 9 4-4-4-4"/>
</svg>
<% end %>
<% end %>
</li>
</ul>
</nav>
</div>
<% end %>
</div>
<% end %>

0 comments on commit 16a8c4b

Please sign in to comment.