pagy 9.0.0 → 9.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/apps/calendar.ru +1 -1
- data/apps/demo.ru +1 -1
- data/apps/rails.ru +1 -1
- data/apps/repro.ru +1 -1
- data/apps/tmp/pagy-keyset-ar.sqlite3 +0 -0
- data/apps/tmp/pagy-keyset-ar.sqlite3-shm +0 -0
- data/apps/tmp/pagy-keyset-ar.sqlite3-wal +0 -0
- data/bin/pagy +1 -1
- data/config/pagy.rb +5 -1
- data/javascripts/pagy.min.js +2 -2
- data/javascripts/pagy.min.js.map +2 -2
- data/javascripts/pagy.mjs +1 -1
- data/lib/pagy/extras/countless.rb +10 -1
- data/lib/pagy/extras/headers.rb +4 -4
- data/lib/pagy/extras/keyset.rb +10 -0
- data/lib/pagy/keyset.rb +3 -4
- data/lib/pagy/shared_methods.rb +27 -0
- data/lib/pagy/url_helpers.rb +1 -1
- data/lib/pagy.rb +2 -24
- metadata +3 -3
- data/pkg/pagy-9.0.0.gem +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 84fb84478a3d43cc133f13476dd6d010e3d84156ff7704796b38beb566539fa8
|
4
|
+
data.tar.gz: 1d694c518d6f5d22fc93336286abda94a881672ef8f4d90079f26a452738dfcf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4ecd31ce348069d557454bf751b719fbd05f0f82c08bde7f10ee0ac8aea2c5c2c63c0bbc3e2b03dc9a606102bf4ed319cc1b8b60f6d77635be3d498e275f504b
|
7
|
+
data.tar.gz: 258bcd1fb0b66948aefb1798c9a04b998ce18fffc4ded3bea78c6517a6de33b0bc2f75d429d95025916f6d5621d38420670222ec31683cc66ebbbf68182277d2
|
data/apps/calendar.ru
CHANGED
data/apps/demo.ru
CHANGED
data/apps/rails.ru
CHANGED
data/apps/repro.ru
CHANGED
Binary file
|
Binary file
|
Binary file
|
data/bin/pagy
CHANGED
data/config/pagy.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Pagy initializer file (9.0.
|
3
|
+
# Pagy initializer file (9.0.2)
|
4
4
|
# Customize only what you really need and notice that the core Pagy works also without any of the following lines.
|
5
5
|
# Should you just cherry pick part of this file, please maintain the require-order of the extras
|
6
6
|
|
@@ -79,6 +79,10 @@
|
|
79
79
|
# count: 'Total-Count',
|
80
80
|
# pages: 'Total-Pages' } # default
|
81
81
|
|
82
|
+
# Keyset extra: Paginate with the Pagy keyset pagination technique
|
83
|
+
# See http://ddnexus.github.io/pagy/extras/keyset
|
84
|
+
# require 'pagy/extras/keyset'
|
85
|
+
|
82
86
|
# Meilisearch extra: Paginate `Meilisearch` result objects
|
83
87
|
# See https://ddnexus.github.io/pagy/docs/extras/meilisearch
|
84
88
|
# Default :pagy_search method: change only if you use also
|
data/javascripts/pagy.min.js
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
window.Pagy=(()=>{const j=new ResizeObserver((B)=>B.forEach((D)=>D.target.querySelectorAll(".pagy-rjs").forEach((E)=>E.pagyRender()))),x=(B,[D,E,z,G])=>{const F=B.parentElement??B,K=Object.keys(E).map((H)=>parseInt(H)).sort((H,M)=>M-H);let L=-1;const T=(H,M,R)=>H.replace(/__pagy_page__/g,M).replace(/__pagy_label__/g,R);if((B.pagyRender=function(){const H=K.find((Q)=>Q<F.clientWidth)||0;if(H===L)return;let M=D.before;const R=E[H.toString()],X=z?.[H.toString()]??R.map((Q)=>Q.toString());R.forEach((Q,J)=>{const $=X[J];let U;if(typeof Q==="number")U=T(D.a,Q.toString(),$);else if(Q==="gap")U=D.gap;else U=T(D.current,Q,$);M+=typeof G==="string"&&Q==1?Z(U,G):U}),M+=D.after,B.innerHTML="",B.insertAdjacentHTML("afterbegin",M),L=H})(),B.classList.contains("pagy-rjs"))j.observe(F)},A=(B,[D,E])=>Y(B,(z)=>[z,D.replace(/__pagy_page__/,z)],E),C=(B,[D,E,z])=>{Y(B,(G)=>{const F=Math.max(Math.ceil(D/parseInt(G)),1).toString(),K=E.replace(/__pagy_page__/,F).replace(/__pagy_limit__/,G);return[F,K]},z)},Y=(B,D,E)=>{const z=B.querySelector("input"),G=B.querySelector("a"),F=z.value,K=function(){if(z.value===F)return;const[L,T,H]=[z.min,z.value,z.max].map((X)=>parseInt(X)||0);if(T<L||T>H){z.value=F,z.select();return}let[M,R]=D(z.value);if(typeof E==="string"&&M==="1")R=Z(R,E);G.href=R,G.click()};["change","focus"].forEach((L)=>z.addEventListener(L,()=>z.select())),z.addEventListener("focusout",K),z.addEventListener("keypress",(L)=>{if(L.key==="Enter")K()})},Z=(B,D)=>B.replace(new RegExp(`[?&]${D}=1\\b(?!&)|\\b${D}=1&`),"");return{version:"9.0.
|
1
|
+
window.Pagy=(()=>{const j=new ResizeObserver((B)=>B.forEach((D)=>D.target.querySelectorAll(".pagy-rjs").forEach((E)=>E.pagyRender()))),x=(B,[D,E,z,G])=>{const F=B.parentElement??B,K=Object.keys(E).map((H)=>parseInt(H)).sort((H,M)=>M-H);let L=-1;const T=(H,M,R)=>H.replace(/__pagy_page__/g,M).replace(/__pagy_label__/g,R);if((B.pagyRender=function(){const H=K.find((Q)=>Q<F.clientWidth)||0;if(H===L)return;let M=D.before;const R=E[H.toString()],X=z?.[H.toString()]??R.map((Q)=>Q.toString());R.forEach((Q,J)=>{const $=X[J];let U;if(typeof Q==="number")U=T(D.a,Q.toString(),$);else if(Q==="gap")U=D.gap;else U=T(D.current,Q,$);M+=typeof G==="string"&&Q==1?Z(U,G):U}),M+=D.after,B.innerHTML="",B.insertAdjacentHTML("afterbegin",M),L=H})(),B.classList.contains("pagy-rjs"))j.observe(F)},A=(B,[D,E])=>Y(B,(z)=>[z,D.replace(/__pagy_page__/,z)],E),C=(B,[D,E,z])=>{Y(B,(G)=>{const F=Math.max(Math.ceil(D/parseInt(G)),1).toString(),K=E.replace(/__pagy_page__/,F).replace(/__pagy_limit__/,G);return[F,K]},z)},Y=(B,D,E)=>{const z=B.querySelector("input"),G=B.querySelector("a"),F=z.value,K=function(){if(z.value===F)return;const[L,T,H]=[z.min,z.value,z.max].map((X)=>parseInt(X)||0);if(T<L||T>H){z.value=F,z.select();return}let[M,R]=D(z.value);if(typeof E==="string"&&M==="1")R=Z(R,E);G.href=R,G.click()};["change","focus"].forEach((L)=>z.addEventListener(L,()=>z.select())),z.addEventListener("focusout",K),z.addEventListener("keypress",(L)=>{if(L.key==="Enter")K()})},Z=(B,D)=>B.replace(new RegExp(`[?&]${D}=1\\b(?!&)|\\b${D}=1&`),"");return{version:"9.0.2",init(B){const E=(B instanceof Element?B:document).querySelectorAll("[data-pagy]");for(let z of E)try{const G=Uint8Array.from(atob(z.getAttribute("data-pagy")),(L)=>L.charCodeAt(0)),[F,...K]=JSON.parse((new TextDecoder()).decode(G));if(F==="nav")x(z,K);else if(F==="combo")A(z,K);else if(F==="selector")C(z,K);else console.warn("Skipped Pagy.init() for: %o\nUnknown keyword '%s'",z,F)}catch(G){console.warn("Skipped Pagy.init() for: %o\n%s",z,G)}}}})();
|
2
2
|
|
3
|
-
//# debugId=
|
3
|
+
//# debugId=F551263AEB70D01764756E2164756E21
|
4
4
|
//# sourceMappingURL=pagy.min.js.map
|
data/javascripts/pagy.min.js.map
CHANGED
@@ -2,9 +2,9 @@
|
|
2
2
|
"version": 3,
|
3
3
|
"sources": ["../../src/pagy.ts"],
|
4
4
|
"sourcesContent": [
|
5
|
-
"type NavArgs = readonly [Tokens, Sequels, null | LabelSequels, string?]\ntype ComboArgs = readonly [string, string?]\ntype SelectorArgs = readonly [number, string, string?]\ntype JsonArgs = ['nav', NavArgs] | ['combo', ComboArgs] | ['selector', SelectorArgs]\n\ninterface Tokens {\n readonly before:string\n readonly a:string\n readonly current:string\n readonly gap:string\n readonly after:string\n}\ninterface Sequels {readonly [width:string]:(string | number)[]}\ninterface LabelSequels {readonly [width:string]:string[]}\ninterface NavElement extends Element {pagyRender():void}\n\nconst Pagy = (() => {\n // The observer instance for responsive navs\n const rjsObserver = new ResizeObserver(\n entries => entries.forEach(e => e.target.querySelectorAll<NavElement>(\".pagy-rjs\")\n .forEach(el => el.pagyRender())));\n // Init the *_nav_js helpers\n const initNav = (el:NavElement, [tokens, sequels, labelSequels, trimParam]:NavArgs) => {\n const container = el.parentElement ?? el;\n const widths = Object.keys(sequels).map(w => parseInt(w)).sort((a, b) => b - a);\n let lastWidth = -1;\n const fillIn = (a:string, page:string, label:string):string =>\n a.replace(/__pagy_page__/g, page).replace(/__pagy_label__/g, label);\n (el.pagyRender = function () {\n const width = widths.find(w => w < container.clientWidth) || 0;\n if (width === lastWidth) { return } // no change: abort\n let html = tokens.before; // already trimmed in html\n const series = sequels[width.toString()];\n const labels = labelSequels?.[width.toString()] ?? series.map(l => l.toString());\n series.forEach((item, i) => {\n const label = labels[i];\n let filled;\n if (typeof item === \"number\") {\n filled = fillIn(tokens.a, item.toString(), label);\n } else if (item === \"gap\") {\n filled = tokens.gap;\n } else { // active page\n filled = fillIn(tokens.current, item, label);\n }\n html += (typeof trimParam === \"string\" && item == 1) ? trim(filled, trimParam) : filled;\n });\n html += tokens.after;\n el.innerHTML = \"\";\n el.insertAdjacentHTML(\"afterbegin\", html);\n lastWidth = width;\n })();\n if (el.classList.contains(\"pagy-rjs\")) { rjsObserver.observe(container) }\n };\n\n // Init the *_combo_nav_js helpers\n const initCombo = (el:Element, [url_token, trimParam]:ComboArgs) =>\n initInput(el, inputValue => [inputValue, url_token.replace(/__pagy_page__/, inputValue)], trimParam);\n\n // Init the limit_selector_js helper\n const initSelector = (el:Element, [from, url_token, trimParam]:SelectorArgs) => {\n initInput(el, inputValue => {\n const page = Math.max(Math.ceil(from / parseInt(inputValue)), 1).toString();\n const url = url_token.replace(/__pagy_page__/, page).replace(/__pagy_limit__/, inputValue);\n return [page, url];\n }, trimParam);\n };\n\n // Init the input element\n const initInput = (el:Element, getVars:(v:string) => [string, string], trimParam?:string) => {\n const input = el.querySelector(\"input\") as HTMLInputElement;\n const link = el.querySelector(\"a\") as HTMLAnchorElement;\n const initial = input.value;\n const action = function () {\n if (input.value === initial) { return } // not changed\n const [min, val, max] = [input.min, input.value, input.max].map(n => parseInt(n) || 0);\n if (val < min || val > max) { // reset invalid/out-of-range\n input.value = initial;\n input.select();\n return;\n }\n let [page, url] = getVars(input.value); // eslint-disable-line prefer-const\n if (typeof trimParam === \"string\" && page === \"1\") { url = trim(url, trimParam) }\n link.href = url;\n link.click();\n };\n [\"change\", \"focus\"].forEach(e => input.addEventListener(e, () => input.select())); // auto-select\n input.addEventListener(\"focusout\", action); // trigger action\n input.addEventListener(\"keypress\", e => { if (e.key === \"Enter\") { action() } }); // trigger action\n };\n\n // Trim the ${page-param}=1 params in links\n const trim = (a:string, param:string) =>\n a.replace(new RegExp(`[?&]${param}=1\\\\b(?!&)|\\\\b${param}=1&`), \"\");\n\n // Public interface\n return {\n version: \"9.0.
|
5
|
+
"type NavArgs = readonly [Tokens, Sequels, null | LabelSequels, string?]\ntype ComboArgs = readonly [string, string?]\ntype SelectorArgs = readonly [number, string, string?]\ntype JsonArgs = ['nav', NavArgs] | ['combo', ComboArgs] | ['selector', SelectorArgs]\n\ninterface Tokens {\n readonly before:string\n readonly a:string\n readonly current:string\n readonly gap:string\n readonly after:string\n}\ninterface Sequels {readonly [width:string]:(string | number)[]}\ninterface LabelSequels {readonly [width:string]:string[]}\ninterface NavElement extends Element {pagyRender():void}\n\nconst Pagy = (() => {\n // The observer instance for responsive navs\n const rjsObserver = new ResizeObserver(\n entries => entries.forEach(e => e.target.querySelectorAll<NavElement>(\".pagy-rjs\")\n .forEach(el => el.pagyRender())));\n // Init the *_nav_js helpers\n const initNav = (el:NavElement, [tokens, sequels, labelSequels, trimParam]:NavArgs) => {\n const container = el.parentElement ?? el;\n const widths = Object.keys(sequels).map(w => parseInt(w)).sort((a, b) => b - a);\n let lastWidth = -1;\n const fillIn = (a:string, page:string, label:string):string =>\n a.replace(/__pagy_page__/g, page).replace(/__pagy_label__/g, label);\n (el.pagyRender = function () {\n const width = widths.find(w => w < container.clientWidth) || 0;\n if (width === lastWidth) { return } // no change: abort\n let html = tokens.before; // already trimmed in html\n const series = sequels[width.toString()];\n const labels = labelSequels?.[width.toString()] ?? series.map(l => l.toString());\n series.forEach((item, i) => {\n const label = labels[i];\n let filled;\n if (typeof item === \"number\") {\n filled = fillIn(tokens.a, item.toString(), label);\n } else if (item === \"gap\") {\n filled = tokens.gap;\n } else { // active page\n filled = fillIn(tokens.current, item, label);\n }\n html += (typeof trimParam === \"string\" && item == 1) ? trim(filled, trimParam) : filled;\n });\n html += tokens.after;\n el.innerHTML = \"\";\n el.insertAdjacentHTML(\"afterbegin\", html);\n lastWidth = width;\n })();\n if (el.classList.contains(\"pagy-rjs\")) { rjsObserver.observe(container) }\n };\n\n // Init the *_combo_nav_js helpers\n const initCombo = (el:Element, [url_token, trimParam]:ComboArgs) =>\n initInput(el, inputValue => [inputValue, url_token.replace(/__pagy_page__/, inputValue)], trimParam);\n\n // Init the limit_selector_js helper\n const initSelector = (el:Element, [from, url_token, trimParam]:SelectorArgs) => {\n initInput(el, inputValue => {\n const page = Math.max(Math.ceil(from / parseInt(inputValue)), 1).toString();\n const url = url_token.replace(/__pagy_page__/, page).replace(/__pagy_limit__/, inputValue);\n return [page, url];\n }, trimParam);\n };\n\n // Init the input element\n const initInput = (el:Element, getVars:(v:string) => [string, string], trimParam?:string) => {\n const input = el.querySelector(\"input\") as HTMLInputElement;\n const link = el.querySelector(\"a\") as HTMLAnchorElement;\n const initial = input.value;\n const action = function () {\n if (input.value === initial) { return } // not changed\n const [min, val, max] = [input.min, input.value, input.max].map(n => parseInt(n) || 0);\n if (val < min || val > max) { // reset invalid/out-of-range\n input.value = initial;\n input.select();\n return;\n }\n let [page, url] = getVars(input.value); // eslint-disable-line prefer-const\n if (typeof trimParam === \"string\" && page === \"1\") { url = trim(url, trimParam) }\n link.href = url;\n link.click();\n };\n [\"change\", \"focus\"].forEach(e => input.addEventListener(e, () => input.select())); // auto-select\n input.addEventListener(\"focusout\", action); // trigger action\n input.addEventListener(\"keypress\", e => { if (e.key === \"Enter\") { action() } }); // trigger action\n };\n\n // Trim the ${page-param}=1 params in links\n const trim = (a:string, param:string) =>\n a.replace(new RegExp(`[?&]${param}=1\\\\b(?!&)|\\\\b${param}=1&`), \"\");\n\n // Public interface\n return {\n version: \"9.0.2\",\n\n // Scan for elements with a \"data-pagy\" attribute and call their init functions with the decoded args\n init(arg?:Element) {\n const target = arg instanceof Element ? arg : document;\n const elements = target.querySelectorAll(\"[data-pagy]\");\n for (const el of elements) {\n try {\n const uint8array = Uint8Array.from(atob(el.getAttribute(\"data-pagy\") as string), c => c.charCodeAt(0));\n const [keyword, ...args] = JSON.parse((new TextDecoder()).decode(uint8array)) as JsonArgs; // base64-utf8 -> JSON -> Array\n if (keyword === \"nav\") {\n initNav(el as NavElement, args as unknown as NavArgs);\n } else if (keyword === \"combo\") {\n initCombo(el, args as unknown as ComboArgs);\n } else if (keyword === \"selector\") {\n initSelector(el, args as unknown as SelectorArgs);\n } else {\n console.warn(\"Skipped Pagy.init() for: %o\\nUnknown keyword '%s'\", el, keyword);\n }\n } catch (err) { console.warn(\"Skipped Pagy.init() for: %o\\n%s\", el, err) }\n }\n }\n };\n})();\n\nexport default Pagy;\n"
|
6
6
|
],
|
7
7
|
"mappings": "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",
|
8
|
-
"debugId": "
|
8
|
+
"debugId": "F551263AEB70D01764756E2164756E21",
|
9
9
|
"names": []
|
10
10
|
}
|
data/javascripts/pagy.mjs
CHANGED
@@ -73,7 +73,7 @@ const Pagy = (() => {
|
|
73
73
|
};
|
74
74
|
const trim = (a, param) => a.replace(new RegExp(`[?&]${param}=1\\b(?!&)|\\b${param}=1&`), "");
|
75
75
|
return {
|
76
|
-
version: "9.0.
|
76
|
+
version: "9.0.2",
|
77
77
|
init(arg) {
|
78
78
|
const target = arg instanceof Element ? arg : document;
|
79
79
|
const elements = target.querySelectorAll("[data-pagy]");
|
@@ -12,7 +12,7 @@ class Pagy # :nodoc:
|
|
12
12
|
|
13
13
|
# Return Pagy object and records
|
14
14
|
def pagy_countless(collection, **vars)
|
15
|
-
pagy = Countless.new(**
|
15
|
+
pagy = Countless.new(**pagy_countless_get_vars(collection, vars))
|
16
16
|
[pagy, pagy_countless_get_items(collection, pagy)]
|
17
17
|
end
|
18
18
|
|
@@ -25,6 +25,15 @@ class Pagy # :nodoc:
|
|
25
25
|
pagy.finalize(fetched.size) # finalize the pagy object
|
26
26
|
fetched[0, pagy.limit] # ignore eventual extra item
|
27
27
|
end
|
28
|
+
|
29
|
+
# Sub-method called only by #pagy: here for easy customization of variables by overriding
|
30
|
+
# You may need to override the count call for non AR collections
|
31
|
+
def pagy_countless_get_vars(_collection, vars)
|
32
|
+
vars.tap do |v|
|
33
|
+
v[:limit] ||= pagy_get_limit(v)
|
34
|
+
v[:page] ||= pagy_get_page(v)
|
35
|
+
end
|
36
|
+
end
|
28
37
|
end
|
29
38
|
Backend.prepend CountlessExtra
|
30
39
|
end
|
data/lib/pagy/extras/headers.rb
CHANGED
@@ -22,7 +22,7 @@ class Pagy # :nodoc:
|
|
22
22
|
# Generate a hash of RFC-8288 compliant http headers
|
23
23
|
def pagy_headers(pagy)
|
24
24
|
headers = pagy.vars[:headers]
|
25
|
-
|
25
|
+
pagy_link_header(pagy).tap do |hash|
|
26
26
|
hash[headers[:page]] = pagy.page.to_s if pagy.page && headers[:page]
|
27
27
|
hash[headers[:limit]] = pagy.limit.to_s \
|
28
28
|
if headers[:limit] && !(defined?(Calendar) && pagy.is_a?(Calendar::Unit))
|
@@ -34,8 +34,8 @@ class Pagy # :nodoc:
|
|
34
34
|
end
|
35
35
|
end
|
36
36
|
|
37
|
-
def
|
38
|
-
[].tap do |link|
|
37
|
+
def pagy_link_header(pagy)
|
38
|
+
{ 'link' => [].tap do |link|
|
39
39
|
if defined?(Keyset) && pagy.is_a?(Keyset)
|
40
40
|
link << %(<#{pagy_url_for(pagy, nil, absolute: true)}>; rel="first")
|
41
41
|
link << %(<#{pagy_url_for(pagy, pagy.next, absolute: true)}>; rel="next") if pagy.next
|
@@ -47,7 +47,7 @@ class Pagy # :nodoc:
|
|
47
47
|
link << %(<#{url_str.sub(PAGE_TOKEN, pagy.last.to_s)}>; rel="last") \
|
48
48
|
unless defined?(Countless) && pagy.is_a?(Countless)
|
49
49
|
end
|
50
|
-
end.join(', ')
|
50
|
+
end.join(', ') }
|
51
51
|
end
|
52
52
|
end
|
53
53
|
Backend.prepend HeadersExtra
|
data/lib/pagy/extras/keyset.rb
CHANGED
@@ -21,6 +21,16 @@ class Pagy # :nodoc:
|
|
21
21
|
v[:limit] ||= pagy_get_limit(v)
|
22
22
|
end
|
23
23
|
end
|
24
|
+
|
25
|
+
# Return the URL string for the first page
|
26
|
+
def pagy_keyset_first_url(pagy, **vars)
|
27
|
+
pagy_url_for(pagy, nil, **vars)
|
28
|
+
end
|
29
|
+
|
30
|
+
# Return the URL string for the next page or nil
|
31
|
+
def pagy_keyset_next_url(pagy, **vars)
|
32
|
+
pagy_url_for(pagy, pagy.next, **vars) if pagy.next
|
33
|
+
end
|
24
34
|
end
|
25
35
|
Backend.prepend KeysetExtra
|
26
36
|
end
|
data/lib/pagy/keyset.rb
CHANGED
@@ -3,6 +3,7 @@
|
|
3
3
|
|
4
4
|
require 'json'
|
5
5
|
require_relative 'b64'
|
6
|
+
require_relative 'shared_methods'
|
6
7
|
|
7
8
|
class Pagy
|
8
9
|
# Implement wicked-fast keyset pagination for big data
|
@@ -68,17 +69,15 @@ class Pagy
|
|
68
69
|
|
69
70
|
protected
|
70
71
|
|
71
|
-
# Prepare the literal query to filter out the already
|
72
|
+
# Prepare the literal query to filter out the already fetched records
|
72
73
|
def after_latest_query
|
73
74
|
operator = { asc: '>', desc: '<' }
|
74
75
|
directions = @keyset.values
|
75
|
-
if @vars[:
|
76
|
-
# Row comparison: check if your DB supports it (especially if you have mixed order rows)
|
76
|
+
if @vars[:tuple_comparison] && (directions.all?(:asc) || directions.all?(:desc))
|
77
77
|
columns = @keyset.keys
|
78
78
|
placeholders = columns.map { |column| ":#{column}" }.join(', ')
|
79
79
|
"( #{columns.join(', ')} ) #{operator[directions.first]} ( #{placeholders} )"
|
80
80
|
else
|
81
|
-
# Generic comparison: works for keysets ordered in mixed or same directions
|
82
81
|
keyset = @keyset.to_a
|
83
82
|
where = []
|
84
83
|
until keyset.empty?
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Pagy
|
4
|
+
# Shared with Keyset
|
5
|
+
module SharedMethods
|
6
|
+
attr_reader :page, :limit, :vars
|
7
|
+
|
8
|
+
# Validates and assign the passed vars: var must be present and value.to_i must be >= to min
|
9
|
+
def assign_and_check(name_min)
|
10
|
+
name_min.each do |name, min|
|
11
|
+
raise VariableError.new(self, name, ">= #{min}", @vars[name]) \
|
12
|
+
unless @vars[name]&.respond_to?(:to_i) && \
|
13
|
+
instance_variable_set(:"@#{name}", @vars[name].to_i) >= min
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# Assign @limit (overridden by the gearbox extra)
|
18
|
+
def assign_limit
|
19
|
+
assign_and_check(limit: 1)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Assign @vars
|
23
|
+
def assign_vars(default, vars)
|
24
|
+
@vars = { **default, **vars.delete_if { |k, v| default.key?(k) && (v.nil? || v == '') } }
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/pagy/url_helpers.rb
CHANGED
@@ -19,7 +19,7 @@ class Pagy
|
|
19
19
|
# Add the page and limit params
|
20
20
|
# Overridable by the jsonapi extra
|
21
21
|
def pagy_set_query_params(page, vars, query_params)
|
22
|
-
query_params[vars[:page_param].to_s] = page
|
22
|
+
query_params[vars[:page_param].to_s] = page
|
23
23
|
query_params[vars[:limit_param].to_s] = vars[:limit] if vars[:limit_extra]
|
24
24
|
end
|
25
25
|
end
|
data/lib/pagy.rb
CHANGED
@@ -2,10 +2,11 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require 'pathname'
|
5
|
+
require_relative 'pagy/shared_methods'
|
5
6
|
|
6
7
|
# Top superclass: it should define only what's common to all the subclasses
|
7
8
|
class Pagy
|
8
|
-
VERSION = '9.0.
|
9
|
+
VERSION = '9.0.2'
|
9
10
|
|
10
11
|
# Core default: constant for easy access, but mutable for customizable defaults
|
11
12
|
DEFAULT = { count_args: [:all], # rubocop:disable Style/MutableConstant
|
@@ -21,29 +22,6 @@ class Pagy
|
|
21
22
|
@root ||= Pathname.new(__dir__).parent.freeze
|
22
23
|
end
|
23
24
|
|
24
|
-
# Shared with Keyset
|
25
|
-
module SharedMethods
|
26
|
-
attr_reader :page, :limit, :vars
|
27
|
-
|
28
|
-
# Validates and assign the passed vars: var must be present and value.to_i must be >= to min
|
29
|
-
def assign_and_check(name_min)
|
30
|
-
name_min.each do |name, min|
|
31
|
-
raise VariableError.new(self, name, ">= #{min}", @vars[name]) \
|
32
|
-
unless @vars[name]&.respond_to?(:to_i) && \
|
33
|
-
instance_variable_set(:"@#{name}", @vars[name].to_i) >= min
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
# Assign @limit (overridden by the gearbox extra)
|
38
|
-
def assign_limit
|
39
|
-
assign_and_check(limit: 1)
|
40
|
-
end
|
41
|
-
|
42
|
-
# Assign @vars
|
43
|
-
def assign_vars(default, vars)
|
44
|
-
@vars = { **default, **vars.delete_if { |k, v| default.key?(k) && (v.nil? || v == '') } }
|
45
|
-
end
|
46
|
-
end
|
47
25
|
include SharedMethods
|
48
26
|
|
49
27
|
attr_reader :count, :from, :in, :last, :next, :offset, :prev, :to
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pagy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 9.0.
|
4
|
+
version: 9.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Domizio Demichelis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-07-
|
11
|
+
date: 2024-07-20 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Agnostic pagination in plain ruby. It does it all. Better.
|
14
14
|
email:
|
@@ -82,6 +82,7 @@ files:
|
|
82
82
|
- lib/pagy/keyset.rb
|
83
83
|
- lib/pagy/keyset/active_record.rb
|
84
84
|
- lib/pagy/keyset/sequel.rb
|
85
|
+
- lib/pagy/shared_methods.rb
|
85
86
|
- lib/pagy/url_helpers.rb
|
86
87
|
- locales/ar.yml
|
87
88
|
- locales/be.yml
|
@@ -119,7 +120,6 @@ files:
|
|
119
120
|
- locales/zh-CN.yml
|
120
121
|
- locales/zh-HK.yml
|
121
122
|
- locales/zh-TW.yml
|
122
|
-
- pkg/pagy-9.0.0.gem
|
123
123
|
- stylesheets/pagy.css
|
124
124
|
- stylesheets/pagy.scss
|
125
125
|
- stylesheets/pagy.tailwind.css
|
data/pkg/pagy-9.0.0.gem
DELETED
Binary file
|