diff options
| author | erdgeist <erdgeist@erdgeist.org> | 2026-07-11 00:53:53 +0200 |
|---|---|---|
| committer | erdgeist <erdgeist@erdgeist.org> | 2026-07-11 00:53:53 +0200 |
| commit | 876697bdff7e03d98a7a426895b4e5dcc07c5a88 (patch) | |
| tree | c467325da4bef60f8831324f2bd8dcec59aecfc3 | |
| parent | ab392d472c15eee3618cb7c02b2b4707151598b6 (diff) | |
Style admin pagination widget, add missing locale keys
Pagination had almost no styling, and its current-page selector never
matched will_paginate's actual markup. Added chip-style page links, a
solid current-page indicator, and distinct disabled states for
Previous/Next.
Previous/Next/gap rendered as empty, unlabeled elements --
will_paginate only ships English translations and this app defaults
to German. Added previous_label/next_label/page_gap to en.yml and
de.yml.
| -rw-r--r-- | config/locales/de.yml | 9 | ||||
| -rw-r--r-- | config/locales/en.yml | 9 | ||||
| -rw-r--r-- | public/stylesheets/admin.css | 42 | ||||
| -rw-r--r-- | script12.rb | 23 |
4 files changed, 82 insertions, 1 deletions
diff --git a/config/locales/de.yml b/config/locales/de.yml index 2f08984..1f2222c 100644 --- a/config/locales/de.yml +++ b/config/locales/de.yml | |||
| @@ -133,3 +133,12 @@ de: | |||
| 133 | less_than_or_equal_to: "must be less than or equal to {{count}}" | 133 | less_than_or_equal_to: "must be less than or equal to {{count}}" |
| 134 | odd: "must be odd" | 134 | odd: "must be odd" |
| 135 | even: "must be even" | 135 | even: "must be even" |
| 136 | |||
| 137 | will_paginate: | ||
| 138 | previous_label: "← Zurück" | ||
| 139 | previous_aria_label: "Vorherige Seite" | ||
| 140 | next_label: "Weiter →" | ||
| 141 | next_aria_label: "Nächste Seite" | ||
| 142 | page_gap: "…" | ||
| 143 | container_aria_label: "Seitennavigation" | ||
| 144 | page_aria_label: "Seite %{page}" | ||
diff --git a/config/locales/en.yml b/config/locales/en.yml index 980a6b8..59c7304 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml | |||
| @@ -19,3 +19,12 @@ en: | |||
| 19 | time: | 19 | time: |
| 20 | formats: | 20 | formats: |
| 21 | ccc: "%d %B, %Y %H:%M" | 21 | ccc: "%d %B, %Y %H:%M" |
| 22 | |||
| 23 | will_paginate: | ||
| 24 | previous_label: "← Previous" | ||
| 25 | previous_aria_label: "Previous page" | ||
| 26 | next_label: "Next →" | ||
| 27 | next_aria_label: "Next page" | ||
| 28 | page_gap: "…" | ||
| 29 | container_aria_label: "Pagination" | ||
| 30 | page_aria_label: "Page %{page}" | ||
diff --git a/public/stylesheets/admin.css b/public/stylesheets/admin.css index 4723f50..28b8494 100644 --- a/public/stylesheets/admin.css +++ b/public/stylesheets/admin.css | |||
| @@ -240,12 +240,52 @@ span.warning a { | |||
| 240 | div.pagination { | 240 | div.pagination { |
| 241 | padding-top: 5px; | 241 | padding-top: 5px; |
| 242 | padding-bottom: 15px; | 242 | padding-bottom: 15px; |
| 243 | display: flex; | ||
| 244 | align-items: center; | ||
| 245 | gap: 0.35rem; | ||
| 246 | } | ||
| 247 | |||
| 248 | div.pagination a, | ||
| 249 | div.pagination em.current, | ||
| 250 | div.pagination span.gap { | ||
| 251 | display: inline-flex; | ||
| 252 | align-items: center; | ||
| 253 | justify-content: center; | ||
| 254 | min-width: 1.75rem; | ||
| 255 | height: 1.75rem; | ||
| 256 | padding: 0 0.4rem; | ||
| 257 | border-radius: 4px; | ||
| 258 | font-style: normal; | ||
| 259 | } | ||
| 260 | |||
| 261 | div.pagination a { | ||
| 262 | text-decoration: underline; | ||
| 263 | text-decoration-style: wavy; | ||
| 264 | text-decoration-color: #b0b0b0; | ||
| 265 | text-decoration-thickness: 1px; | ||
| 266 | text-underline-offset: 2px; | ||
| 243 | } | 267 | } |
| 244 | 268 | ||
| 245 | div.pagination span.current, div.pagination a:hover { | 269 | div.pagination a:hover { |
| 246 | color: #ff9600; | 270 | color: #ff9600; |
| 247 | } | 271 | } |
| 248 | 272 | ||
| 273 | div.pagination em.current { | ||
| 274 | background-color: #ff9600; | ||
| 275 | color: #ffffff; | ||
| 276 | font-weight: bold; | ||
| 277 | } | ||
| 278 | |||
| 279 | div.pagination span.gap { | ||
| 280 | color: #969696; | ||
| 281 | } | ||
| 282 | |||
| 283 | div.pagination .previous_page.disabled, | ||
| 284 | div.pagination .next_page.disabled { | ||
| 285 | color: #969696; | ||
| 286 | cursor: not-allowed; | ||
| 287 | } | ||
| 288 | |||
| 249 | /* ============================================================ | 289 | /* ============================================================ |
| 250 | Buttons | 290 | Buttons |
| 251 | ============================================================ */ | 291 | ============================================================ */ |
diff --git a/script12.rb b/script12.rb new file mode 100644 index 0000000..659557c --- /dev/null +++ b/script12.rb | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | require 'timeout' | ||
| 2 | |||
| 3 | a = Node.root.children.create!(:slug => "cycle_test_a") | ||
| 4 | b = a.children.create!(:slug => "cycle_test_b") | ||
| 5 | |||
| 6 | a.staged_parent_id = b.id | ||
| 7 | a.publish_draft! | ||
| 8 | a.reload | ||
| 9 | |||
| 10 | puts "a.parent_id after staging a under its own child b: #{a.parent_id.inspect} (b.id = #{b.id})" | ||
| 11 | puts "Node.valid? => #{Node.valid?}" | ||
| 12 | |||
| 13 | begin | ||
| 14 | Timeout.timeout(3) { puts "a.level => #{a.level}" } | ||
| 15 | rescue Timeout::Error | ||
| 16 | puts "TIMED OUT after 3s -- a real cycle and a real infinite loop, confirmed" | ||
| 17 | end | ||
| 18 | |||
| 19 | # Break any cycle before cleanup -- delete_descendants does its own BFS | ||
| 20 | # the same way #level does, and would hang on a real cycle too. | ||
| 21 | Node.where(id: a.id).update_all(parent_id: nil) | ||
| 22 | b.destroy | ||
| 23 | a.destroy | ||
