fix(graphql): fix pagination with order desc

This commit is contained in:
Paul Chavard 2023-10-26 10:38:04 +02:00
parent 9866acc0f8
commit 33f5a553b6
3 changed files with 60 additions and 31 deletions

View file

@ -42,23 +42,10 @@ module Connections
# -> d5, d6
#
# si after ou before present, last ou first donne juste limit
#
# order:
# order, ne sert rien si after ou before
#
# first: 2, order: desc => last: 2
# -> d5, d6
#
# last: 2, order: desc => first 2
# -> d1, d2
def limit_and_inverted(first: nil, last: nil, after: nil, before: nil, order: nil)
def limit_and_inverted(first: nil, last: nil, after: nil, before: nil)
limit = [first, last, max_page_size].compact.min + 1
inverted = last.present? || before.present?
if order == :desc && after.nil? && before.nil?
inverted = !inverted
end
[limit, inverted]
end
@ -73,8 +60,10 @@ module Connections
def load_nodes
@nodes ||= begin
ensure_valid_params
limit, inverted = limit_and_inverted(first:, last:, after:, before:)
return load_nodes_deprecated_order(limit, inverted) if @deprecated_order == :desc
limit, inverted = limit_and_inverted(first:, last:, after:, before:, order: @deprecated_order)
expected_size = limit - 1
nodes = resolve_nodes(limit:, before:, after:, inverted:)
@ -89,6 +78,22 @@ module Connections
end
end
def load_nodes_deprecated_order(limit, inverted)
expected_size = limit - 1
if @deprecated_order == :desc && before.nil?
inverted = !inverted
end
nodes = resolve_nodes(limit:, before: after, after: before, inverted:)
result_size = nodes.size
@has_next_page = previous_page?(before, result_size, limit, inverted)
@has_previous_page = next_page?(after, result_size, limit, inverted)
nodes.first(expected_size)
end
def ensure_valid_params
if first.present? && last.present?
raise GraphQL::ExecutionError.new('Arguments "first" and "last" are exclusive', extensions: { code: :bad_request })
@ -105,6 +110,10 @@ module Connections
if last.present? && last < 0
raise GraphQL::ExecutionError.new('Argument "last" must be a non-negative integer', extensions: { code: :bad_request })
end
if last.present? && @deprecated_order == :desc
raise GraphQL::ExecutionError.new('Argument "last" is not supported with order "desc"', extensions: { code: :bad_request })
end
end
def timestamp_and_id_from_cursor(cursor)