edgarj 0.01.12
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.rdoc +23 -0
- data/Rakefile +40 -0
- data/app/assets/javascripts/edgarj/base.js +49 -0
- data/app/assets/javascripts/edgarj/menu.js +39 -0
- data/app/assets/javascripts/edgarj/operator_selection.js +133 -0
- data/app/assets/stylesheets/edgarj/base.css +304 -0
- data/app/assets/stylesheets/edgarj/menu.css +65 -0
- data/app/controllers/edgarj/authentication_mixin.rb.sample +30 -0
- data/app/controllers/edgarj/controller_mixin_common.rb +80 -0
- data/app/controllers/edgarj/controller_mixin_for_app.rb +71 -0
- data/app/controllers/edgarj/edgarj_controller.rb +535 -0
- data/app/controllers/edgarj/model_permissions_controller.rb +8 -0
- data/app/controllers/edgarj/permission_mixin.rb +84 -0
- data/app/controllers/edgarj/popup_controller.rb +128 -0
- data/app/controllers/edgarj/rescue_mixin.rb +37 -0
- data/app/controllers/edgarj/user_group_users_controller.rb +8 -0
- data/app/controllers/edgarj/user_groups_controller.rb +9 -0
- data/app/controllers/edgarj/user_groups_popup_controller.rb +8 -0
- data/app/helpers/edgarj/assoc_helper.rb +369 -0
- data/app/helpers/edgarj/common_helper.rb +37 -0
- data/app/helpers/edgarj/edgarj_helper.rb +20 -0
- data/app/helpers/edgarj/field_helper.rb +397 -0
- data/app/helpers/edgarj/form_drawer.rb +322 -0
- data/app/helpers/edgarj/list_drawer.rb +169 -0
- data/app/helpers/edgarj/menu_helper.rb +92 -0
- data/app/helpers/edgarj/model_permissions_helper.rb +9 -0
- data/app/helpers/edgarj/popup_helper.rb +40 -0
- data/app/helpers/edgarj/search_helper.rb +14 -0
- data/app/helpers/edgarj/sessions_helper.rb +9 -0
- data/app/helpers/edgarj/user_group_users_helper.rb +9 -0
- data/app/helpers/edgarj/user_groups_helper.rb +9 -0
- data/app/helpers/edgarj/user_groups_popup_helper.rb +9 -0
- data/app/models/edgarj/drawer/base.rb +234 -0
- data/app/models/edgarj/drawer/normal.rb +6 -0
- data/app/models/edgarj/drawer/popup.rb +47 -0
- data/app/models/edgarj/drawer.rb +13 -0
- data/app/models/edgarj/model_permission.rb +41 -0
- data/app/models/edgarj/page_info.rb +47 -0
- data/app/models/edgarj/search.rb +81 -0
- data/app/models/edgarj/search_form.rb +255 -0
- data/app/models/edgarj/search_popup.rb +44 -0
- data/app/models/edgarj/sssn.rb +120 -0
- data/app/models/edgarj/user_group.rb +67 -0
- data/app/models/edgarj/user_group_user.rb +18 -0
- data/app/models/edgarj.rb +5 -0
- data/app/views/edgarj/edgarj/_form.html.erb +25 -0
- data/app/views/edgarj/edgarj/_list.html.erb +52 -0
- data/app/views/edgarj/edgarj/_message_popup.html.erb +15 -0
- data/app/views/edgarj/edgarj/_search_form.html.erb +64 -0
- data/app/views/edgarj/edgarj/_search_operator.html.erb +17 -0
- data/app/views/edgarj/edgarj/_search_operator_selection.html.erb +12 -0
- data/app/views/edgarj/edgarj/clear.js.erb +1 -0
- data/app/views/edgarj/edgarj/create.js.erb +4 -0
- data/app/views/edgarj/edgarj/destroy.js.erb +2 -0
- data/app/views/edgarj/edgarj/index.html.erb +37 -0
- data/app/views/edgarj/edgarj/index.js.erb +1 -0
- data/app/views/edgarj/edgarj/message_popup.js.erb +3 -0
- data/app/views/edgarj/edgarj/page_info_save.js.erb +1 -0
- data/app/views/edgarj/edgarj/search.js.erb +4 -0
- data/app/views/edgarj/edgarj/search_clear.js.erb +1 -0
- data/app/views/edgarj/edgarj/show.js.erb +1 -0
- data/app/views/edgarj/edgarj/top.html.erb +4 -0
- data/app/views/edgarj/edgarj/update.js.erb +4 -0
- data/app/views/edgarj/popup/_index.html.erb +16 -0
- data/app/views/edgarj/popup/_list.html.erb +42 -0
- data/app/views/edgarj/popup/_message_popup.html.erb +15 -0
- data/app/views/edgarj/popup/_search.html.erb +42 -0
- data/app/views/edgarj/popup/_search_save_popup.html.erb +16 -0
- data/app/views/edgarj/popup/index.js.erb +5 -0
- data/app/views/edgarj/popup/message_popup.js.erb +3 -0
- data/app/views/edgarj/popup/page_info_save.js.erb +1 -0
- data/app/views/edgarj/popup/search.js.erb +15 -0
- data/app/views/edgarj/popup/view_status_save.js.erb +1 -0
- data/config/routes.rb +15 -0
- data/config/settings.yml +5 -0
- data/db/migrate/20131118084600_create_edgar_sssns.rb +14 -0
- data/db/migrate/20131123124730_create_edgar_page_infos.rb +15 -0
- data/db/migrate/20140116062252_create_edgar_user_groups.rb +18 -0
- data/db/migrate/20140116062327_create_edgar_user_group_users.rb +10 -0
- data/db/migrate/20140206222308_create_edgar_model_permissions.rb +14 -0
- data/db/migrate/20141209053055_rename_edgar_to_edgarj.rb +17 -0
- data/lib/core_ext/active_record.rb +123 -0
- data/lib/core_ext/resources.rb +71 -0
- data/lib/edgarj/engine.rb +64 -0
- data/lib/edgarj/enum_cache.rb +46 -0
- data/lib/edgarj/templates/rails/helper/helper.rb +10 -0
- data/lib/edgarj/templates/test_unit/scaffold/functional_test.rb +575 -0
- data/lib/edgarj/version.rb +3 -0
- data/lib/edgarj.rb +14 -0
- data/lib/generators/edgarj/popup_scaffold/USAGE +6 -0
- data/lib/generators/edgarj/popup_scaffold/popup_scaffold_generator.rb +35 -0
- data/lib/generators/edgarj/popup_scaffold/templates/controller.rb +13 -0
- data/lib/generators/edgarj/popup_scaffold/templates/functional_test.rb +197 -0
- data/lib/generators/edgarj/popup_scaffold/templates/helper.rb +9 -0
- data/lib/generators/edgarj/scaffold/USAGE +17 -0
- data/lib/generators/edgarj/scaffold/scaffold_generator.rb +40 -0
- data/lib/generators/edgarj/scaffold/templates/controller.rb +13 -0
- data/lib/tasks/edgarj_tasks.rake +32 -0
- data/lib/tasks/pakcage.rake +18 -0
- data/locale/en.yml +94 -0
- data/locale/ja.yml +100 -0
- data/test/dummy/README.rdoc +28 -0
- data/test/dummy/Rakefile +6 -0
- data/test/dummy/app/assets/javascripts/application.js +21 -0
- data/test/dummy/app/assets/javascripts/authors.js +2 -0
- data/test/dummy/app/assets/stylesheets/application.css +16 -0
- data/test/dummy/app/assets/stylesheets/authors.css +4 -0
- data/test/dummy/app/assets/stylesheets/scaffold.css +56 -0
- data/test/dummy/app/controllers/application_controller.rb +15 -0
- data/test/dummy/app/controllers/authors_controller.rb +6 -0
- data/test/dummy/app/controllers/authors_popup_controller.rb +6 -0
- data/test/dummy/app/controllers/books_controller.rb +6 -0
- data/test/dummy/app/controllers/dummy_auth_mixin.rb +36 -0
- data/test/dummy/app/decorators/models/edgarj/user_group_decorator.rb +1 -0
- data/test/dummy/app/helpers/application_helper.rb +3 -0
- data/test/dummy/app/helpers/authors_helper.rb +7 -0
- data/test/dummy/app/helpers/authors_popup_helper.rb +7 -0
- data/test/dummy/app/helpers/books_helper.rb +7 -0
- data/test/dummy/app/models/author.rb +32 -0
- data/test/dummy/app/models/book.rb +5 -0
- data/test/dummy/app/models/user.rb +13 -0
- data/test/dummy/app/views/layouts/application.html.erb +32 -0
- data/test/dummy/app/views/layouts/login.html.erb +20 -0
- data/test/dummy/bin/bundle +3 -0
- data/test/dummy/bin/rails +4 -0
- data/test/dummy/bin/rake +4 -0
- data/test/dummy/config/application.rb +59 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +15 -0
- data/test/dummy/config/edgarj/menu_config.rb +28 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +42 -0
- data/test/dummy/config/environments/production.rb +79 -0
- data/test/dummy/config/environments/test.rb +34 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/test/dummy/config/initializers/inflections.rb +16 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +12 -0
- data/test/dummy/config/initializers/session_store.rb +3 -0
- data/test/dummy/config/initializers/strong_parameter.rb +3 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +26 -0
- data/test/dummy/config/routes.rb +60 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/db/migrate/20131107120635_create_authors.rb +9 -0
- data/test/dummy/db/migrate/20131218011851_create_books.rb +10 -0
- data/test/dummy/db/migrate/20140201000000_add_user_group_id_to_authors.rb +5 -0
- data/test/dummy/db/migrate/20140807065420_create_users.rb +10 -0
- data/test/dummy/db/schema.rb +93 -0
- data/test/dummy/public/404.html +58 -0
- data/test/dummy/public/422.html +58 -0
- data/test/dummy/public/500.html +57 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/rails +6 -0
- data/test/dummy/test/functional/authors_controller_test.rb +631 -0
- data/test/dummy/test/functional/books_controller_test.rb +516 -0
- data/test/dummy/test/helpers/authors_helper_test.rb +4 -0
- data/test/dummy/test/unit/author_test.rb +7 -0
- data/test/dummy/test/unit/book_test.rb +7 -0
- data/test/edgar_test.rb +7 -0
- data/test/fixtures/authors.yml +32 -0
- data/test/fixtures/books.yml +56 -0
- data/test/fixtures/edgarj/model_permissions.yml +97 -0
- data/test/fixtures/edgarj/page_infos.yml +84 -0
- data/test/fixtures/edgarj/sssns.yml +38 -0
- data/test/fixtures/edgarj/user_group_users.yml +114 -0
- data/test/fixtures/edgarj/user_groups.yml +95 -0
- data/test/fixtures/users.yml +49 -0
- data/test/functional/edgarj/edgarj_controller_test.rb +24 -0
- data/test/functional/edgarj/model_permissions_controller_test.rb +554 -0
- data/test/functional/edgarj/user_group_users_controller_test.rb +567 -0
- data/test/integration/navigation_test.rb +10 -0
- data/test/support/edgarj/controller_supporter.rb +23 -0
- data/test/test_helper.rb +23 -0
- data/test/unit/edgarj/model_permission_test.rb +27 -0
- data/test/unit/edgarj/page_info_test.rb +7 -0
- data/test/unit/edgarj/sssn_test.rb +10 -0
- data/test/unit/edgarj/user_group_test.rb +32 -0
- data/test/unit/edgarj/user_group_user_test.rb +9 -0
- data/test/unit/helpers/edgarj/model_permissions_helper_test.rb +6 -0
- data/test/unit/helpers/edgarj/user_group_users_helper_test.rb +6 -0
- metadata +456 -0
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
module Edgarj
|
|
2
|
+
module Drawer
|
|
3
|
+
# 'Mediator' to draw list and form of the model on the view.
|
|
4
|
+
class Base
|
|
5
|
+
attr_accessor :vc
|
|
6
|
+
|
|
7
|
+
# * options
|
|
8
|
+
# * list_drawer_options - options for Edgarj::ListDrawer::Normal
|
|
9
|
+
# * draw_form_options - options for draw_form_options
|
|
10
|
+
def initialize(view_context, params, page_info, model, options={})
|
|
11
|
+
@vc = view_context
|
|
12
|
+
@params = params
|
|
13
|
+
@page_info = page_info
|
|
14
|
+
@model = model
|
|
15
|
+
@options = options.dup
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# level-1 methods which may be modified most frequently:
|
|
19
|
+
|
|
20
|
+
# define model-wide default columns for view.
|
|
21
|
+
#
|
|
22
|
+
# If you need to customize, overwrite it at derived model class.
|
|
23
|
+
# Example:
|
|
24
|
+
# def columns
|
|
25
|
+
# %w(id name email updated_at)
|
|
26
|
+
# end
|
|
27
|
+
#
|
|
28
|
+
# === SEE ALSO
|
|
29
|
+
# list_columns:: define list columns
|
|
30
|
+
# form_columns:: define form columns
|
|
31
|
+
# search_form_columns:: define search form columns
|
|
32
|
+
def columns
|
|
33
|
+
@model.columns.map{|c| c.name}
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# This defines list columns.
|
|
37
|
+
# You can overwrite this method at each model if it is different from
|
|
38
|
+
# columns. Default is calling columns().
|
|
39
|
+
#
|
|
40
|
+
# === SEE ALSO
|
|
41
|
+
# columns:: define default columns
|
|
42
|
+
# form_columns:: define form columns
|
|
43
|
+
# search_form_columns:: define search form columns
|
|
44
|
+
#
|
|
45
|
+
def list_columns
|
|
46
|
+
columns
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# This defines form columns.
|
|
50
|
+
# You can overwrite this method at each model if it is different from
|
|
51
|
+
# columns. Default is calling columns().
|
|
52
|
+
#
|
|
53
|
+
# === SEE ALSO
|
|
54
|
+
# columns:: define default columns
|
|
55
|
+
# list_columns:: define list columns
|
|
56
|
+
# search_form_columns:: define search form columns
|
|
57
|
+
#
|
|
58
|
+
def form_columns
|
|
59
|
+
columns
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# This defines search-form columns.
|
|
63
|
+
# You can overwrite this method at each model if it is different from
|
|
64
|
+
# columns. Default is calling columns().
|
|
65
|
+
#
|
|
66
|
+
# === SEE ALSO
|
|
67
|
+
# columns:: define default columns
|
|
68
|
+
# list_columns:: define list columns
|
|
69
|
+
# form_columns:: define form columns
|
|
70
|
+
#
|
|
71
|
+
def search_form_columns
|
|
72
|
+
columns
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# level-2 methods which may be modified occasionally:
|
|
76
|
+
|
|
77
|
+
# This defines popup path for the column on the model.
|
|
78
|
+
#
|
|
79
|
+
# Default returns parent model's popup-controller.
|
|
80
|
+
# For example, book.author_id -> 'authors_popup' path
|
|
81
|
+
#
|
|
82
|
+
# You can overwrite this method at each model if it is different from
|
|
83
|
+
# columns.
|
|
84
|
+
#
|
|
85
|
+
# @see popup_path_on_search popup path for the column on the model's search form
|
|
86
|
+
def popup_path(col)
|
|
87
|
+
parent_model = @model.belongs_to_AR(col)
|
|
88
|
+
raise 'Parent is nil' if !parent_model
|
|
89
|
+
|
|
90
|
+
popup_field = PopupHelper::PopupField.new_builder(@model.model_name.param_key, col.name)
|
|
91
|
+
@vc.main_app.url_for(
|
|
92
|
+
controller: parent_model.model_name.collection + '_popup',
|
|
93
|
+
id_target: popup_field.id_target)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
# This defines popup path for the search column on the model.
|
|
97
|
+
#
|
|
98
|
+
# Default returns parent model's popup-controller with id_target
|
|
99
|
+
# on the search column.
|
|
100
|
+
#
|
|
101
|
+
# @see popup_path popup path for the column on the model itself
|
|
102
|
+
def popup_path_on_search(col)
|
|
103
|
+
parent_model = @model.belongs_to_AR(col)
|
|
104
|
+
raise 'Parent is nil' if !parent_model
|
|
105
|
+
|
|
106
|
+
popup_field = PopupHelper::PopupField.new_builder(Edgarj::SearchForm.model_name.param_key, col.name)
|
|
107
|
+
@vc.main_app.url_for(
|
|
108
|
+
controller: parent_model.model_name.collection + '_popup',
|
|
109
|
+
id_target: popup_field.id_target)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# draw sort link on list column header
|
|
113
|
+
#
|
|
114
|
+
# === INPUTS
|
|
115
|
+
# col:: column data
|
|
116
|
+
# options:: options to url_for
|
|
117
|
+
def draw_sort(col, options={})
|
|
118
|
+
label = @model.human_attribute_name(col.name)
|
|
119
|
+
dir = 'asc'
|
|
120
|
+
if @page_info.order_by == fullname(col)
|
|
121
|
+
# toggle direction
|
|
122
|
+
if @page_info.dir == 'asc' || @page_info.dir.blank?
|
|
123
|
+
label += '▲'
|
|
124
|
+
dir = 'desc'
|
|
125
|
+
else
|
|
126
|
+
label += '▼'
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
@vc.link_to(label,
|
|
130
|
+
{
|
|
131
|
+
:controller => @params[:controller],
|
|
132
|
+
:action => 'page_info_save',
|
|
133
|
+
:id => @page_info.id,
|
|
134
|
+
'edgarj_page_info[order_by]' => fullname(col),
|
|
135
|
+
'edgarj_page_info[dir]' => dir
|
|
136
|
+
}.merge(options),
|
|
137
|
+
:remote => true,
|
|
138
|
+
:method => :put)
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# draw list column header for both usual list and popup list
|
|
142
|
+
def draw_list_column_header(col, options={})
|
|
143
|
+
parent = @model.belongs_to_AR(col)
|
|
144
|
+
if parent then
|
|
145
|
+
@vc.draw_belongs_to_label_sub(@model, col.name, parent)
|
|
146
|
+
else
|
|
147
|
+
draw_sort(col, options)
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def list_drawer_class
|
|
152
|
+
Edgarj::ListDrawer::Normal
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def draw_list(list)
|
|
156
|
+
line_color = 1
|
|
157
|
+
d = list_drawer_class.new(
|
|
158
|
+
self,
|
|
159
|
+
@options[:list_drawer_options] || {})
|
|
160
|
+
|
|
161
|
+
@vc.content_tag(:table, width: '100%', class: 'list') do
|
|
162
|
+
@vc.content_tag(:tr) do
|
|
163
|
+
''.html_safe.tap do |result|
|
|
164
|
+
for col in columns_for(list_columns) do
|
|
165
|
+
result << @vc.content_tag(:th) do
|
|
166
|
+
draw_list_column_header(col)
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
end +
|
|
171
|
+
''.html_safe.tap do |trs|
|
|
172
|
+
for rec in list do
|
|
173
|
+
line_color = 1 - line_color
|
|
174
|
+
d.set_path(rec)
|
|
175
|
+
trs << @vc.content_tag(:tr, class: "list_line#{line_color}") do
|
|
176
|
+
''.html_safe.tap do |cols|
|
|
177
|
+
for col in columns_for(list_columns) do
|
|
178
|
+
cols << d.draw_column(rec, col)
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
# return table_name + col.name
|
|
188
|
+
def fullname(col)
|
|
189
|
+
@model.table_name + '.' + col.name
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
def form_drawer_class
|
|
193
|
+
Edgarj::FormDrawer::Base
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def draw_form(record)
|
|
197
|
+
url_hash = {
|
|
198
|
+
controller: @params[:controller],
|
|
199
|
+
action: record.new_record? ? 'create' : 'update',
|
|
200
|
+
}
|
|
201
|
+
url_hash[:id] = record.id if record.persisted?
|
|
202
|
+
@vc.form_for(record,
|
|
203
|
+
remote: true,
|
|
204
|
+
url: url_hash,
|
|
205
|
+
html: {
|
|
206
|
+
id: '_edgarj_form',
|
|
207
|
+
method: record.new_record? ? 'post' : 'put',
|
|
208
|
+
multipart: true,
|
|
209
|
+
#target: 'edgarj_form_frame'
|
|
210
|
+
}) do |f|
|
|
211
|
+
form_drawer_class.new(self, record, f).draw() +
|
|
212
|
+
|
|
213
|
+
# to avoid submit on 1-textfield form when hit [ENTER] key
|
|
214
|
+
'<input type="text" name="dummy" style="visibility:hidden" size=0>'.html_safe
|
|
215
|
+
end +
|
|
216
|
+
@vc.draw_form_buttons(@options[:draw_form_options] || {})
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
# return array of model columns (ActiveRecord::ConnectionAdapters::X_Column type).
|
|
220
|
+
#
|
|
221
|
+
# === INPUTS
|
|
222
|
+
# column_name_list:: column name list
|
|
223
|
+
def columns_for(column_name_list)
|
|
224
|
+
[].tap do |result|
|
|
225
|
+
for col_name in column_name_list do
|
|
226
|
+
if (col = @model.columns_hash[col_name])
|
|
227
|
+
result << col
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module Edgarj
|
|
2
|
+
module Drawer
|
|
3
|
+
# PopupDrawer is the same as Drawer to draw 'belongs_to' model
|
|
4
|
+
# to popup window.
|
|
5
|
+
#
|
|
6
|
+
# For example, AuthorPopupDrawer is to draw Author popup,
|
|
7
|
+
# which is called from Book page.
|
|
8
|
+
#
|
|
9
|
+
# * options
|
|
10
|
+
# * list_drawer_options - options for Edgarj::ListDrawer::Normal
|
|
11
|
+
class Popup < Base
|
|
12
|
+
def draw_list(list)
|
|
13
|
+
line_color = 1
|
|
14
|
+
d = Edgarj::ListDrawer::Normal.new(
|
|
15
|
+
self,
|
|
16
|
+
@options[:list_drawer_options] || {})
|
|
17
|
+
|
|
18
|
+
@vc.content_tag(:table, width: '100%', class: 'list') do
|
|
19
|
+
@vc.content_tag(:tr) do
|
|
20
|
+
''.html_safe.tap do |result|
|
|
21
|
+
for col in columns_for(list_columns) do
|
|
22
|
+
result << @vc.content_tag(:th) do
|
|
23
|
+
draw_list_column_header(col, id_target: @params[:id_target])
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end +
|
|
28
|
+
''.html_safe.tap do |trs|
|
|
29
|
+
for rec in list do
|
|
30
|
+
line_color = 1 - line_color
|
|
31
|
+
d.set_path(rec)
|
|
32
|
+
trs << @vc.content_tag(:tr,
|
|
33
|
+
class: "list_line#{line_color} edgarj_popup_list_row",
|
|
34
|
+
data: {id: rec.id, name: rec.name}) do
|
|
35
|
+
''.html_safe.tap do |cols|
|
|
36
|
+
for col in columns_for(list_columns) do
|
|
37
|
+
cols << d.draw_column(rec, col)
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
module Edgarj
|
|
2
|
+
# Drawer is a 'presentor' and it is similar to decorator (like Draper),
|
|
3
|
+
# but this simply connects model to view in order to have view-related
|
|
4
|
+
# information for the model (or, to isolate view-related information
|
|
5
|
+
# from the model), while decorator inherits both model and
|
|
6
|
+
# view.
|
|
7
|
+
module Drawer
|
|
8
|
+
end
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
require 'edgarj/drawer/base'
|
|
12
|
+
require 'edgarj/drawer/normal'
|
|
13
|
+
require 'edgarj/drawer/popup'
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Model-wide CRUD permission for role. In other words,
|
|
2
|
+
# CRUD permission for each model for each role is defined by this.
|
|
3
|
+
#
|
|
4
|
+
# This permission is used for two purposes:
|
|
5
|
+
#
|
|
6
|
+
# 1. page access permission
|
|
7
|
+
# * If this object,which relates to a model by model-attribute, exists and
|
|
8
|
+
# user belongs to the role (= user-group), then the controller,
|
|
9
|
+
# which 'model_class' method returns the model, can be accessed.
|
|
10
|
+
# 1. popup access permission
|
|
11
|
+
# * Popup access for a model-class is an read-permission for that.
|
|
12
|
+
#
|
|
13
|
+
# Example:
|
|
14
|
+
# 1. User 'u' belongs to 'x-role' Edgarj::UserGroup.
|
|
15
|
+
# 1. x-role has author model permission.
|
|
16
|
+
# 1. User 'u' can access AuthorController page.
|
|
17
|
+
# 1. If x-role has READ permission on author model, then
|
|
18
|
+
# user 'u' can see author-popup on any 'belongs_to' related page
|
|
19
|
+
# (e.g. BookController book form's author-popup).
|
|
20
|
+
module Edgarj
|
|
21
|
+
class ModelPermission < ActiveRecord::Base
|
|
22
|
+
self.table_name = 'edgarj_model_permissions'
|
|
23
|
+
belongs_to :user_group
|
|
24
|
+
|
|
25
|
+
# define bitset on 'flags' column
|
|
26
|
+
module FlagsBitset
|
|
27
|
+
CREATE = 0x01
|
|
28
|
+
READ = 0x02
|
|
29
|
+
UPDATE = 0x04
|
|
30
|
+
DELETE = 0x08
|
|
31
|
+
end
|
|
32
|
+
FLAGS_ALL = FlagsBitset.constants.inject(0){|sum, flag|
|
|
33
|
+
sum += FlagsBitset.const_get(flag)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
# return true if *ALL* requested flags are included in flags
|
|
37
|
+
def permitted?(requested_flags)
|
|
38
|
+
(self.flags & requested_flags) == requested_flags
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module Edgarj
|
|
2
|
+
class PageInfo < ActiveRecord::Base
|
|
3
|
+
self.table_name = 'edgarj_page_infos'
|
|
4
|
+
|
|
5
|
+
belongs_to :sssn
|
|
6
|
+
|
|
7
|
+
def self.intern(sssn, view, search_obj)
|
|
8
|
+
if !sssn || !(page_info = sssn.page_infos.find_by_view(view))
|
|
9
|
+
page_info = sssn.page_infos.build(
|
|
10
|
+
view: view,
|
|
11
|
+
lines: 10,
|
|
12
|
+
order_by: '',
|
|
13
|
+
dir: '',
|
|
14
|
+
page: 1)
|
|
15
|
+
page_info.record = search_obj
|
|
16
|
+
|
|
17
|
+
# save it to get id since id will be used later e.g.
|
|
18
|
+
# @vs.link_to(... @page_info.id) in Edgarj::Drawer::Base#draw_sort
|
|
19
|
+
page_info.save!
|
|
20
|
+
end
|
|
21
|
+
page_info
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# serialize model and set it to model_data
|
|
25
|
+
#
|
|
26
|
+
def record=(record)
|
|
27
|
+
self.record_data = Base64.encode64(Marshal.dump(record))
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# de-serialize in model_data and return it
|
|
31
|
+
#
|
|
32
|
+
def record
|
|
33
|
+
if self.record_data
|
|
34
|
+
# FIXME: Following code fixes the error:
|
|
35
|
+
# - ArgumentError (undefined class/module Search)
|
|
36
|
+
# - ArgumentError (undefined class/module SearchForm)
|
|
37
|
+
#
|
|
38
|
+
# But some autoload may smartlier fixes this?
|
|
39
|
+
Search
|
|
40
|
+
SearchForm
|
|
41
|
+
Marshal.load(Base64.decode64(self.record_data))
|
|
42
|
+
else
|
|
43
|
+
nil
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
module Edgarj
|
|
2
|
+
# Search condition
|
|
3
|
+
#
|
|
4
|
+
# Abstract class to SearchForm and SearchPopup to provide common method
|
|
5
|
+
# 'conditions'.
|
|
6
|
+
#
|
|
7
|
+
# 'Search' instance will be stored in view_status.model.
|
|
8
|
+
#
|
|
9
|
+
# \@errors will be used for error_messages_for helper in search-form.
|
|
10
|
+
class Search
|
|
11
|
+
# required at 'form_for' helper
|
|
12
|
+
extend ActiveModel::Naming
|
|
13
|
+
extend ActiveModel::Conversion
|
|
14
|
+
# include ActiveModel::Conversion ??
|
|
15
|
+
include ActiveModel::Validations
|
|
16
|
+
|
|
17
|
+
# to support 'human_attribute_name'
|
|
18
|
+
extend ActiveModel::Translation
|
|
19
|
+
|
|
20
|
+
# cache the map: column name -> column type
|
|
21
|
+
#
|
|
22
|
+
# SearchForm instance is serialized to be stored at session so that
|
|
23
|
+
# another class (=Cache) is introduced to store cache information.
|
|
24
|
+
class Cache
|
|
25
|
+
include Singleton
|
|
26
|
+
|
|
27
|
+
attr_accessor :klass_hash, :hit, :miss
|
|
28
|
+
|
|
29
|
+
def initialize
|
|
30
|
+
@klass_hash = {}
|
|
31
|
+
|
|
32
|
+
# for cache statistics
|
|
33
|
+
@hit = 0
|
|
34
|
+
@miss = 0
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# report hit rate
|
|
38
|
+
def klass_hash_report
|
|
39
|
+
sprintf("%d/%d", @hit, @hit + @miss)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
attr_accessor :errors, :_klass_str
|
|
44
|
+
|
|
45
|
+
def initialize(klass)
|
|
46
|
+
@errors = ActiveModel::Errors.new(self)
|
|
47
|
+
@_klass_str = klass.to_s
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# generate search-conditions from ActiveRecord attributes
|
|
51
|
+
#
|
|
52
|
+
# === RETURN
|
|
53
|
+
# [condition_string, value_array]:: values for :conditions option on model
|
|
54
|
+
def conditions
|
|
55
|
+
raise "Not implemented"
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def persisted?
|
|
59
|
+
false
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
private
|
|
63
|
+
# cache column type
|
|
64
|
+
def column_type(col_name)
|
|
65
|
+
cache = Cache.instance
|
|
66
|
+
cache.klass_hash[@_klass_str] ||= {}
|
|
67
|
+
if v = cache.klass_hash[@_klass_str][col_name.to_s]
|
|
68
|
+
cache.hit += 1
|
|
69
|
+
v
|
|
70
|
+
else
|
|
71
|
+
cache.miss += 1
|
|
72
|
+
col = @_klass_str.constantize.columns.find{|c|
|
|
73
|
+
c.name == col_name.to_s
|
|
74
|
+
}
|
|
75
|
+
if col
|
|
76
|
+
cache.klass_hash[@_klass_str][col_name.to_s] = col.type
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|