Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rails5 ajax fixes #2570

Merged
merged 14 commits into from
Jul 1, 2020
67 changes: 40 additions & 27 deletions app/controllers/concerns/paginable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -50,36 +50,45 @@ def paginable_renderise(partial: nil, controller: nil, action: nil,
@paginable_options = {}.merge(options)
@paginable_options[:view_all] = options.fetch(:view_all, true)
# Assignment for paginable_params based on arguments passed to the method
paginable_params[:controller] = controller if controller
paginable_params[:action] = action if action
@args = paginable_params.to_h
@args[:controller] = controller if controller
@args[:action] = action if action

# if duplicate keys, those from @paginable_params take precedence
paginable_params = query_params.symbolize_keys.merge(paginable_params.to_h)
@args = query_params.symbolize_keys.merge(@args)
# Additional path_params passed to this function got special treatment
# (e.g. it is taking into account when building base_url)
@paginable_path_params = path_params.symbolize_keys
if paginable_params[:page] == "ALL" &&
paginable_params[:search].blank? &&
if @args[:page] == "ALL" &&
@args[:search].blank? &&
@paginable_options[:view_all] == false
render(
status: :forbidden,
html: _("Restricted access to View All the records")
)
else
@refined_scope = refine_query(scope)
render(layout: "/layouts/paginable",
partial: partial,
locals: locals.merge(
scope: @refined_scope,
search_term: paginable_params[:search])
locals = locals.merge(
scope: @refined_scope,
paginable_params: @args,
search_term: @args[:search]
)
# If this was an ajax call then render as JSON
if options[:format] == :json
render json: { html: render_to_string(layout: "/layouts/paginable",
partial: partial, locals: locals) }
else
render(layout: "/layouts/paginable", partial: partial, locals: locals)
end
end
end

# Returns the base url of the paginable route for a given page passed
def paginable_base_url(page = 1)
@args = @args.with_indifferent_access
url_params = @paginable_path_params.merge(
controller: paginable_params[:controller],
action: paginable_params[:action],
controller: @args[:controller],
action: @args[:action],
page: page
)
url_for(url_params)
Expand All @@ -99,7 +108,7 @@ def paginable_sort_link(sort_field)

# Determines whether or not the latest request included the search functionality
def searchable?
paginable_params[:search].present?
@args[:search].present?
end

# Determines whether or not the scoped query is paginated or not
Expand All @@ -110,34 +119,37 @@ def paginable?
# Refine a scope passed to this concern if any of the params (search,
# sort_field or page) are present
def refine_query(scope)
if paginable_params[:search].present?
scope = scope.search(paginable_params[:search])
@args = @args.with_indifferent_access
if @args[:search].present?
scope = scope.search(@args[:search])
end
# Can raise NoMethodError if the scope does not define a search method
if paginable_params[:sort_field].present?
unless paginable_params[:sort_field][SORT_COLUMN_FORMAT]
if @args[:sort_field].present?
unless @args[:sort_field][SORT_COLUMN_FORMAT]
raise ArgumentError, "sort_field param looks unsafe"
end
# Can raise ActiveRecord::StatementInvalid (e.g. column does not
# exist, ambiguity on column, etc)
scope = scope.order("#{paginable_params[:sort_field]} #{sort_direction}")
scope = scope.order("#{@args[:sort_field]} #{sort_direction}")
end
if paginable_params[:page] != "ALL"
if @args[:page] != "ALL"
# Can raise error if page is not a number
scope = scope.page(paginable_params[:page])
scope = scope.page(@args[:page])
end
scope
end

def sort_direction
@sort_direction ||= SortDirection.new(paginable_params[:sort_direction])
@args = @args.with_indifferent_access
@sort_direction ||= SortDirection.new(@args[:sort_direction])
end

# Returns the sort link name for a given sort_field. The link name includes
# html prevented of being escaped
def sort_link_name(sort_field)
@args = @args.with_indifferent_access
class_name = "fa-sort"
if paginable_params[:sort_field] == sort_field
if @args[:sort_field] == sort_field
class_name = "fa-sort-#{sort_direction.downcase}"
end
<<~HTML.html_safe
Expand All @@ -154,10 +166,11 @@ def sort_link_name(sort_field)

# Returns the sort url for a given sort_field.
def sort_link_url(sort_field)
@args = @args.with_indifferent_access
query_params = {}
query_params[:page] = paginable_params[:page] == "ALL" ? "ALL" : 1
query_params[:page] = @args[:page] == "ALL" ? "ALL" : 1
query_params[:sort_field] = sort_field
if paginable_params[:sort_field] == sort_field
if @args[:sort_field] == sort_field
query_params[:sort_direction] = sort_direction.opposite
else
query_params[:sort_direction] = sort_direction
Expand All @@ -171,11 +184,11 @@ def sort_link_url(sort_field)

# Retrieve any query params that are not a part of the paginable concern
def stringify_nonpagination_query_params
paginable_params.except(*PAGINATION_QUERY_PARAMS).to_param
@args.except(*PAGINATION_QUERY_PARAMS).to_param
end

def stringify_query_params(page: 1, search: paginable_params[:search],
sort_field: paginable_params[:sort_field],
def stringify_query_params(page: 1, search: @args[:search],
sort_field: @args[:sort_field],
sort_direction: nil)

query_string = {}
Expand Down
3 changes: 2 additions & 1 deletion app/controllers/paginable/contributors_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ def index
paginable_renderise(
partial: "index",
scope: Contributor.where(plan_id: @plan.id),
query_params: { sort_field: "contributors.name", sort_direction: :asc }
query_params: { sort_field: "contributors.name", sort_direction: :asc },
format: :json
)
end

Expand Down
3 changes: 2 additions & 1 deletion app/controllers/paginable/departments_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ def index
paginable_renderise(
partial: "index",
scope: departments,
query_params: { sort_field: "departments.name", sort_direction: :asc }
query_params: { sort_field: "departments.name", sort_direction: :asc },
format: :json
)
end

Expand Down
3 changes: 2 additions & 1 deletion app/controllers/paginable/guidance_groups_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ def index
paginable_renderise(
partial: "index",
scope: GuidanceGroup.by_org(current_user.org),
query_params: { sort_field: "guidance_groups.name", sort_direction: :asc }
query_params: { sort_field: "guidance_groups.name", sort_direction: :asc },
format: :json
)
end

Expand Down
3 changes: 2 additions & 1 deletion app/controllers/paginable/guidances_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ def index
partial: "index",
scope: Guidance.by_org(current_user.org)
.includes(:guidance_group, :themes),
query_params: { sort_field: "guidances.text", sort_direction: :asc }
query_params: { sort_field: "guidances.text", sort_direction: :asc },
format: :json
)
end

Expand Down
2 changes: 1 addition & 1 deletion app/controllers/paginable/notifications_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class Paginable::NotificationsController < ApplicationController
# /paginable/notifications/index/:page
def index
authorize(Notification)
paginable_renderise(partial: "index", scope: Notification.all)
paginable_renderise(partial: "index", scope: Notification.all, format: :json)
end

end
4 changes: 3 additions & 1 deletion app/controllers/paginable/orgs_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@ def index
paginable_renderise(
partial: "index",
scope: Org.with_template_and_user_counts,
query_params: { sort_field: "orgs.name", sort_direction: :asc })
query_params: { sort_field: "orgs.name", sort_direction: :asc },
format: :json
)
end

end
10 changes: 7 additions & 3 deletions app/controllers/paginable/plans_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@ def privately_visible
unless Paginable::PlanPolicy.new(current_user).privately_visible?
raise Pundit::NotAuthorizedError
end

paginable_renderise(
partial: "privately_visible",
scope: Plan.active(current_user),
query_params: { sort_field: 'plans.updated_at', sort_direction: :desc }
query_params: { sort_field: 'plans.updated_at', sort_direction: :desc },
format: :json
)
end

Expand All @@ -24,7 +26,8 @@ def organisationally_or_publicly_visible
paginable_renderise(
partial: "organisationally_or_publicly_visible",
scope: Plan.organisationally_or_publicly_visible(current_user),
query_params: { sort_field: 'plans.updated_at', sort_direction: :desc }
query_params: { sort_field: 'plans.updated_at', sort_direction: :desc },
format: :json
)
end

Expand All @@ -33,7 +36,8 @@ def publicly_visible
paginable_renderise(
partial: "publicly_visible",
scope: Plan.publicly_visible.includes(:template),
query_params: { sort_field: 'plans.updated_at', sort_direction: :desc }
query_params: { sort_field: 'plans.updated_at', sort_direction: :desc },
format: :json
)
end

Expand Down
12 changes: 8 additions & 4 deletions app/controllers/paginable/templates_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ def index
partial: "index",
scope: templates.includes(:org),
query_params: { sort_field: 'templates.title', sort_direction: :asc },
locals: { action: "index" }
locals: { action: "index" },
format: :json
)
end

Expand All @@ -47,7 +48,8 @@ def organisational
partial: "organisational",
scope: templates,
query_params: { sort_field: 'templates.title', sort_direction: :asc },
locals: { action: "organisational" }
locals: { action: "organisational" },
format: :json
)
end

Expand All @@ -71,7 +73,8 @@ def customisable
partial: "customisable",
scope: templates.joins(:org).includes(:org),
query_params: { sort_field: 'templates.title', sort_direction: :asc },
locals: { action: "customisable", customizations: customizations }
locals: { action: "customisable", customizations: customizations },
format: :json
)
end

Expand All @@ -89,7 +92,8 @@ def publicly_visible
.includes(:org)
.where(id: templates.uniq.flatten)
.published,
query_params: { sort_field: 'templates.title', sort_direction: :asc }
query_params: { sort_field: 'templates.title', sort_direction: :asc },
format: :json
)
end

Expand Down
2 changes: 1 addition & 1 deletion app/controllers/paginable/themes_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class Paginable::ThemesController < ApplicationController
# /paginable/themes/index/:page
def index
authorize(Theme)
paginable_renderise(partial: "index", scope: Theme.all)
paginable_renderise(partial: "index", scope: Theme.all, format: :json)
end

end
1 change: 1 addition & 0 deletions app/controllers/paginable/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ def index
partial: "index",
scope: scope,
query_params: { sort_field: 'users.surname', sort_direction: :asc },
format: :json,
view_all: !current_user.can_super_admin?
)
end
Expand Down
10 changes: 5 additions & 5 deletions app/controllers/plans_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -389,13 +389,13 @@ def set_test
# rubocop:disable Metrics/LineLength
if plan.save
render json: {
code: 1,
msg: (plan.is_test? ? _("Your project is now a test.") : _("Your project is no longer a test."))
}
code: 1,
msg: (plan.is_test? ? _("Your project is now a test.") : _("Your project is no longer a test."))
}
else
render status: :bad_request, json: {
code: 0, msg: _("Unable to change the plan's test status")
}
code: 0, msg: _("Unable to change the plan's test status")
}
end
# rubocop:enable Metrics/LineLength
end
Expand Down
7 changes: 6 additions & 1 deletion app/javascript/packs/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,12 @@ import '../src/superAdmin/users/edit';
// Since we're using Webpacker to manage JS we need to startup Rails' Unobtrusive JS
// and Turbolinks. ActiveStorage and ActionCable would also need to be in here
// if we decide to implement either before Rails 6
require('@rails/ujs').start();
import Rails from '@rails/ujs';

// Make Rails UJS functions available in our custom JS and js.erb files
Rails.start();
window.Rails = Rails;

// TODO: Disabled turbolinks for the time being because our custom JS is not
// properly setup to work with it. We should review the docs:
// https://github.com/turbolinks/turbolinks
Expand Down
6 changes: 4 additions & 2 deletions app/javascript/src/plans/index.js.erb
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import { paginableSelector } from '../utils/paginable';
$(() => {
$(paginableSelector).on('click, change', '.set_test_plan input[type="checkbox"]', (e) => {
const form = $(e.target).closest('form');
form.submit();
Rails.fire(form[0], 'submit');
});
$(paginableSelector).on('ajax:success', '.set_test_plan', (e, data) => {

$(paginableSelector).on('ajax:success', 'form.set_test_plan', (e) => {
const form = $(e.target);
const data = e.detail[0];
if (data.code === 1 && data.msg && data.msg !== '') {
notifier.renderNotice(data.msg);
} else {
Expand Down
6 changes: 4 additions & 2 deletions app/javascript/src/plans/share.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ $(() => {
$('#set_visibility [name="plan[visibility]"]').click((e) => {
$(e.target).closest('form').submit();
});
$('#set_visibility').on('ajax:success', (e, data) => {
$('#set_visibility').on('ajax:success', (e) => {
const data = e.detail[0];
if (isObject(data) && isString(data.msg)) {
notifier.renderNotice(data.msg);
}
});
$('#set_visibility').on('ajax:error', (e, xhr) => {
$('#set_visibility').on('ajax:error', (e) => {
const xhr = e.detail[2];
if (isObject(xhr.responseJSON)) {
notifier.renderAlert(xhr.responseJSON.msg);
} else {
Expand Down
15 changes: 9 additions & 6 deletions app/javascript/src/roles/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,20 @@ $(() => {
$('form.edit_role select').on('change', (e) => {
$(e.target).closest('form').submit();
});
$('form.edit_role').on('ajax:success', (e, data) => {
$('form.edit_role').on('ajax:success', (e) => {
const data = e.detail[0];
if (isObject(data) && isString(data.msg)) {
renderNotice(data.msg);
scrollTo('#notification-area');
}
});
$('form.edit_role').on('ajax:error', (e, xhr) => {
const error = xhr.responseJSON;
if (isObject(error) && isString(error)) {
renderAlert(error.msg);
scrollTo('#notification-area');
$('form.edit_role').on('ajax:error', (e) => {
if (isObject(e.detail[2])) {
const error = e.detail[2].responseJSON;
if (isObject(error) && isString(error)) {
renderAlert(error.msg);
scrollTo('#notification-area');
}
}
});
});
4 changes: 2 additions & 2 deletions app/javascript/src/superAdmin/notifications/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ $(() => {
form.submit();
});

$(paginableSelector).on('ajax:success', '.enable_notification', (e, data) => {
// const form = $(e.target);
$(paginableSelector).on('ajax:success', '.enable_notification', (e) => {
const data = e.detail[0];
if (data.code === 1 && data.msg && data.msg !== '') {
notifier.renderNotice(data.msg);
} else {
Expand Down
Loading