mensa 0.1.9 → 0.1.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +23 -14
- data/app/components/mensa/control_bar/component.html.slim +2 -1
- data/app/components/mensa/search/component_controller.js +27 -25
- data/app/components/mensa/table/component_controller.js +52 -46
- data/app/components/mensa/view/component.html.slim +1 -1
- data/app/components/mensa/view/paging.css +4 -4
- data/app/tables/mensa/base.rb +1 -0
- data/app/tables/mensa/cell.rb +2 -2
- data/app/tables/mensa/config/table_dsl.rb +2 -0
- data/lib/mensa/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3a2b7ad58071b68c158f645d3df7547d90f57c27d97bdf3ed079f8f98b4f3c06
|
4
|
+
data.tar.gz: dab761020168bf26e4e2f057652564aaad35831480152e00ab5c4c7ebd629ed7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aeb2f7ca363b1e966284137490a78b1af5cfc7c8afe6ecd9c2dec3a4c16f1fef118f91f9ef4d5bbcd7cb321561f092fea456333de23926a3ebfc1d6973566912
|
7
|
+
data.tar.gz: edcdb113d4447154c999bf75ca0c40ed9842cd811705831ec69423b3fe9ee461bb9649c7dcf6536454cb49ddbd572bec58438fa21a5c8841fc30014f70274021
|
data/README.md
CHANGED
@@ -1,21 +1,24 @@
|
|
1
1
|
# Mensa
|
2
|
+
|
2
3
|
Fast and awesome tables, with pagination, sorting, filtering and custom views.
|
3
4
|
|
4
5
|
Wanted features:
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
6
|
+
|
7
|
+
- [x] very fast
|
8
|
+
- [x] row-links
|
9
|
+
- [x] sorting
|
10
|
+
- [x] tables without headers (and without most of the above)
|
11
|
+
- [ ] column sorting
|
12
|
+
- [ ] filtering (of multiple columns, single is done)
|
13
|
+
- [ ] view selection and exports per view
|
14
|
+
- [ ] group by
|
15
|
+
- [ ] sum/max/min
|
16
|
+
- [ ] tables backed by arrays (of ActiveModel)
|
15
17
|
|
16
18
|
Todo:
|
17
|
-
|
18
|
-
|
19
|
+
|
20
|
+
- [ ] Hide filter icon in case there are no filters
|
21
|
+
- [ ] Search only works on table columns
|
19
22
|
|
20
23
|
## Usage
|
21
24
|
|
@@ -28,7 +31,7 @@ class UserTable < ApplicationTable
|
|
28
31
|
model User # implicit from name
|
29
32
|
|
30
33
|
order name: :desc
|
31
|
-
|
34
|
+
|
32
35
|
column(:name) do
|
33
36
|
attribute :name # Optional, we can deduct this from the column name
|
34
37
|
sortable true
|
@@ -49,7 +52,7 @@ class UserTable < ApplicationTable
|
|
49
52
|
# You can add one or more actions to a row
|
50
53
|
action :delete do
|
51
54
|
link { |user| user_path(user) }
|
52
|
-
icon "fa fa-trash"
|
55
|
+
icon "fa-regular fa-trash"
|
53
56
|
link_attributes data: {"turbo-confirm": "Are you sure you want to delete the user?", "turbo-method": :delete}
|
54
57
|
show ->(user) { true }
|
55
58
|
end
|
@@ -86,6 +89,7 @@ end
|
|
86
89
|
```
|
87
90
|
|
88
91
|
## Installation
|
92
|
+
|
89
93
|
Add this line to your application's Gemfile:
|
90
94
|
|
91
95
|
```ruby
|
@@ -93,21 +97,25 @@ gem "mensa"
|
|
93
97
|
```
|
94
98
|
|
95
99
|
And then execute:
|
100
|
+
|
96
101
|
```bash
|
97
102
|
$ bundle
|
98
103
|
```
|
99
104
|
|
100
105
|
Or install it yourself as:
|
106
|
+
|
101
107
|
```bash
|
102
108
|
$ gem install mensa
|
103
109
|
```
|
104
110
|
|
105
111
|
Always use `bundle` to install the gem. Next use the install generator to install migrations, add an initializer and do other setup:
|
112
|
+
|
106
113
|
```bash
|
107
114
|
$ bin/rails g mensa:install
|
108
115
|
```
|
109
116
|
|
110
117
|
## Contributing
|
118
|
+
|
111
119
|
```
|
112
120
|
Contribution directions go here.
|
113
121
|
|
@@ -115,3 +123,4 @@ Contribution directions go here.
|
|
115
123
|
|
116
124
|
## License
|
117
125
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
126
|
+
```
|
@@ -3,7 +3,8 @@
|
|
3
3
|
button.flex.justify-right.cursor-pointer.py-1.5.h-full.text-gray-400 class="#{table.supports_views? ? 'w-8' : 'w-4'}" data-action="mensa-table#openFiltersAndSearch"
|
4
4
|
- if table.supports_views?
|
5
5
|
i class=Mensa.config.icons[:control_bar_search]
|
6
|
-
|
6
|
+
- if table.supports_filters?
|
7
|
+
i class=Mensa.config.icons[:control_bar_filter]
|
7
8
|
/- if view_columns_sorting?
|
8
9
|
button.cursor-pointer.w-6.h-full.text-gray-400
|
9
10
|
i class=Mensa.config.icons[:control_bar_edit]
|
@@ -1,62 +1,64 @@
|
|
1
|
-
import ApplicationController from
|
1
|
+
import ApplicationController from "mensa/controllers/application_controller"
|
2
2
|
|
3
|
-
import { get } from
|
3
|
+
import { get } from "@rails/request.js"
|
4
4
|
|
5
5
|
export default class SearchComponentController extends ApplicationController {
|
6
|
-
static targets = [
|
7
|
-
|
8
|
-
|
9
|
-
]
|
10
|
-
static outlets = [
|
11
|
-
"mensa-table"
|
12
|
-
]
|
13
|
-
connect () {
|
6
|
+
static targets = ["resetSearchButton", "searchInput"]
|
7
|
+
static outlets = ["mensa-table"]
|
8
|
+
connect() {
|
14
9
|
super.connect()
|
15
10
|
this.monitorSearch()
|
16
11
|
}
|
17
12
|
|
18
|
-
monitorSearch
|
13
|
+
monitorSearch(event) {
|
14
|
+
event && event.preventDefault()
|
15
|
+
|
19
16
|
if (this.searchInputTarget.value.length >= 1) {
|
20
|
-
this.resetSearchButtonTarget.classList.remove(
|
21
|
-
this.searchInputTarget.focus()
|
17
|
+
this.resetSearchButtonTarget.classList.remove("hidden")
|
18
|
+
this.searchInputTarget.focus()
|
22
19
|
} else {
|
23
|
-
this.resetSearchButtonTarget.classList.add(
|
20
|
+
this.resetSearchButtonTarget.classList.add("hidden")
|
24
21
|
}
|
25
22
|
}
|
26
23
|
|
27
|
-
resetSearch
|
28
|
-
|
24
|
+
resetSearch(event) {
|
25
|
+
event.preventDefault()
|
26
|
+
|
27
|
+
this.searchInputTarget.value = ""
|
29
28
|
this.searchInputTarget.focus()
|
30
|
-
this.resetSearchButtonTarget.classList.add(
|
29
|
+
this.resetSearchButtonTarget.classList.add("hidden")
|
31
30
|
|
32
|
-
let turboFrame = this.element.closest(
|
31
|
+
let turboFrame = this.element.closest("turbo-frame")
|
33
32
|
let url = this.ourUrl
|
34
|
-
url.searchParams.delete(
|
33
|
+
url.searchParams.delete("query")
|
35
34
|
|
36
35
|
get(url, {
|
37
|
-
responseKind:
|
36
|
+
responseKind: "turbo-stream",
|
38
37
|
})
|
39
38
|
}
|
40
39
|
|
41
|
-
search
|
40
|
+
search(event) {
|
41
|
+
event.preventDefault()
|
42
|
+
|
42
43
|
if (this.query.length < 3) {
|
43
44
|
return
|
44
45
|
}
|
45
46
|
|
46
47
|
// FIXME: This doesn't prevent searching twice on enter, the turbo-frame URL doesn't change
|
47
48
|
let url = this.ourUrl
|
48
|
-
if(url.searchParams.get(
|
49
|
+
if (url.searchParams.get("query") === this.query) {
|
49
50
|
return
|
50
51
|
}
|
51
52
|
|
52
|
-
url.searchParams.
|
53
|
+
url.searchParams.set("page", 1)
|
54
|
+
url.searchParams.set("query", this.query)
|
53
55
|
|
54
56
|
get(url, {
|
55
|
-
responseKind:
|
57
|
+
responseKind: "turbo-stream",
|
56
58
|
})
|
57
59
|
}
|
58
60
|
|
59
61
|
get query() {
|
60
62
|
return this.searchInputTarget.value
|
61
63
|
}
|
62
|
-
}
|
64
|
+
}
|
@@ -1,72 +1,78 @@
|
|
1
|
-
import ApplicationController from
|
2
|
-
import { get } from
|
1
|
+
import ApplicationController from "mensa/controllers/application_controller";
|
2
|
+
import { get } from "@rails/request.js";
|
3
3
|
|
4
4
|
export default class TableComponentController extends ApplicationController {
|
5
5
|
static targets = [
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
]
|
6
|
+
"controlBar", // Bar with buttons
|
7
|
+
"condenseExpandIcon", // Icon
|
8
|
+
"filters", // Tabs or list of filters
|
9
|
+
"views", // Tabs or list of views
|
10
|
+
"viewButtons", // Cancel and save buttons for views
|
11
|
+
"search", // Search bar
|
12
|
+
"view", // View contains table element
|
13
|
+
"turboFrame", // The turbo-frame
|
14
|
+
];
|
15
15
|
static values = {
|
16
|
-
supportsViews: Boolean
|
17
|
-
}
|
16
|
+
supportsViews: Boolean,
|
17
|
+
};
|
18
18
|
|
19
|
-
connect
|
20
|
-
super.connect()
|
19
|
+
connect() {
|
20
|
+
super.connect();
|
21
21
|
}
|
22
22
|
|
23
23
|
openFiltersAndSearch(event) {
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
this.
|
28
|
-
this.
|
24
|
+
event.preventDefault();
|
25
|
+
|
26
|
+
if (this.supportsViewsValue) {
|
27
|
+
this.viewButtonsTarget.classList.remove("hidden");
|
28
|
+
this.searchTarget.classList.remove("hidden");
|
29
|
+
this.viewsTarget.classList.add("hidden");
|
30
|
+
this.filtersTarget.classList.remove("hidden");
|
29
31
|
} else {
|
30
|
-
this.controlBarTarget.classList.add(
|
31
|
-
this.viewButtonsTarget.classList.remove(
|
32
|
-
this.filtersTarget.classList.remove(
|
32
|
+
this.controlBarTarget.classList.add("hidden");
|
33
|
+
this.viewButtonsTarget.classList.remove("hidden");
|
34
|
+
this.filtersTarget.classList.remove("hidden");
|
33
35
|
}
|
34
36
|
}
|
35
37
|
|
36
38
|
cancelFiltersAndSearch(event) {
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
this.
|
41
|
-
this.
|
39
|
+
event.preventDefault();
|
40
|
+
|
41
|
+
if (this.supportsViewsValue) {
|
42
|
+
this.searchTarget.classList.add("hidden");
|
43
|
+
this.viewButtonsTarget.classList.add("hidden");
|
44
|
+
this.filtersTarget.classList.add("hidden");
|
45
|
+
this.viewsTarget.classList.remove("hidden");
|
42
46
|
} else {
|
43
|
-
this.controlBarTarget.classList.remove(
|
44
|
-
this.viewButtonsTarget.classList.add(
|
45
|
-
this.filtersTarget.classList.add(
|
47
|
+
this.controlBarTarget.classList.remove("hidden");
|
48
|
+
this.viewButtonsTarget.classList.add("hidden");
|
49
|
+
this.filtersTarget.classList.add("hidden");
|
46
50
|
}
|
47
51
|
}
|
48
52
|
|
49
53
|
saveFiltersAndSearch(event) {
|
50
|
-
|
54
|
+
event.preventDefault();
|
51
55
|
}
|
52
56
|
|
53
|
-
condenseExpand
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
this.
|
57
|
+
condenseExpand(event) {
|
58
|
+
event.preventDefault();
|
59
|
+
|
60
|
+
if (this.viewTarget.classList.contains("mensa-table__condensed")) {
|
61
|
+
this.viewTarget.classList.remove("mensa-table__condensed");
|
62
|
+
this.condenseExpandIconTarget.classList.add("fa-compress");
|
63
|
+
this.condenseExpandIconTarget.classList.remove("fa-expand");
|
58
64
|
} else {
|
59
|
-
this.viewTarget.classList.add(
|
60
|
-
this.condenseExpandIconTarget.classList.remove(
|
61
|
-
this.condenseExpandIconTarget.classList.add(
|
65
|
+
this.viewTarget.classList.add("mensa-table__condensed");
|
66
|
+
this.condenseExpandIconTarget.classList.remove("fa-compress");
|
67
|
+
this.condenseExpandIconTarget.classList.add("fa-expand");
|
62
68
|
}
|
63
69
|
}
|
64
70
|
|
65
71
|
export(event) {
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
})
|
72
|
+
event.preventDefault();
|
73
|
+
|
74
|
+
let url = this.ourUrl;
|
75
|
+
url.pathname += ".xlsx";
|
76
|
+
get(url, {}).then(() => {});
|
71
77
|
}
|
72
|
-
}
|
78
|
+
}
|
@@ -3,10 +3,10 @@
|
|
3
3
|
@apply flex items-center justify-between border-t border-gray-100 dark:border-gray-600 bg-white dark:bg-gray-800 px-4 py-3 sm:px-6;
|
4
4
|
|
5
5
|
.pagy {
|
6
|
-
@apply isolate inline-flex -space-x-px
|
6
|
+
@apply isolate inline-flex -space-x-px text-gray-500 dark:text-gray-400;
|
7
7
|
|
8
8
|
a:not(.gap) {
|
9
|
-
@apply relative inline-flex items-center px-4 py-1.5 text-
|
9
|
+
@apply relative inline-flex items-center px-4 py-1.5 text-gray-500 dark:text-gray-400 bg-gray-100 dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-700 focus:z-20 no-underline;
|
10
10
|
|
11
11
|
&:first-child {
|
12
12
|
border-top-left-radius: 4px;
|
@@ -24,11 +24,11 @@
|
|
24
24
|
|
25
25
|
&:not([href]) {
|
26
26
|
/* disabled links */
|
27
|
-
@apply
|
27
|
+
@apply bg-gray-100 dark:bg-gray-600 hover:bg-gray-100 hover:dark:bg-gray-600 text-gray-700 dark:text-gray-100 text-opacity-25 dark:text-opacity-50 cursor-default;
|
28
28
|
}
|
29
29
|
|
30
30
|
&.current {
|
31
|
-
@apply z-10 bg-
|
31
|
+
@apply z-10 bg-primary-200 dark:bg-primary-800 hover:bg-primary-200 hover:dark:bg-primary-400 text-opacity-75 dark:text-opacity-75 border-none;
|
32
32
|
}
|
33
33
|
}
|
34
34
|
|
data/app/tables/mensa/base.rb
CHANGED
data/app/tables/mensa/cell.rb
CHANGED
@@ -35,9 +35,9 @@ module Mensa
|
|
35
35
|
when NilClass
|
36
36
|
''
|
37
37
|
when TrueClass
|
38
|
-
content_tag(:i, '', class: 'fa fa-check')
|
38
|
+
content_tag(:i, '', class: 'fa-regular fa-check')
|
39
39
|
when FalseClass
|
40
|
-
content_tag(:i, '', class: 'fa fa-xmark')
|
40
|
+
content_tag(:i, '', class: 'fa-regular fa-xmark')
|
41
41
|
when Date
|
42
42
|
respond_to?(:dt) ? dt(value) : value.strftime('%d.%m.%Y')
|
43
43
|
when Time, DateTime
|
@@ -31,6 +31,7 @@
|
|
31
31
|
# link { |user| edit_user_path(user) }
|
32
32
|
#
|
33
33
|
# supports_views true
|
34
|
+
# supports_filters true
|
34
35
|
#
|
35
36
|
# action :activate do
|
36
37
|
# link { |user| edit_user_path(user) }
|
@@ -63,6 +64,7 @@ module Mensa::Config
|
|
63
64
|
dsl_option :render, Mensa::Config::RenderDsl
|
64
65
|
|
65
66
|
option :supports_views, default: false
|
67
|
+
option :supports_filters, default: true
|
66
68
|
option :show_header, default: true
|
67
69
|
option :view_columns_sorting, default: true
|
68
70
|
option :view_condensed, default: false
|
data/lib/mensa/version.rb
CHANGED
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.1.
|
4
|
+
version: 0.1.10
|
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: 2024-
|
11
|
+
date: 2024-10-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: caxlsx_rails
|