mensa 0.2.4 → 0.2.5
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/CHANGELOG.md +6 -0
- data/Gemfile.lock +3 -3
- data/README.md +13 -3
- data/app/assets/stylesheets/mensa/application.css +1 -1
- data/app/components/mensa/add_filter/component.html.slim +2 -2
- data/app/components/mensa/add_filter/component.rb +1 -1
- data/app/components/mensa/add_filter/component_controller.js +21 -23
- data/app/components/mensa/control_bar/component.html.slim +1 -1
- data/app/components/mensa/control_bar/component.rb +2 -2
- data/app/components/mensa/filter_pill/component.html.slim +6 -0
- data/app/components/mensa/filter_pill/component.rb +15 -0
- data/app/components/mensa/{filter → filter_pill}/component_controller.js +1 -1
- data/app/components/mensa/filter_pill_list/component.html.slim +8 -0
- data/app/components/mensa/{filter_list → filter_pill_list}/component.rb +1 -1
- data/app/components/mensa/filter_pill_list/component_controller.js +50 -0
- data/app/components/mensa/header/component.rb +1 -1
- data/app/components/mensa/row_action/component.rb +1 -1
- data/app/components/mensa/search/component.html.slim +1 -1
- data/app/components/mensa/search/component.rb +1 -1
- data/app/components/mensa/search/component_controller.js +2 -2
- data/app/components/mensa/table/component.html.slim +3 -3
- data/app/components/mensa/table/component_controller.js +14 -2
- data/app/components/mensa/table_row/component.rb +1 -1
- data/app/components/mensa/views/component.html.slim +1 -1
- data/app/controllers/mensa/application_controller.rb +1 -1
- data/app/controllers/mensa/tables/filters_controller.rb +2 -1
- data/app/controllers/mensa/tables_controller.rb +3 -9
- data/app/helpers/mensa/application_helper.rb +0 -1
- data/app/javascript/mensa/controllers/application_controller.js +5 -21
- data/app/javascript/mensa/controllers/index.js +4 -4
- data/app/jobs/mensa/export_job.rb +10 -11
- data/app/tables/mensa/action.rb +3 -1
- data/app/tables/mensa/base.rb +10 -15
- data/app/tables/mensa/cell.rb +6 -6
- data/app/tables/mensa/column.rb +16 -24
- data/app/tables/mensa/config/action_dsl.rb +1 -1
- data/app/tables/mensa/config/dsl_logic.rb +8 -4
- data/app/tables/mensa/config/table_dsl.rb +4 -1
- data/app/tables/mensa/config_readers.rb +15 -3
- data/app/tables/mensa/filter.rb +11 -14
- data/app/tables/mensa/row.rb +1 -1
- data/app/tables/mensa/scope.rb +3 -3
- data/app/views/mensa/tables/filters/show.turbo_stream.slim +7 -6
- data/app/views/mensa/tables/show.html.slim +2 -0
- data/app/views/mensa/tables/show.turbo_stream.slim +1 -1
- data/bin/setup +1 -1
- data/config/locales/en.yml +1 -1
- data/config/locales/nl.yml +1 -1
- data/lib/generators/mensa/tailwind_config_generator.rb +3 -3
- data/lib/generators/mensa/templates/config/initializers/mensa.rb +1 -1
- data/lib/mensa/configuration.rb +2 -3
- data/lib/mensa/engine.rb +9 -9
- data/lib/mensa/version.rb +1 -1
- data/lib/mensa.rb +2 -2
- data/lib/tasks/mensa_tasks.rake +1 -1
- data/mensa.gemspec +1 -1
- metadata +12 -9
- data/app/components/mensa/filter_list/component.html.slim +0 -14
- data/app/components/mensa/filter_list/component_controller.js +0 -14
- /data/{rubocop.yml → .rubocop.yml} +0 -0
- /data/app/components/mensa/{filter_list → filter_pill_list}/component.css +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: fa2c03e8e00ac20aa0a68e6a19b43de5f4262bd7601bf32a51679d9b8bbe7541
|
|
4
|
+
data.tar.gz: b94c0a5f9a3242fde92cffd8ee19a3add4ef60f95cd594f80cc53c02f525e2f7
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 623466449dc736362fed892249981bb374b1f76b541272e65205bebbea1b2b20d2f4f0b94d700040849bc297f874a4f1041197b3fb09e69a147649b87920ae56
|
|
7
|
+
data.tar.gz: 872085623dfbde8c840a2c4fe03f0105c23c46c60c62b00af26c34373731008a163004fa24c668dd49682d93618e0b113c2686e2a138868d08dcdef49572cc60
|
data/CHANGELOG.md
ADDED
data/Gemfile.lock
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
mensa (0.2.
|
|
4
|
+
mensa (0.2.4)
|
|
5
5
|
caxlsx_rails (~> 0)
|
|
6
6
|
importmap-rails
|
|
7
7
|
pagy (>= 43)
|
|
@@ -122,7 +122,7 @@ GEM
|
|
|
122
122
|
reline (>= 0.3.8)
|
|
123
123
|
diffy (3.4.4)
|
|
124
124
|
drb (2.2.3)
|
|
125
|
-
erb (
|
|
125
|
+
erb (6.0.0)
|
|
126
126
|
erubi (1.13.1)
|
|
127
127
|
globalid (1.3.0)
|
|
128
128
|
activesupport (>= 6.1)
|
|
@@ -353,7 +353,7 @@ GEM
|
|
|
353
353
|
rubocop-performance (~> 1.25.0)
|
|
354
354
|
stimulus-rails (1.3.4)
|
|
355
355
|
railties (>= 6.0.0)
|
|
356
|
-
stringio (3.1.
|
|
356
|
+
stringio (3.1.8)
|
|
357
357
|
tailwindcss-rails (3.3.2)
|
|
358
358
|
railties (>= 7.0.0)
|
|
359
359
|
tailwindcss-ruby (~> 3.0)
|
data/README.md
CHANGED
|
@@ -70,11 +70,13 @@ class UserTable < ApplicationTable
|
|
|
70
70
|
link { |user| edit_user_path(user) }
|
|
71
71
|
supports_views true # This table supports custom views
|
|
72
72
|
show_header true
|
|
73
|
-
|
|
73
|
+
view_columns_ordering false # Disabled for now
|
|
74
74
|
view_condensed false # Default false
|
|
75
75
|
view_condensed_toggle true # Whether to show the toggle, default true
|
|
76
76
|
|
|
77
77
|
# Add system views
|
|
78
|
+
# Mensa will always create a systemview (:default) with name 'All' showing all records.
|
|
79
|
+
# If you want to rename it, for example because you don't show all records in your default scope, add it and give it a name like below.
|
|
78
80
|
view :concept do
|
|
79
81
|
name "Concept"
|
|
80
82
|
filter :state do
|
|
@@ -99,7 +101,7 @@ Custom views are views not defined by the developer (SystemViews) but by the end
|
|
|
99
101
|
|
|
100
102
|
Initial support for custom-views is there, but pretty rudimentary:
|
|
101
103
|
|
|
102
|
-
`Mensa::TableView.create(table: "users", name: "Guests",
|
|
104
|
+
`Mensa::TableView.create(table: "users", name: "Guests", config: {filters: {role: {value: "guest"}}})`
|
|
103
105
|
|
|
104
106
|
### Fast
|
|
105
107
|
|
|
@@ -124,10 +126,16 @@ end
|
|
|
124
126
|
export BUNDLE_RUBYGEMS__PKG__GITHUB__COM=ghp_xxxxxxw
|
|
125
127
|
export RBENV_VERSION=$(cat .ruby-version)
|
|
126
128
|
```
|
|
129
|
+
|
|
127
130
|
- Run `direnv allow`
|
|
131
|
+
|
|
132
|
+
If you use devcontainers:
|
|
128
133
|
- Open with Visual Studio Code (or with any other editor) and reopen in container.
|
|
129
134
|
- Run `bin/overmind s`
|
|
130
135
|
|
|
136
|
+
If you're not using devcontainers:
|
|
137
|
+
- Run `bin/overmind s`
|
|
138
|
+
|
|
131
139
|
### Docs
|
|
132
140
|
|
|
133
141
|
Using the following in your view will render Mensa::Table::Component
|
|
@@ -137,7 +145,9 @@ Using the following in your view will render Mensa::Table::Component
|
|
|
137
145
|
|
|
138
146
|
The Mensa::Table::Component will render:
|
|
139
147
|
- Mensa::Search::Component
|
|
140
|
-
- Mensa::
|
|
148
|
+
- Mensa::FilterPillList::Component
|
|
149
|
+
- Mensa::FilterPill::Component
|
|
150
|
+
- Mensa::AddFilter::Component
|
|
141
151
|
- Mensa::Views::Component
|
|
142
152
|
- renders a views list
|
|
143
153
|
- Mensa::ControlBar::Component
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
@import '../../../components/mensa/add_filter/component.css';
|
|
2
2
|
@import '../../../components/mensa/cell/component.css';
|
|
3
3
|
@import '../../../components/mensa/control_bar/component.css';
|
|
4
|
-
@import '../../../components/mensa/
|
|
4
|
+
@import '../../../components/mensa/filter_pill_list/component.css';
|
|
5
5
|
@import '../../../components/mensa/header/component.css';
|
|
6
6
|
@import '../../../components/mensa/row_action/component.css';
|
|
7
7
|
@import '../../../components/mensa/search/component.css';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
.sts-table__add_filter data-controller="mensa-add-filter" data-mensa-add-filter-mensa-
|
|
1
|
+
.sts-table__add_filter data-controller="mensa-add-filter" data-mensa-add-filter-mensa-filter-pill-list-outlet="#mensa-filter-pill-list-#{table.table_id}"
|
|
2
2
|
button.relative.w-full.cursor-default.rounded-md.bg-white.dark:bg-gray-800.py-1.5.pl-3.pr-6.text-left.text-gray-400.dark:text-gray-400.shadow-sm.border.border-dashed.focus:outline-none.focus:ring-2.focus:ring-primary-600.sm:text-sm.sm:leading-6 type="button" data-action="mensa-add-filter#toggle"
|
|
3
3
|
span.mr-2.block.truncate data-mensa-add-filter-target="description"
|
|
4
4
|
= t('.add_filter')
|
|
@@ -13,4 +13,4 @@
|
|
|
13
13
|
.check.hidden.text-primary-600.absolute.inset-y-0.left-0.flex.items-center.pl-3
|
|
14
14
|
.fal.fa-check
|
|
15
15
|
|
|
16
|
-
div.hidden.sts-table__add_filter__popover_container data-mensa-add-filter-target="valuePopover" id="mensa-filter-value-#{SecureRandom.base36}"
|
|
16
|
+
div.hidden.sts-table__add_filter__popover_container data-mensa-add-filter-target="valuePopover" id="mensa-filter-pill-value-#{SecureRandom.base36}"
|
|
@@ -4,13 +4,14 @@ import { get } from '@rails/request.js'
|
|
|
4
4
|
|
|
5
5
|
export default class AddFilterComponentController extends ApplicationController {
|
|
6
6
|
static outlets = [
|
|
7
|
-
"mensa-
|
|
7
|
+
"mensa-filter-pill-list"
|
|
8
8
|
]
|
|
9
9
|
static targets = [
|
|
10
10
|
'filterList', // all filters
|
|
11
11
|
'filterListItem', // individual filters
|
|
12
12
|
'description', // contains the filter description in the "tab"
|
|
13
|
-
'valuePopover'
|
|
13
|
+
'valuePopover', // contains the filter-value
|
|
14
|
+
'value'
|
|
14
15
|
]
|
|
15
16
|
static values = {
|
|
16
17
|
supportsViews: Boolean
|
|
@@ -21,7 +22,7 @@ export default class AddFilterComponentController extends ApplicationController
|
|
|
21
22
|
|
|
22
23
|
// this.filterValueEntered = debounce(this.filterValueEntered, 500).bind(this)
|
|
23
24
|
// this.filterValueEntered = this.filterValueEntered.bind(this)
|
|
24
|
-
this.
|
|
25
|
+
this._selectedFilterColumn = null
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
// Called when you click add-filter
|
|
@@ -31,7 +32,7 @@ export default class AddFilterComponentController extends ApplicationController
|
|
|
31
32
|
|
|
32
33
|
// Called when you selected a column
|
|
33
34
|
openValuePopover(event) {
|
|
34
|
-
let url = this.ourUrl
|
|
35
|
+
let url = this.mensaFilterPillListOutlet.ourUrl
|
|
35
36
|
url.pathname += `/filters/${this.selectedFilterColumn}`
|
|
36
37
|
url.searchParams.append('target', this.valuePopoverTarget.id)
|
|
37
38
|
|
|
@@ -63,26 +64,23 @@ export default class AddFilterComponentController extends ApplicationController
|
|
|
63
64
|
filterValueEntered(event) {
|
|
64
65
|
this.valuePopoverTarget.classList.add('hidden')
|
|
65
66
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
let filters = url.searchParams.get('filters') || {}
|
|
69
|
-
this.mensaTableOutlet.mensaFilterOutlets.forEach((filterOutlet) => {
|
|
70
|
-
url.searchParams.append(`filters[${filterOutlet.columnNameValue}][value]`, filterOutlet.valueValue)
|
|
71
|
-
url.searchParams.append(`filters[${filterOutlet.columnNameValue}][operator]`, filterOutlet.operatorValue)
|
|
72
|
-
})
|
|
73
|
-
// FIXME: Needs better way of getting value
|
|
74
|
-
url.searchParams.append(`filters[${this.selectedFilterColumn}][value]`, event.target.value)
|
|
75
|
-
|
|
76
|
-
get(url, {
|
|
77
|
-
responseKind: 'turbo-stream'
|
|
78
|
-
}).then(() => {
|
|
79
|
-
// FIXME: There should be a better way to do this, possibly using
|
|
80
|
-
// this.mensaTableOutlet.filterListTarget.addEventListener("turbo:after-stream-render", this.unhide.bind(this)) ?
|
|
81
|
-
setTimeout(() => {
|
|
82
|
-
this.mensaTableOutlet.filterListTarget.classList.remove('hidden')
|
|
83
|
-
}, 50)
|
|
84
|
-
})
|
|
67
|
+
this.mensaFilterPillListOutlet.refreshFilters()
|
|
85
68
|
event.preventDefault()
|
|
86
69
|
return false
|
|
87
70
|
}
|
|
71
|
+
|
|
72
|
+
reset(event) {
|
|
73
|
+
this.descriptionTarget.innerText = 'Add filter'
|
|
74
|
+
this.selectedFilterColumn = null
|
|
75
|
+
this.valuePopoverTarget.classList.add('hidden')
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
get selectedFilterColumn() {
|
|
80
|
+
return this._selectedFilterColumn
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
set selectedFilterColumn(value) {
|
|
84
|
+
this._selectedFilterColumn = value
|
|
85
|
+
}
|
|
88
86
|
}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
i class=Mensa.config.icons[:control_bar_search]
|
|
6
6
|
- if table.supports_filters? && table.filters?
|
|
7
7
|
i class=Mensa.config.icons[:control_bar_filter]
|
|
8
|
-
/- if
|
|
8
|
+
/- if view_columns_ordering?
|
|
9
9
|
button.cursor-pointer.w-6.h-full.text-gray-400
|
|
10
10
|
i class=Mensa.config.icons[:control_bar_edit]
|
|
11
11
|
- if view_condensed_toggle?
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
.relative.mensa-filter-pill data-controller="mensa-filter-pill" data-mensa-filter-pill-column-name-value=filter.column.name data-mensa-filter-pill-value-value=filter.value data-mensa-filter-pill-operator-value=filter.operator
|
|
2
|
+
button.relative.w-full.cursor-default.rounded-md.bg-white.dark:bg-gray-800.py-1.5.pl-3.text-left.text-gray-900.dark:text-gray-400.shadow-sm.ring-1.ring-inset.ring-gray-300.dark:ring-gray-600.focus:outline-none.focus:ring-2.focus:ring-primary-600.sm:text-sm.sm:leading-6[type="button" aria-haspopup="listbox" aria-expanded="true" aria-labelledby="listbox-label"]
|
|
3
|
+
span.block.truncate.pr-8
|
|
4
|
+
= filter
|
|
5
|
+
span.pointer-events-none.absolute.inset-y-0.right-0.flex.items-center.pr-2
|
|
6
|
+
.fa.fal.fa-xmark
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Mensa
|
|
4
|
+
module FilterPill
|
|
5
|
+
class Component < ::Mensa::ApplicationComponent
|
|
6
|
+
with_collection_parameter :filter
|
|
7
|
+
|
|
8
|
+
attr_reader :filter
|
|
9
|
+
|
|
10
|
+
def initialize(filter:)
|
|
11
|
+
@filter = filter
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import ApplicationController from 'mensa/controllers/application_controller'
|
|
2
2
|
|
|
3
|
-
export default class
|
|
3
|
+
export default class FilterPillComponentController extends ApplicationController {
|
|
4
4
|
static values = {
|
|
5
5
|
columnName: String,
|
|
6
6
|
operator: String,
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
.mensa-table__filters.hidden id="mensa-filter-pill-list-#{table.table_id}" data-controller="mensa-filter-pill-list" data-mensa-table-target="filterList" 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]"
|
|
2
|
+
.block
|
|
3
|
+
nav
|
|
4
|
+
.flex.space-x-2.overflow-none.whitespace-nowrap.scroll-p-0[aria-label="Tabs"]
|
|
5
|
+
/ existing filters first
|
|
6
|
+
= render Mensa::FilterPill::Component.with_collection(table.active_filters)
|
|
7
|
+
|
|
8
|
+
= render Mensa::AddFilter::Component.new(table: table)
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import ApplicationController from 'mensa/controllers/application_controller'
|
|
2
|
+
import { get } from '@rails/request.js'
|
|
3
|
+
|
|
4
|
+
export default class FilterPillListComponentController extends ApplicationController {
|
|
5
|
+
static outlets = [
|
|
6
|
+
"mensa-table",
|
|
7
|
+
"mensa-filter-pill",
|
|
8
|
+
"mensa-add-filter"
|
|
9
|
+
]
|
|
10
|
+
|
|
11
|
+
static targets = [
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
static values = {
|
|
15
|
+
supportsViews: Boolean
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
connect() {
|
|
19
|
+
super.connect()
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
refreshFilters() {
|
|
23
|
+
let url = this.mensaTableOutlet.ourUrl
|
|
24
|
+
|
|
25
|
+
let filters = url.searchParams.get('filters') || {}
|
|
26
|
+
this.mensaFilterPillOutlets.forEach((filterOutlet) => {
|
|
27
|
+
url.searchParams.append(`filters[${filterOutlet.columnNameValue}][value]`, filterOutlet.valueValue)
|
|
28
|
+
url.searchParams.append(`filters[${filterOutlet.columnNameValue}][operator]`, filterOutlet.operatorValue)
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
url.searchParams.append(`filters[${this.mensaAddFilterOutlet.selectedFilterColumn}][value]`, this.mensaAddFilterOutlet.valueTarget.value)
|
|
32
|
+
url.searchParams.append(`filters[${this.mensaAddFilterOutlet.selectedFilterColumn}][operator]`, 'equals')
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
get(url, {
|
|
36
|
+
responseKind: 'turbo-stream'
|
|
37
|
+
}).then(() => {
|
|
38
|
+
// FIXME: There should be a better way to do this, possibly using
|
|
39
|
+
// this.mensaTableOutlet.filterListTarget.addEventListener("turbo:after-stream-render", this.unhide.bind(this)) ?
|
|
40
|
+
setTimeout(() => {
|
|
41
|
+
this.mensaTableOutlet.filterListTarget.classList.remove('hidden')
|
|
42
|
+
}, 50)
|
|
43
|
+
})
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
get ourUrl() {
|
|
47
|
+
let url = this.mensaTableOutlet.ourUrl
|
|
48
|
+
return url
|
|
49
|
+
}
|
|
50
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
.mensa-table__search data-mensa-table-target="search" data-controller="mensa-search" data-mensa-search-target="search" class="#{table.supports_views? ? 'hidden' : ''}"
|
|
1
|
+
.mensa-table__search data-mensa-table-target="search" data-controller="mensa-search" data-mensa-search-target="search" class="#{table.supports_views? ? 'hidden' : ''}" data-mensa-search-mensa-table-outlet=".mensa-table#table-#{table.table_id}"
|
|
2
2
|
.flex
|
|
3
3
|
.flex-none.w-6.h-22.text-right.text-gray-500.dark:text-gray-400
|
|
4
4
|
i.cursor-pointer class=Mensa.config.icons[:search]
|
|
@@ -29,7 +29,7 @@ export default class SearchComponentController extends ApplicationController {
|
|
|
29
29
|
this.resetSearchButtonTarget.classList.add("hidden")
|
|
30
30
|
|
|
31
31
|
let turboFrame = this.element.closest("turbo-frame")
|
|
32
|
-
let url = this.ourUrl
|
|
32
|
+
let url = this.mensaTableOutlet.ourUrl
|
|
33
33
|
url.searchParams.delete("query")
|
|
34
34
|
|
|
35
35
|
get(url, {
|
|
@@ -45,7 +45,7 @@ export default class SearchComponentController extends ApplicationController {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
// FIXME: This doesn't prevent searching twice on enter, the turbo-frame URL doesn't change
|
|
48
|
-
let url = this.ourUrl
|
|
48
|
+
let url = this.mensaTableOutlet.ourUrl
|
|
49
49
|
if (url.searchParams.get("query") === this.query) {
|
|
50
50
|
return
|
|
51
51
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
.mensa-table id="table-#{table.table_id}" data-mensa-table-view-condensed-value="#{table.view_condensed?}" data-mensa-table-supports-views-value="#{table.supports_views?}" data-controller="mensa-table" data-mensa-table-mensa-filter-outlet="[data-controller='mensa-filter']"
|
|
1
|
+
.mensa-table id="table-#{table.table_id}" data-mensa-table-view-condensed-value="#{table.view_condensed?}" data-mensa-table-supports-views-value="#{table.supports_views?}" data-controller="mensa-table" data-mensa-table-mensa-filter-pill-outlet="[data-controller='mensa-filter-pill']"
|
|
2
2
|
= render Mensa::Search::Component.new(table: table)
|
|
3
3
|
div id="filters-#{table.table_id}"
|
|
4
|
-
= render Mensa::
|
|
4
|
+
= render Mensa::FilterPillList::Component.new(table: table)
|
|
5
5
|
- if table.supports_views? && table.show_header?
|
|
6
6
|
= render Mensa::Views::Component.new(table: table)
|
|
7
|
-
turbo-frame id=table.table_id src=helpers.mensa.
|
|
7
|
+
turbo-frame id=table.table_id src=helpers.mensa.table_url(table.name, {turbo_frame_id: table.table_id}.merge(params)) target="_top" loading="lazy" data-mensa-table-target="turboFrame" data-turbo-permanent=""
|
|
@@ -2,8 +2,6 @@ import ApplicationController from "mensa/controllers/application_controller";
|
|
|
2
2
|
import { get } from "@rails/request.js";
|
|
3
3
|
|
|
4
4
|
export default class TableComponentController extends ApplicationController {
|
|
5
|
-
static outlets = ["mensa-filter"]
|
|
6
|
-
|
|
7
5
|
static targets = [
|
|
8
6
|
"controlBar", // Bar with buttons
|
|
9
7
|
"condenseExpandIcon", // Icon
|
|
@@ -20,6 +18,9 @@ export default class TableComponentController extends ApplicationController {
|
|
|
20
18
|
|
|
21
19
|
connect() {
|
|
22
20
|
super.connect();
|
|
21
|
+
|
|
22
|
+
// FIXME: Workaround for https://github.com/hotwired/turbo/issues/886
|
|
23
|
+
this.turboFrameTarget.removeAttribute('loading');
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
openFiltersAndSearch(event) {
|
|
@@ -77,4 +78,15 @@ export default class TableComponentController extends ApplicationController {
|
|
|
77
78
|
url.pathname += ".xlsx";
|
|
78
79
|
get(url, {}).then(() => { });
|
|
79
80
|
}
|
|
81
|
+
|
|
82
|
+
get ourUrl() {
|
|
83
|
+
let url
|
|
84
|
+
|
|
85
|
+
if (this.turboFrameTarget?.getAttribute('src')) {
|
|
86
|
+
url = new URL(this.turboFrameTarget.getAttribute('src'))
|
|
87
|
+
} else {
|
|
88
|
+
url = new URL(window.location.href)
|
|
89
|
+
}
|
|
90
|
+
return url
|
|
91
|
+
}
|
|
80
92
|
}
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
nav.flex.justify-between[aria-label="Tabs"]
|
|
10
10
|
.flex.space-x-2.overflow-x-auto.whitespace-nowrap.scroll-p-0
|
|
11
11
|
- table.all_views.each.with_index do |view, index|
|
|
12
|
-
= link_to(table.path(table_view_id: view.id, turbo_frame_id: table.table_id), "data-turbo-frame": table.table_id, class: "view #{(view.id == table.table_view&.id || view.id == :
|
|
12
|
+
= link_to(table.path(table_view_id: view.id, turbo_frame_id: table.table_id), "data-turbo-frame": table.table_id, class: "view #{(view.id == table.table_view&.id || view.id == :default && table.table_view.blank?) ? 'selected' : ''}", data: {"mensa-views-target": "view", action: "mensa-views#select", "tippy-content": view.description}) do
|
|
13
13
|
= view.name
|
|
14
14
|
|
|
15
15
|
- if table.supports_custom_views?
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
module Mensa
|
|
2
|
-
class TablesController <
|
|
3
|
-
layout :decide_layout
|
|
4
|
-
|
|
2
|
+
class TablesController < ApplicationController
|
|
5
3
|
def show
|
|
6
4
|
@table = Mensa.for_name(params[:id])
|
|
7
5
|
|
|
@@ -21,17 +19,13 @@ module Mensa
|
|
|
21
19
|
@table.original_view_context = helpers
|
|
22
20
|
|
|
23
21
|
respond_to do |format|
|
|
24
|
-
format.turbo_stream
|
|
22
|
+
format.turbo_stream # Used for filterering
|
|
25
23
|
format.html
|
|
26
24
|
format.xlsx do
|
|
27
25
|
Mensa::ExportJob.perform_later(current_user, params[:id])
|
|
28
|
-
head
|
|
26
|
+
head :ok
|
|
29
27
|
end
|
|
30
28
|
end
|
|
31
29
|
end
|
|
32
|
-
|
|
33
|
-
def decide_layout
|
|
34
|
-
false if params[:turbo_frame_id]
|
|
35
|
-
end
|
|
36
30
|
end
|
|
37
31
|
end
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
import { Controller } from '@hotwired/stimulus'
|
|
3
3
|
|
|
4
4
|
export default class ApplicationController extends Controller {
|
|
5
|
-
connect
|
|
5
|
+
connect() {
|
|
6
6
|
this.element[this.identifier] = this
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
getController
|
|
9
|
+
getController(element, identifier) {
|
|
10
10
|
return this.application.getControllerForElementAndIdentifier(element, identifier)
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
triggerEvent
|
|
13
|
+
triggerEvent(el, name, data) {
|
|
14
14
|
let event
|
|
15
15
|
if (typeof window.CustomEvent === 'function') {
|
|
16
16
|
event = new CustomEvent(name, { detail: data, cancelable: true, bubbles: true })
|
|
@@ -21,14 +21,14 @@ export default class ApplicationController extends Controller {
|
|
|
21
21
|
el.dispatchEvent(event)
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
elementScrolled
|
|
24
|
+
elementScrolled(element) {
|
|
25
25
|
if (element.scrollHeight - Math.round(element.scrollTop) === element.clientHeight) {
|
|
26
26
|
return true
|
|
27
27
|
}
|
|
28
28
|
return false
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
debouncedHover
|
|
31
|
+
debouncedHover(element, timeout, handler) {
|
|
32
32
|
var timeoutId = null
|
|
33
33
|
element.addEventListener(marker, 'mouseover', function () {
|
|
34
34
|
timeoutId = setTimeout(handler, timeout)
|
|
@@ -38,20 +38,4 @@ export default class ApplicationController extends Controller {
|
|
|
38
38
|
clearTimeout(timeoutId)
|
|
39
39
|
})
|
|
40
40
|
}
|
|
41
|
-
|
|
42
|
-
get ourUrl () {
|
|
43
|
-
// This requires the mensaTableOutlet
|
|
44
|
-
let turboFrame = this.mensaTableOutlet?.turboFrameTarget
|
|
45
|
-
if(!turboFrame) {
|
|
46
|
-
turboFrame = this.turboFrameTarget
|
|
47
|
-
}
|
|
48
|
-
let url
|
|
49
|
-
|
|
50
|
-
if (turboFrame && turboFrame.getAttribute('src')) {
|
|
51
|
-
url = new URL(turboFrame.getAttribute('src'))
|
|
52
|
-
} else {
|
|
53
|
-
url = new URL(window.location.href)
|
|
54
|
-
}
|
|
55
|
-
return url
|
|
56
|
-
}
|
|
57
41
|
}
|
|
@@ -6,11 +6,11 @@ import { application } from "mensa/controllers/application"
|
|
|
6
6
|
import AddFilterComponentController from "mensa/components/add_filter/component_controller";
|
|
7
7
|
application.register("mensa-add-filter", AddFilterComponentController);
|
|
8
8
|
|
|
9
|
-
import
|
|
10
|
-
application.register("mensa-filter",
|
|
9
|
+
import FilterPillComponentController from "mensa/components/filter_pill/component_controller";
|
|
10
|
+
application.register("mensa-filter-pill", FilterPillComponentController);
|
|
11
11
|
|
|
12
|
-
import
|
|
13
|
-
application.register("mensa-filter-list",
|
|
12
|
+
import FilterPillListComponentController from "mensa/components/filter_pill_list/component_controller";
|
|
13
|
+
application.register("mensa-filter-pill-list", FilterPillListComponentController);
|
|
14
14
|
|
|
15
15
|
import SearchComponentController from "mensa/components/search/component_controller";
|
|
16
16
|
application.register("mensa-search", SearchComponentController);
|
|
@@ -16,28 +16,27 @@ module Mensa
|
|
|
16
16
|
context = Mensa.config.callbacks[:export_started].call(user, table_name)
|
|
17
17
|
|
|
18
18
|
styles = []
|
|
19
|
-
default_style = {
|
|
20
|
-
|
|
19
|
+
default_style = {b: true, bg_color: "3B82F6", fg_color: "FFFFFF", border: {style: :thin, color: "000000"}, sz: 8,
|
|
20
|
+
alignment: {vertical: :bottom, horizontal: :left}}
|
|
21
21
|
|
|
22
22
|
p = Axlsx::Package.new
|
|
23
23
|
p.use_shared_strings = true
|
|
24
24
|
|
|
25
25
|
wb = p.workbook
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
nowrap_text = wb.styles.add_style({
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
27
|
+
wb.styles.add_style({format_code: "@", alignment: {horizontal: :left, vertical: :top, wrap_text: true}})
|
|
28
|
+
nowrap_text = wb.styles.add_style({format_code: "@", alignment: {horizontal: :left, vertical: :top, wrap_text: false}})
|
|
29
|
+
wb.styles.add_style format_code: "#"
|
|
30
|
+
wb.styles.add_style format_code: "dddd, d mmmm yyyy hh:mm:ss"
|
|
31
|
+
wb.styles.add_style format_code: "dddd, d mmmm yyyy"
|
|
32
32
|
|
|
33
33
|
# custom_styles = ActionTable.config.format_config.each_with_object({}) { |(key, value), hash| hash[key] = value[:xlsx_style] if value.key?(:xlsx_style) }
|
|
34
|
-
custom_style = {}
|
|
35
34
|
|
|
36
35
|
wb.add_worksheet(name: table_name.first(31)) do |sheet|
|
|
37
36
|
column_widths = []
|
|
38
37
|
# TODO: Separate display columns for export?
|
|
39
38
|
table.display_columns.map.with_index do |column, index|
|
|
40
|
-
styles[index] = sheet.styles.add_style(default_style)
|
|
39
|
+
styles[index] = sheet.styles.add_style(default_style) # .merge(column.export_style || {}))
|
|
41
40
|
# width = column.export_style.delete(:width)
|
|
42
41
|
# column_widths[index] = width if width
|
|
43
42
|
end
|
|
@@ -99,8 +98,8 @@ module Mensa
|
|
|
99
98
|
end
|
|
100
99
|
stringio.rewind
|
|
101
100
|
|
|
102
|
-
attachment = {
|
|
103
|
-
|
|
101
|
+
attachment = {io: stringio,
|
|
102
|
+
content_type: "application/zip", filename: "#{base_filename}.zip"}
|
|
104
103
|
if password.present?
|
|
105
104
|
attachment[:password] = password
|
|
106
105
|
end
|
data/app/tables/mensa/action.rb
CHANGED