mensa 0.3.2 → 0.3.3

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 (57) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/Gemfile.lock +1 -17
  4. data/README.md +16 -42
  5. data/app/components/mensa/add_filter/component.html.erb +31 -0
  6. data/app/components/mensa/cell/component.html.erb +1 -0
  7. data/app/components/mensa/column_customizer/component.html.erb +31 -0
  8. data/app/components/mensa/control_bar/component.html.erb +56 -0
  9. data/app/components/mensa/empty_state/component.html.erb +10 -0
  10. data/app/components/mensa/filter_pill/component.html.erb +20 -0
  11. data/app/components/mensa/filter_pill_list/component.html.erb +30 -0
  12. data/app/components/mensa/header/component.html.erb +12 -0
  13. data/app/components/mensa/row_action/component.html.erb +9 -0
  14. data/app/components/mensa/search/component.html.erb +26 -0
  15. data/app/components/mensa/table/component.html.erb +25 -0
  16. data/app/components/mensa/table_row/component.html.erb +18 -0
  17. data/app/components/mensa/view/component.html.erb +51 -0
  18. data/app/components/mensa/views/component.html.erb +74 -0
  19. data/app/views/mensa/exports/_badge.html.erb +6 -0
  20. data/app/views/mensa/exports/_dialog.html.erb +52 -0
  21. data/app/views/mensa/exports/_list.html.erb +32 -0
  22. data/app/views/mensa/tables/filters/show.turbo_stream.erb +58 -0
  23. data/app/views/mensa/tables/show.html.erb +5 -0
  24. data/app/views/mensa/tables/show.turbo_stream.erb +7 -0
  25. data/app/views/mensa/tables/views/create.turbo_stream.erb +11 -0
  26. data/app/views/mensa/tables/views/destroy.turbo_stream.erb +11 -0
  27. data/app/views/mensa/tables/views/update.turbo_stream.erb +11 -0
  28. data/lib/generators/mensa/table_generator.rb +15 -0
  29. data/lib/generators/mensa/templates/config/initializers/mensa.rb +4 -5
  30. data/lib/generators/mensa/templates/table.rb.tt +18 -0
  31. data/lib/mensa/engine.rb +0 -1
  32. data/lib/mensa/version.rb +1 -1
  33. data/mensa.gemspec +2 -4
  34. metadata +29 -54
  35. data/app/components/mensa/add_filter/component.html.slim +0 -14
  36. data/app/components/mensa/cell/component.html.slim +0 -1
  37. data/app/components/mensa/column_customizer/component.html.slim +0 -14
  38. data/app/components/mensa/control_bar/component.html.slim +0 -43
  39. data/app/components/mensa/empty_state/component.html.slim +0 -7
  40. data/app/components/mensa/filter_pill/component.html.slim +0 -9
  41. data/app/components/mensa/filter_pill_list/component.html.slim +0 -11
  42. data/app/components/mensa/header/component.html.slim +0 -8
  43. data/app/components/mensa/row_action/component.html.slim +0 -6
  44. data/app/components/mensa/search/component.html.slim +0 -21
  45. data/app/components/mensa/table/component.html.slim +0 -10
  46. data/app/components/mensa/table_row/component.html.slim +0 -11
  47. data/app/components/mensa/view/component.html.slim +0 -30
  48. data/app/components/mensa/views/component.html.slim +0 -52
  49. data/app/views/mensa/exports/_badge.html.slim +0 -5
  50. data/app/views/mensa/exports/_dialog.html.slim +0 -42
  51. data/app/views/mensa/exports/_list.html.slim +0 -29
  52. data/app/views/mensa/tables/filters/show.turbo_stream.slim +0 -36
  53. data/app/views/mensa/tables/show.html.slim +0 -4
  54. data/app/views/mensa/tables/show.turbo_stream.slim +0 -5
  55. data/app/views/mensa/tables/views/create.turbo_stream.slim +0 -11
  56. data/app/views/mensa/tables/views/destroy.turbo_stream.slim +0 -11
  57. data/app/views/mensa/tables/views/update.turbo_stream.slim +0 -11
@@ -0,0 +1,52 @@
1
+ <% user = table.current_user %>
2
+ <% exports = Mensa::Export.for_table(table.name).for_user(user).recent %>
3
+ <dialog class="mensa-table__export-dialog" data-mensa-table-target="exportDialog" data-action="click->mensa-table#exportDialogBackdrop">
4
+ <div class="mensa-table__export-dialog__panel">
5
+ <header class="mensa-table__export-dialog__header">
6
+ <h2 class="mensa-table__export-dialog__title"><%= t("mensa.exports.title", default: "Export %{table}", table: table.name.to_s.humanize) %></h2>
7
+ <button class="mensa-table__export-dialog__close" type="button" data-action="mensa-table#cancelExport" aria-label="<%= t("mensa.exports.close", default: "Close") %>">
8
+ <i class="fa-solid fa-xmark"></i>
9
+ </button>
10
+ </header>
11
+
12
+ <div class="mensa-table__export-dialog__body">
13
+ <%= render partial: "mensa/exports/list", locals: {table_name: table.name, user: user, exports: exports} %>
14
+
15
+ <form class="mensa-table__export-dialog__form" data-action="submit->mensa-table#confirmExport">
16
+ <fieldset class="mensa-table__export-dialog__fieldset">
17
+ <legend class="mensa-table__export-dialog__section-title"><%= t("mensa.exports.new_export", default: "New export") %></legend>
18
+ <label class="mensa-table__export-dialog__option">
19
+ <input type="radio" name="scope" value="all" checked>
20
+ <span><%= t("mensa.exports.scope_all", default: "All records (matching current filters)") %></span>
21
+ </label>
22
+ <label class="mensa-table__export-dialog__option">
23
+ <input type="radio" name="scope" value="current_page">
24
+ <span><%= t("mensa.exports.scope_current_page", default: "Current page") %></span>
25
+ </label>
26
+ </fieldset>
27
+
28
+ <fieldset class="mensa-table__export-dialog__fieldset">
29
+ <legend class="mensa-table__export-dialog__section-title"><%= t("mensa.exports.export_as", default: "Export as") %></legend>
30
+ <label class="mensa-table__export-dialog__option">
31
+ <input type="radio" name="export_format" value="csv_excel" checked>
32
+ <span><%= t("mensa.exports.format_excel", default: "CSV for Excel, Numbers, or other spreadsheet programs") %></span>
33
+ </label>
34
+ <label class="mensa-table__export-dialog__option">
35
+ <input type="radio" name="export_format" value="plain_csv">
36
+ <span><%= t("mensa.exports.format_plain", default: "Plain CSV file") %></span>
37
+ </label>
38
+ </fieldset>
39
+
40
+ <div class="mensa-table__export-dialog__actions">
41
+ <button class="mensa-table__export-dialog__button mensa-table__export-dialog__button--secondary" type="button" data-action="mensa-table#cancelExport">
42
+ <%= t("mensa.exports.cancel", default: "Cancel") %>
43
+ </button>
44
+ <button class="mensa-table__export-dialog__button mensa-table__export-dialog__button--primary" type="submit">
45
+ <i class="fa-solid fa-file-export"></i>
46
+ <%= t("mensa.exports.submit", default: "Export") %>
47
+ </button>
48
+ </div>
49
+ </form>
50
+ </div>
51
+ </div>
52
+ </dialog>
@@ -0,0 +1,32 @@
1
+ <div id="<%= Mensa::Export.list_dom_id(table_name, user) %>" class="mensa-table__export-dialog__downloads">
2
+ <h3 class="mensa-table__export-dialog__section-title"><%= t("mensa.exports.available_downloads", default: "Available downloads") %></h3>
3
+ <% if exports.blank? %>
4
+ <p class="mensa-table__export-dialog__empty"><%= t("mensa.exports.empty", default: "You have no downloads yet. Create one below.") %></p>
5
+ <% else %>
6
+ <ul class="mensa-table__export-dialog__list">
7
+ <% exports.each do |export| %>
8
+ <li class="mensa-table__export-dialog__item">
9
+ <div class="mensa-table__export-dialog__item-info">
10
+ <span class="mensa-table__export-dialog__item-name"><%= export.filename.presence || t("mensa.exports.item_name", default: "%{table} export", table: export.table_name.to_s.humanize) %></span>
11
+ <span class="mensa-table__export-dialog__item-meta"><%= export.created_at.strftime("%Y-%m-%d %H:%M") %></span>
12
+ </div>
13
+ <div class="mensa-table__export-dialog__item-action">
14
+ <% if export.downloadable? %>
15
+ <%= link_to mensa.download_table_export_path(export.table_name, export), class: "mensa-table__export-dialog__download", data: {turbo: false} do %>
16
+ <i class="fa-solid fa-download"></i>
17
+ <%= t("mensa.exports.download", default: "Download") %>
18
+ <% end %>
19
+ <% elsif export.failed? %>
20
+ <span class="mensa-table__export-dialog__status mensa-table__export-dialog__status--failed"><%= t("mensa.exports.failed", default: "Failed") %></span>
21
+ <% else %>
22
+ <span class="mensa-table__export-dialog__status mensa-table__export-dialog__status--pending">
23
+ <i class="fa-solid fa-spinner fa-spin"></i>
24
+ <%= t("mensa.exports.processing", default: "Preparing…") %>
25
+ </span>
26
+ <% end %>
27
+ </div>
28
+ </li>
29
+ <% end %>
30
+ </ul>
31
+ <% end %>
32
+ </div>
@@ -0,0 +1,58 @@
1
+ <%= turbo_stream.update params[:target] do %>
2
+ <div class="mensa-table__add_filter__popover_container__heading"><%= @column.human_name %></div>
3
+ <% if @column.filter.operator_with_value? %>
4
+ <% collection = @column.filter.collection %>
5
+ <% if collection.present? %>
6
+ <% unless @multiple %>
7
+ <input type="hidden" data-mensa-add-filter-target="value" value="<%= @values.first %>">
8
+ <% end %>
9
+ <ul class="mensa-table__add_filter__popover_container__values" data-multiple="<%= 'true' if @multiple %>">
10
+ <% collection.each do |item| %>
11
+ <% opt_label = item.is_a?(Array) ? item.first.to_s : item.to_s %>
12
+ <% opt_value = item.is_a?(Array) ? item.last.to_s : item.to_s %>
13
+ <% is_selected = @values.include?(opt_value) %>
14
+ <li class="mensa-table__add_filter__popover_container__value"
15
+ data-mensa-add-filter-target="valueOption"
16
+ data-value="<%= opt_value %>"
17
+ data-label="<%= opt_label %>"
18
+ data-selected="<%= 'true' if is_selected %>"
19
+ data-action="click->mensa-add-filter#selectValue mouseenter->mensa-add-filter#highlightItem">
20
+ <% if @multiple %>
21
+ <span class="mensa-table__add_filter__checkbox<%= ' mensa-table__add_filter__checkbox--checked' if is_selected %>"></span>
22
+ <% else %>
23
+ <i class="mensa-table__add_filter__popover_container__value__check fa-solid fa-check<%= ' invisible' unless is_selected %>"></i>
24
+ <% end %>
25
+ <span class="flex-1"><%= opt_label %></span>
26
+ <span class="mensa-table__add_filter__enter-hint">↵ Enter</span>
27
+ </li>
28
+ <% end %>
29
+ </ul>
30
+ <% else %>
31
+ <input class="mensa-table__add_filter__popover_container__input"
32
+ type="<%= @column.filter.input_type %>"
33
+ value="<%= @values.first %>"
34
+ autocomplete="off"
35
+ inputmode="<%= @column.type == :integer ? 'numeric' : nil %>"
36
+ step="<%= @column.type == :integer ? 1 : (@column.type == :datetime ? 1 : nil) %>"
37
+ data-mensa-add-filter-target="value"
38
+ data-action="input->mensa-add-filter#manualValueChanged keydown.enter->mensa-add-filter#applyManualValue">
39
+ <% end %>
40
+ <hr class="mensa-table__add_filter__popover_container__separator">
41
+ <% end %>
42
+ <ul class="mensa-table__add_filter__popover_container__operators">
43
+ <% @column.filter.operators.each do |operator_name, label, requires_value| %>
44
+ <li class="mensa-table__add_filter__popover_container__operator"
45
+ data-mensa-add-filter-target="operatorOption"
46
+ data-operator="<%= operator_name %>"
47
+ data-requires-value="<%= requires_value ? 'true' : 'false' %>"
48
+ data-selected="<%= 'true' if @operator == operator_name.to_s %>"
49
+ data-action="click->mensa-add-filter#selectOperator mouseenter->mensa-add-filter#highlightItem">
50
+ <i class="mensa-table__add_filter__popover_container__operator__check fa-solid fa-check<%= ' invisible' unless @operator == operator_name.to_s %>"></i>
51
+ <span class="flex-1"><%= label %></span>
52
+ <span class="mensa-table__add_filter__enter-hint">↵ Enter</span>
53
+ </li>
54
+ <% end %>
55
+ </ul>
56
+ <hr class="mensa-table__add_filter__popover_container__separator">
57
+ <a class="mensa-table__add_filter__popover_container__clear" href="#" data-action="click->mensa-add-filter#reset">Clear</a>
58
+ <% end %>
@@ -0,0 +1,5 @@
1
+ Test
2
+ <button class="text-xs">Esc</button>
3
+ <turbo-frame id="<%= @table.table_id %>" target="_top">
4
+ <%= render Mensa::View::Component.new(@table) %>
5
+ </turbo-frame>
@@ -0,0 +1,7 @@
1
+ <%= turbo_stream.update "filters-#{@table.table_id}" do %>
2
+ <%= render Mensa::FilterPillList::Component.new(table: @table) %>
3
+ <% end %>
4
+
5
+ <%= turbo_stream.update @table.table_id do %>
6
+ <%= render Mensa::View::Component.new(@table) %>
7
+ <% end %>
@@ -0,0 +1,11 @@
1
+ <%= turbo_stream.replace "mensa-views-#{@table.table_id}" do %>
2
+ <%= render Mensa::Views::Component.new(table: @table) %>
3
+ <% end %>
4
+
5
+ <%= turbo_stream.update "filters-#{@table.table_id}" do %>
6
+ <%= render Mensa::FilterPillList::Component.new(table: @table) %>
7
+ <% end %>
8
+
9
+ <%= turbo_stream.update @table.table_id do %>
10
+ <%= render Mensa::View::Component.new(@table) %>
11
+ <% end %>
@@ -0,0 +1,11 @@
1
+ <%= turbo_stream.replace "mensa-views-#{@table.table_id}" do %>
2
+ <%= render Mensa::Views::Component.new(table: @table) %>
3
+ <% end %>
4
+
5
+ <%= turbo_stream.update "filters-#{@table.table_id}" do %>
6
+ <%= render Mensa::FilterPillList::Component.new(table: @table) %>
7
+ <% end %>
8
+
9
+ <%= turbo_stream.update @table.table_id do %>
10
+ <%= render Mensa::View::Component.new(@table) %>
11
+ <% end %>
@@ -0,0 +1,11 @@
1
+ <%= turbo_stream.replace "mensa-views-#{@table.table_id}" do %>
2
+ <%= render Mensa::Views::Component.new(table: @table) %>
3
+ <% end %>
4
+
5
+ <%= turbo_stream.update "filters-#{@table.table_id}" do %>
6
+ <%= render Mensa::FilterPillList::Component.new(table: @table) %>
7
+ <% end %>
8
+
9
+ <%= turbo_stream.update @table.table_id do %>
10
+ <%= render Mensa::View::Component.new(@table) %>
11
+ <% end %>
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "rails/generators"
4
+
5
+ module Mensa
6
+ class TableGenerator < ::Rails::Generators::NamedBase
7
+ desc "Generates a table"
8
+
9
+ source_root File.expand_path("templates", __dir__)
10
+
11
+ def copy_table_file
12
+ template "table.rb", "app/tables/#{name}_table.rb"
13
+ end
14
+ end
15
+ end
@@ -1,17 +1,16 @@
1
1
  Mensa.setup do |config|
2
2
  # Callbacks for exporting of tables
3
3
  config.callbacks = {
4
- export_started: lambda do |user_id, table_name|
4
+ export_started: lambda do |export|
5
5
  end,
6
- export_completed: lambda do |user_id, table_name, context, attachment|
6
+ export_completed: lambda do |export|
7
7
  end
8
8
  }
9
9
 
10
10
  # Override icons in use
11
11
  config.icons = {
12
- order_indicator_asc: "fa-solid fa-sort-up",
13
- order_indicator_desc: "fa-solid fa-sort-down",
14
- order_indicator: "fa-solid fa-sort",
12
+ order_indicator_asc: "fa-solid fa-arrow-up",
13
+ order_indicator_desc: "fa-solid fa-arrow-down",
15
14
  control_bar_search: "fa-solid fa-magnifying-glass",
16
15
  control_bar_filter: "fa-solid fa-filter",
17
16
  control_bar_edit: "fa-solid fa-table-columns",
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ class <%= name.camelize %>Table < Mensa::Base
4
+ model <%= name.camelize %>
5
+
6
+ <%-
7
+ klass = class_name&.safe_constantize
8
+ if klass.present?
9
+ -%>
10
+ <%- klass.columns.each do |column| -%>
11
+ column(:<%= column.name %>)
12
+ <%- end -%>
13
+ <%- end -%>
14
+
15
+ scope do
16
+ <%= class_name %>.all
17
+ end
18
+ end
data/lib/mensa/engine.rb CHANGED
@@ -1,6 +1,5 @@
1
1
  require "pagy"
2
2
  require "textacular"
3
- require "slim"
4
3
  require "tailwindcss-rails"
5
4
  require "importmap-rails"
6
5
  require "turbo-rails"
data/lib/mensa/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Mensa
2
- VERSION = "0.3.2"
2
+ VERSION = "0.3.3"
3
3
  end
data/mensa.gemspec CHANGED
@@ -18,7 +18,8 @@ Gem::Specification.new do |spec|
18
18
  Mensa requires additional setup. Please run the following
19
19
  command to install the necessary files:
20
20
 
21
- bin/rails mensa:install:migrations
21
+ rails g mensa:install
22
+ rails mensa:install:migrations
22
23
  MESSAGE
23
24
 
24
25
  spec.metadata["homepage_uri"] = spec.homepage
@@ -37,11 +38,8 @@ Gem::Specification.new do |spec|
37
38
  spec.add_dependency "textacular", ">=5"
38
39
  spec.add_dependency "view_component", "~> 3.11"
39
40
 
40
- spec.add_dependency "slim"
41
41
  spec.add_dependency "tailwindcss-rails", "~> 3.3"
42
42
  spec.add_dependency "importmap-rails"
43
43
  spec.add_dependency "turbo-rails"
44
44
  spec.add_dependency "stimulus-rails"
45
-
46
- spec.add_development_dependency "sqlite3", "~> 2.8"
47
45
  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.3.2
4
+ version: 0.3.3
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-06-10 00:00:00.000000000 Z
11
+ date: 2026-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -108,20 +108,6 @@ dependencies:
108
108
  - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '3.11'
111
- - !ruby/object:Gem::Dependency
112
- name: slim
113
- requirement: !ruby/object:Gem::Requirement
114
- requirements:
115
- - - ">="
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :runtime
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- requirements:
122
- - - ">="
123
- - !ruby/object:Gem::Version
124
- version: '0'
125
111
  - !ruby/object:Gem::Dependency
126
112
  name: tailwindcss-rails
127
113
  requirement: !ruby/object:Gem::Requirement
@@ -178,20 +164,6 @@ dependencies:
178
164
  - - ">="
179
165
  - !ruby/object:Gem::Version
180
166
  version: '0'
181
- - !ruby/object:Gem::Dependency
182
- name: sqlite3
183
- requirement: !ruby/object:Gem::Requirement
184
- requirements:
185
- - - "~>"
186
- - !ruby/object:Gem::Version
187
- version: '2.8'
188
- type: :development
189
- prerelease: false
190
- version_requirements: !ruby/object:Gem::Requirement
191
- requirements:
192
- - - "~>"
193
- - !ruby/object:Gem::Version
194
- version: '2.8'
195
167
  description: Fast and awesome tables, with pagination, sorting, filtering and custom
196
168
  views.
197
169
  email:
@@ -221,55 +193,55 @@ files:
221
193
  - app/assets/images/mensa/.keep
222
194
  - app/assets/stylesheets/mensa/application.css
223
195
  - app/components/mensa/add_filter/component.css
224
- - app/components/mensa/add_filter/component.html.slim
196
+ - app/components/mensa/add_filter/component.html.erb
225
197
  - app/components/mensa/add_filter/component.rb
226
198
  - app/components/mensa/add_filter/component_controller.js
227
199
  - app/components/mensa/application_component.rb
228
200
  - app/components/mensa/cell/component.css
229
- - app/components/mensa/cell/component.html.slim
201
+ - app/components/mensa/cell/component.html.erb
230
202
  - app/components/mensa/cell/component.rb
231
203
  - app/components/mensa/column_customizer/component.css
232
- - app/components/mensa/column_customizer/component.html.slim
204
+ - app/components/mensa/column_customizer/component.html.erb
233
205
  - app/components/mensa/column_customizer/component.rb
234
206
  - app/components/mensa/column_customizer/component_controller.js
235
207
  - app/components/mensa/control_bar/component.css
236
- - app/components/mensa/control_bar/component.html.slim
208
+ - app/components/mensa/control_bar/component.html.erb
237
209
  - app/components/mensa/control_bar/component.rb
238
210
  - app/components/mensa/empty_state/component.css
239
- - app/components/mensa/empty_state/component.html.slim
211
+ - app/components/mensa/empty_state/component.html.erb
240
212
  - app/components/mensa/empty_state/component.rb
241
213
  - app/components/mensa/filter_pill/component.css
242
- - app/components/mensa/filter_pill/component.html.slim
214
+ - app/components/mensa/filter_pill/component.html.erb
243
215
  - app/components/mensa/filter_pill/component.rb
244
216
  - app/components/mensa/filter_pill/component_controller.js
245
217
  - app/components/mensa/filter_pill_list/component.css
246
- - app/components/mensa/filter_pill_list/component.html.slim
218
+ - app/components/mensa/filter_pill_list/component.html.erb
247
219
  - app/components/mensa/filter_pill_list/component.rb
248
220
  - app/components/mensa/filter_pill_list/component_controller.js
249
221
  - app/components/mensa/header/component.css
250
- - app/components/mensa/header/component.html.slim
222
+ - app/components/mensa/header/component.html.erb
251
223
  - app/components/mensa/header/component.rb
252
224
  - app/components/mensa/row_action/component.css
253
- - app/components/mensa/row_action/component.html.slim
225
+ - app/components/mensa/row_action/component.html.erb
254
226
  - app/components/mensa/row_action/component.rb
255
227
  - app/components/mensa/search/component.css
256
- - app/components/mensa/search/component.html.slim
228
+ - app/components/mensa/search/component.html.erb
257
229
  - app/components/mensa/search/component.rb
258
230
  - app/components/mensa/search/component_controller.js
259
231
  - app/components/mensa/selection/component_controller.js
260
232
  - app/components/mensa/table/component.css
261
- - app/components/mensa/table/component.html.slim
233
+ - app/components/mensa/table/component.html.erb
262
234
  - app/components/mensa/table/component.rb
263
235
  - app/components/mensa/table/component_controller.js
264
236
  - app/components/mensa/table_row/component.css
265
- - app/components/mensa/table_row/component.html.slim
237
+ - app/components/mensa/table_row/component.html.erb
266
238
  - app/components/mensa/table_row/component.rb
267
239
  - app/components/mensa/view/component.css
268
- - app/components/mensa/view/component.html.slim
240
+ - app/components/mensa/view/component.html.erb
269
241
  - app/components/mensa/view/component.rb
270
242
  - app/components/mensa/view/paging.css
271
243
  - app/components/mensa/views/component.css
272
- - app/components/mensa/views/component.html.slim
244
+ - app/components/mensa/views/component.html.erb
273
245
  - app/components/mensa/views/component.rb
274
246
  - app/components/mensa/views/component_controller.js
275
247
  - app/controllers/concerns/.keep
@@ -311,15 +283,15 @@ files:
311
283
  - app/tables/mensa/row.rb
312
284
  - app/tables/mensa/scope.rb
313
285
  - app/tables/mensa/system_view.rb
314
- - app/views/mensa/exports/_badge.html.slim
315
- - app/views/mensa/exports/_dialog.html.slim
316
- - app/views/mensa/exports/_list.html.slim
317
- - app/views/mensa/tables/filters/show.turbo_stream.slim
318
- - app/views/mensa/tables/show.html.slim
319
- - app/views/mensa/tables/show.turbo_stream.slim
320
- - app/views/mensa/tables/views/create.turbo_stream.slim
321
- - app/views/mensa/tables/views/destroy.turbo_stream.slim
322
- - app/views/mensa/tables/views/update.turbo_stream.slim
286
+ - app/views/mensa/exports/_badge.html.erb
287
+ - app/views/mensa/exports/_dialog.html.erb
288
+ - app/views/mensa/exports/_list.html.erb
289
+ - app/views/mensa/tables/filters/show.turbo_stream.erb
290
+ - app/views/mensa/tables/show.html.erb
291
+ - app/views/mensa/tables/show.turbo_stream.erb
292
+ - app/views/mensa/tables/views/create.turbo_stream.erb
293
+ - app/views/mensa/tables/views/destroy.turbo_stream.erb
294
+ - app/views/mensa/tables/views/update.turbo_stream.erb
323
295
  - bin/importmap
324
296
  - bin/overmind
325
297
  - bin/rails
@@ -336,8 +308,10 @@ files:
336
308
  - docs/filters.png
337
309
  - docs/table.png
338
310
  - lib/generators/mensa/install_generator.rb
311
+ - lib/generators/mensa/table_generator.rb
339
312
  - lib/generators/mensa/tailwind_config_generator.rb
340
313
  - lib/generators/mensa/templates/config/initializers/mensa.rb
314
+ - lib/generators/mensa/templates/table.rb.tt
341
315
  - lib/mensa.rb
342
316
  - lib/mensa/configuration.rb
343
317
  - lib/mensa/engine.rb
@@ -359,7 +333,8 @@ post_install_message: |
359
333
  Mensa requires additional setup. Please run the following
360
334
  command to install the necessary files:
361
335
 
362
- bin/rails mensa:install:migrations
336
+ rails g mensa:install
337
+ rails mensa:install:migrations
363
338
  rdoc_options: []
364
339
  require_paths:
365
340
  - lib
@@ -1,14 +0,0 @@
1
- .mensa-table__add_filter data-controller="mensa-add-filter" data-mensa-add-filter-mensa-filter-pill-list-outlet="#mensa-filter-pill-list-#{table.table_id}" data-mensa-add-filter-operator-labels-value=operator_labels.to_json
2
- button.mensa-table__add_filter__trigger[type="button" title=t("mensa.add_filter.add", default: "Add filter") data-action="mensa-add-filter#openAllColumns"]
3
- i.fa-solid.fa-circle-plus
4
- ul.hidden.fixed.z-50.max-h-96.overflow-auto.rounded-lg.bg-white.dark:bg-gray-800.p-2.text-base.shadow-lg.ring-1.ring-black.ring-opacity-5.focus:outline-none.sm:text-sm data-mensa-add-filter-target="filterList"
5
- - table.columns.select(&:filter?).each do |column|
6
- li.text-gray-900.dark:text-gray-300.hover:bg-gray-100.dark:hover:bg-gray-700.relative.cursor-default.select-none.rounded-md.py-2.px-3.flex.items-center.gap-2 data-mensa-add-filter-target="filterListItem" data-action="click->mensa-add-filter#selectColumn mouseenter->mensa-add-filter#columnItemHovered" data-filter-column-name=column.name
7
- .label.font-normal.block.truncate.flex-1
8
- = column.human_name
9
- .check.hidden.text-primary-600.flex.items-center
10
- .fal.fa-check
11
- span.mensa-table__add_filter__enter-hint
12
- | ↵ Enter
13
-
14
- div.hidden.mensa-table__add_filter__popover_container data-mensa-add-filter-target="valuePopover" id="mensa-filter-pill-value-#{SecureRandom.base36}"
@@ -1 +0,0 @@
1
- td = cell.render(:html)
@@ -1,14 +0,0 @@
1
- .relative data-controller="mensa-column-customizer" data-mensa-column-customizer-table-name-value=table.name data-mensa-column-customizer-turbo-frame-id-value=table.table_id data-mensa-column-customizer-mensa-table-outlet="#table-#{table.table_id}"
2
- button.mensa-table__control_bar__button type="button" data-action="click->mensa-column-customizer#toggle"
3
- i class=Mensa.config.icons[:control_bar_edit]
4
- .mensa-table__column_customizer__popover.hidden data-mensa-column-customizer-target="popover"
5
- p.mensa-table__column_customizer__heading Columns
6
- ul
7
- - table.columns.reject(&:internal?).each do |column|
8
- li.mensa-table__column_customizer__row[data-mensa-column-customizer-target="columnRow" data-column-name=column.name.to_s data-visible=column.visible?.to_s draggable="true" data-action="dragstart->mensa-column-customizer#dragStart dragover->mensa-column-customizer#dragOver drop->mensa-column-customizer#drop dragend->mensa-column-customizer#dragEnd"]
9
- i.mensa-table__column_customizer__handle.fa-solid.fa-grip-vertical
10
- span.mensa-table__column_customizer__name[class=(!column.visible? ? "mensa-table__column_customizer__name--hidden" : "")]
11
- = column.human_name
12
- button.mensa-table__column_customizer__visibility type="button" data-action="click->mensa-column-customizer#toggleVisibility"
13
- i.fa-solid.fa-eye
14
- i.fa-solid.fa-eye-slash
@@ -1,43 +0,0 @@
1
- .mensa-table__control_bar data-mensa-table-target="controlBar"
2
- .flex.items-center.gap-1.py-0
3
- / Column customizer (always shown first when available)
4
- - if view_columns_ordering?
5
- = render Mensa::ColumnCustomizer::Component.new(table: table)
6
-
7
- / Save/Reset buttons — shown when there are unsaved filters or search
8
- .mensa-table__save-reset.hidden data-mensa-table-target="saveResetButtons"
9
- button.mensa-table__control_bar__button[type="button" title=t('.reset', default: 'Reset') data-action="mensa-table#cancelFiltersAndSearch"]
10
- i.fa-solid.fa-rotate-left
11
- - if table.current_user && table.supports_custom_views?
12
- .relative
13
- / Simple save — shown when the default/system view is active
14
- button.mensa-table__control_bar__button.hidden[type="button" data-mensa-table-target="saveSimple" data-action="mensa-table#saveAsNewView"]
15
- = t('.save', default: 'Save')
16
- / Save with dropdown — shown when a user-created view is active
17
- button.mensa-table__control_bar__button.hidden[type="button" data-mensa-table-target="saveSplit" data-action="mensa-table#toggleSaveDropdown"]
18
- = t('.save', default: 'Save')
19
- i.fa-solid.fa-chevron-down.text-xs
20
- ul.mensa-table__control_bar__save-dropdown.hidden data-mensa-table-target="saveDropdown"
21
- li
22
- button.mensa-table__control_bar__save-dropdown-item[type="button" data-action="mensa-table#updateCurrentViewAction"]
23
- = t('.update_view', default: 'Update view')
24
- li
25
- button.mensa-table__control_bar__save-dropdown-item[type="button" data-action="mensa-table#saveAsNewView"]
26
- = t('.save_as_new_view', default: 'Save as new view')
27
- - else
28
- button.mensa-table__control_bar__button[type="button" data-action="mensa-table#saveAsNewView"]
29
- = t('.save', default: 'Save')
30
-
31
- / Eye icon — toggles visibility of view-origin filter pills (shown by JS when needed)
32
- button.mensa-table__control_bar__button.hidden[type="button" data-mensa-table-target="eyeButton" data-action="click->mensa-table#toggleViewFilters"]
33
- i.fa-solid.fa-eye
34
-
35
- / Export
36
- - if table.exportable?
37
- button.mensa-table__control_bar__button.relative[type="button" data-action="mensa-table#export"]
38
- i data-mensa-table-target="exportIcon" class=Mensa.config.icons[:control_bar_export]
39
- = helpers.render partial: "mensa/exports/badge", locals: {table_name: table.name, user: table.current_user}
40
-
41
- - if table.exportable?
42
- = helpers.turbo_stream_from Mensa::Export.stream_name(table.name, table.current_user)
43
- = helpers.render partial: "mensa/exports/dialog", locals: {table: table}
@@ -1,7 +0,0 @@
1
- .mensa-empty-state
2
- .mensa-empty-state__icon
3
- i class=Mensa.config.icons[:search]
4
- h3.mensa-empty-state__title = t("mensa.empty_state.title", model: model_name_plural)
5
- p.mensa-empty-state__subtitle = t("mensa.empty_state.subtitle")
6
- button.mensa-empty-state__button type="button" data-action="click->mensa-table#cancelFiltersAndSearch"
7
- = t("mensa.empty_state.clear_button")
@@ -1,9 +0,0 @@
1
- .mensa-filter-pill data-controller="mensa-filter-pill" data-mensa-filter-pill-mensa-filter-pill-list-outlet="#mensa-filter-pill-list-#{filter.table.table_id}" data-mensa-filter-pill-column-name-value=filter.column.name data-mensa-filter-pill-value-value=(filter.operator_with_value? ? (filter.value.is_a?(Array) ? filter.value.to_json : filter.value) : nil ) data-mensa-filter-pill-operator-value=filter.operator data-mensa-filter-pill-operator-without-value-value=("true" unless filter.operator_with_value?) data-view-filter=("true" if view_filter?)
2
- button.mensa-filter-pill__chip[type="button" data-action="click->mensa-filter-pill#edit"]
3
- span.mensa-filter-pill__column = filter.column.human_name
4
- span.mensa-filter-pill__operator = filter.operator_label
5
- - formatted_value = filter.value.is_a?(Array) ? filter.value.join(", ") : filter.value
6
- - if formatted_value.present? && filter.operator_with_value?
7
- span.mensa-filter-pill__value = formatted_value
8
- button.mensa-filter-pill__remove[type="button" title="Remove filter" data-action="click->mensa-filter-pill#remove"]
9
- i.fa-solid.fa-xmark
@@ -1,11 +0,0 @@
1
- - has_filterable_columns = table.columns.any?(&:filter?)
2
- .mensa-table__search-bar id="mensa-filter-pill-list-#{table.table_id}" data-controller="mensa-filter-pill-list" data-mensa-table-target="filterList" data-mensa-filter-pill-list-table-name-value=table.name data-mensa-filter-pill-list-mensa-table-outlet=".mensa-table#table-#{table.table_id}" data-mensa-filter-pill-list-mensa-filter-pill-outlet=".mensa-filter-pill" data-mensa-filter-pill-list-mensa-add-filter-outlet="[data-controller=mensa-add-filter]"
3
- .mensa-table__search-bar__pills-area
4
- = render Mensa::FilterPill::Component.with_collection(table.active_filters)
5
- - if has_filterable_columns
6
- = render Mensa::AddFilter::Component.new(table: table)
7
- .mensa-table__search-bar__input-wrapper
8
- input.mensa-table__search-bar__input[type="text" name="search_query" autocomplete="off" placeholder=t(has_filterable_columns ? ".search" : ".search_only") data-mensa-filter-pill-list-target="searchInput" data-action="input->mensa-filter-pill-list#monitorSearch keydown.enter->mensa-filter-pill-list#search keydown.esc->mensa-filter-pill-list#resetSearch focus->mensa-filter-pill-list#searchFocused keydown.down->mensa-filter-pill-list#navigateDown keydown.up->mensa-filter-pill-list#navigateUp" value=params[:query]]
9
- i.mensa-table__search-bar__search-icon class=Mensa.config.icons[:search]
10
- button.mensa-table__search-bar__clear.hidden[type="button" data-mensa-filter-pill-list-target="resetSearchButton" data-action="mensa-filter-pill-list#resetSearch"]
11
- i.fas.fa-xmark
@@ -1,8 +0,0 @@
1
- th
2
- - if column.sortable?
3
- = link_to table.path(order: {column.name => column.next_sort_direction}, turbo_frame_id: table.table_id), "data-turbo-frame": "_self", class: "order cursor-pointer"
4
- span = column.human_name
5
- i class=Mensa.config.icons["order_indicator#{column.sort_direction.to_s.present? ? "_#{column.sort_direction.to_s}" : ""}".to_sym]
6
- - else
7
- .container
8
- .title = column.human_name
@@ -1,6 +0,0 @@
1
- - if action.show.call(row.record)
2
- a.action href=(action.link ? table.original_view_context.instance_exec(row.record, &action.link) : '') title=action.title *action.link_attributes
3
- - if action.icon
4
- i.fa class=action.icon
5
- - else
6
- = name
@@ -1,21 +0,0 @@
1
- - if table.current_user
2
- dialog.mensa-table__save-view-dialog data-mensa-table-target="saveViewDialog" data-action="click->mensa-table#saveViewDialogBackdrop"
3
- form.mensa-table__save-view-dialog__form data-action="submit->mensa-table#confirmSaveView"
4
- header.mensa-table__save-view-dialog__header
5
- h2.mensa-table__save-view-dialog__title
6
- = t('.save_view_title', default: 'Save view')
7
- p.mensa-table__save-view-dialog__subtitle
8
- = t('.save_view_subtitle', default: 'Save the current filters, ordering and search as a reusable view.')
9
- label.mensa-table__save-view-dialog__field
10
- span.mensa-table__save-view-dialog__label
11
- = t('.view_name', default: 'Name')
12
- input.mensa-table__save-view-dialog__input type="text" required=true placeholder=t('.view_name_placeholder', default: 'e.g. Active customers') data-mensa-table-target="saveViewName"
13
- label.mensa-table__save-view-dialog__field
14
- span.mensa-table__save-view-dialog__label
15
- = t('.view_description', default: 'Description')
16
- textarea.mensa-table__save-view-dialog__textarea rows="3" placeholder=t('.view_description_placeholder', default: 'Optional notes about this view') data-mensa-table-target="saveViewDescription"
17
- .mensa-table__save-view-dialog__actions
18
- button.mensa-table__save-view-dialog__button.mensa-table__save-view-dialog__button--secondary type="button" data-action="mensa-table#cancelSaveView"
19
- = t('.cancel')
20
- button.mensa-table__save-view-dialog__button.mensa-table__save-view-dialog__button--primary type="submit"
21
- = t('.save')