mensa 0.6.15 → 0.6.17

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: cd9ef2e0b14473937b5da9f4e7d82628501bb106e03dc892c3f055a15e2c562f
4
- data.tar.gz: 8b088073a2fcc12813252c42e04ba277b97c44126e786c157a7090c253f4868a
3
+ metadata.gz: 40f5c40722b8f985ed92ec054bffb1495379772be630b967fae55f6fc77bc8b9
4
+ data.tar.gz: 1b5e668bb60387b99492c4eaf12f21fe548bdc913c4b6f9ecaa02dd3f8659b44
5
5
  SHA512:
6
- metadata.gz: 949a19530126d3a298bd4c34b10ea1c3db21c86555565f0ea7db3289cba10067f82a9ca289384c940358a34bf98d1109f364723333e9420e0c663318fffca6f7
7
- data.tar.gz: 7670004d48f01f5aeec0e56772f51a4eee30d9b910c9c11bccb57b82d22c56ae62ea4d763d5ae1fbfd99c50ac1486f055774d1bda6af2dcc390b757c534322db
6
+ metadata.gz: f36c28f26ae32c725cd0f2696e8fcd2bb57fe77cd75552f7daf24e4737e397eb91e8484a1d18b25cf6093cdef3e69a433e756e7815c10592dd29b635e4ee43f2
7
+ data.tar.gz: 516d7dfe990004a70d878561f8697e46dada6323db733eeb640625a03ff43d7e006f08d7385aaaf89b84f306636cdea2d5d1b2796d5a23aa3ed4ee88d9939cd1
data/.shipkit.yml CHANGED
@@ -1,2 +1,2 @@
1
1
  ---
2
- previous_version: 0.6.14
2
+ previous_version: 0.6.16
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.6.16
4
+
5
+ - Custom filter `scope` blocks can take the operator as a second argument,
6
+ e.g. `scope ->(value, operator) { ... }`, so they can handle `isnt`,
7
+ `is_empty` and the other operators. Existing `->(value) { ... }` scopes keep
8
+ working unchanged.
9
+
3
10
  ## 0.6.15
4
11
 
5
12
  - Custom filter `scope` blocks now work. Applied filters are built from the
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- mensa (0.6.14)
4
+ mensa (0.6.16)
5
5
  csv
6
6
  importmap-rails
7
7
  pagy (>= 43)
data/README.md CHANGED
@@ -118,6 +118,59 @@ You can show your tables on the page using the following:
118
118
  Custom views are views not defined by the developer (SystemViews) but by the end-user by adding/removing filters.
119
119
  When you enable these, they are stored in the database and can be used across sessions, by the user who created them.
120
120
 
121
+ ### Filters
122
+
123
+ Add `filter` to a column to let users filter on it. By default Mensa compares the
124
+ column's attribute with the chosen value, using operators that fit the column type.
125
+ The filter block takes these options:
126
+
127
+ ```ruby
128
+ column(:role) do
129
+ filter do
130
+ collection -> { User::ROLES } # Values to choose from (array or proc)
131
+ multiple true # Allow choosing several values
132
+ operators [:is, :isnt] # Limit the operators users can pick
133
+ operator :isnt # Default operator
134
+ having true # Filter with HAVING, for aggregate attributes
135
+ end
136
+ end
137
+ ```
138
+
139
+ The operators are `is`, `isnt`, `matches`, `does_not_match`, `gt`, `gteq`, `lt`,
140
+ `lteq`, `is_duplicate`, `is_current`, `is_empty` and `isnt_empty`.
141
+
142
+ #### Custom filter scopes
143
+
144
+ When comparing the attribute isn't enough, give the filter a `scope`. It runs on the
145
+ table's scope and receives the chosen value, an array when `multiple` is set:
146
+
147
+ ```ruby
148
+ column(:account_names) do
149
+ attribute %((SELECT STRING_AGG(accounts.name, ', ') FROM accounts WHERE accounts.id = ANY(containers.account_ids)))
150
+ filter do
151
+ collection -> { Account.order(:name).pluck(:name) }
152
+ multiple true
153
+ operators [:is]
154
+ scope ->(value) { where("containers.account_ids && ARRAY[:ids]::uuid[]", ids: Account.where(name: Array(value)).pluck(:id)) }
155
+ end
156
+ end
157
+ ```
158
+
159
+ To support more operators, accept the operator (a symbol) as a second argument:
160
+
161
+ ```ruby
162
+ filter do
163
+ operators [:is, :isnt, :is_empty]
164
+ scope ->(value, operator) {
165
+ case operator
166
+ when :isnt then where.not(account_id: value)
167
+ when :is_empty then where(account_id: nil)
168
+ else where(account_id: value)
169
+ end
170
+ }
171
+ end
172
+ ```
173
+
121
174
  ### Grouping
122
175
 
123
176
  Rows can be shown in groups, each with a header that shows the group's value and
@@ -80,7 +80,7 @@ module Mensa
80
80
 
81
81
  def filter_scope(record_scope)
82
82
  if scope
83
- record_scope.instance_exec(normalize(value), &scope)
83
+ record_scope.instance_exec(*scope_arguments, &scope)
84
84
  else
85
85
  return apply_duplicate_filter(record_scope) if operator == :is_duplicate
86
86
 
@@ -119,6 +119,7 @@ module Mensa
119
119
  when :isnt_empty
120
120
  (column.type == :string) ? "#{col} IS NOT NULL AND #{col} != ''" : "#{col} IS NOT NULL"
121
121
  when :is_current
122
+ hash[:value] = Current.public_send(column.name)
122
123
  "#{col} = :value"
123
124
  when :matches
124
125
  "#{col} LIKE :value"
@@ -182,6 +183,17 @@ module Mensa
182
183
  end
183
184
  end
184
185
 
186
+ # Arguments for a custom filter scope: the value and the operator. Lambdas
187
+ # only get as many as they declare, so `->(value) { ... }` keeps working
188
+ # next to `->(value, operator) { ... }`. Plain procs ignore extra arguments.
189
+ def scope_arguments
190
+ args = [normalize(value), operator]
191
+ return args unless scope.lambda?
192
+ return args if scope.parameters.any? { |type, _| type == :rest }
193
+
194
+ args.first(scope.parameters.count { |type, _| type == :req || type == :opt })
195
+ end
196
+
185
197
  def label_for_value(selected_value, options)
186
198
  option = options.find { |_label, value| value.to_s == selected_value.to_s }
187
199
  option ? option.first : selected_value
data/lib/mensa/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Mensa
2
- VERSION = "0.6.15"
2
+ VERSION = "0.6.17"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mensa
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.15
4
+ version: 0.6.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tom de Grunt