mensa 0.6.13 → 0.6.14

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.
Files changed (40) hide show
  1. checksums.yaml +4 -4
  2. data/.shipkit.yml +1 -1
  3. data/Gemfile.lock +1 -1
  4. data/README.md +38 -9
  5. data/app/assets/stylesheets/mensa/application.css +2 -0
  6. data/app/components/mensa/cell/component.html.erb +1 -1
  7. data/app/components/mensa/control_bar/component.html.erb +1 -0
  8. data/app/components/mensa/filter_pill_list/component_controller.js +55 -1
  9. data/app/components/mensa/group_by/component.css +49 -0
  10. data/app/components/mensa/group_by/component.html.erb +41 -0
  11. data/app/components/mensa/group_by/component.rb +27 -0
  12. data/app/components/mensa/group_by/component_controller.js +168 -0
  13. data/app/components/mensa/group_header/component.css +39 -0
  14. data/app/components/mensa/group_header/component.html.erb +34 -0
  15. data/app/components/mensa/group_header/component.rb +40 -0
  16. data/app/components/mensa/group_header/component_controller.js +63 -0
  17. data/app/components/mensa/table/component_controller.js +30 -1
  18. data/app/components/mensa/table_row/component.html.erb +1 -1
  19. data/app/components/mensa/table_row/component.rb +9 -1
  20. data/app/components/mensa/view/component.html.erb +17 -3
  21. data/app/controllers/mensa/tables/exports_controller.rb +1 -0
  22. data/app/controllers/mensa/tables/views_controller.rb +1 -1
  23. data/app/controllers/mensa/tables_controller.rb +3 -1
  24. data/app/javascript/mensa/controllers/index.js +6 -0
  25. data/app/tables/mensa/base.rb +14 -1
  26. data/app/tables/mensa/cell.rb +31 -4
  27. data/app/tables/mensa/column.rb +18 -0
  28. data/app/tables/mensa/config/column_dsl.rb +10 -0
  29. data/app/tables/mensa/config/table_dsl.rb +5 -0
  30. data/app/tables/mensa/config/view_dsl.rb +2 -0
  31. data/app/tables/mensa/filter.rb +17 -14
  32. data/app/tables/mensa/group.rb +47 -0
  33. data/app/tables/mensa/grouping.rb +94 -0
  34. data/app/tables/mensa/row.rb +5 -0
  35. data/app/tables/mensa/scope.rb +20 -12
  36. data/config/locales/en.yml +12 -0
  37. data/config/locales/nl.yml +12 -0
  38. data/lib/mensa/configuration.rb +6 -0
  39. data/lib/mensa/version.rb +1 -1
  40. metadata +12 -2
@@ -5,6 +5,7 @@ module Mensa
5
5
  module Scope
6
6
  extend ActiveSupport::Concern
7
7
  include Search
8
+ include Grouping
8
9
 
9
10
  included do
10
11
  end
@@ -28,16 +29,17 @@ module Mensa
28
29
  def ordered_scope
29
30
  return @ordered_scope if @ordered_scope
30
31
 
31
- @ordered_scope = filtered_scope
32
- @ordered_scope = if effective_order.present?
33
- @ordered_scope.reorder(effective_order)
34
- elsif search_order_clause.present?
35
- @ordered_scope.reorder(Arel.sql(search_order_clause))
36
- else
37
- @ordered_scope.reorder(nil)
38
- end
32
+ # Builds the search order clause too, so do this first
33
+ relation = filtered_scope
34
+
35
+ # Grouped rows are sorted by the group first, so groups stay together
36
+ clauses = []
37
+ clauses << group_order_clause if grouped?
38
+ clauses << effective_order(except: group_column&.name)
39
+ clauses << search_order_clause if clauses.last.blank?
40
+ clause = clauses.compact_blank.join(", ")
39
41
 
40
- @ordered_scope
42
+ @ordered_scope = relation.reorder(clause.presence && Arel.sql(clause))
41
43
  end
42
44
 
43
45
  # Return the ordered_scope, but with only the columns selected
@@ -48,6 +50,7 @@ module Mensa
48
50
 
49
51
  @selected_scope = ordered_scope
50
52
  @selected_scope = @selected_scope.select((id_column? ? [:id] : []) + columns.filter_map(&:attribute))
53
+ @selected_scope = @selected_scope.select(group_select) if grouped?
51
54
 
52
55
  @selected_scope
53
56
  end
@@ -116,18 +119,23 @@ module Mensa
116
119
  # Effective ordering for SQL: when the request includes any order[] params
117
120
  # (even with blank values), use only those — blank means "explicitly no sort".
118
121
  # Falls back to the view/config default only when no order params were sent.
119
- def effective_order
122
+ def effective_order(except: nil)
120
123
  result = current_order_provided? ? (current_order || {}) : (config[:order] || {})
121
- result = result.symbolize_keys.compact_blank.transform_values(&:to_sym)
122
- result.filter_map { |k, v|
124
+ result = result.symbolize_keys.compact_blank.transform_values { |v| v.to_s.downcase }
125
+ clause = result.filter_map { |k, v|
126
+ next if k == except
127
+
123
128
  col = column(k)
124
129
  # Skip orders on unknown names, e.g. from browser state saved for
125
130
  # different params.
126
131
  next unless col || model_attribute?(k)
132
+ next unless %w[asc desc].include?(v)
127
133
 
128
134
  attribute = col&.attribute_for_condition || k
129
135
  "#{attribute} #{v} NULLS LAST"
130
136
  }.join(", ")
137
+
138
+ clause.presence && Arel.sql(clause)
131
139
  end
132
140
 
133
141
  def model_attribute?(name)
@@ -2,6 +2,18 @@ en:
2
2
  mensa:
3
3
  column_customizer:
4
4
  heading: Columns
5
+ group_by:
6
+ heading: Group by
7
+ none: No grouping
8
+ aggregates: Calculations
9
+ groups:
10
+ empty: No %{column}
11
+ aggregates:
12
+ none: None
13
+ count: Count
14
+ sum: Sum
15
+ min: Min
16
+ max: Max
5
17
  tables:
6
18
  filters:
7
19
  show:
@@ -2,6 +2,18 @@ nl:
2
2
  mensa:
3
3
  column_customizer:
4
4
  heading: Kolommen
5
+ group_by:
6
+ heading: Groeperen op
7
+ none: Niet groeperen
8
+ aggregates: Berekeningen
9
+ groups:
10
+ empty: Geen %{column}
11
+ aggregates:
12
+ none: Geen
13
+ count: Aantal
14
+ sum: Som
15
+ min: Min
16
+ max: Max
5
17
  tables:
6
18
  filters:
7
19
  show:
@@ -57,6 +57,9 @@ module Mensa
57
57
  filter_pill_remove: "fa-solid fa-xmark",
58
58
  filter_pill_list_search: "fa-solid fa-sm fa-magnifying-glass",
59
59
  filter_pill_list_clear: "fa-solid fa-xmark",
60
+ group_by_toggle: "fa-regular fa-rectangle-list",
61
+ group_by_selected: "fa-solid fa-check",
62
+ group_toggle: "fa-solid fa-chevron-down",
60
63
  header_order_indicator_asc: "fa-solid fa-sm fa-arrow-up",
61
64
  header_order_indicator_desc: "fa-solid fa-sm fa-arrow-down",
62
65
  header_order_indicator_numeric_asc: "fa-solid fa-sm fa-arrow-down-1-9",
@@ -97,6 +100,9 @@ module Mensa
97
100
  # filter_pill_remove: "fa-light fa-xmark",
98
101
  # filter_pill_list_search: "fa-light fa-sm fa-magnifying-glass",
99
102
  # filter_pill_list_clear: "fa-light fa-xmark",
103
+ # group_by_toggle: "fa-light fa-rectangle-list",
104
+ # group_by_selected: "fa-light fa-check",
105
+ # group_toggle: "fa-light fa-chevron-down",
100
106
  # header_order_indicator_asc: "fa-regular fa-sm fa-arrow-up-short-wide",
101
107
  # header_order_indicator_desc: "fa-regular fa-sm fa-arrow-down-wide-short",
102
108
  # views_trigger: "fa-light fa-sort",
data/lib/mensa/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Mensa
2
- VERSION = "0.6.13"
2
+ VERSION = "0.6.14"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mensa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.13
4
+ version: 0.6.14
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom de Grunt
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2026-10-09 00:00:00.000000000 Z
11
+ date: 2026-10-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -209,6 +209,14 @@ files:
209
209
  - app/components/mensa/filter_pill_list/component.html.erb
210
210
  - app/components/mensa/filter_pill_list/component.rb
211
211
  - app/components/mensa/filter_pill_list/component_controller.js
212
+ - app/components/mensa/group_by/component.css
213
+ - app/components/mensa/group_by/component.html.erb
214
+ - app/components/mensa/group_by/component.rb
215
+ - app/components/mensa/group_by/component_controller.js
216
+ - app/components/mensa/group_header/component.css
217
+ - app/components/mensa/group_header/component.html.erb
218
+ - app/components/mensa/group_header/component.rb
219
+ - app/components/mensa/group_header/component_controller.js
212
220
  - app/components/mensa/header/component.css
213
221
  - app/components/mensa/header/component.html.erb
214
222
  - app/components/mensa/header/component.rb
@@ -274,6 +282,8 @@ files:
274
282
  - app/tables/mensa/config_readers.rb
275
283
  - app/tables/mensa/filter.rb
276
284
  - app/tables/mensa/format.rb
285
+ - app/tables/mensa/group.rb
286
+ - app/tables/mensa/grouping.rb
277
287
  - app/tables/mensa/row.rb
278
288
  - app/tables/mensa/scope.rb
279
289
  - app/tables/mensa/search.rb