mensa 0.2.5 → 0.2.6
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 +4 -4
- data/.devcontainer/Dockerfile +6 -2
- data/.devcontainer/compose.yaml +1 -1
- data/.devcontainer/devcontainer.json +31 -29
- data/.devcontainer/postCreate.sh +8 -0
- data/.devcontainer/postStart.sh +9 -0
- data/.gitignore +3 -1
- data/.zed/tasks.json +12 -0
- data/Gemfile.lock +155 -153
- data/Procfile +1 -1
- data/README.md +85 -60
- data/app/assets/stylesheets/mensa/application.css +14 -11
- data/app/components/mensa/add_filter/component.css +110 -5
- data/app/components/mensa/add_filter/component.html.slim +10 -12
- data/app/components/mensa/add_filter/component.rb +7 -1
- data/app/components/mensa/add_filter/component_controller.js +697 -83
- data/app/components/mensa/cell/component.css +9 -0
- data/app/components/mensa/column_customizer/component.css +40 -0
- data/app/components/mensa/column_customizer/component.html.slim +14 -0
- data/app/components/mensa/column_customizer/component.rb +13 -0
- data/app/components/mensa/column_customizer/component_controller.js +383 -0
- data/app/components/mensa/control_bar/component.css +127 -4
- data/app/components/mensa/control_bar/component.html.slim +41 -14
- data/app/components/mensa/control_bar/component.rb +0 -4
- data/app/components/mensa/empty_state/component.css +20 -0
- data/app/components/mensa/empty_state/component.html.slim +7 -0
- data/app/components/mensa/empty_state/component.rb +18 -0
- data/app/components/mensa/filter_pill/component.css +23 -0
- data/app/components/mensa/filter_pill/component.html.slim +9 -6
- data/app/components/mensa/filter_pill/component.rb +9 -0
- data/app/components/mensa/filter_pill/component_controller.js +50 -10
- data/app/components/mensa/filter_pill_list/component.css +58 -9
- data/app/components/mensa/filter_pill_list/component.html.slim +11 -8
- data/app/components/mensa/filter_pill_list/component_controller.js +747 -48
- data/app/components/mensa/header/component.css +41 -43
- data/app/components/mensa/header/component.html.slim +7 -7
- data/app/components/mensa/row_action/component.html.slim +2 -2
- data/app/components/mensa/search/component.css +68 -9
- data/app/components/mensa/search/component.html.slim +19 -15
- data/app/components/mensa/search/component_controller.js +39 -49
- data/app/components/mensa/selection/component_controller.js +147 -0
- data/app/components/mensa/table/component.css +28 -0
- data/app/components/mensa/table/component.html.slim +9 -6
- data/app/components/mensa/table/component.rb +1 -0
- data/app/components/mensa/table/component_controller.js +524 -88
- data/app/components/mensa/table_row/component.css +6 -0
- data/app/components/mensa/table_row/component.html.slim +8 -3
- data/app/components/mensa/view/component.css +97 -29
- data/app/components/mensa/view/component.html.slim +23 -10
- data/app/components/mensa/view/component.rb +5 -0
- data/app/components/mensa/views/component.css +106 -13
- data/app/components/mensa/views/component.html.slim +51 -17
- data/app/components/mensa/views/component_controller.js +245 -20
- data/app/controllers/mensa/tables/batch_actions_controller.rb +24 -0
- data/app/controllers/mensa/tables/exports_controller.rb +96 -0
- data/app/controllers/mensa/tables/filters_controller.rb +4 -1
- data/app/controllers/mensa/tables/views_controller.rb +108 -0
- data/app/controllers/mensa/tables_controller.rb +3 -6
- data/app/helpers/mensa/application_helper.rb +4 -0
- data/app/javascript/mensa/application.js +2 -2
- data/app/javascript/mensa/controllers/index.js +13 -4
- data/app/jobs/mensa/export_job.rb +77 -84
- data/app/models/mensa/export.rb +93 -0
- data/app/tables/mensa/base.rb +103 -12
- data/app/tables/mensa/batch_action.rb +27 -0
- data/app/tables/mensa/cell.rb +15 -0
- data/app/tables/mensa/column.rb +15 -2
- data/app/tables/mensa/config/batch_dsl.rb +13 -0
- data/app/tables/mensa/config/column_dsl.rb +1 -0
- data/app/tables/mensa/config/filter_dsl.rb +4 -1
- data/app/tables/mensa/config/render_dsl.rb +1 -1
- data/app/tables/mensa/config/table_dsl.rb +12 -5
- data/app/tables/mensa/config/view_dsl.rb +2 -0
- data/app/tables/mensa/config_readers.rb +20 -1
- data/app/tables/mensa/filter.rb +86 -3
- data/app/tables/mensa/scope.rb +24 -12
- data/app/views/mensa/exports/_badge.html.slim +5 -0
- data/app/views/mensa/exports/_dialog.html.slim +42 -0
- data/app/views/mensa/exports/_list.html.slim +29 -0
- data/app/views/mensa/tables/filters/show.turbo_stream.slim +35 -8
- data/app/views/mensa/tables/views/create.turbo_stream.slim +11 -0
- data/app/views/mensa/tables/views/destroy.turbo_stream.slim +11 -0
- data/app/views/mensa/tables/views/update.turbo_stream.slim +11 -0
- data/config/locales/en.yml +44 -0
- data/config/locales/nl.yml +45 -0
- data/config/routes.rb +7 -0
- data/db/migrate/20260604120000_create_mensa_exports.rb +25 -0
- data/docs/columns.png +0 -0
- data/docs/export.png +0 -0
- data/docs/filters.png +0 -0
- data/docs/table.png +0 -0
- data/lib/mensa/configuration.rb +33 -12
- data/lib/mensa/engine.rb +7 -2
- data/lib/mensa/version.rb +1 -1
- data/mensa.gemspec +2 -1
- data/mise.toml +8 -0
- data/package-lock.json +0 -7
- metadata +50 -8
|
@@ -1,9 +1,36 @@
|
|
|
1
1
|
= turbo_stream.update params[:target] do
|
|
2
|
-
|
|
3
|
-
=
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
2
|
+
.mensa-table__add_filter__popover_container__heading
|
|
3
|
+
= @column.human_name
|
|
4
|
+
- if @column.filter.operator_with_value?
|
|
5
|
+
- collection = @column.filter.collection
|
|
6
|
+
- if collection.present?
|
|
7
|
+
- unless @multiple
|
|
8
|
+
input[type="hidden" data-mensa-add-filter-target="value" value=@values.first]
|
|
9
|
+
ul.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.mensa-table__add_filter__popover_container__value[data-mensa-add-filter-target="valueOption" data-value=opt_value data-label=opt_label data-selected=("true" if is_selected) data-action="click->mensa-add-filter#selectValue mouseenter->mensa-add-filter#highlightItem"]
|
|
15
|
+
- if @multiple
|
|
16
|
+
span.mensa-table__add_filter__checkbox class=("mensa-table__add_filter__checkbox--checked" if is_selected)
|
|
17
|
+
- else
|
|
18
|
+
i.mensa-table__add_filter__popover_container__value__check.fa-solid.fa-check class=("invisible" unless is_selected)
|
|
19
|
+
span.flex-1
|
|
20
|
+
= opt_label
|
|
21
|
+
span.mensa-table__add_filter__enter-hint
|
|
22
|
+
| ↵ Enter
|
|
23
|
+
- else
|
|
24
|
+
input.mensa-table__add_filter__popover_container__input[type=@column.filter.input_type value=@values.first autocomplete="off" inputmode=(@column.type == :integer ? "numeric" : nil) step=(@column.type == :integer ? 1 : (@column.type == :datetime ? 1 : nil)) data-mensa-add-filter-target="value" data-action="input->mensa-add-filter#manualValueChanged keydown.enter->mensa-add-filter#applyManualValue"]
|
|
25
|
+
hr.mensa-table__add_filter__popover_container__separator
|
|
26
|
+
ul.mensa-table__add_filter__popover_container__operators
|
|
27
|
+
- @column.filter.operators.each do |operator_name, label, requires_value|
|
|
28
|
+
li.mensa-table__add_filter__popover_container__operator[data-mensa-add-filter-target="operatorOption" data-operator=operator_name data-requires-value=(requires_value ? "true" : "false") data-selected=("true" if @operator == operator_name.to_s) data-action="click->mensa-add-filter#selectOperator mouseenter->mensa-add-filter#highlightItem"]
|
|
29
|
+
i.mensa-table__add_filter__popover_container__operator__check.fa-solid.fa-check class=("invisible" unless @operator == operator_name.to_s)
|
|
30
|
+
span.flex-1
|
|
31
|
+
= label
|
|
32
|
+
span.mensa-table__add_filter__enter-hint
|
|
33
|
+
| ↵ Enter
|
|
34
|
+
hr.mensa-table__add_filter__popover_container__separator
|
|
35
|
+
a.mensa-table__add_filter__popover_container__clear[href="#" data-action="click->mensa-add-filter#reset"]
|
|
36
|
+
| Clear
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/ Replace the views tabs so the newly saved view tab appears, selected.
|
|
2
|
+
= turbo_stream.replace "mensa-views-#{@table.table_id}" do
|
|
3
|
+
= render Mensa::Views::Component.new(table: @table)
|
|
4
|
+
|
|
5
|
+
/ Clear the filter pills — the saved view starts fresh with no extra filters.
|
|
6
|
+
= turbo_stream.update "filters-#{@table.table_id}" do
|
|
7
|
+
= render Mensa::FilterPillList::Component.new(table: @table)
|
|
8
|
+
|
|
9
|
+
/ Re-render the table body with the saved view's data.
|
|
10
|
+
= turbo_stream.update @table.table_id do
|
|
11
|
+
= render Mensa::View::Component.new(@table)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/ Replace the views dropdown without the deleted view; @table is at the default view.
|
|
2
|
+
= turbo_stream.replace "mensa-views-#{@table.table_id}" do
|
|
3
|
+
= render Mensa::Views::Component.new(table: @table)
|
|
4
|
+
|
|
5
|
+
/ Reset the search bar to the default view state.
|
|
6
|
+
= turbo_stream.update "filters-#{@table.table_id}" do
|
|
7
|
+
= render Mensa::FilterPillList::Component.new(table: @table)
|
|
8
|
+
|
|
9
|
+
/ Re-render the table body with the default view data.
|
|
10
|
+
= turbo_stream.update @table.table_id do
|
|
11
|
+
= render Mensa::View::Component.new(@table)
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/ Replace the views tabs so the updated view tab stays selected.
|
|
2
|
+
= turbo_stream.replace "mensa-views-#{@table.table_id}" do
|
|
3
|
+
= render Mensa::Views::Component.new(table: @table)
|
|
4
|
+
|
|
5
|
+
/ Clear the filter pills — the view now reflects the saved config.
|
|
6
|
+
= turbo_stream.update "filters-#{@table.table_id}" do
|
|
7
|
+
= render Mensa::FilterPillList::Component.new(table: @table)
|
|
8
|
+
|
|
9
|
+
/ Re-render the table body with the updated view's data.
|
|
10
|
+
= turbo_stream.update @table.table_id do
|
|
11
|
+
= render Mensa::View::Component.new(@table)
|
data/config/locales/en.yml
CHANGED
|
@@ -1,11 +1,55 @@
|
|
|
1
1
|
en:
|
|
2
2
|
mensa:
|
|
3
|
+
operators:
|
|
4
|
+
is: is
|
|
5
|
+
isnt: isn't
|
|
6
|
+
matches: matches
|
|
7
|
+
does_not_match: doesn't match
|
|
8
|
+
is_current: is current
|
|
9
|
+
gt: greater than
|
|
10
|
+
lt: less than
|
|
11
|
+
gteq: greater than or equal to
|
|
12
|
+
lteq: less than or equal to
|
|
3
13
|
add_filter:
|
|
4
14
|
component:
|
|
5
15
|
add_filter: Add filter
|
|
16
|
+
filter_pill_list:
|
|
17
|
+
component:
|
|
18
|
+
search: Search and filter
|
|
19
|
+
search_only: Search
|
|
6
20
|
search:
|
|
7
21
|
component:
|
|
22
|
+
search_in: Search in %{view}
|
|
8
23
|
cancel: Cancel
|
|
9
24
|
save: Save
|
|
25
|
+
save_view_title: Save view
|
|
26
|
+
save_view_subtitle: Save the current filters, ordering and search as a reusable view.
|
|
27
|
+
view_name: Name
|
|
28
|
+
view_name_placeholder: e.g. Active customers
|
|
29
|
+
view_description: Description
|
|
30
|
+
view_description_placeholder: Optional notes about this view
|
|
31
|
+
exports:
|
|
32
|
+
title: "Export %{table}"
|
|
33
|
+
close: Close
|
|
34
|
+
available_downloads: Available downloads
|
|
35
|
+
empty: You have no downloads yet. Create one below.
|
|
36
|
+
item_name: "%{table} export"
|
|
37
|
+
download: Download
|
|
38
|
+
processing: Preparing…
|
|
39
|
+
failed: Failed
|
|
40
|
+
new_export: New export
|
|
41
|
+
scope_all: All records (matching current filters)
|
|
42
|
+
scope_current_page: Current page
|
|
43
|
+
export_as: Export as
|
|
44
|
+
format_excel: CSV for Excel, Numbers, or other spreadsheet programs
|
|
45
|
+
format_plain: Plain CSV file
|
|
46
|
+
cancel: Cancel
|
|
47
|
+
submit: Export
|
|
48
|
+
paging:
|
|
49
|
+
info: Displaying %{model} %{from}-%{to} of %{count}
|
|
50
|
+
empty_state:
|
|
51
|
+
title: No %{model} found
|
|
52
|
+
subtitle: Try changing the filters or search terms for this view
|
|
53
|
+
clear_button: Clear search and filters
|
|
10
54
|
views:
|
|
11
55
|
default: All
|
data/config/locales/nl.yml
CHANGED
|
@@ -1,11 +1,56 @@
|
|
|
1
1
|
nl:
|
|
2
2
|
mensa:
|
|
3
|
+
operators:
|
|
4
|
+
is: is
|
|
5
|
+
isnt: is niet
|
|
6
|
+
matches: matcht
|
|
7
|
+
does_not_match: matcht niet
|
|
8
|
+
is_current: is huidige
|
|
9
|
+
gt: groter dan
|
|
10
|
+
lt: kleiner dan
|
|
11
|
+
gteq: groter dan of gelijk aan
|
|
12
|
+
lteq: kleiner dan of gelijk aan
|
|
3
13
|
add_filter:
|
|
4
14
|
component:
|
|
5
15
|
add_filter: Filter toevoegen
|
|
16
|
+
filter_pill_list:
|
|
17
|
+
component:
|
|
18
|
+
search: Zoeken en filteren
|
|
19
|
+
search_only: Zoeken
|
|
6
20
|
search:
|
|
7
21
|
component:
|
|
22
|
+
search: Zoek en filter
|
|
23
|
+
search_in: Zoek in %{view}
|
|
8
24
|
cancel: Annuleer
|
|
9
25
|
save: Bewaar
|
|
26
|
+
save_view_title: Weergave bewaren
|
|
27
|
+
save_view_subtitle: Bewaar de huidige filters, sortering en zoekopdracht als een herbruikbare weergave.
|
|
28
|
+
view_name: Naam
|
|
29
|
+
view_name_placeholder: bijv. Actieve klanten
|
|
30
|
+
view_description: Omschrijving
|
|
31
|
+
view_description_placeholder: Optionele notities over deze weergave
|
|
32
|
+
exports:
|
|
33
|
+
title: "%{table} exporteren"
|
|
34
|
+
close: Sluiten
|
|
35
|
+
available_downloads: Beschikbare downloads
|
|
36
|
+
empty: Je hebt nog geen downloads. Maak er hieronder een aan.
|
|
37
|
+
item_name: "%{table} export"
|
|
38
|
+
download: Downloaden
|
|
39
|
+
processing: Bezig…
|
|
40
|
+
failed: Mislukt
|
|
41
|
+
new_export: Nieuwe export
|
|
42
|
+
scope_all: Alle records (volgens huidige filters)
|
|
43
|
+
scope_current_page: Huidige pagina
|
|
44
|
+
export_as: Exporteren als
|
|
45
|
+
format_excel: CSV voor Excel, Numbers of andere spreadsheetprogramma's
|
|
46
|
+
format_plain: Eenvoudig CSV-bestand
|
|
47
|
+
cancel: Annuleer
|
|
48
|
+
submit: Exporteren
|
|
49
|
+
paging:
|
|
50
|
+
info: "%{model} %{from}-%{to} van %{count} weergeven"
|
|
51
|
+
empty_state:
|
|
52
|
+
title: Geen %{model} gevonden
|
|
53
|
+
subtitle: Probeer de filters of zoektermen voor deze weergave te wijzigen
|
|
54
|
+
clear_button: Zoekopdracht en filters wissen
|
|
10
55
|
views:
|
|
11
56
|
default: Alles
|
data/config/routes.rb
CHANGED
|
@@ -2,6 +2,13 @@ Mensa::Engine.routes.draw do
|
|
|
2
2
|
resources :tables do
|
|
3
3
|
scope module: :tables do
|
|
4
4
|
resources :filters
|
|
5
|
+
resources :views, only: [:create, :update, :destroy]
|
|
6
|
+
resources :batch_actions, only: [:create]
|
|
7
|
+
resources :exports, only: [:index, :create] do
|
|
8
|
+
member do
|
|
9
|
+
get :download
|
|
10
|
+
end
|
|
11
|
+
end
|
|
5
12
|
end
|
|
6
13
|
end
|
|
7
14
|
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
class CreateMensaExports < ActiveRecord::Migration[7.1]
|
|
2
|
+
def change
|
|
3
|
+
create_table :mensa_exports, id: :uuid do |t|
|
|
4
|
+
t.string :table_name, null: false
|
|
5
|
+
# The view (system or custom) the export was generated for, if applicable.
|
|
6
|
+
t.references :table_view, null: true, type: :uuid, foreign_key: {to_table: :mensa_table_views}
|
|
7
|
+
|
|
8
|
+
# Scope ("all" / "current_page") and output format ("csv_excel" / "plain_csv").
|
|
9
|
+
t.string :scope
|
|
10
|
+
t.string :format
|
|
11
|
+
# Lifecycle: pending -> processing -> completed / failed.
|
|
12
|
+
t.string :status, null: false, default: "pending"
|
|
13
|
+
# The request configuration (filters, query, order, page) used to build the export.
|
|
14
|
+
t.jsonb :config, null: false, default: {}
|
|
15
|
+
t.string :filename
|
|
16
|
+
|
|
17
|
+
t.references :user, null: true, foreign_key: true, type: :uuid
|
|
18
|
+
|
|
19
|
+
t.timestamps
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
add_index :mensa_exports, :table_name
|
|
23
|
+
add_index :mensa_exports, :status
|
|
24
|
+
end
|
|
25
|
+
end
|
data/docs/columns.png
ADDED
|
Binary file
|
data/docs/export.png
ADDED
|
Binary file
|
data/docs/filters.png
CHANGED
|
Binary file
|
data/docs/table.png
CHANGED
|
Binary file
|
data/lib/mensa/configuration.rb
CHANGED
|
@@ -3,9 +3,20 @@
|
|
|
3
3
|
module Mensa
|
|
4
4
|
module Options
|
|
5
5
|
module ClassMethods
|
|
6
|
-
def option(name, default: nil)
|
|
7
|
-
|
|
8
|
-
schema[name] = default
|
|
6
|
+
def option(name, default: nil, proc: false)
|
|
7
|
+
attr_writer(name)
|
|
8
|
+
schema[name] = {default: default, proc: proc}
|
|
9
|
+
|
|
10
|
+
if schema[name][:proc]
|
|
11
|
+
define_method(name) do |*params|
|
|
12
|
+
value = instance_variable_get(:"@#{name}")
|
|
13
|
+
instance_exec(*params, &value)
|
|
14
|
+
end
|
|
15
|
+
else
|
|
16
|
+
define_method(name) do
|
|
17
|
+
instance_variable_get(:"@#{name}")
|
|
18
|
+
end
|
|
19
|
+
end
|
|
9
20
|
end
|
|
10
21
|
|
|
11
22
|
def schema
|
|
@@ -14,8 +25,8 @@ module Mensa
|
|
|
14
25
|
end
|
|
15
26
|
|
|
16
27
|
def set_defaults!
|
|
17
|
-
self.class.schema.each do |name,
|
|
18
|
-
instance_variable_set("@#{name}", default)
|
|
28
|
+
self.class.schema.each do |name, options|
|
|
29
|
+
instance_variable_set(:"@#{name}", options[:default])
|
|
19
30
|
end
|
|
20
31
|
end
|
|
21
32
|
|
|
@@ -32,9 +43,8 @@ module Mensa
|
|
|
32
43
|
|
|
33
44
|
# TODO: add all icons below
|
|
34
45
|
option :icons, default: {
|
|
35
|
-
order_indicator_asc: "fa-solid fa-
|
|
36
|
-
order_indicator_desc: "fa-solid fa-
|
|
37
|
-
order_indicator: "fa-solid fa-sort",
|
|
46
|
+
order_indicator_asc: "fa-solid fa-arrow-up",
|
|
47
|
+
order_indicator_desc: "fa-solid fa-arrow-down",
|
|
38
48
|
control_bar_search: "fa-solid fa-magnifying-glass",
|
|
39
49
|
control_bar_filter: "fa-solid fa-filter",
|
|
40
50
|
control_bar_edit: "fa-solid fa-table-columns",
|
|
@@ -57,14 +67,25 @@ module Mensa
|
|
|
57
67
|
# }
|
|
58
68
|
|
|
59
69
|
option :callbacks, default: {
|
|
60
|
-
#
|
|
61
|
-
|
|
62
|
-
export_started: lambda do |user_id, table_name|
|
|
70
|
+
# Called with the Mensa::Export when the export job starts processing.
|
|
71
|
+
export_started: lambda do |export|
|
|
63
72
|
end,
|
|
64
|
-
|
|
73
|
+
# Called with the Mensa::Export once the CSV has been generated and
|
|
74
|
+
# attached (export.asset). Use this to e.g. notify or email the user.
|
|
75
|
+
export_complete: lambda do |export|
|
|
65
76
|
end
|
|
66
77
|
}
|
|
67
78
|
|
|
79
|
+
option :row_actions_position, default: :back
|
|
80
|
+
# It's either :basic or :fuzzy, for fuzzy search you need to have `pg_trgm` extension installed
|
|
81
|
+
option :search, default: -> {
|
|
82
|
+
@_search_cache ||= begin
|
|
83
|
+
(ActiveRecord::Base.connection.execute("SELECT extname FROM pg_extension where extname='pg_trgm';")&.first&.[]("extname") == "pg_trgm") ? :fuzzy : :basic
|
|
84
|
+
rescue
|
|
85
|
+
:basic
|
|
86
|
+
end
|
|
87
|
+
}, proc: true
|
|
88
|
+
|
|
68
89
|
def initialize
|
|
69
90
|
set_defaults!
|
|
70
91
|
end
|
data/lib/mensa/engine.rb
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
require "pagy"
|
|
2
2
|
require "satis"
|
|
3
3
|
require "textacular"
|
|
4
|
-
require "caxlsx_rails"
|
|
5
4
|
require "slim"
|
|
6
5
|
require "tailwindcss-rails"
|
|
7
6
|
require "importmap-rails"
|
|
@@ -28,8 +27,14 @@ module Mensa
|
|
|
28
27
|
|
|
29
28
|
initializer "mensa.helper" do
|
|
30
29
|
Rails.application.reloader.to_prepare do
|
|
30
|
+
ActiveSupport.on_load(:action_view) do
|
|
31
|
+
include Mensa::ApplicationHelper
|
|
32
|
+
end
|
|
31
33
|
ActiveSupport.on_load(:action_controller) do
|
|
32
|
-
Satis
|
|
34
|
+
# Only do this if Satis is defined, this will be deprecated!
|
|
35
|
+
if defined?(Satis)
|
|
36
|
+
Satis.add_helper(:table, ::Mensa::Table::Component)
|
|
37
|
+
end
|
|
33
38
|
end
|
|
34
39
|
end
|
|
35
40
|
end
|
data/lib/mensa/version.rb
CHANGED
data/mensa.gemspec
CHANGED
|
@@ -29,8 +29,9 @@ Gem::Specification.new do |spec|
|
|
|
29
29
|
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
-
spec.add_dependency "caxlsx_rails", "~> 0"
|
|
33
32
|
spec.add_dependency "rails", ">= 7.1"
|
|
33
|
+
spec.add_dependency "csv"
|
|
34
|
+
spec.add_dependency "rubyzip", ">= 1.2.2"
|
|
34
35
|
spec.add_dependency "pagy", ">=43"
|
|
35
36
|
spec.add_dependency "textacular", ">=5"
|
|
36
37
|
spec.add_dependency "view_component", "~> 3.11"
|
data/mise.toml
ADDED
data/package-lock.json
CHANGED
|
@@ -305,7 +305,6 @@
|
|
|
305
305
|
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz",
|
|
306
306
|
"integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==",
|
|
307
307
|
"license": "MIT",
|
|
308
|
-
"peer": true,
|
|
309
308
|
"bin": {
|
|
310
309
|
"acorn": "bin/acorn"
|
|
311
310
|
},
|
|
@@ -1098,7 +1097,6 @@
|
|
|
1098
1097
|
"integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==",
|
|
1099
1098
|
"deprecated": "This version is no longer supported. Please see https://eslint.org/version-support for other options.",
|
|
1100
1099
|
"license": "MIT",
|
|
1101
|
-
"peer": true,
|
|
1102
1100
|
"dependencies": {
|
|
1103
1101
|
"@eslint-community/eslint-utils": "^4.2.0",
|
|
1104
1102
|
"@eslint-community/regexpp": "^4.6.1",
|
|
@@ -1296,7 +1294,6 @@
|
|
|
1296
1294
|
"resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz",
|
|
1297
1295
|
"integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==",
|
|
1298
1296
|
"license": "MIT",
|
|
1299
|
-
"peer": true,
|
|
1300
1297
|
"dependencies": {
|
|
1301
1298
|
"@rtsao/scc": "^1.1.0",
|
|
1302
1299
|
"array-includes": "^3.1.9",
|
|
@@ -1373,7 +1370,6 @@
|
|
|
1373
1370
|
"resolved": "https://registry.npmjs.org/eslint-plugin-n/-/eslint-plugin-n-15.7.0.tgz",
|
|
1374
1371
|
"integrity": "sha512-jDex9s7D/Qial8AGVIHq4W7NswpUD5DPDL2RH8Lzd9EloWUuvUkHfv4FRLMipH5q2UtyurorBkPeNi1wVWNh3Q==",
|
|
1375
1372
|
"license": "MIT",
|
|
1376
|
-
"peer": true,
|
|
1377
1373
|
"dependencies": {
|
|
1378
1374
|
"builtins": "^5.0.1",
|
|
1379
1375
|
"eslint-plugin-es": "^4.1.0",
|
|
@@ -1433,7 +1429,6 @@
|
|
|
1433
1429
|
"resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.6.0.tgz",
|
|
1434
1430
|
"integrity": "sha512-57Zzfw8G6+Gq7axm2Pdo3gW/Rx3h9Yywgn61uE/3elTCOePEHVrn2i5CdfBwA1BLK0Q0WqctICIUSqXZW/VprQ==",
|
|
1435
1431
|
"license": "ISC",
|
|
1436
|
-
"peer": true,
|
|
1437
1432
|
"engines": {
|
|
1438
1433
|
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
|
|
1439
1434
|
},
|
|
@@ -1449,7 +1444,6 @@
|
|
|
1449
1444
|
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz",
|
|
1450
1445
|
"integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==",
|
|
1451
1446
|
"license": "MIT",
|
|
1452
|
-
"peer": true,
|
|
1453
1447
|
"dependencies": {
|
|
1454
1448
|
"array-includes": "^3.1.8",
|
|
1455
1449
|
"array.prototype.findlast": "^1.2.5",
|
|
@@ -3451,7 +3445,6 @@
|
|
|
3451
3445
|
}
|
|
3452
3446
|
],
|
|
3453
3447
|
"license": "MIT",
|
|
3454
|
-
"peer": true,
|
|
3455
3448
|
"dependencies": {
|
|
3456
3449
|
"nanoid": "^3.3.11",
|
|
3457
3450
|
"picocolors": "^1.1.1",
|
metadata
CHANGED
|
@@ -1,43 +1,57 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: mensa
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.6
|
|
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:
|
|
11
|
+
date: 2026-06-10 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
|
-
name:
|
|
14
|
+
name: rails
|
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
|
16
16
|
requirements:
|
|
17
|
-
- - "
|
|
17
|
+
- - ">="
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '7.1'
|
|
20
|
+
type: :runtime
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ">="
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '7.1'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: csv
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - ">="
|
|
18
32
|
- !ruby/object:Gem::Version
|
|
19
33
|
version: '0'
|
|
20
34
|
type: :runtime
|
|
21
35
|
prerelease: false
|
|
22
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
23
37
|
requirements:
|
|
24
|
-
- - "
|
|
38
|
+
- - ">="
|
|
25
39
|
- !ruby/object:Gem::Version
|
|
26
40
|
version: '0'
|
|
27
41
|
- !ruby/object:Gem::Dependency
|
|
28
|
-
name:
|
|
42
|
+
name: rubyzip
|
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
|
30
44
|
requirements:
|
|
31
45
|
- - ">="
|
|
32
46
|
- !ruby/object:Gem::Version
|
|
33
|
-
version:
|
|
47
|
+
version: 1.2.2
|
|
34
48
|
type: :runtime
|
|
35
49
|
prerelease: false
|
|
36
50
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
51
|
requirements:
|
|
38
52
|
- - ">="
|
|
39
53
|
- !ruby/object:Gem::Version
|
|
40
|
-
version:
|
|
54
|
+
version: 1.2.2
|
|
41
55
|
- !ruby/object:Gem::Dependency
|
|
42
56
|
name: pagy
|
|
43
57
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -175,10 +189,13 @@ files:
|
|
|
175
189
|
- ".devcontainer/Dockerfile"
|
|
176
190
|
- ".devcontainer/compose.yaml"
|
|
177
191
|
- ".devcontainer/devcontainer.json"
|
|
192
|
+
- ".devcontainer/postCreate.sh"
|
|
193
|
+
- ".devcontainer/postStart.sh"
|
|
178
194
|
- ".gem_release.yml"
|
|
179
195
|
- ".github/workflows/gem-push.yml"
|
|
180
196
|
- ".gitignore"
|
|
181
197
|
- ".rubocop.yml"
|
|
198
|
+
- ".zed/tasks.json"
|
|
182
199
|
- CHANGELOG.md
|
|
183
200
|
- Gemfile
|
|
184
201
|
- Gemfile.lock
|
|
@@ -197,9 +214,17 @@ files:
|
|
|
197
214
|
- app/components/mensa/cell/component.css
|
|
198
215
|
- app/components/mensa/cell/component.html.slim
|
|
199
216
|
- app/components/mensa/cell/component.rb
|
|
217
|
+
- app/components/mensa/column_customizer/component.css
|
|
218
|
+
- app/components/mensa/column_customizer/component.html.slim
|
|
219
|
+
- app/components/mensa/column_customizer/component.rb
|
|
220
|
+
- app/components/mensa/column_customizer/component_controller.js
|
|
200
221
|
- app/components/mensa/control_bar/component.css
|
|
201
222
|
- app/components/mensa/control_bar/component.html.slim
|
|
202
223
|
- app/components/mensa/control_bar/component.rb
|
|
224
|
+
- app/components/mensa/empty_state/component.css
|
|
225
|
+
- app/components/mensa/empty_state/component.html.slim
|
|
226
|
+
- app/components/mensa/empty_state/component.rb
|
|
227
|
+
- app/components/mensa/filter_pill/component.css
|
|
203
228
|
- app/components/mensa/filter_pill/component.html.slim
|
|
204
229
|
- app/components/mensa/filter_pill/component.rb
|
|
205
230
|
- app/components/mensa/filter_pill/component_controller.js
|
|
@@ -217,6 +242,7 @@ files:
|
|
|
217
242
|
- app/components/mensa/search/component.html.slim
|
|
218
243
|
- app/components/mensa/search/component.rb
|
|
219
244
|
- app/components/mensa/search/component_controller.js
|
|
245
|
+
- app/components/mensa/selection/component_controller.js
|
|
220
246
|
- app/components/mensa/table/component.css
|
|
221
247
|
- app/components/mensa/table/component.html.slim
|
|
222
248
|
- app/components/mensa/table/component.rb
|
|
@@ -234,7 +260,10 @@ files:
|
|
|
234
260
|
- app/components/mensa/views/component_controller.js
|
|
235
261
|
- app/controllers/concerns/.keep
|
|
236
262
|
- app/controllers/mensa/application_controller.rb
|
|
263
|
+
- app/controllers/mensa/tables/batch_actions_controller.rb
|
|
264
|
+
- app/controllers/mensa/tables/exports_controller.rb
|
|
237
265
|
- app/controllers/mensa/tables/filters_controller.rb
|
|
266
|
+
- app/controllers/mensa/tables/views_controller.rb
|
|
238
267
|
- app/controllers/mensa/tables_controller.rb
|
|
239
268
|
- app/helpers/mensa/application_helper.rb
|
|
240
269
|
- app/helpers/mensa/tables_helper.rb
|
|
@@ -247,12 +276,15 @@ files:
|
|
|
247
276
|
- app/jobs/mensa/export_job.rb
|
|
248
277
|
- app/models/concerns/.keep
|
|
249
278
|
- app/models/mensa/application_record.rb
|
|
279
|
+
- app/models/mensa/export.rb
|
|
250
280
|
- app/models/mensa/table_view.rb
|
|
251
281
|
- app/tables/mensa/action.rb
|
|
252
282
|
- app/tables/mensa/base.rb
|
|
283
|
+
- app/tables/mensa/batch_action.rb
|
|
253
284
|
- app/tables/mensa/cell.rb
|
|
254
285
|
- app/tables/mensa/column.rb
|
|
255
286
|
- app/tables/mensa/config/action_dsl.rb
|
|
287
|
+
- app/tables/mensa/config/batch_dsl.rb
|
|
256
288
|
- app/tables/mensa/config/column_dsl.rb
|
|
257
289
|
- app/tables/mensa/config/dsl_logic.rb
|
|
258
290
|
- app/tables/mensa/config/filter_dsl.rb
|
|
@@ -264,9 +296,15 @@ files:
|
|
|
264
296
|
- app/tables/mensa/row.rb
|
|
265
297
|
- app/tables/mensa/scope.rb
|
|
266
298
|
- app/tables/mensa/system_view.rb
|
|
299
|
+
- app/views/mensa/exports/_badge.html.slim
|
|
300
|
+
- app/views/mensa/exports/_dialog.html.slim
|
|
301
|
+
- app/views/mensa/exports/_list.html.slim
|
|
267
302
|
- app/views/mensa/tables/filters/show.turbo_stream.slim
|
|
268
303
|
- app/views/mensa/tables/show.html.slim
|
|
269
304
|
- app/views/mensa/tables/show.turbo_stream.slim
|
|
305
|
+
- app/views/mensa/tables/views/create.turbo_stream.slim
|
|
306
|
+
- app/views/mensa/tables/views/destroy.turbo_stream.slim
|
|
307
|
+
- app/views/mensa/tables/views/update.turbo_stream.slim
|
|
270
308
|
- bin/importmap
|
|
271
309
|
- bin/overmind
|
|
272
310
|
- bin/rails
|
|
@@ -277,6 +315,9 @@ files:
|
|
|
277
315
|
- config/routes.rb
|
|
278
316
|
- db/migrate/20240201184752_create_mensa_table_views.rb
|
|
279
317
|
- db/migrate/20251112143558_add_description_to_table_view.rb
|
|
318
|
+
- db/migrate/20260604120000_create_mensa_exports.rb
|
|
319
|
+
- docs/columns.png
|
|
320
|
+
- docs/export.png
|
|
280
321
|
- docs/filters.png
|
|
281
322
|
- docs/table.png
|
|
282
323
|
- lib/generators/mensa/install_generator.rb
|
|
@@ -288,6 +329,7 @@ files:
|
|
|
288
329
|
- lib/mensa/version.rb
|
|
289
330
|
- lib/tasks/mensa_tasks.rake
|
|
290
331
|
- mensa.gemspec
|
|
332
|
+
- mise.toml
|
|
291
333
|
- package-lock.json
|
|
292
334
|
- package.json
|
|
293
335
|
- vendor/javascript/@rails--request.js.js
|