drive 0.23.0 → 0.24.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 58e9f6a2677e071843a4bf8f1ad9f8b1946c522461888b0accb86924d20a6ded
4
- data.tar.gz: ec1a65b60c6f8171253c83b382f18194fcb96af344872dd139c78f75a0aef32e
3
+ metadata.gz: 997efef34fcfa1c15ac00a55be7dbc1d4859550071a8f2e3dd183d136537ebaf
4
+ data.tar.gz: 5901698e48b529d2bcbec483d3b750f66c476f346c03e11767f43dabba021c9b
5
5
  SHA512:
6
- metadata.gz: 6d311ad2ade0e6b7a4a18b61d6c0211d155c4228c40c8d27eafedd8b9a9aa6a91ec08d449181ea144593109666623bfa25e9ffc206076862470104be77f30e50
7
- data.tar.gz: 5d815b355a96036c180dfdd61b999fd18f3d2042813f3c4b1ebcebbf624cb1c712ef8ec7465e56f8330ac33944182c0460159b2a7d1688cef46acfb70adb98ed
6
+ metadata.gz: 1810c82f86dc0cb889f86468e74d9927618f1b0b2d5cfd879afe593b016051ebca9577069d2d5f8b73046c325146ca9bcfe839fe08a809af800193404fe956e2
7
+ data.tar.gz: 3b2d8fd49ccbda6b77c223e01876ede32b805968065c4e9fea8f3bbc8e248c2e5ece52a4cefebd5659dc8c64c1298e1be4c697dce8f1e965f00937460ef5ac0a
data/CHANGELOG.md CHANGED
@@ -6,6 +6,11 @@ For more information about changelogs, check [Keep a Changelog](http://keepachan
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## 0.24.0 - 2026-11-09
10
+
11
+ * [FEATURE] `easy/report_head`: the head of a report or list as a partial, with its heading, switches, search and a sort
12
+ button, flipped in the browser by `easy/report_sort`.
13
+
9
14
  ## 0.23.0 - 2026-11-09
10
15
 
11
16
  * [FEATURE] A `calendar` icon in the sprite.
@@ -0,0 +1,44 @@
1
+ // The sort button of easy/report_head: flips the list named by data-sort-list by each row's data-sort, remembered in
2
+ // this browser. ES5 alone. A page that redraws its list calls window.easyReportSort() after. Without this script the
3
+ // list stays as the server sent it, and the button hidden.
4
+ (function () {
5
+ function saved(head) {
6
+ try { return localStorage.getItem('report-sort:' + head.getAttribute('data-sort-list')); } catch (blocked) { return null; }
7
+ }
8
+
9
+ function save(head, order) {
10
+ try { localStorage.setItem('report-sort:' + head.getAttribute('data-sort-list'), order); } catch (blocked) { return; }
11
+ }
12
+
13
+ function order(head) { return head.easyOrder || saved(head) || head.getAttribute('data-sort-default'); }
14
+
15
+ function compared(a, b) {
16
+ return a.getAttribute('data-sort').localeCompare(b.getAttribute('data-sort'), undefined, { numeric: true });
17
+ }
18
+
19
+ function apply(head) {
20
+ var list = document.querySelector(head.getAttribute('data-sort-list')), item = head.querySelector('.sort-button-item');
21
+ if (!list || !item) { return; }
22
+ var way = order(head), newest = way === 'newest';
23
+ Array.prototype.slice.call(list.children).filter(function (row) { return row.hasAttribute('data-sort'); })
24
+ .sort(function (a, b) { return newest ? compared(b, a) : compared(a, b); })
25
+ .forEach(function (row) { list.appendChild(row); });
26
+ item.hidden = false;
27
+ item.querySelector('.js-sort-label').textContent = newest ? 'Newest first' : 'Oldest first';
28
+ var icon = item.querySelector('use'), ref = icon.getAttribute('href').split('#')[0] + '#i-' + way;
29
+ icon.setAttribute('href', ref);
30
+ icon.setAttribute('xlink:href', ref);
31
+ }
32
+
33
+ window.easyReportSort = function () { Array.prototype.forEach.call(document.querySelectorAll('[data-sort-list]'), apply); };
34
+
35
+ document.addEventListener('click', function (event) {
36
+ var button = event.target.closest && event.target.closest('.js-sort'), head = button && button.closest('[data-sort-list]');
37
+ if (!head) { return; }
38
+ head.easyOrder = order(head) === 'newest' ? 'oldest' : 'newest';
39
+ save(head, head.easyOrder);
40
+ apply(head);
41
+ });
42
+
43
+ window.easyReportSort();
44
+ }());
@@ -91,7 +91,10 @@
91
91
  .word-search:focus-within{border-color:var(--color-primary);box-shadow:0 0 0 3px var(--color-primary-soft)}
92
92
  .word-search .i{color:var(--color-text-muted);margin-right:8px;flex:none}
93
93
  .word-search input{flex:1;min-width:0;border:0;background:transparent;color:var(--color-text);font:inherit;font-size:16px;padding:5px 0;outline:0}
94
- .switches li.sort-button-item{margin:0 0 0 auto;padding:0;border:0;background:none}
94
+ .switches li.sort-button-item{margin:6px 0 6px auto;padding:0;border:0;background:none}
95
+ .sort-button-item .sort-button{margin:0}
96
+ @media (max-width:600px){.switches li.sort-button-item{margin-left:6px}}
97
+ .report-search[hidden]{display:none}
95
98
  .sort-button{flex:none;margin:6px 0 6px 12px;display:inline-flex;align-items:center;border:0;border-radius:8px;background:none;color:var(--color-text);font:inherit;font-size:15px;font-weight:600;padding:8px 4px;cursor:pointer;white-space:nowrap}
96
99
  .sort-button .i{margin-right:8px}
97
100
  .sort-button:hover{color:var(--color-primary)}
@@ -0,0 +1,19 @@
1
+ <%# locals: (heading: nil, heading_id: nil, before: nil, switches_id: "switches", switches: [], after: nil, search: nil, search_label: search, sort_list: nil, sort_default: "newest") -%>
2
+ <%# The head of a report or list: its heading, its switches (each { state:, css:, icon:, count:, label:, off: }), with the
3
+ sort button at their end, and a search. before and after go above and below the switches. sort_list is the list the
4
+ button flips by each row's data-sort (easy/report_sort); without it the page sorts by itself. -%>
5
+ <%= tag.section class: "report-head", data: { sort_list:, sort_default: (sort_default if sort_list) }.compact do %>
6
+ <% if heading %><%= tag.h2 heading, id: heading_id %><% end %>
7
+ <%= before %>
8
+ <% if switches.any? %>
9
+ <%= tag.ul class: "switches levels", id: switches_id do %>
10
+ <% switches.each do |item| %>
11
+ <%= tag.li class: item[:css], data: { state: item[:state], off: item[:off] }.compact do %><% if item[:icon] %><%= easy_icon item[:icon] %><% end %><span class="n"><%= item[:count] %></span> <%= item[:label] %><% end %>
12
+ <% end %>
13
+ <li class="sort-button-item" hidden><button type="button" class="sort-button js-sort"><%= easy_icon sort_default %><span class="js-sort-label"><%= sort_default.capitalize %> first</span></button></li>
14
+ <% end %>
15
+ <% end %>
16
+ <%= after %>
17
+ <% if search %><label class="word-search report-search js-words" hidden><%= easy_icon "search" %><input type="search" placeholder="<%= search %>" aria-label="<%= search_label %>" autocomplete="off" spellcheck="false"></label><% end %>
18
+ <% end %>
19
+ <% if sort_list %><%= javascript_include_tag "easy/report_sort", defer: true %><% end %>
data/lib/drive/version.rb CHANGED
@@ -1,4 +1,4 @@
1
1
  module Drive
2
2
  # Version of the gem, read by the gemspec.
3
- VERSION = '0.23.0'.freeze
3
+ VERSION = '0.24.0'.freeze
4
4
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: drive
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.23.0
4
+ version: 0.24.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - claudiob
@@ -41,6 +41,7 @@ files:
41
41
  - app/assets/javascripts/easy/konami.js
42
42
  - app/assets/javascripts/easy/modal.js
43
43
  - app/assets/javascripts/easy/pin_code.js
44
+ - app/assets/javascripts/easy/report_sort.js
44
45
  - app/assets/javascripts/easy/rotating_placeholder.js
45
46
  - app/assets/stylesheets/easy/base.css
46
47
  - app/assets/stylesheets/easy/components.css
@@ -58,6 +59,7 @@ files:
58
59
  - app/views/easy/_flyer.html.erb
59
60
  - app/views/easy/_modal.html.erb
60
61
  - app/views/easy/_pin_code.html.erb
62
+ - app/views/easy/_report_head.html.erb
61
63
  - app/views/easy/mailer/_code.html.erb
62
64
  - app/views/easy/mailer/_code.text.erb
63
65
  - app/views/layouts/drive/errors.html.erb