edgarj 0.01.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (185) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.rdoc +23 -0
  4. data/Rakefile +40 -0
  5. data/app/assets/javascripts/edgarj/base.js +49 -0
  6. data/app/assets/javascripts/edgarj/menu.js +39 -0
  7. data/app/assets/javascripts/edgarj/operator_selection.js +133 -0
  8. data/app/assets/stylesheets/edgarj/base.css +304 -0
  9. data/app/assets/stylesheets/edgarj/menu.css +65 -0
  10. data/app/controllers/edgarj/authentication_mixin.rb.sample +30 -0
  11. data/app/controllers/edgarj/controller_mixin_common.rb +80 -0
  12. data/app/controllers/edgarj/controller_mixin_for_app.rb +71 -0
  13. data/app/controllers/edgarj/edgarj_controller.rb +535 -0
  14. data/app/controllers/edgarj/model_permissions_controller.rb +8 -0
  15. data/app/controllers/edgarj/permission_mixin.rb +84 -0
  16. data/app/controllers/edgarj/popup_controller.rb +128 -0
  17. data/app/controllers/edgarj/rescue_mixin.rb +37 -0
  18. data/app/controllers/edgarj/user_group_users_controller.rb +8 -0
  19. data/app/controllers/edgarj/user_groups_controller.rb +9 -0
  20. data/app/controllers/edgarj/user_groups_popup_controller.rb +8 -0
  21. data/app/helpers/edgarj/assoc_helper.rb +369 -0
  22. data/app/helpers/edgarj/common_helper.rb +37 -0
  23. data/app/helpers/edgarj/edgarj_helper.rb +20 -0
  24. data/app/helpers/edgarj/field_helper.rb +397 -0
  25. data/app/helpers/edgarj/form_drawer.rb +322 -0
  26. data/app/helpers/edgarj/list_drawer.rb +169 -0
  27. data/app/helpers/edgarj/menu_helper.rb +92 -0
  28. data/app/helpers/edgarj/model_permissions_helper.rb +9 -0
  29. data/app/helpers/edgarj/popup_helper.rb +40 -0
  30. data/app/helpers/edgarj/search_helper.rb +14 -0
  31. data/app/helpers/edgarj/sessions_helper.rb +9 -0
  32. data/app/helpers/edgarj/user_group_users_helper.rb +9 -0
  33. data/app/helpers/edgarj/user_groups_helper.rb +9 -0
  34. data/app/helpers/edgarj/user_groups_popup_helper.rb +9 -0
  35. data/app/models/edgarj/drawer/base.rb +234 -0
  36. data/app/models/edgarj/drawer/normal.rb +6 -0
  37. data/app/models/edgarj/drawer/popup.rb +47 -0
  38. data/app/models/edgarj/drawer.rb +13 -0
  39. data/app/models/edgarj/model_permission.rb +41 -0
  40. data/app/models/edgarj/page_info.rb +47 -0
  41. data/app/models/edgarj/search.rb +81 -0
  42. data/app/models/edgarj/search_form.rb +255 -0
  43. data/app/models/edgarj/search_popup.rb +44 -0
  44. data/app/models/edgarj/sssn.rb +120 -0
  45. data/app/models/edgarj/user_group.rb +67 -0
  46. data/app/models/edgarj/user_group_user.rb +18 -0
  47. data/app/models/edgarj.rb +5 -0
  48. data/app/views/edgarj/edgarj/_form.html.erb +25 -0
  49. data/app/views/edgarj/edgarj/_list.html.erb +52 -0
  50. data/app/views/edgarj/edgarj/_message_popup.html.erb +15 -0
  51. data/app/views/edgarj/edgarj/_search_form.html.erb +64 -0
  52. data/app/views/edgarj/edgarj/_search_operator.html.erb +17 -0
  53. data/app/views/edgarj/edgarj/_search_operator_selection.html.erb +12 -0
  54. data/app/views/edgarj/edgarj/clear.js.erb +1 -0
  55. data/app/views/edgarj/edgarj/create.js.erb +4 -0
  56. data/app/views/edgarj/edgarj/destroy.js.erb +2 -0
  57. data/app/views/edgarj/edgarj/index.html.erb +37 -0
  58. data/app/views/edgarj/edgarj/index.js.erb +1 -0
  59. data/app/views/edgarj/edgarj/message_popup.js.erb +3 -0
  60. data/app/views/edgarj/edgarj/page_info_save.js.erb +1 -0
  61. data/app/views/edgarj/edgarj/search.js.erb +4 -0
  62. data/app/views/edgarj/edgarj/search_clear.js.erb +1 -0
  63. data/app/views/edgarj/edgarj/show.js.erb +1 -0
  64. data/app/views/edgarj/edgarj/top.html.erb +4 -0
  65. data/app/views/edgarj/edgarj/update.js.erb +4 -0
  66. data/app/views/edgarj/popup/_index.html.erb +16 -0
  67. data/app/views/edgarj/popup/_list.html.erb +42 -0
  68. data/app/views/edgarj/popup/_message_popup.html.erb +15 -0
  69. data/app/views/edgarj/popup/_search.html.erb +42 -0
  70. data/app/views/edgarj/popup/_search_save_popup.html.erb +16 -0
  71. data/app/views/edgarj/popup/index.js.erb +5 -0
  72. data/app/views/edgarj/popup/message_popup.js.erb +3 -0
  73. data/app/views/edgarj/popup/page_info_save.js.erb +1 -0
  74. data/app/views/edgarj/popup/search.js.erb +15 -0
  75. data/app/views/edgarj/popup/view_status_save.js.erb +1 -0
  76. data/config/routes.rb +15 -0
  77. data/config/settings.yml +5 -0
  78. data/db/migrate/20131118084600_create_edgar_sssns.rb +14 -0
  79. data/db/migrate/20131123124730_create_edgar_page_infos.rb +15 -0
  80. data/db/migrate/20140116062252_create_edgar_user_groups.rb +18 -0
  81. data/db/migrate/20140116062327_create_edgar_user_group_users.rb +10 -0
  82. data/db/migrate/20140206222308_create_edgar_model_permissions.rb +14 -0
  83. data/db/migrate/20141209053055_rename_edgar_to_edgarj.rb +17 -0
  84. data/lib/core_ext/active_record.rb +123 -0
  85. data/lib/core_ext/resources.rb +71 -0
  86. data/lib/edgarj/engine.rb +64 -0
  87. data/lib/edgarj/enum_cache.rb +46 -0
  88. data/lib/edgarj/templates/rails/helper/helper.rb +10 -0
  89. data/lib/edgarj/templates/test_unit/scaffold/functional_test.rb +575 -0
  90. data/lib/edgarj/version.rb +3 -0
  91. data/lib/edgarj.rb +14 -0
  92. data/lib/generators/edgarj/popup_scaffold/USAGE +6 -0
  93. data/lib/generators/edgarj/popup_scaffold/popup_scaffold_generator.rb +35 -0
  94. data/lib/generators/edgarj/popup_scaffold/templates/controller.rb +13 -0
  95. data/lib/generators/edgarj/popup_scaffold/templates/functional_test.rb +197 -0
  96. data/lib/generators/edgarj/popup_scaffold/templates/helper.rb +9 -0
  97. data/lib/generators/edgarj/scaffold/USAGE +17 -0
  98. data/lib/generators/edgarj/scaffold/scaffold_generator.rb +40 -0
  99. data/lib/generators/edgarj/scaffold/templates/controller.rb +13 -0
  100. data/lib/tasks/edgarj_tasks.rake +32 -0
  101. data/lib/tasks/pakcage.rake +18 -0
  102. data/locale/en.yml +94 -0
  103. data/locale/ja.yml +100 -0
  104. data/test/dummy/README.rdoc +28 -0
  105. data/test/dummy/Rakefile +6 -0
  106. data/test/dummy/app/assets/javascripts/application.js +21 -0
  107. data/test/dummy/app/assets/javascripts/authors.js +2 -0
  108. data/test/dummy/app/assets/stylesheets/application.css +16 -0
  109. data/test/dummy/app/assets/stylesheets/authors.css +4 -0
  110. data/test/dummy/app/assets/stylesheets/scaffold.css +56 -0
  111. data/test/dummy/app/controllers/application_controller.rb +15 -0
  112. data/test/dummy/app/controllers/authors_controller.rb +6 -0
  113. data/test/dummy/app/controllers/authors_popup_controller.rb +6 -0
  114. data/test/dummy/app/controllers/books_controller.rb +6 -0
  115. data/test/dummy/app/controllers/dummy_auth_mixin.rb +36 -0
  116. data/test/dummy/app/decorators/models/edgarj/user_group_decorator.rb +1 -0
  117. data/test/dummy/app/helpers/application_helper.rb +3 -0
  118. data/test/dummy/app/helpers/authors_helper.rb +7 -0
  119. data/test/dummy/app/helpers/authors_popup_helper.rb +7 -0
  120. data/test/dummy/app/helpers/books_helper.rb +7 -0
  121. data/test/dummy/app/models/author.rb +32 -0
  122. data/test/dummy/app/models/book.rb +5 -0
  123. data/test/dummy/app/models/user.rb +13 -0
  124. data/test/dummy/app/views/layouts/application.html.erb +32 -0
  125. data/test/dummy/app/views/layouts/login.html.erb +20 -0
  126. data/test/dummy/bin/bundle +3 -0
  127. data/test/dummy/bin/rails +4 -0
  128. data/test/dummy/bin/rake +4 -0
  129. data/test/dummy/config/application.rb +59 -0
  130. data/test/dummy/config/boot.rb +10 -0
  131. data/test/dummy/config/database.yml +15 -0
  132. data/test/dummy/config/edgarj/menu_config.rb +28 -0
  133. data/test/dummy/config/environment.rb +5 -0
  134. data/test/dummy/config/environments/development.rb +42 -0
  135. data/test/dummy/config/environments/production.rb +79 -0
  136. data/test/dummy/config/environments/test.rb +34 -0
  137. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  138. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  139. data/test/dummy/config/initializers/inflections.rb +16 -0
  140. data/test/dummy/config/initializers/mime_types.rb +5 -0
  141. data/test/dummy/config/initializers/secret_token.rb +12 -0
  142. data/test/dummy/config/initializers/session_store.rb +3 -0
  143. data/test/dummy/config/initializers/strong_parameter.rb +3 -0
  144. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  145. data/test/dummy/config/locales/en.yml +26 -0
  146. data/test/dummy/config/routes.rb +60 -0
  147. data/test/dummy/config.ru +4 -0
  148. data/test/dummy/db/migrate/20131107120635_create_authors.rb +9 -0
  149. data/test/dummy/db/migrate/20131218011851_create_books.rb +10 -0
  150. data/test/dummy/db/migrate/20140201000000_add_user_group_id_to_authors.rb +5 -0
  151. data/test/dummy/db/migrate/20140807065420_create_users.rb +10 -0
  152. data/test/dummy/db/schema.rb +93 -0
  153. data/test/dummy/public/404.html +58 -0
  154. data/test/dummy/public/422.html +58 -0
  155. data/test/dummy/public/500.html +57 -0
  156. data/test/dummy/public/favicon.ico +0 -0
  157. data/test/dummy/script/rails +6 -0
  158. data/test/dummy/test/functional/authors_controller_test.rb +631 -0
  159. data/test/dummy/test/functional/books_controller_test.rb +516 -0
  160. data/test/dummy/test/helpers/authors_helper_test.rb +4 -0
  161. data/test/dummy/test/unit/author_test.rb +7 -0
  162. data/test/dummy/test/unit/book_test.rb +7 -0
  163. data/test/edgar_test.rb +7 -0
  164. data/test/fixtures/authors.yml +32 -0
  165. data/test/fixtures/books.yml +56 -0
  166. data/test/fixtures/edgarj/model_permissions.yml +97 -0
  167. data/test/fixtures/edgarj/page_infos.yml +84 -0
  168. data/test/fixtures/edgarj/sssns.yml +38 -0
  169. data/test/fixtures/edgarj/user_group_users.yml +114 -0
  170. data/test/fixtures/edgarj/user_groups.yml +95 -0
  171. data/test/fixtures/users.yml +49 -0
  172. data/test/functional/edgarj/edgarj_controller_test.rb +24 -0
  173. data/test/functional/edgarj/model_permissions_controller_test.rb +554 -0
  174. data/test/functional/edgarj/user_group_users_controller_test.rb +567 -0
  175. data/test/integration/navigation_test.rb +10 -0
  176. data/test/support/edgarj/controller_supporter.rb +23 -0
  177. data/test/test_helper.rb +23 -0
  178. data/test/unit/edgarj/model_permission_test.rb +27 -0
  179. data/test/unit/edgarj/page_info_test.rb +7 -0
  180. data/test/unit/edgarj/sssn_test.rb +10 -0
  181. data/test/unit/edgarj/user_group_test.rb +32 -0
  182. data/test/unit/edgarj/user_group_user_test.rb +9 -0
  183. data/test/unit/helpers/edgarj/model_permissions_helper_test.rb +6 -0
  184. data/test/unit/helpers/edgarj/user_group_users_helper_test.rb +6 -0
  185. metadata +456 -0
@@ -0,0 +1,128 @@
1
+ # Modal popup controller module to pick-up 'belongs_to' record
2
+ #
3
+ # == Requrements for popup
4
+ # 1. Multiple 'belongs_to' parents for one model
5
+ # 1. Easy customize as the same as EdgarjController
6
+ module Edgarj
7
+ class PopupController < ApplicationController
8
+ include ControllerMixinCommon
9
+ include Edgarj::PermissionMixin
10
+
11
+ helper_method :model, :popup_drawer
12
+ before_filter :require_read_permission
13
+
14
+ # draw popup windows
15
+ #
16
+ # === INPUTS
17
+ # params[:id_target]:: id target DOM on click entry of popup
18
+ # params[:page]:: on paginate
19
+ #
20
+ # === Paginate logic
21
+ # - params[:page] exists -> save it to @page_info and use it
22
+ # - params[:page] doesn't exist -> use @page_info.page
23
+ #
24
+ # === call flow
25
+ # ==== draw popup
26
+ # EdgarjHelper.draw_belongs_to_label() is called. Example:
27
+ # <a href='http://.../edgarj_popup?...' data-remote=true>Author</a>
28
+ # <input type=hidden name='book[author_id]'>
29
+ # <span id='popup_target_book_author'>...</span>
30
+ # :
31
+ #
32
+ # ==== on opening popup
33
+ # 1. edgarj_popup URL http://.../edgarj_popup?... is executed.
34
+ # 1. EdgarjPopupController.index() is called.
35
+ # 1. data is searched based on @page_info and user_scoped and
36
+ # set it to \@list.
37
+ # 1. app/views/edgarj_popup/index.js.erb
38
+ # 1. $('#edgarj_form_popup') dialog is opened.
39
+ #
40
+ # ==== on paginate
41
+ # Same as above('on opening popup'), but page=N parameter is added.
42
+ #
43
+ # ==== on search
44
+ # 1. post search condition to EdgarjPopupController.search().
45
+ #
46
+ # ==== on clicking entry on the popup
47
+ # TBD
48
+ def index
49
+ page_info
50
+ @page_info.page = (params[:page] || 1)
51
+ prepare_list
52
+ @search = page_info.record
53
+ end
54
+
55
+ # Ajax method to execute search
56
+ #
57
+ # Actually, this saves condition for later use.
58
+ # Execution of search could be done at 'index' method, but
59
+ # do it in this action to avoid 'POST' redirect issue(
60
+ # POST method redirect resulted in 'POST index', not 'GET index').
61
+ #
62
+ # === INPUTS
63
+ # params[:id_target]:: id target DOM on click entry of popup
64
+ # params[:edgarj_search_form]:: search condition
65
+ def search
66
+ page_info
67
+ @page_info.record = SearchPopup.new(model, params[:edgarj_search_form])
68
+ @page_info.update_attribute(:page, 1)
69
+ @search = @page_info.record
70
+ prepare_list if @search.valid?
71
+ end
72
+
73
+ private
74
+ # # derive model class from this controller.
75
+ #
76
+ # If controller cannot guess model class, overwrite this.
77
+ #
78
+ # === Examples:
79
+ # * PopupAuthorsController -> Author
80
+ def model
81
+ @_model ||=
82
+ if self.class.name =~ /^(.+)PopupController$/
83
+ $1.singularize.constantize
84
+ else
85
+ raise 'Cannot guess popup model from controller'
86
+ end
87
+ end
88
+
89
+ # return search-form object.
90
+ #
91
+ # called from page_info
92
+ def search_form
93
+ SearchPopup.new(model)
94
+ end
95
+
96
+ # drawer class of this controller.
97
+ #
98
+ # Derived popup controller should implement this method.
99
+ #
100
+ # === Examples:
101
+ # * AuthorsController -> AuthorPopupHelper::AuthorPopupDrawer
102
+ def drawer_class
103
+ raise 'Derived popup controller class should implement'
104
+ end
105
+
106
+ # set drawer instance as drawer for later use on rendering view
107
+ def set_popup_drawer
108
+ @popup_drawer = drawer_class.new(view_context, params, page_info)
109
+ end
110
+
111
+ def popup_drawer
112
+ @popup_drawer
113
+ end
114
+
115
+ # This works as:
116
+ #
117
+ # before_render :set_popup_drawer
118
+ #
119
+ # to set drawer just before rendering.
120
+ #
121
+ # See http://stackoverflow.com/questions/9281224/filter-to-execute-before-render-but-after-controller
122
+ def render(*args)
123
+ # set_drawer should be called only when finishing before_filters.
124
+ set_popup_drawer if current_user
125
+ super
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,37 @@
1
+ # rescue part for EdgarjController (or ApplicationController) and
2
+ # EdgarjPopupController
3
+ #
4
+ module Edgarj
5
+ module RescueMixin
6
+ private
7
+
8
+ # rescue callback sub method to show message by flush on normal http request
9
+ # or by popup-dialog on Ajax request.
10
+ def edgarj_rescue_sub(ex, message)
11
+ logger.info(
12
+ "#{ex.class} #{ex.message} bactrace:\n " +
13
+ ex.backtrace.join("\n "))
14
+
15
+ respond_to do |format|
16
+ format.html {
17
+ flash[:error] = message
18
+ redirect_to top_path
19
+ }
20
+ format.js {
21
+ flash.now[:error] = message
22
+ render 'message_popup'
23
+ }
24
+ end
25
+ end
26
+
27
+ # rescue callback for 404
28
+ def edgarj_rescue_404(ex)
29
+ edgarj_rescue_sub(ex, v('not_found'))
30
+ end
31
+
32
+ # rescue callback
33
+ def edgarj_rescue_app_error(ex)
34
+ edgarj_rescue_sub(ex, ex.message)
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,8 @@
1
+ module Edgarj
2
+ class UserGroupUsersController < Edgarj::EdgarjController
3
+ private
4
+ def drawer_class
5
+ UserGroupUsersHelper::UserGroupUserDrawer
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ module Edgarj
2
+ class UserGroupsController < Edgarj::EdgarjController
3
+ private
4
+ def drawer_class
5
+ UserGroupsHelper::UserGroupDrawer
6
+ end
7
+ end
8
+ end
9
+
@@ -0,0 +1,8 @@
1
+ module Edgarj
2
+ class UserGroupsPopupController < Edgarj::PopupController
3
+ private
4
+ def drawer_class
5
+ UserGroupsPopupHelper::UserGroupPopupDrawer
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,369 @@
1
+ module Edgarj
2
+ module AssocHelper
3
+ =begin
4
+ # remote_function + spinner
5
+ def edgarj_remote_function(url, method='get')
6
+ "Edgarj._simple_ajax('#{j(url_for(url))}', '#{method}')"
7
+ end
8
+
9
+ # form_for which supports Ajax-like file upload.
10
+ #
11
+ # In order to support Ajax-like file upload, use
12
+ # form-target-iframe-responds_to_parent mechanism.
13
+ def edgarj_form(&block)
14
+ url_hash = {
15
+ controller: params[:controller],
16
+ action: @model.new_record? ? 'create' : 'update',
17
+ format: :js
18
+ }
19
+ url_hash[:id] = @model.id if @model.persisted?
20
+ form_for(@model,
21
+ remote: true,
22
+ url: url_hash,
23
+ html: {
24
+ id: '_edgarj_form',
25
+ method: @model.new_record? ? 'post' : 'put',
26
+ multipart: true,
27
+ #target: 'edgarj_form_frame'
28
+ }, &block)
29
+ end
30
+
31
+ # According to http://khamsouk.souvanlasy.com/articles/ajax_file_uploads_in_rails
32
+ # 'display:none' style should *NOT* used:
33
+ def iframe_for_edgarj_form
34
+ %Q(<iframe id=edgarj_form_frame name=edgarj_form_frame
35
+ style='width:1px;height:1px;border:0px' src='about:blank'></iframe>
36
+ ).html_safe
37
+ end
38
+
39
+ # === INPUTS
40
+ # o:: operator form builder
41
+ # method:: column name
42
+ def draw_search_operator(o, method)
43
+ render '/edgarj/search_operator',
44
+ o: o,
45
+ method: method
46
+ end
47
+
48
+ # Edgarj standard datetime format
49
+ def datetime_fmt(dt)
50
+ if dt.blank? then
51
+ ''
52
+ else
53
+ I18n.l(dt, format: I18n.t('edgarj.time.format'))
54
+ end
55
+ end
56
+
57
+ # Edgarj standard date format
58
+ def date_fmt(dt)
59
+ if dt == nil then
60
+ ''
61
+ else
62
+ dt.strftime(I18n.t('date.formats.default'))
63
+ end
64
+ end
65
+
66
+ def draw_view_status_load_menu
67
+ content_tag(:div, :id=>'edgarj_load_condition_menu', :class=>'edgarj_menu') do
68
+ content_tag(:table) do
69
+ content_tag(:tr) do
70
+ if current_user.saved_view_statuss.count(:conditions=>['view=?', controller_name]) > 0
71
+ draw_menu_top_and_pulldown('saved_conditions', t('load_condition')) do
72
+ out = ""
73
+ for svc in current_user.saved_view_statuss.find_all_by_view(controller_name) do
74
+ out += edgarj_link_to_remote(
75
+ svc.name, {:action=>'search_load', :id=>svc.id})
76
+ end
77
+ out
78
+ end
79
+ else
80
+ # not to draw empty sub menu of 'saved_conditions'
81
+ ''
82
+ end +
83
+ content_tag(:td) do
84
+ link_to 'Help', url_for(:controller=>'/help',
85
+ :action=>'search.html'), {:target=>'help'}
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ # draw sort link on list column header
93
+ #
94
+ # === INPUTS
95
+ # col:: column data
96
+ # options:: options to url_for
97
+ def draw_sort(col, options={})
98
+ label = model_class.human_attribute_name(col.name)
99
+ dir = 'asc'
100
+ if @view_status.order_by == col.name
101
+ # toggle direction
102
+ if @view_status.dir == 'asc' || @view_status.dir.blank?
103
+ label += '▲'
104
+ dir = 'desc'
105
+ else
106
+ label += '▼'
107
+ end
108
+ end
109
+ link_to(label,
110
+ {
111
+ :controller => params[:controller],
112
+ :action => 'view_status_save',
113
+ :id => @view_status.id,
114
+ 'edgarj_view_status[order_by]' => col.name,
115
+ 'edgarj_view_status[dir]' => dir
116
+ }.merge(options),
117
+ :remote => true,
118
+ :method => :put)
119
+ end
120
+ =end
121
+
122
+ # 1. column I18n is used if defined
123
+ # 2. else, parent.human_name is used.
124
+ def draw_belongs_to_label_sub(model, col_name, parent_model)
125
+ I18n.t(col_name,
126
+ scope: "activerecord.attributes.#{model.to_s.underscore}",
127
+ default: parent_model.human_name)
128
+ end
129
+
130
+ =begin
131
+ # draw belongs_to name. When link=true(default), draw it as hyper-link
132
+ def draw_belongs_to(parent_obj, link=true)
133
+ if link
134
+ link_to( parent_obj.name,
135
+ controller: '/' + parent_obj.class.name.underscore.pluralize,
136
+ action: 'show',
137
+ id: parent_obj.id)
138
+ else
139
+ h(parent_obj.name)
140
+ end
141
+ end
142
+ =end
143
+
144
+ # draw 'belongs_to' popup button(link) label. This is used at:
145
+ #
146
+ # * edgarj form for data entry
147
+ # * edgarj search form(Edgarj::SearchForm) for search-condition entry
148
+ #
149
+ # === INPUTS
150
+ # f:: FormBuilder object
151
+ # popup_path:: popup path(url)
152
+ # col_name:: 'belongs_to' column name
153
+ # model:: data model class
154
+ def draw_belongs_to_label(f, popup_path, col_name, model = f.object.class)
155
+ col = model.columns.detect{|c| c.name == col_name.to_s}
156
+ return "no column found" if !col
157
+
158
+ parent_model = model.belongs_to_AR(col)
159
+ return "parent_model is nil" if !parent_model
160
+
161
+ link_to(
162
+ draw_belongs_to_label_sub(model, col.name, parent_model),
163
+ popup_path,
164
+ remote: true)
165
+ end
166
+
167
+ # draw 'clear' link for 'belongs_to' popup data-entry field
168
+ #
169
+ # === INPUTS
170
+ # f:: FormBuilder object
171
+ # col_name:: 'belongs_to' column name
172
+ # popup_field:: Edgarj::PopupHelper::PopupField object
173
+ # parent_name:: initial parent name
174
+ def draw_belongs_to_clear_link(f, col_name, popup_field, parent_name)
175
+ ('&nbsp;&nbsp;' +
176
+ link_to("[#{I18n.t('edgarj.default.clear')}]", '#',
177
+ onClick: sprintf("Edgarj.Popup.clear('%s'); return false;",
178
+ popup_field.id_target),
179
+ id: popup_field.clear_link,
180
+ style: 'display:' + (parent_name.blank? ? 'none' : '')) +
181
+ f.hidden_field(col_name)).html_safe
182
+ end
183
+
184
+ # draw 'belongs_to' popup data-entry field
185
+ #
186
+ # This is usually used with draw_belongs_to_label().
187
+ #
188
+ # === INPUTS
189
+ # f:: FormBuilder object
190
+ # col_name:: 'belongs_to' column name
191
+ # model:: data model class
192
+ def draw_belongs_to_field(f, col_name, model = f.object.class)
193
+ col = model.columns.detect{|c| c.name == col_name.to_s}
194
+ return "no column found" if !col
195
+
196
+ parent_model = model.belongs_to_AR(col)
197
+ return "parent_model is nil" if !parent_model
198
+
199
+ parent_obj = f.object.belongs_to_AR(col)
200
+ popup_field = Edgarj::PopupHelper::PopupField.new_builder(
201
+ f.object_name, col_name)
202
+ label = sprintf("<span id='%s'>%s</span>",
203
+ popup_field.label_target,
204
+ parent_obj ? parent_obj.name : '').html_safe
205
+ if parent_obj
206
+ link_to(label,
207
+ # TODO: Hardcoded 'master' prefix should be fixed
208
+ controller: url_prefix + parent_obj.class.name.underscore.pluralize,
209
+ action: 'show',
210
+ id: parent_obj,
211
+ topic_path: 'add')
212
+ else
213
+ label
214
+ end +
215
+ draw_belongs_to_clear_link(f, col.name, popup_field, parent_obj && parent_obj.name)
216
+ end
217
+
218
+ # Is flag in column_value on?
219
+ def flag_on?(column_value, bitset, flag)
220
+ val = column_value || 0
221
+ (val & bitset.const_get(flag)) != 0
222
+ end
223
+
224
+ # get bitset Module.
225
+ #
226
+ # When ColBitset(camelized argument col name + 'Bitset') module exists,
227
+ # the ColBitset is assumed enum definition.
228
+ def get_bitset(model, col)
229
+ bitset_name = col.name.camelize + 'Bitset'
230
+ if model.const_defined?(bitset_name, false)
231
+ _module = model.const_get(bitset_name)
232
+ _module.is_a?(Module) ? _module : nil
233
+ else
234
+ nil
235
+ end
236
+ end
237
+
238
+ # draw bitset column in list.
239
+ #
240
+ # === INPUTS
241
+ # rec:: AR object
242
+ # col_or_sym:: column object returned by rec.class.columns
243
+ # bitset:: Module which contains bitset constants
244
+ #
245
+ # === SEE ALSO
246
+ # get_bitset():: get bitset definition
247
+ # draw_bitset():: draw bitste checkboxes field
248
+ # draw_column_enum():: draw bitset column in list
249
+ def draw_column_bitset(rec, col_or_sym, bitset)
250
+ turn_on_flags = []
251
+ value = rec.send(get_column_name(col_or_sym))
252
+ for flag in bitset.constants do
253
+ turn_on_flags << flag if flag_on?(value, bitset, flag)
254
+ end
255
+ turn_on_flags.map{|f| rec.class.human_const_name(bitset, f) }.join(' ')
256
+ end
257
+
258
+ # get enum Module.
259
+ #
260
+ # When Col(camelized argument col name) module exists, the Col is
261
+ # assumed enum definition.
262
+ def get_enum(model, col)
263
+ col_name = col.name
264
+ if model.const_defined?(col_name.camelize, false)
265
+ enum = model.const_get(col_name.camelize)
266
+ enum.is_a?(Module) ? enum : nil
267
+ else
268
+ nil
269
+ end
270
+ end
271
+
272
+ # draw enum column in list.
273
+ #
274
+ # When enum for col is defined, constant string (rather than rec.col value)
275
+ # is drawn. See get_enum() for more detail of enum for the col.
276
+ #
277
+ # === EXAMPLE
278
+ # Question has status attribute and Question::Status enum.
279
+ # When question.status == 300,
280
+ # draw_column_enum(question, status_col, Question::Status) returns
281
+ # I18n.t('WORKING').
282
+ #
283
+ # Where:
284
+ # * question is Question AR object.
285
+ # * status_col is one of Question.columns object for status column.
286
+ #
287
+ # === INPUTS
288
+ # rec:: AR object
289
+ # col_or_sym:: column object returned by rec.class.columns
290
+ # enum:: Module which contains constants
291
+ #
292
+ # === SEE ALSO
293
+ # get_enum():: get enum definition
294
+ # draw_enum():: draw enum selection field
295
+ # draw_column_bitset():: draw bitset column in list
296
+ #
297
+ def draw_column_enum(rec, col_or_sym, enum)
298
+ Edgarj::EnumCache.instance.label(rec, get_column_name(col_or_sym), enum)
299
+ end
300
+
301
+ # return address element string or ''
302
+ def adrs_str_sub(model, prefix, element)
303
+ e = model.send(prefix + element)
304
+ e.blank? ? '' : e
305
+ end
306
+
307
+ # model & adrs_prefix -> address string
308
+ def adrs_str(model, adrs_prefix)
309
+ result = ''
310
+ for adrs_element in ['prefecture', 'city', 'other', 'bldg'] do
311
+ result << adrs_str_sub(model, adrs_prefix, adrs_element)
312
+ end
313
+ result
314
+ end
315
+
316
+ # return true if login user has enough permission on current controller.
317
+ def permitted?(requested_flags = 0)
318
+ current_user_roles.any?{|ug| ug.admin?} ||
319
+ current_model_permissions.any?{|cp| cp.permitted?(requested_flags)}
320
+ end
321
+
322
+ # return true if login user has any permission on the controller.
323
+ def permitted_on?(controller)
324
+ true # TBD
325
+ end
326
+
327
+ # Visit @list and generate csv
328
+ class CsvVisitor
329
+ # === INPUTS
330
+ # t:: template object
331
+ def initialize(t)
332
+ @t = t
333
+ end
334
+
335
+ def visit_column(rec, col)
336
+ val = rec.send(col.name)
337
+ case col.type
338
+ when :date
339
+ @t.date_fmt(val)
340
+ when :datetime
341
+ @t.datetime_fmt(val)
342
+ else
343
+ rec.send(col.name)
344
+ end
345
+ end
346
+ end
347
+
348
+ private
349
+ def top_menu_td(id, name)
350
+ content_tag(:td,
351
+ :id => id,
352
+ :onMouseOver => "Edgarj.Menu.show('#{id}')",
353
+ :onMouseOut => "Edgarj.Menu.hide('#{id}')") do
354
+
355
+ content_tag(:a, name, :href=>'#') + yield
356
+ end
357
+ end
358
+
359
+ # Provide consistency between <td> tag id and its sub contents <div> id.
360
+ # This concistency is required for javascript pull-down action.
361
+ def draw_menu_top_and_pulldown(id, name)
362
+ top_menu_td(id, name) do
363
+ content_tag(:div, :class=>'submenu', :id=>"sub#{id}") do
364
+ yield
365
+ end
366
+ end
367
+ end
368
+ end
369
+ end
@@ -0,0 +1,37 @@
1
+ # coding: UTF-8
2
+
3
+ module Edgarj
4
+ module CommonHelper
5
+ # Edgarj standard datetime format
6
+ def datetime_fmt(dt)
7
+ if dt.blank? then
8
+ ''
9
+ else
10
+ I18n.l(dt, format: I18n.t('edgarj.time.format'))
11
+ end
12
+ end
13
+
14
+ # Edgarj standard date format
15
+ def date_fmt(dt)
16
+ if dt == nil then
17
+ ''
18
+ else
19
+ dt.strftime(I18n.t('date.formats.default'))
20
+ end
21
+ end
22
+
23
+ # get enum Module.
24
+ #
25
+ # When Col(camelized argument col name) module exists, the Col is
26
+ # assumed enum definition.
27
+ def get_enum(model, col)
28
+ col_name = col.name
29
+ if model.const_defined?(col_name.camelize, false)
30
+ enum = model.const_get(col_name.camelize)
31
+ enum.is_a?(Module) ? enum : nil
32
+ else
33
+ nil
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,20 @@
1
+ # coding: UTF-8
2
+
3
+ require 'edgarj/common_helper'
4
+ require 'edgarj/assoc_helper'
5
+ require 'edgarj/field_helper'
6
+ require 'edgarj/popup_helper'
7
+ require 'edgarj/form_drawer'
8
+ require 'edgarj/list_drawer'
9
+
10
+ module Edgarj
11
+ module EdgarjHelper
12
+ include CommonHelper
13
+ include AssocHelper
14
+ include FieldHelper
15
+ include PopupHelper
16
+ include FormDrawer
17
+ include ListDrawer
18
+ include SearchHelper
19
+ end
20
+ end