infotable 0.1.0
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 +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +1043 -0
- data/Rakefile +6 -0
- data/app/assets/javascripts/infotable/controllers/drawer_controller.js +1412 -0
- data/app/assets/javascripts/infotable/controllers/table_controller.js +921 -0
- data/app/assets/javascripts/infotable/index.js +14 -0
- data/app/controllers/infotable/application_controller.rb +4 -0
- data/app/controllers/infotable/tables_controller.rb +299 -0
- data/app/helpers/infotable/application_helper.rb +5 -0
- data/app/helpers/infotable/tables_helper.rb +354 -0
- data/app/jobs/infotable/application_job.rb +4 -0
- data/app/mailers/infotable/application_mailer.rb +6 -0
- data/app/models/infotable/application_record.rb +5 -0
- data/app/views/infotable/tables/_column_visibility.html.erb +100 -0
- data/app/views/infotable/tables/_filter_drawer.html.erb +65 -0
- data/app/views/infotable/tables/_next_page_frame.html.erb +39 -0
- data/app/views/infotable/tables/_pagination.html.erb +101 -0
- data/app/views/infotable/tables/_side_panel.html.erb +63 -0
- data/app/views/infotable/tables/_table.html.erb +135 -0
- data/app/views/infotable/tables/_table_rows.html.erb +38 -0
- data/app/views/infotable/tables/filters/_boolean.html.erb +22 -0
- data/app/views/infotable/tables/filters/_date.html.erb +30 -0
- data/app/views/infotable/tables/filters/_number.html.erb +32 -0
- data/app/views/infotable/tables/filters/_select.html.erb +68 -0
- data/app/views/infotable/tables/filters/_text.html.erb +38 -0
- data/app/views/infotable/tables/show.html.erb +113 -0
- data/app/views/layouts/infotable/application.html.erb +15 -0
- data/config/importmap.rb +6 -0
- data/config/locales/en.yml +88 -0
- data/config/locales/pl.yml +88 -0
- data/config/routes.rb +6 -0
- data/lib/generators/infotable/install/install_generator.rb +565 -0
- data/lib/generators/infotable/install/templates/TAILWIND_CONFIG.md +131 -0
- data/lib/generators/infotable/install/templates/initializer.rb +26 -0
- data/lib/generators/infotable/install/templates/tailwind.config.js +284 -0
- data/lib/generators/infotable/table/table_generator.rb +95 -0
- data/lib/generators/infotable/table/templates/table.rb.tt +26 -0
- data/lib/infotable/base.rb +463 -0
- data/lib/infotable/batch_actions.rb +34 -0
- data/lib/infotable/configuration.rb +53 -0
- data/lib/infotable/engine.rb +51 -0
- data/lib/infotable/filter_processor.rb +326 -0
- data/lib/infotable/formatters/action_formatter.rb +141 -0
- data/lib/infotable/formatters/avatar_formatter.rb +49 -0
- data/lib/infotable/formatters/badge_formatter.rb +80 -0
- data/lib/infotable/formatters/base_formatter.rb +47 -0
- data/lib/infotable/formatters/boolean_formatter.rb +38 -0
- data/lib/infotable/formatters/currency_formatter.rb +22 -0
- data/lib/infotable/formatters/date_formatter.rb +58 -0
- data/lib/infotable/formatters/link_formatter.rb +48 -0
- data/lib/infotable/formatters/percent_formatter.rb +27 -0
- data/lib/infotable/search_processor.rb +42 -0
- data/lib/infotable/table_resolver.rb +45 -0
- data/lib/infotable/version.rb +3 -0
- data/lib/infotable.rb +54 -0
- data/lib/tasks/infotable.rake +55 -0
- metadata +216 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# InfoTable Configuration
|
|
2
|
+
# For more configuration options, see: https://github.com/jcieslar/infotable
|
|
3
|
+
|
|
4
|
+
Infotable.configure do |config|
|
|
5
|
+
# Default number of items per page
|
|
6
|
+
config.default_per_page = 25
|
|
7
|
+
|
|
8
|
+
# Available per-page options
|
|
9
|
+
config.per_page_options = [ 10, 25, 50, 100 ]
|
|
10
|
+
|
|
11
|
+
# Filter drawer position (:left or :right)
|
|
12
|
+
config.drawer_position = :right
|
|
13
|
+
|
|
14
|
+
# Drawer width
|
|
15
|
+
config.drawer_width = "26rem" # px, rem, em, vw or %
|
|
16
|
+
|
|
17
|
+
# Controller the engine controllers inherit from. Use your app's controller so
|
|
18
|
+
# authentication, locale, tenant scoping etc. also protect the tables:
|
|
19
|
+
# config.parent_controller = "ApplicationController"
|
|
20
|
+
|
|
21
|
+
# Mirror search, filters, sort and page in the address bar (shareable links, Back button)
|
|
22
|
+
# config.url_state = true
|
|
23
|
+
|
|
24
|
+
# Filter behavior: true = auto-apply filters (debounced, no Apply button), false = manual apply button
|
|
25
|
+
config.autofilter = true
|
|
26
|
+
end
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
const { execSync } = require('child_process');
|
|
2
|
+
const path = require('path');
|
|
3
|
+
|
|
4
|
+
// Helper to resolve gem path dynamically (works with path:, git:, and rubygems)
|
|
5
|
+
function resolveGemPath(gemName) {
|
|
6
|
+
try {
|
|
7
|
+
const bundlerCmd = `bundle show ${gemName}`;
|
|
8
|
+
const gemPath = execSync(bundlerCmd, { encoding: 'utf-8' }).trim();
|
|
9
|
+
return gemPath;
|
|
10
|
+
} catch (error) {
|
|
11
|
+
console.warn(`Warning: Could not resolve ${gemName} gem path:`, error.message);
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const infotableGemPath = resolveGemPath('infotable');
|
|
17
|
+
|
|
18
|
+
// Build content paths
|
|
19
|
+
const contentPaths = [
|
|
20
|
+
'./app/javascript/**/*.js',
|
|
21
|
+
'./app/**/*.html.erb',
|
|
22
|
+
'./app/helpers/**/*.rb',
|
|
23
|
+
'./app/infotable/**/*.rb'
|
|
24
|
+
];
|
|
25
|
+
|
|
26
|
+
// Add infotable gem views if gem path is resolved
|
|
27
|
+
if (infotableGemPath) {
|
|
28
|
+
contentPaths.push(path.join(infotableGemPath, 'app/views/infotable/**/*.{erb,rb}'));
|
|
29
|
+
contentPaths.push(path.join(infotableGemPath, 'app/assets/javascripts/infotable/**/*.js'));
|
|
30
|
+
contentPaths.push(path.join(infotableGemPath, 'lib/infotable/formatters/**/*.rb'));
|
|
31
|
+
contentPaths.push(path.join(infotableGemPath, 'app/components/**/*.rb'));
|
|
32
|
+
contentPaths.push(path.join(infotableGemPath, 'app/components/**/*.html.erb'));
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
module.exports = {
|
|
36
|
+
content: contentPaths,
|
|
37
|
+
theme: {
|
|
38
|
+
extend: {
|
|
39
|
+
fontFamily: {
|
|
40
|
+
sans: [
|
|
41
|
+
'Nunito',
|
|
42
|
+
'ui-sans-serif',
|
|
43
|
+
'system-ui',
|
|
44
|
+
'-apple-system',
|
|
45
|
+
'BlinkMacSystemFont',
|
|
46
|
+
'Segoe UI',
|
|
47
|
+
'Roboto',
|
|
48
|
+
'Helvetica Neue',
|
|
49
|
+
'Arial',
|
|
50
|
+
'Noto Sans',
|
|
51
|
+
'sans-serif',
|
|
52
|
+
'Apple Color Emoji',
|
|
53
|
+
'Segoe UI Emoji',
|
|
54
|
+
'Segoe UI Symbol',
|
|
55
|
+
'Noto Color Emoji',
|
|
56
|
+
],
|
|
57
|
+
},
|
|
58
|
+
colors: {
|
|
59
|
+
transparent: 'transparent',
|
|
60
|
+
current: 'currentColor',
|
|
61
|
+
|
|
62
|
+
black: '#000',
|
|
63
|
+
white: '#fff',
|
|
64
|
+
|
|
65
|
+
purple: {
|
|
66
|
+
50: '#DBCDDD',
|
|
67
|
+
100: '#C3AABE',
|
|
68
|
+
200: '#A787A1',
|
|
69
|
+
300: '#9D6795',
|
|
70
|
+
400: '#895482',
|
|
71
|
+
500: '#7F4677',
|
|
72
|
+
600: '#742669',
|
|
73
|
+
700: '#691B5E',
|
|
74
|
+
800: '#58114E',
|
|
75
|
+
900: '#47023D',
|
|
76
|
+
},
|
|
77
|
+
primary: {
|
|
78
|
+
50: '#F7F5FA',
|
|
79
|
+
100: '#F0EAF6',
|
|
80
|
+
200: '#D7C6E3',
|
|
81
|
+
300: '#A887B5',
|
|
82
|
+
400: '#835696',
|
|
83
|
+
500: '#733982',
|
|
84
|
+
600: '#701A75',
|
|
85
|
+
700: '#5F1568',
|
|
86
|
+
800: '#510761',
|
|
87
|
+
900: '#4A044E',
|
|
88
|
+
},
|
|
89
|
+
|
|
90
|
+
blue: {
|
|
91
|
+
50: '#E9F3F9',
|
|
92
|
+
100: '#D8E9F2',
|
|
93
|
+
200: '#C0DAE8',
|
|
94
|
+
300: '#9ECDE6',
|
|
95
|
+
400: '#63ADD4',
|
|
96
|
+
500: '#2B8ABD',
|
|
97
|
+
600: '#006DA7',
|
|
98
|
+
700: '#075985',
|
|
99
|
+
800: '#004164',
|
|
100
|
+
900: '#002E47',
|
|
101
|
+
},
|
|
102
|
+
silver: {
|
|
103
|
+
50: '#F6F8FA',
|
|
104
|
+
100: '#F0F2F4',
|
|
105
|
+
200: '#EAEDF0',
|
|
106
|
+
300: '#E2E5E9',
|
|
107
|
+
400: '#D0D8E1',
|
|
108
|
+
500: '#C4CED9',
|
|
109
|
+
600: '#B6BFCA',
|
|
110
|
+
700: '#94A4B7',
|
|
111
|
+
800: '#6A7D93',
|
|
112
|
+
900: '#4D5F74',
|
|
113
|
+
},
|
|
114
|
+
gray: {
|
|
115
|
+
50: '#F6F6F6',
|
|
116
|
+
100: '#EFEFF0',
|
|
117
|
+
200: '#E4E4E7',
|
|
118
|
+
300: '#D7D7D7',
|
|
119
|
+
400: '#CBCACA',
|
|
120
|
+
500: '#AFAFAF',
|
|
121
|
+
600: '#8C8C8C',
|
|
122
|
+
700: '#6B6B6B',
|
|
123
|
+
800: '#555555',
|
|
124
|
+
900: '#3B3B3B',
|
|
125
|
+
},
|
|
126
|
+
'rating-green': {
|
|
127
|
+
50: '#F3F8EC',
|
|
128
|
+
100: '#E5F5CF',
|
|
129
|
+
200: '#D2E9B4',
|
|
130
|
+
300: '#C2DC9E',
|
|
131
|
+
400: '#A9CE78',
|
|
132
|
+
500: '#83B83D',
|
|
133
|
+
600: '#53A925',
|
|
134
|
+
700: '#04812A',
|
|
135
|
+
800: '#006332',
|
|
136
|
+
900: '#064E31',
|
|
137
|
+
},
|
|
138
|
+
pink: {
|
|
139
|
+
50: '#F6EDF3',
|
|
140
|
+
100: '#EAD1E0',
|
|
141
|
+
200: '#D7A3C2',
|
|
142
|
+
300: '#D078AD',
|
|
143
|
+
400: '#D060A3',
|
|
144
|
+
500: '#BD438C',
|
|
145
|
+
600: '#AC2C78',
|
|
146
|
+
700: '#9C0B62',
|
|
147
|
+
800: '#880353',
|
|
148
|
+
900: '#6B0040',
|
|
149
|
+
},
|
|
150
|
+
'rating-red': {
|
|
151
|
+
50: '#FEF2F2',
|
|
152
|
+
100: '#FEE2E2',
|
|
153
|
+
200: '#FECACA',
|
|
154
|
+
300: '#FCA5A5',
|
|
155
|
+
400: '#F87171',
|
|
156
|
+
500: '#EF444D',
|
|
157
|
+
600: '#E31C37',
|
|
158
|
+
700: '#BF1229',
|
|
159
|
+
800: '#990317',
|
|
160
|
+
900: '#7D0011',
|
|
161
|
+
},
|
|
162
|
+
red: {
|
|
163
|
+
50: '#FFF5F3',
|
|
164
|
+
100: '#FDE8E5',
|
|
165
|
+
200: '#FCD9D3',
|
|
166
|
+
300: '#FCBEB3',
|
|
167
|
+
400: '#F99280',
|
|
168
|
+
500: '#DD655A',
|
|
169
|
+
600: '#D7443D',
|
|
170
|
+
700: '#BD3730',
|
|
171
|
+
800: '#A41008',
|
|
172
|
+
900: '#710400',
|
|
173
|
+
},
|
|
174
|
+
yellow: {
|
|
175
|
+
50: '#FFFBEB',
|
|
176
|
+
100: '#FEF3C7',
|
|
177
|
+
200: '#FDE68A',
|
|
178
|
+
300: '#FCD34D',
|
|
179
|
+
400: '#FBBF24',
|
|
180
|
+
500: '#F59E0B',
|
|
181
|
+
600: '#D97706',
|
|
182
|
+
700: '#AA5B0B',
|
|
183
|
+
800: '#924900',
|
|
184
|
+
900: '#763B00',
|
|
185
|
+
},
|
|
186
|
+
|
|
187
|
+
gold: {
|
|
188
|
+
50: '#FDFAF4',
|
|
189
|
+
100: '#FFFAE9',
|
|
190
|
+
200: '#F8EEDA',
|
|
191
|
+
300: '#EFDCB4',
|
|
192
|
+
400: '#E5C582',
|
|
193
|
+
500: '#EDB745',
|
|
194
|
+
600: '#E7A212',
|
|
195
|
+
700: '#CA8A04',
|
|
196
|
+
800: '#A16207',
|
|
197
|
+
900: '#854D0E',
|
|
198
|
+
},
|
|
199
|
+
|
|
200
|
+
'rating-yellow': {
|
|
201
|
+
50: '#FEF7ED',
|
|
202
|
+
100: '#FBECD5',
|
|
203
|
+
200: '#FDE3BA',
|
|
204
|
+
300: '#F4D199',
|
|
205
|
+
400: '#EFBA66',
|
|
206
|
+
500: '#E9A333',
|
|
207
|
+
600: '#E48D00',
|
|
208
|
+
700: '#C86400',
|
|
209
|
+
800: '#B15200',
|
|
210
|
+
900: '#854D0E',
|
|
211
|
+
},
|
|
212
|
+
|
|
213
|
+
bronze: {
|
|
214
|
+
50: '#FAFAF9',
|
|
215
|
+
100: '#F6F4F3',
|
|
216
|
+
200: '#F1EFEF',
|
|
217
|
+
300: '#ECEAE9',
|
|
218
|
+
400: '#E5DFDF',
|
|
219
|
+
500: '#CEC3C0',
|
|
220
|
+
600: '#B8A8A4',
|
|
221
|
+
700: '#B1938C',
|
|
222
|
+
800: '#96736A',
|
|
223
|
+
900: '#825E55',
|
|
224
|
+
},
|
|
225
|
+
|
|
226
|
+
orange: {
|
|
227
|
+
50: '#FEF0E6',
|
|
228
|
+
100: '#FCE7D6',
|
|
229
|
+
200: '#F9CEAD',
|
|
230
|
+
300: '#F6AA71',
|
|
231
|
+
400: '#F18533',
|
|
232
|
+
500: '#EE6600',
|
|
233
|
+
600: '#D75E02',
|
|
234
|
+
700: '#B14C00',
|
|
235
|
+
800: '#883B00',
|
|
236
|
+
900: '#672C00',
|
|
237
|
+
},
|
|
238
|
+
|
|
239
|
+
green: {
|
|
240
|
+
50: '#EDF7F2',
|
|
241
|
+
100: '#D3EADF',
|
|
242
|
+
200: '#B1D7C5',
|
|
243
|
+
300: '#87BCA3',
|
|
244
|
+
400: '#5CA482',
|
|
245
|
+
500: '#399175',
|
|
246
|
+
600: '#267767',
|
|
247
|
+
700: '#0A635D',
|
|
248
|
+
800: '#1E4443',
|
|
249
|
+
900: '#072120',
|
|
250
|
+
},
|
|
251
|
+
|
|
252
|
+
tags: {
|
|
253
|
+
50: '#E8EFF2',
|
|
254
|
+
100: '#C1D8DE',
|
|
255
|
+
200: '#A1BFC8',
|
|
256
|
+
300: '#739EAC',
|
|
257
|
+
400: '#3E90A6',
|
|
258
|
+
500: '#0E7490',
|
|
259
|
+
600: '#155E75',
|
|
260
|
+
700: '#164E63',
|
|
261
|
+
800: '#174253',
|
|
262
|
+
900: '#002A3A',
|
|
263
|
+
},
|
|
264
|
+
'gray-purple': {
|
|
265
|
+
50: '#F1F0F5',
|
|
266
|
+
100: '#E2E0EA',
|
|
267
|
+
200: '#D0CCE4',
|
|
268
|
+
300: '#BFBBD1',
|
|
269
|
+
400: '#B3A4C7',
|
|
270
|
+
500: '#A082C9',
|
|
271
|
+
600: '#8459A6',
|
|
272
|
+
700: '#5E3181',
|
|
273
|
+
800: '#2D1554',
|
|
274
|
+
900: '#201633',
|
|
275
|
+
},
|
|
276
|
+
},
|
|
277
|
+
},
|
|
278
|
+
},
|
|
279
|
+
plugins: [
|
|
280
|
+
require('@tailwindcss/forms')({
|
|
281
|
+
strategy: 'class',
|
|
282
|
+
}),
|
|
283
|
+
],
|
|
284
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
module Infotable
|
|
2
|
+
module Generators
|
|
3
|
+
# rails generate infotable:table User
|
|
4
|
+
# rails generate infotable:table Admin::Order --only=id,number,status --skip=notes
|
|
5
|
+
class TableGenerator < Rails::Generators::NamedBase
|
|
6
|
+
source_root File.expand_path("templates", __dir__)
|
|
7
|
+
|
|
8
|
+
desc "Create an InfoTable definition in app/infotable from a model's columns"
|
|
9
|
+
|
|
10
|
+
class_option :only, type: :array, default: [], desc: "Only these columns"
|
|
11
|
+
class_option :skip, type: :array, default: [], desc: "Leave these columns out"
|
|
12
|
+
|
|
13
|
+
# Attributes that must never end up in a table by accident
|
|
14
|
+
SENSITIVE = /password|digest|token|secret|otp|encrypted/
|
|
15
|
+
|
|
16
|
+
TYPE_MAP = {
|
|
17
|
+
string: { type: :string, filter: :text },
|
|
18
|
+
text: { type: :text, filter: :text },
|
|
19
|
+
integer: { type: :integer, filter: :number },
|
|
20
|
+
bigint: { type: :integer, filter: :number },
|
|
21
|
+
float: { type: :float, filter: :number },
|
|
22
|
+
decimal: { type: :decimal, filter: :number },
|
|
23
|
+
boolean: { type: :boolean, filter: :boolean },
|
|
24
|
+
date: { type: :date, filter: :date },
|
|
25
|
+
datetime: { type: :datetime, filter: :date },
|
|
26
|
+
timestamp: { type: :datetime, filter: :date },
|
|
27
|
+
time: { type: :string, filter: :text }
|
|
28
|
+
}.freeze
|
|
29
|
+
|
|
30
|
+
def create_table_file
|
|
31
|
+
@model = model_class
|
|
32
|
+
say_status :warning, "#{class_name} not found; generating an empty table to fill in", :yellow unless @model
|
|
33
|
+
|
|
34
|
+
template "table.rb.tt", File.join("app/infotable", class_path, "#{table_file_name}.rb")
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
def table_file_name
|
|
40
|
+
"#{file_name.pluralize}_table"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def table_class_name
|
|
44
|
+
(class_path.map(&:camelize) + [ "#{file_name.pluralize.camelize}Table" ]).join("::")
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def model_class
|
|
48
|
+
class_name.safe_constantize
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Column definitions as hashes: name, type, filter, searchable, select options
|
|
52
|
+
def column_specs
|
|
53
|
+
return [] unless @model.respond_to?(:columns)
|
|
54
|
+
|
|
55
|
+
foreign_keys = @model.respond_to?(:reflect_on_all_associations) ? @model.reflect_on_all_associations(:belongs_to).map { _1.foreign_key.to_s } : []
|
|
56
|
+
|
|
57
|
+
@model.columns.filter_map do |column|
|
|
58
|
+
name = column.name
|
|
59
|
+
next if SENSITIVE.match?(name)
|
|
60
|
+
next if foreign_keys.include?(name)
|
|
61
|
+
next if options[:only].any? && options[:only].exclude?(name)
|
|
62
|
+
next if options[:skip].include?(name)
|
|
63
|
+
|
|
64
|
+
spec = TYPE_MAP[column.type] || { type: :string, filter: :text }
|
|
65
|
+
enum_values = @model.respond_to?(:defined_enums) ? @model.defined_enums[name]&.keys : nil
|
|
66
|
+
|
|
67
|
+
{
|
|
68
|
+
name: name,
|
|
69
|
+
type: enum_values ? :badge : spec[:type],
|
|
70
|
+
filter: enum_values ? :select : spec[:filter],
|
|
71
|
+
enum_values: enum_values,
|
|
72
|
+
searchable: %i[string text].include?(column.type) && enum_values.nil?,
|
|
73
|
+
primary_key: name == @model.primary_key.to_s
|
|
74
|
+
}
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# belongs_to associations become commented hints: they need a join the app has to choose
|
|
79
|
+
def association_hints
|
|
80
|
+
return [] unless @model.respond_to?(:reflect_on_all_associations)
|
|
81
|
+
|
|
82
|
+
@model.reflect_on_all_associations(:belongs_to).map(&:name)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def default_sort_line
|
|
86
|
+
names = column_specs.map { _1[:name] }
|
|
87
|
+
if names.include?("created_at")
|
|
88
|
+
"default_sort :created_at, :desc"
|
|
89
|
+
elsif names.any?
|
|
90
|
+
"default_sort :#{names.first}, :asc"
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
class <%= table_class_name %> < Infotable::Base
|
|
2
|
+
query { <%= class_name %>.all }<%= " # TODO: #{class_name} was not found, point this at your model" unless model_class %>
|
|
3
|
+
<% if column_specs.empty? %>
|
|
4
|
+
|
|
5
|
+
# column :name, label: "Name", type: :string, sortable: true, searchable: true, filterable: true, filter_type: :text
|
|
6
|
+
<% end %>
|
|
7
|
+
<% column_specs.each do |spec| -%>
|
|
8
|
+
|
|
9
|
+
column :<%= spec[:name] %>,
|
|
10
|
+
type: :<%= spec[:type] %>,
|
|
11
|
+
sortable: true<%= ",\n searchable: true" if spec[:searchable] %>,
|
|
12
|
+
filterable: <%= spec[:primary_key] ? "false" : "true" %><%= ",\n filter_type: :#{spec[:filter]}" unless spec[:primary_key] %><%= ",\n filter_options: %w[#{spec[:enum_values].join(' ')}]" if spec[:enum_values] %><%= ",\n visible: false" if spec[:primary_key] %>
|
|
13
|
+
<% end -%>
|
|
14
|
+
<% if association_hints.any? %>
|
|
15
|
+
|
|
16
|
+
# Associations: show them with a join, e.g.
|
|
17
|
+
<% association_hints.each do |association| -%>
|
|
18
|
+
# column :<%= association %>, sql: "<%= association.to_s.pluralize %>.name", includes: :<%= association %>, value: ->(record) { record.<%= association %>&.name }
|
|
19
|
+
<% end -%>
|
|
20
|
+
<% end -%>
|
|
21
|
+
|
|
22
|
+
per_page 25
|
|
23
|
+
<% if default_sort_line %>
|
|
24
|
+
<%= default_sort_line %>
|
|
25
|
+
<% end -%>
|
|
26
|
+
end
|