flexirails 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +20 -0
- data/README.md +171 -0
- data/Rakefile +39 -0
- data/app/assets/stylesheets/flexirails.scss +55 -0
- data/app/helpers/flexirails_helper.rb +25 -0
- data/app/models/flexirails/array_view.rb +17 -0
- data/app/models/flexirails/view.rb +123 -0
- data/app/views/flexirails/_container.html.erb +28 -0
- data/app/views/flexirails/_navigation.html.erb +66 -0
- data/lib/flexirails.rb +5 -0
- data/lib/flexirails/engine.rb +4 -0
- data/lib/flexirails/version.rb +3 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +9 -0
- data/test/dummy/app/assets/stylesheets/application.scss +7 -0
- data/test/dummy/app/controllers/active_record_controller.rb +70 -0
- data/test/dummy/app/controllers/application_controller.rb +3 -0
- data/test/dummy/app/controllers/static_controller.rb +68 -0
- data/test/dummy/app/helpers/application_helper.rb +2 -0
- data/test/dummy/app/models/active_record_view.rb +23 -0
- data/test/dummy/app/models/person.rb +2 -0
- data/test/dummy/app/models/static.rb +5 -0
- data/test/dummy/app/models/static_view.rb +5 -0
- data/test/dummy/app/views/active_record/index.html.erb +7 -0
- data/test/dummy/app/views/layouts/application.html.erb +14 -0
- data/test/dummy/app/views/static/index.html.erb +7 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +44 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +30 -0
- data/test/dummy/config/environments/production.rb +60 -0
- data/test/dummy/config/environments/test.rb +42 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +10 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +8 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/de.yml +8 -0
- data/test/dummy/config/locales/en.yml +8 -0
- data/test/dummy/config/routes.rb +60 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/migrate/20131109204431_create_people.rb +9 -0
- data/test/dummy/db/schema.rb +23 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/development.log +5482 -0
- data/test/dummy/log/test.log +4932 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +26 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/dummy/tmp/cache/assets/development/sass/62614c0f166e45da36cfbb2781f9667e47799670/application.scssc +0 -0
- data/test/dummy/tmp/cache/assets/development/sass/9178b5a65ff97d4c91c8e2380e5ac8d8eb939b91/flexirails.scssc +0 -0
- data/test/dummy/tmp/cache/assets/development/sass/b2a814b45c3cca5078e8af8655d3f89a5f705998/flexirails.scssc +0 -0
- data/test/dummy/tmp/cache/assets/development/sass/e91bee6f7bc4c18550721ba1f2d7361da7e3d2e5/application.scssc +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/24585794383ac6ae2640d6c9e4affdbd +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/2edad7c2ee0e34d5988da78ef799ca6c +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/2ef811475ef30c8afbab72317974e714 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/33fea692ac14771a738e10ee5d76ae96 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/352bab412d75fa19d0a07504553b59df +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/5584751febc87e8b2ba4b7f38285eceb +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/69e627a9d109212088a08e7938543d9d +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/6e1bd95023705b5529e7ccc754a02867 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/836b5f0381caa8a96cebbee674df2708 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/85c3b8d54510866ae2cc33aedc247eb0 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/889b9afc807369ef171867cb782dd99c +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/92613a75279536c4bcf4f3ba6cfde494 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/c0f4ca569d58f951461e6ccadfdd2649 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/dcea77c9b7315ca8f48eb8357e38a219 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/e714eeaf481f5a44ddca306c4a9c7137 +0 -0
- data/test/dummy/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/test/dummy/tmp/cache/assets/test/sass/9178b5a65ff97d4c91c8e2380e5ac8d8eb939b91/flexirails.scssc +0 -0
- data/test/dummy/tmp/cache/assets/test/sass/e91bee6f7bc4c18550721ba1f2d7361da7e3d2e5/application.scssc +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/2ef811475ef30c8afbab72317974e714 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/352bab412d75fa19d0a07504553b59df +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/5584751febc87e8b2ba4b7f38285eceb +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/6e1bd95023705b5529e7ccc754a02867 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/836b5f0381caa8a96cebbee674df2708 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/85c3b8d54510866ae2cc33aedc247eb0 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/889b9afc807369ef171867cb782dd99c +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/92613a75279536c4bcf4f3ba6cfde494 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/c0f4ca569d58f951461e6ccadfdd2649 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
- data/test/dummy/tmp/pids/server.pid +1 -0
- data/test/models/flexirails/array_view_test.rb +44 -0
- data/test/models/flexirails/view_test.rb +46 -0
- data/test/rails-localization-engine_test.rb +7 -0
- data/test/test_helper.rb +14 -0
- data/test/views/flexirails/navigation_test.rb +65 -0
- metadata +306 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 13cd7f185547a32a1c78255b13533dde98c348a2
|
4
|
+
data.tar.gz: 7566fb2bb29edaf12737db45c5e6c71aeee5df50
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 7168c88257719d55a31be8bd847f12872ab6d4b98de945e789669e1c0a1907cc927209508c2633ba9f09e2f49415f68c21a9529504f48a3817448018bed2b284
|
7
|
+
data.tar.gz: 4e597fe640fbe4c06db3502114f54921375ba73dba8e7dfbb84ead2b789256e94e91bb631122e048a03e5137c0675454b876137beb9b94afadb9b480e6c3541b
|
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2011-2013 Raphael Randschau (nicolai86@me.com)
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,171 @@
|
|
1
|
+
# Flexirails
|
2
|
+
|
3
|
+
ORM independent table view for Ruby on Rails.
|
4
|
+
Has support for partial rendering, turbolinks and i18n as well as basic sorting and filtering facilities.
|
5
|
+
If you want more abstraction you need to build it yourself.
|
6
|
+
|
7
|
+
Look at the bright side: want to use bananadb? Go ahead.<br>
|
8
|
+
Just wrote your self CSV-In-Memory-DB? No Problem.<br>
|
9
|
+
Reading each row from /dev/null. Sure, why not?
|
10
|
+
|
11
|
+
You are in control. Just need to know how!
|
12
|
+
|
13
|
+
### Installation
|
14
|
+
|
15
|
+
Add `gem "flexirails"` to your `Gemfile`.
|
16
|
+
|
17
|
+
### Usage
|
18
|
+
|
19
|
+
Now you need two more steps to get going:
|
20
|
+
|
21
|
+
1. subclass `::Flexirails::View` or `::Flexirails::ArrayView`.
|
22
|
+
|
23
|
+
``` ruby
|
24
|
+
class PeopleView < ::Flexirails::View
|
25
|
+
def total
|
26
|
+
Person.count
|
27
|
+
end
|
28
|
+
|
29
|
+
def query offset, limit
|
30
|
+
Person.offset(offset).limit(limit)
|
31
|
+
end
|
32
|
+
|
33
|
+
def columns
|
34
|
+
%w(id name)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
```
|
38
|
+
|
39
|
+
2. instanciate your view class in your controller:
|
40
|
+
|
41
|
+
``` ruby
|
42
|
+
class PeopleController < ApplicationController
|
43
|
+
protected
|
44
|
+
def people_view
|
45
|
+
@people_view ||= PeopleView.new(params)
|
46
|
+
end
|
47
|
+
helper_method :people_view
|
48
|
+
end
|
49
|
+
```
|
50
|
+
|
51
|
+
3. render appropriate partials in your views:
|
52
|
+
|
53
|
+
``` erb
|
54
|
+
<%= render :partial => '/flexirails/navigation', :locals => { :view => people_view } %>
|
55
|
+
<%= render_flexirails_view(people_view, { :class => 'statics' }) %>
|
56
|
+
```
|
57
|
+
|
58
|
+
Columns are translated as `<lang>.<view_as_snake_case>.<column>`, e.g. `de.people_view.name`.
|
59
|
+
|
60
|
+
### Advanced Usage
|
61
|
+
|
62
|
+
You can pass additional informations to your view - e.g. the current user for complex logic
|
63
|
+
|
64
|
+
``` ruby
|
65
|
+
class PeopleView < ::Flexirails::View
|
66
|
+
attr_reader :current_user, :current_project
|
67
|
+
def initialize params, user, project
|
68
|
+
@current_user = user
|
69
|
+
@current_project = project
|
70
|
+
super params
|
71
|
+
end
|
72
|
+
|
73
|
+
def scoped
|
74
|
+
if current_user.admin?
|
75
|
+
Person.scoped
|
76
|
+
else
|
77
|
+
current_project.people
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def total
|
82
|
+
scoped.count
|
83
|
+
end
|
84
|
+
|
85
|
+
def query offset, limit
|
86
|
+
scoped.offset(offset).limit(limit)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
```
|
90
|
+
|
91
|
+
By default attributes are extracted from the current row object. But you can render partials if you want to:
|
92
|
+
``` ruby
|
93
|
+
class PeopleView < ::Flexirails::View
|
94
|
+
def total
|
95
|
+
Person.count
|
96
|
+
end
|
97
|
+
|
98
|
+
def query offset, limit
|
99
|
+
Person.offset(offset).limit(limit)
|
100
|
+
end
|
101
|
+
|
102
|
+
def columns
|
103
|
+
%w(id name actions)
|
104
|
+
end
|
105
|
+
|
106
|
+
def render_actions person, context
|
107
|
+
context.render :partial => "actions", :locals => { :person => person }
|
108
|
+
end
|
109
|
+
end
|
110
|
+
```
|
111
|
+
|
112
|
+
You can sort your data if you want to. `order` and `direction` are sanitized by default, no need to check.
|
113
|
+
``` ruby
|
114
|
+
class PeopleView < ::Flexirails::View
|
115
|
+
def query offset, limit
|
116
|
+
scope = if order_query?
|
117
|
+
Person.order("#{order} #{direction}")
|
118
|
+
else
|
119
|
+
Person
|
120
|
+
end
|
121
|
+
scope.offset(offset).limit(limit)
|
122
|
+
end
|
123
|
+
|
124
|
+
def sortable_columns
|
125
|
+
%w(id)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
```
|
129
|
+
|
130
|
+
You can filter your data if you want to:
|
131
|
+
``` ruby
|
132
|
+
class PeopleView < ::Flexirails::View
|
133
|
+
attr_reader :minimum_id
|
134
|
+
def initialize params
|
135
|
+
@minimum_id = params.fetch(:minimum_id, nil)
|
136
|
+
|
137
|
+
super params
|
138
|
+
end
|
139
|
+
|
140
|
+
def scoped
|
141
|
+
if minimum_id.present?
|
142
|
+
Person.where(["id > ?", minimum_id])
|
143
|
+
else
|
144
|
+
Person.scoped
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def total
|
149
|
+
scoped.count
|
150
|
+
end
|
151
|
+
|
152
|
+
def query offset, limit
|
153
|
+
scoped.offset(offset).limit(limit)
|
154
|
+
end
|
155
|
+
end
|
156
|
+
```
|
157
|
+
|
158
|
+
### TODO
|
159
|
+
|
160
|
+
- enhance the test suite
|
161
|
+
- refactor the small, inlined- js a little. its ugly as hell
|
162
|
+
- refactor the css. its ugly as hell as well
|
163
|
+
- maybe add a small abstraction for ActiveRecord Views
|
164
|
+
|
165
|
+
### Contributing
|
166
|
+
|
167
|
+
1. Fork it
|
168
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
169
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
170
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
171
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
begin
|
3
|
+
require 'bundler/setup'
|
4
|
+
require "bundler/gem_tasks"
|
5
|
+
rescue LoadError
|
6
|
+
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
|
7
|
+
end
|
8
|
+
|
9
|
+
begin
|
10
|
+
require 'rdoc/task'
|
11
|
+
rescue LoadError
|
12
|
+
require 'rdoc/rdoc'
|
13
|
+
require 'rake/rdoctask'
|
14
|
+
RDoc::Task = Rake::RDocTask
|
15
|
+
end
|
16
|
+
|
17
|
+
RDoc::Task.new(:rdoc) do |rdoc|
|
18
|
+
rdoc.rdoc_dir = 'rdoc'
|
19
|
+
rdoc.title = 'Flexirails'
|
20
|
+
rdoc.options << '--line-numbers'
|
21
|
+
rdoc.rdoc_files.include('README.rdoc')
|
22
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
|
27
|
+
Bundler::GemHelper.install_tasks
|
28
|
+
|
29
|
+
require 'rake/testtask'
|
30
|
+
|
31
|
+
Rake::TestTask.new(:test) do |t|
|
32
|
+
t.libs << 'lib'
|
33
|
+
t.libs << 'test'
|
34
|
+
t.pattern = 'test/**/*_test.rb'
|
35
|
+
t.verbose = false
|
36
|
+
end
|
37
|
+
|
38
|
+
|
39
|
+
task :default => :test
|
@@ -0,0 +1,55 @@
|
|
1
|
+
.filter {
|
2
|
+
.row .columns {
|
3
|
+
height: 32px !important;
|
4
|
+
line-height: 32px !important;
|
5
|
+
margin-bottom: 3px;
|
6
|
+
}
|
7
|
+
margin-bottom: 5px;
|
8
|
+
}
|
9
|
+
|
10
|
+
div.flexirails {
|
11
|
+
overflow: scroll;
|
12
|
+
}
|
13
|
+
|
14
|
+
nav.flexirails {
|
15
|
+
div {
|
16
|
+
display: inline-block;
|
17
|
+
}
|
18
|
+
input {
|
19
|
+
display: inline-block;
|
20
|
+
}
|
21
|
+
.page {
|
22
|
+
input {
|
23
|
+
width: 50px;
|
24
|
+
}
|
25
|
+
}
|
26
|
+
svg {
|
27
|
+
fill: white;
|
28
|
+
}
|
29
|
+
.pagination a {
|
30
|
+
height: 32px;
|
31
|
+
line-height: 34px;
|
32
|
+
display: inline-block;
|
33
|
+
vertical-align: middle;
|
34
|
+
}
|
35
|
+
}
|
36
|
+
|
37
|
+
.flexirails table {
|
38
|
+
width: 100%;
|
39
|
+
th {
|
40
|
+
text-align: left;
|
41
|
+
}
|
42
|
+
td {
|
43
|
+
padding: 5px;
|
44
|
+
}
|
45
|
+
td.actions {
|
46
|
+
span {
|
47
|
+
display: inline-block;
|
48
|
+
}
|
49
|
+
|
50
|
+
a {
|
51
|
+
min-width: 32px;
|
52
|
+
min-height: 32px;
|
53
|
+
}
|
54
|
+
}
|
55
|
+
}
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'url_plumber'
|
2
|
+
|
3
|
+
module FlexirailsHelper
|
4
|
+
def pagination_first_icon
|
5
|
+
return '<svg version="1.2" baseProfile="tiny" id="Navigation_first" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="16px" height="16px" viewBox="0 0 512 512" overflow="inherit" xml:space="preserve"> <path d="M186.178,256.243l211.583,166.934V89.312L186.178,256.243z M112.352,422.512h66.179V89.975h-66.179V422.512z"/> </svg>'
|
6
|
+
end
|
7
|
+
def pagination_prev_icon
|
8
|
+
return '<svg version="1.2" baseProfile="tiny" id="Navigation_left" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="16px" height="16px" viewBox="0 0 512 512" overflow="inherit" xml:space="preserve"> <polygon points="148.584,255.516 360.168,88.583 360.166,422.445 "/> </svg>'
|
9
|
+
end
|
10
|
+
def pagination_last_icon
|
11
|
+
return '<svg version="1.2" baseProfile="tiny" id="Navigation_last" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="16px" height="16px" viewBox="0 0 512 512" overflow="inherit" xml:space="preserve"> <path d="M111.708,424.514l211.581-166.927L111.708,90.654V424.514z M330.935,87.311v332.544h66.173V87.311H330.935z"/> </svg>'
|
12
|
+
end
|
13
|
+
def pagination_next_icon
|
14
|
+
return '<svg version="1.2" baseProfile="tiny" id="Navigation_right" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="16px" height="16px" viewBox="0 0 512 512" overflow="inherit" xml:space="preserve"> <polygon points="360.124,255.513 148.535,422.442 148.537,88.58 "/> </svg>'
|
15
|
+
end
|
16
|
+
def render_flexirails_view view, opts = {}
|
17
|
+
return render partial: '/flexirails/container', locals: { view: view, table_class: opts.fetch(:class) { "" } }
|
18
|
+
end
|
19
|
+
def url_plumb(key, value)
|
20
|
+
url_for(::UrlPlumber::Plumber.new(params).plumb(key => value))
|
21
|
+
end
|
22
|
+
def url_batch_plumb(hash)
|
23
|
+
url_for(::UrlPlumber::Plumber.new(params).plumb(hash))
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Flexirails
|
2
|
+
class ArrayView < ::Flexirails::View
|
3
|
+
attr_reader :items
|
4
|
+
def initialize params, items
|
5
|
+
@items = items
|
6
|
+
super params
|
7
|
+
end
|
8
|
+
|
9
|
+
def query offset, limit
|
10
|
+
items[offset..(offset+limit-1)]
|
11
|
+
end
|
12
|
+
|
13
|
+
def total
|
14
|
+
items.size
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
module Flexirails
|
2
|
+
class View
|
3
|
+
attr_reader :offset, :limit, :current_page, :per_page, :order, :direction, :params
|
4
|
+
|
5
|
+
def initialize params
|
6
|
+
@params = params
|
7
|
+
pagination = params.fetch(:pagination) { params || Hash.new }
|
8
|
+
|
9
|
+
@current_page = pagination.fetch(:current_page) { 1 }.to_i
|
10
|
+
@per_page = pagination.fetch(:per_page) { 25 }.to_i
|
11
|
+
@order = sanitize(pagination.fetch(:order) { nil })
|
12
|
+
@direction = sanitize_direction(pagination.fetch(:direction) { nil })
|
13
|
+
|
14
|
+
if @current_page > total_page_count
|
15
|
+
@current_page = 1
|
16
|
+
end
|
17
|
+
|
18
|
+
@offset = (current_page-1) * per_page
|
19
|
+
@limit = per_page
|
20
|
+
end
|
21
|
+
|
22
|
+
def next_pagination_direction column
|
23
|
+
if order == column
|
24
|
+
if direction == "DESC"
|
25
|
+
nil
|
26
|
+
else
|
27
|
+
if direction == nil
|
28
|
+
"ASC"
|
29
|
+
else
|
30
|
+
"DESC"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
else
|
34
|
+
"ASC"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def total_page_count
|
39
|
+
return (self.total.to_f / self.per_page.to_f).ceil
|
40
|
+
end
|
41
|
+
|
42
|
+
def total
|
43
|
+
raise "ImplementationMissing"
|
44
|
+
end
|
45
|
+
|
46
|
+
def query offset = self.offset, limit = self.limit
|
47
|
+
raise "ImplementationMissing"
|
48
|
+
end
|
49
|
+
|
50
|
+
def has_prev_path
|
51
|
+
return self.current_page > 1
|
52
|
+
end
|
53
|
+
def has_next_path
|
54
|
+
return self.current_page < total_page_count
|
55
|
+
end
|
56
|
+
|
57
|
+
def sortable_columns
|
58
|
+
return %w()
|
59
|
+
end
|
60
|
+
|
61
|
+
def columns
|
62
|
+
sortable_columns
|
63
|
+
end
|
64
|
+
|
65
|
+
def order_query?
|
66
|
+
return order.present? && direction.present?
|
67
|
+
end
|
68
|
+
alias_method :order_results?, :order_query?
|
69
|
+
|
70
|
+
def rows
|
71
|
+
return @rows ||= query(offset, limit)
|
72
|
+
end
|
73
|
+
|
74
|
+
def i18n_scope clazz = self.class
|
75
|
+
return clazz.name.tableize.singularize.gsub('/','.')
|
76
|
+
end
|
77
|
+
|
78
|
+
def i18n_default name
|
79
|
+
scopes = []
|
80
|
+
clazz = self.class
|
81
|
+
clazz.ancestors.each do |ancestor|
|
82
|
+
break if ancestor == Object
|
83
|
+
scopes << [i18n_scope(ancestor),name].compact.join('.').to_sym
|
84
|
+
end
|
85
|
+
return scopes
|
86
|
+
end
|
87
|
+
|
88
|
+
def t name, args = {}
|
89
|
+
I18n.t([i18n_scope,name].compact.join('.'), { default: i18n_default(name) }.merge(args))
|
90
|
+
end
|
91
|
+
|
92
|
+
def render_column column, row, context
|
93
|
+
method_to_call = "render_#{column.gsub(/\./, '_')}"
|
94
|
+
if self.respond_to?(method_to_call.to_sym)
|
95
|
+
return self.send method_to_call.to_sym, row, context
|
96
|
+
else
|
97
|
+
parts = column.split('.').map(&:to_sym)
|
98
|
+
object = row
|
99
|
+
parts.each do |part|
|
100
|
+
object = object.send(part)
|
101
|
+
end
|
102
|
+
return object
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def pagination_hash
|
107
|
+
return {
|
108
|
+
current_page: self.current_page,
|
109
|
+
per_page: self.per_page,
|
110
|
+
order: self.order,
|
111
|
+
direction: self.direction
|
112
|
+
}
|
113
|
+
end
|
114
|
+
|
115
|
+
private
|
116
|
+
def sanitize_direction direction
|
117
|
+
return %w(ASC DESC).include?(direction) ? direction : nil
|
118
|
+
end
|
119
|
+
def sanitize attribute
|
120
|
+
return columns.include?(attribute) ? attribute : nil
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|