abstracted 0.0.6 → 0.0.14

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.
Files changed (224) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/Gemfile.lock +11 -8
  4. data/app/assets/javascripts/abstract_resources.js +29 -25
  5. data/app/assets/javascripts/crud.js.coffee +174 -29
  6. data/app/assets/javascripts/initializers.js.coffee +403 -58
  7. data/app/assets/javascripts/pagescrolling.js.coffee +92 -0
  8. data/app/assets/stylesheets/abstract_resources.css +5 -0
  9. data/app/assets/stylesheets/scaffold.css +4 -2
  10. data/app/assets/stylesheets/selectize.css.scss +0 -0
  11. data/app/controllers/abstract_resources_controller.rb +473 -134
  12. data/app/controllers/application_controller.rb +22 -7
  13. data/app/helpers/abstract_resources_helper.rb +515 -9
  14. data/app/helpers/fab_button_helper.rb +82 -0
  15. data/app/models/abstract_resource.rb +141 -89
  16. data/app/models/ancestry_abstract_resource.rb +27 -0
  17. data/app/models/concerns/roleable.rb +1 -1
  18. data/app/policies/abstract_resource_policy.rb +25 -0
  19. data/app/views/abstract_resources/_title.html.haml +2 -0
  20. data/app/views/abstract_resources/activate.html.haml +5 -0
  21. data/app/views/abstract_resources/attach.html.haml +6 -0
  22. data/app/views/abstract_resources/deactivate.html.haml +5 -0
  23. data/app/views/abstract_resources/defer.html.haml +5 -0
  24. data/app/views/abstract_resources/destroy.js.haml +2 -1
  25. data/app/views/abstract_resources/detach.html.haml +5 -0
  26. data/app/views/abstract_resources/edit.html.haml +4 -9
  27. data/app/views/abstract_resources/error.html.haml +2 -0
  28. data/app/views/abstract_resources/error.js.haml +2 -0
  29. data/app/views/abstract_resources/index.html.haml +27 -0
  30. data/app/views/abstract_resources/index.js.haml +2 -0
  31. data/app/views/abstract_resources/new.html.haml +4 -10
  32. data/app/views/abstract_resources/prefer.html.haml +5 -0
  33. data/app/views/abstract_resources/print.html.haml +2 -0
  34. data/app/views/abstract_resources/print.js.haml +2 -0
  35. data/app/views/abstract_resources/show.html.haml +5 -11
  36. data/app/views/layouts/_messages.html.haml +1 -0
  37. data/app/views/layouts/_navigation.html.haml +13 -0
  38. data/bower.json +34 -0
  39. data/config/initializers/exception.rb +19 -0
  40. data/config/initializers/pundit.rb +22 -0
  41. data/config/routes.rb +24 -0
  42. data/lib/abstracted.rb +3 -0
  43. data/lib/abstracted/version.rb +1 -1
  44. data/lib/abstracted_responder.rb +1 -0
  45. data/lib/exceptions.rb +61 -0
  46. data/vendor/assets/components/jquery/.bower.json +38 -0
  47. data/vendor/assets/components/jquery/MIT-LICENSE.txt +21 -0
  48. data/vendor/assets/components/jquery/bower.json +28 -0
  49. data/vendor/assets/components/jquery/dist/jquery.js +9210 -0
  50. data/vendor/assets/components/jquery/dist/jquery.min.js +5 -0
  51. data/vendor/assets/components/jquery/dist/jquery.min.map +1 -0
  52. data/vendor/assets/components/jquery/src/ajax.js +786 -0
  53. data/vendor/assets/components/jquery/src/ajax/jsonp.js +89 -0
  54. data/vendor/assets/components/jquery/src/ajax/load.js +75 -0
  55. data/vendor/assets/components/jquery/src/ajax/parseJSON.js +13 -0
  56. data/vendor/assets/components/jquery/src/ajax/parseXML.js +28 -0
  57. data/vendor/assets/components/jquery/src/ajax/script.js +64 -0
  58. data/vendor/assets/components/jquery/src/ajax/var/nonce.js +5 -0
  59. data/vendor/assets/components/jquery/src/ajax/var/rquery.js +3 -0
  60. data/vendor/assets/components/jquery/src/ajax/xhr.js +136 -0
  61. data/vendor/assets/components/jquery/src/attributes.js +11 -0
  62. data/vendor/assets/components/jquery/src/attributes/attr.js +141 -0
  63. data/vendor/assets/components/jquery/src/attributes/classes.js +158 -0
  64. data/vendor/assets/components/jquery/src/attributes/prop.js +94 -0
  65. data/vendor/assets/components/jquery/src/attributes/support.js +35 -0
  66. data/vendor/assets/components/jquery/src/attributes/val.js +161 -0
  67. data/vendor/assets/components/jquery/src/callbacks.js +205 -0
  68. data/vendor/assets/components/jquery/src/core.js +502 -0
  69. data/vendor/assets/components/jquery/src/core/access.js +60 -0
  70. data/vendor/assets/components/jquery/src/core/init.js +123 -0
  71. data/vendor/assets/components/jquery/src/core/parseHTML.js +39 -0
  72. data/vendor/assets/components/jquery/src/core/ready.js +97 -0
  73. data/vendor/assets/components/jquery/src/core/var/rsingleTag.js +4 -0
  74. data/vendor/assets/components/jquery/src/css.js +450 -0
  75. data/vendor/assets/components/jquery/src/css/addGetHookIf.js +22 -0
  76. data/vendor/assets/components/jquery/src/css/curCSS.js +57 -0
  77. data/vendor/assets/components/jquery/src/css/defaultDisplay.js +70 -0
  78. data/vendor/assets/components/jquery/src/css/hiddenVisibleSelectors.js +15 -0
  79. data/vendor/assets/components/jquery/src/css/support.js +96 -0
  80. data/vendor/assets/components/jquery/src/css/swap.js +28 -0
  81. data/vendor/assets/components/jquery/src/css/var/cssExpand.js +3 -0
  82. data/vendor/assets/components/jquery/src/css/var/getStyles.js +12 -0
  83. data/vendor/assets/components/jquery/src/css/var/isHidden.js +13 -0
  84. data/vendor/assets/components/jquery/src/css/var/rmargin.js +3 -0
  85. data/vendor/assets/components/jquery/src/css/var/rnumnonpx.js +5 -0
  86. data/vendor/assets/components/jquery/src/data.js +178 -0
  87. data/vendor/assets/components/jquery/src/data/Data.js +181 -0
  88. data/vendor/assets/components/jquery/src/data/accepts.js +20 -0
  89. data/vendor/assets/components/jquery/src/data/var/data_priv.js +5 -0
  90. data/vendor/assets/components/jquery/src/data/var/data_user.js +5 -0
  91. data/vendor/assets/components/jquery/src/deferred.js +149 -0
  92. data/vendor/assets/components/jquery/src/deprecated.js +13 -0
  93. data/vendor/assets/components/jquery/src/dimensions.js +50 -0
  94. data/vendor/assets/components/jquery/src/effects.js +648 -0
  95. data/vendor/assets/components/jquery/src/effects/Tween.js +114 -0
  96. data/vendor/assets/components/jquery/src/effects/animatedSelector.js +13 -0
  97. data/vendor/assets/components/jquery/src/event.js +868 -0
  98. data/vendor/assets/components/jquery/src/event/ajax.js +13 -0
  99. data/vendor/assets/components/jquery/src/event/alias.js +39 -0
  100. data/vendor/assets/components/jquery/src/event/support.js +9 -0
  101. data/vendor/assets/components/jquery/src/exports/amd.js +24 -0
  102. data/vendor/assets/components/jquery/src/exports/global.js +32 -0
  103. data/vendor/assets/components/jquery/src/intro.js +44 -0
  104. data/vendor/assets/components/jquery/src/jquery.js +37 -0
  105. data/vendor/assets/components/jquery/src/manipulation.js +580 -0
  106. data/vendor/assets/components/jquery/src/manipulation/_evalUrl.js +18 -0
  107. data/vendor/assets/components/jquery/src/manipulation/support.js +32 -0
  108. data/vendor/assets/components/jquery/src/manipulation/var/rcheckableType.js +3 -0
  109. data/vendor/assets/components/jquery/src/offset.js +207 -0
  110. data/vendor/assets/components/jquery/src/outro.js +1 -0
  111. data/vendor/assets/components/jquery/src/queue.js +142 -0
  112. data/vendor/assets/components/jquery/src/queue/delay.js +22 -0
  113. data/vendor/assets/components/jquery/src/selector-native.js +172 -0
  114. data/vendor/assets/components/jquery/src/selector-sizzle.js +14 -0
  115. data/vendor/assets/components/jquery/src/selector.js +1 -0
  116. data/vendor/assets/components/jquery/src/serialize.js +111 -0
  117. data/vendor/assets/components/jquery/src/sizzle/dist/sizzle.js +2067 -0
  118. data/vendor/assets/components/jquery/src/sizzle/dist/sizzle.min.js +3 -0
  119. data/vendor/assets/components/jquery/src/sizzle/dist/sizzle.min.map +1 -0
  120. data/vendor/assets/components/jquery/src/traversing.js +199 -0
  121. data/vendor/assets/components/jquery/src/traversing/findFilter.js +100 -0
  122. data/vendor/assets/components/jquery/src/traversing/var/rneedsContext.js +6 -0
  123. data/vendor/assets/components/jquery/src/var/arr.js +3 -0
  124. data/vendor/assets/components/jquery/src/var/class2type.js +4 -0
  125. data/vendor/assets/components/jquery/src/var/concat.js +5 -0
  126. data/vendor/assets/components/jquery/src/var/hasOwn.js +5 -0
  127. data/vendor/assets/components/jquery/src/var/indexOf.js +5 -0
  128. data/vendor/assets/components/jquery/src/var/pnum.js +3 -0
  129. data/vendor/assets/components/jquery/src/var/push.js +5 -0
  130. data/vendor/assets/components/jquery/src/var/rnotwhite.js +3 -0
  131. data/vendor/assets/components/jquery/src/var/slice.js +5 -0
  132. data/vendor/assets/components/jquery/src/var/strundefined.js +3 -0
  133. data/vendor/assets/components/jquery/src/var/support.js +4 -0
  134. data/vendor/assets/components/jquery/src/var/toString.js +5 -0
  135. data/vendor/assets/components/jquery/src/wrap.js +79 -0
  136. data/vendor/assets/components/microplugin/.bower.json +38 -0
  137. data/vendor/assets/components/microplugin/.gitignore +2 -0
  138. data/vendor/assets/components/microplugin/.npmignore +3 -0
  139. data/vendor/assets/components/microplugin/README.md +115 -0
  140. data/vendor/assets/components/microplugin/bower.json +22 -0
  141. data/vendor/assets/components/microplugin/package.json +15 -0
  142. data/vendor/assets/components/microplugin/src/microplugin.js +135 -0
  143. data/vendor/assets/components/selectize/.bower.json +60 -0
  144. data/vendor/assets/components/selectize/.gitignore +5 -0
  145. data/vendor/assets/components/selectize/LICENSE +202 -0
  146. data/vendor/assets/components/selectize/README.md +105 -0
  147. data/vendor/assets/components/selectize/bower.json +40 -0
  148. data/vendor/assets/components/selectize/dist/css/selectize.bootstrap2.css +487 -0
  149. data/vendor/assets/components/selectize/dist/css/selectize.bootstrap3.css +401 -0
  150. data/vendor/assets/components/selectize/dist/css/selectize.css +317 -0
  151. data/vendor/assets/components/selectize/dist/css/selectize.default.css +387 -0
  152. data/vendor/assets/components/selectize/dist/css/selectize.legacy.css +364 -0
  153. data/vendor/assets/components/selectize/dist/js/selectize.js +3058 -0
  154. data/vendor/assets/components/selectize/dist/js/selectize.min.js +3 -0
  155. data/vendor/assets/components/selectize/dist/js/standalone/selectize.js +3667 -0
  156. data/vendor/assets/components/selectize/dist/js/standalone/selectize.min.js +3 -0
  157. data/vendor/assets/components/selectize/dist/less/plugins/drag_drop.less +16 -0
  158. data/vendor/assets/components/selectize/dist/less/plugins/dropdown_header.less +20 -0
  159. data/vendor/assets/components/selectize/dist/less/plugins/optgroup_columns.less +17 -0
  160. data/vendor/assets/components/selectize/dist/less/plugins/remove_button.less +37 -0
  161. data/vendor/assets/components/selectize/dist/less/selectize.bootstrap2.less +161 -0
  162. data/vendor/assets/components/selectize/dist/less/selectize.bootstrap3.less +150 -0
  163. data/vendor/assets/components/selectize/dist/less/selectize.default.less +84 -0
  164. data/vendor/assets/components/selectize/dist/less/selectize.legacy.less +75 -0
  165. data/vendor/assets/components/selectize/dist/less/selectize.less +295 -0
  166. data/vendor/assets/components/selectize/karma.conf.js +107 -0
  167. data/vendor/assets/components/sifter/.bower.json +44 -0
  168. data/vendor/assets/components/sifter/.gitignore +3 -0
  169. data/vendor/assets/components/sifter/.npmignore +4 -0
  170. data/vendor/assets/components/sifter/README.md +149 -0
  171. data/vendor/assets/components/sifter/bower.json +23 -0
  172. data/vendor/assets/components/sifter/package.json +48 -0
  173. data/vendor/assets/components/sifter/sifter.js +471 -0
  174. data/vendor/assets/components/sifter/sifter.min.js +2 -0
  175. data/vendor/assets/components/sweetalert/.bower.json +36 -0
  176. data/vendor/assets/components/sweetalert/.editorconfig +11 -0
  177. data/vendor/assets/components/sweetalert/.gitignore +5 -0
  178. data/vendor/assets/components/sweetalert/.jshintrc +11 -0
  179. data/vendor/assets/components/sweetalert/.travis.yml +6 -0
  180. data/vendor/assets/components/sweetalert/LICENSE +22 -0
  181. data/vendor/assets/components/sweetalert/README.md +157 -0
  182. data/vendor/assets/components/sweetalert/bower.json +25 -0
  183. data/vendor/assets/components/sweetalert/dev/gulpfile-wrap-template.js +18 -0
  184. data/vendor/assets/components/sweetalert/dev/ie9.css +23 -0
  185. data/vendor/assets/components/sweetalert/dev/loader-animation.css +209 -0
  186. data/vendor/assets/components/sweetalert/dev/modules/default-params.js +26 -0
  187. data/vendor/assets/components/sweetalert/dev/modules/handle-click.js +128 -0
  188. data/vendor/assets/components/sweetalert/dev/modules/handle-dom.js +161 -0
  189. data/vendor/assets/components/sweetalert/dev/modules/handle-key.js +73 -0
  190. data/vendor/assets/components/sweetalert/dev/modules/handle-swal-dom.js +148 -0
  191. data/vendor/assets/components/sweetalert/dev/modules/injected-html.js +69 -0
  192. data/vendor/assets/components/sweetalert/dev/modules/set-params.js +221 -0
  193. data/vendor/assets/components/sweetalert/dev/modules/utils.js +71 -0
  194. data/vendor/assets/components/sweetalert/dev/sweetalert.es6.js +311 -0
  195. data/vendor/assets/components/sweetalert/dev/sweetalert.scss +648 -0
  196. data/vendor/assets/components/sweetalert/dist/sweetalert-dev.js +1281 -0
  197. data/vendor/assets/components/sweetalert/dist/sweetalert.css +932 -0
  198. data/vendor/assets/components/sweetalert/dist/sweetalert.min.js +1 -0
  199. data/vendor/assets/components/sweetalert/example/example.css +442 -0
  200. data/vendor/assets/components/sweetalert/example/example.scss +580 -0
  201. data/vendor/assets/components/sweetalert/example/images/logo_big.png +0 -0
  202. data/vendor/assets/components/sweetalert/example/images/logo_big@2x.png +0 -0
  203. data/vendor/assets/components/sweetalert/example/images/logo_small.png +0 -0
  204. data/vendor/assets/components/sweetalert/example/images/logo_small@2x.png +0 -0
  205. data/vendor/assets/components/sweetalert/example/images/te-logo-small.svg +12 -0
  206. data/vendor/assets/components/sweetalert/example/images/thumbs-up.jpg +0 -0
  207. data/vendor/assets/components/sweetalert/example/images/vs_icon.png +0 -0
  208. data/vendor/assets/components/sweetalert/example/images/vs_icon@2x.png +0 -0
  209. data/vendor/assets/components/sweetalert/gulpfile.js +97 -0
  210. data/vendor/assets/components/sweetalert/index.html +584 -0
  211. data/vendor/assets/components/sweetalert/package.json +45 -0
  212. data/vendor/assets/components/sweetalert/sweetalert.gif +0 -0
  213. data/vendor/assets/components/sweetalert/test/index.html +20 -0
  214. data/vendor/assets/components/sweetalert/test/tests.js +143 -0
  215. data/vendor/assets/components/sweetalert/themes/facebook/facebook.css +111 -0
  216. data/vendor/assets/components/sweetalert/themes/facebook/facebook.scss +146 -0
  217. data/vendor/assets/components/sweetalert/themes/google/google.css +115 -0
  218. data/vendor/assets/components/sweetalert/themes/google/google.scss +148 -0
  219. data/vendor/assets/components/sweetalert/themes/twitter/twitter.css +140 -0
  220. data/vendor/assets/components/sweetalert/themes/twitter/twitter.scss +177 -0
  221. metadata +214 -5
  222. data/abstracted-0.0.4.gem +0 -0
  223. data/abstracted.gemspec +0 -51
  224. data/app/views/abstract_resources/index.html.erb +0 -1
@@ -0,0 +1,92 @@
1
+ loadingPage = false
2
+ currentPage = 0
3
+ totalPages = 0
4
+ navPaginator = ''
5
+ lastPage = 0
6
+ nextPage = 0
7
+ pageUrl = ''
8
+ contxt = null
9
+ scrollTimeout = false
10
+
11
+ @evalPageNumber = (url) ->
12
+ try
13
+ pn = url
14
+ .split('?')[1]
15
+ .split('&')
16
+ .filter (el,i,array) ->
17
+ if el.match /^page/
18
+ return el
19
+ .join('')
20
+ .split('=')[1]
21
+ parseInt(pn)
22
+ catch error
23
+ pn = 0
24
+
25
+ #
26
+ # setVariables prepares for a great scrolling experience
27
+ #
28
+ @setVariables = (elem) ->
29
+ navPaginator = $('nav.pagination')
30
+ try
31
+ pageUrl = navPaginator.find('a[rel=next]')[0].href.replace( '?', '.js?scrolling=true&')
32
+ lastPage = evalPageNumber navPaginator.find('span.last a')[0].href
33
+ nextPage = evalPageNumber navPaginator.find('a[rel=next]')[0].href
34
+ contxt = $(elem)
35
+ if nextPage > 1
36
+ nextPage = 1
37
+ true
38
+
39
+ catch error
40
+ console.log error
41
+ return false
42
+
43
+ #
44
+ # closeToBottom checks to see if you're close to the bottom of the screen
45
+ #
46
+ @closeToBottom = () ->
47
+ return false if navPaginator.size() == 0
48
+ return ($(window).scrollTop() - parseInt($(document).height()) + parseInt($(window).height())) > -200
49
+
50
+ @findNextPageToLoad = () ->
51
+ nextPage += 1
52
+ if nextPage > lastPage
53
+ clearTimeout( scrollTimeout )
54
+ return false
55
+ if !pageUrl.split("?")[0].split(".js")[0].match window.location.href.split("?")[0]
56
+ clearTimeout( scrollTimeout )
57
+ return false
58
+ pageUrl
59
+ .replace /page=\d*&/, 'page=' + nextPage + '&'
60
+
61
+
62
+ @loadNextPage = () ->
63
+ if !loadingPage
64
+ url = findNextPageToLoad()
65
+ if url
66
+ loadingPage = true
67
+ jqxhr = $.ajax
68
+ url: url
69
+ type: 'GET'
70
+ dataType: 'html'
71
+ .done (data) ->
72
+ contxt.find('tbody').append(data)
73
+ loadingPage=false
74
+ .fail (data) ->
75
+ loadingPage = false
76
+ console.log 'err'
77
+ #
78
+ # scroll a list - behind the scenes calling in extra pages of content
79
+ #
80
+ @scrollTable = (elem) ->
81
+ return unless setVariables(elem)
82
+ if nextPage > 0
83
+ scrollHandler = () ->
84
+ clearTimeout( scrollTimeout )
85
+ if closeToBottom()
86
+ $.when loadNextPage()
87
+ .then scrollTimeout = setTimeout( scrollHandler, 250)
88
+ .then navPaginator.hide()
89
+ else
90
+ setTimeout( scrollHandler, 250)
91
+
92
+ scrollTimeout = setTimeout( scrollHandler, 250)
@@ -2,4 +2,9 @@
2
2
  * Place all the styles related to the matching controller here.
3
3
  * They will automatically be included in application.css.
4
4
  *
5
+ * require_self
6
+ *= require sweetalert
7
+ * require materialize-tags/dist/css/materialize-tags.css
8
+ *= require selectize/dist/css/selectize.css
9
+ * require_tree .
5
10
  */
@@ -1,4 +1,4 @@
1
- body { background-color: #fff; color: #333; }
1
+ /*body { background-color: #fff; color: #333; }
2
2
 
3
3
  body, p, ol, ul, td {
4
4
  font-family: verdana, arial, helvetica, sans-serif;
@@ -6,6 +6,8 @@ body, p, ol, ul, td {
6
6
  line-height: 18px;
7
7
  }
8
8
 
9
+ body p.what-a-class { color: #efe; }
10
+
9
11
  pre {
10
12
  background-color: #eee;
11
13
  padding: 10px;
@@ -53,4 +55,4 @@ div.field, div.actions {
53
55
  #error_explanation ul li {
54
56
  font-size: 12px;
55
57
  list-style: square;
56
- }
58
+ }*/
File without changes
@@ -4,8 +4,10 @@ class AbstractResourcesController < ApplicationController
4
4
  self.responder = ::AbstractedResponder
5
5
  respond_to :html, :xml, :js, :json
6
6
 
7
- before_action :set_resource
8
- before_action :set_resources, only: [:index]
7
+ before_action :set_resource #, except: :index
8
+ before_action :set_fab_button_options
9
+ before_filter :set_parents, only: [ :new, :edit, :show ]
10
+ before_action :set_resources, only: [:index, :print]
9
11
  before_action :set_variant_template
10
12
 
11
13
  before_filter :authenticate_user!
@@ -13,6 +15,104 @@ class AbstractResourcesController < ApplicationController
13
15
  # after_action :manage_parenthood, only: [:create,:update,:destroy]
14
16
 
15
17
  # default implementation
18
+
19
+ def prefer
20
+ authorize resource
21
+ if resource.prefer parent
22
+ flash[:info] = t(:resource_preferred_correct)
23
+ render :prefer, layout: false, status: 200 and return
24
+ else
25
+ flash[:error] = t(:resource_preferred_incorrect)
26
+ render :prefer, layout: false, status: 401 and return
27
+ end
28
+
29
+ rescue Exception => e
30
+ scoop_from_error e
31
+ end
32
+
33
+ def defer
34
+ authorize resource
35
+ if resource.defer parent
36
+ flash[:info] = t(:resource_deferred_correct)
37
+ render :defer, layout: false, status: 200 and return
38
+ else
39
+ flash[:error] = t(:resource_deferred_incorrect)
40
+ render :defer, layout: false, status: 401 and return
41
+ end
42
+
43
+ rescue Exception => e
44
+ scoop_from_error e
45
+ end
46
+
47
+ def activate
48
+ authorize resource
49
+ if resource.activate
50
+ flash[:info] = t(:resource_activated_correct)
51
+ render :activate, layout: false, status: 200 and return
52
+ else
53
+ flash[:error] = t(:resource_activated_incorrect)
54
+ render :activate, layout: false, status: 401 and return
55
+ end
56
+
57
+ rescue Exception => e
58
+ scoop_from_error e
59
+ end
60
+
61
+ def deactivate
62
+ authorize resource
63
+ if resource.deactivate
64
+ flash[:info] = t(:resource_deactivated_correct)
65
+ render :deactivate, layout: false, status: 200 and return
66
+ else
67
+ flash[:error] = t(:resource_deactivated_incorrect)
68
+ render :deactivate, layout: false, status: 401 and return
69
+ end
70
+
71
+ rescue Exception => e
72
+ scoop_from_error e
73
+ end
74
+
75
+
76
+ def attach
77
+ authorize resource
78
+ if resource.attach parent
79
+ flash[:info] = t(:resource_attached_correct)
80
+ render :attach, layout: false, status: 200 and return
81
+ else
82
+ flash[:error] = t(:resource_attached_incorrect)
83
+ render :attach, layout: false, status: 401 and return
84
+ end
85
+
86
+ rescue Exception => e
87
+ scoop_from_error e
88
+ end
89
+
90
+ def detach
91
+ authorize resource
92
+ if resource.detach parent
93
+ flash[:info] = t(:resource_detached_correct)
94
+ render :detach, layout: false, status: 200 and return
95
+ else
96
+ flash[:error] = t(:resource_detached_incorrect)
97
+ render :detach, layout: false, status: 401 and return
98
+ end
99
+
100
+ rescue Exception => e
101
+ scoop_from_error e
102
+ end
103
+
104
+ #
105
+ # build an array of the resource - particular to <SELECT>
106
+ def set_parents
107
+ unless (resource_class.respond_to?( 'arraying') && resource? )
108
+ @parents = []
109
+ else
110
+ @parents = resource_class.arraying({ order: 'name'}, resource.possible_parents)
111
+ end
112
+ rescue Exception => e
113
+ scoop_from_error e
114
+ end
115
+
16
116
  def show
17
117
  authorize resource
18
118
  respond_with resource
@@ -35,33 +135,80 @@ class AbstractResourcesController < ApplicationController
35
135
  scoop_from_error e
36
136
  end
37
137
 
138
+ PRINTSUCCESS = 1
139
+ NOQUEUE = -1
140
+ NOUSER = -2
141
+ PRINTRECERROR = -3
142
+ PRINTCMDERROR = -4
143
+ PRINTLISTERROR = -5
144
+ PRINTEXCEPTION = -99
145
+
146
+ #
147
+ # print this view - let the Class handle everything
148
+ # returning either the ID to a print_job or false (in which case something went terribly wrong)
149
+ #
150
+ # always an Ajax call - hence will always update the print_jobs link with 'yellow'-blink
151
+ # POST /printers/print.js
152
+ # params[:id] holds records to be printed
153
+ def print
154
+ authorize resource, :print?
155
+ if resources.any?
156
+ if print_resources > 0
157
+ flash[:info] = t(:resources_printed_correct)
158
+ status = 200
159
+ else
160
+ flash[:error] = t(:resources_not_found_printjob_not_created)
161
+ status = 301
162
+ end
163
+ else
164
+ flash[:error] = I18n.oxt(:resources_not_found_printjob_not_created)
165
+ status = 301
166
+ end
167
+ return if params[:download]
168
+ render :print, layout: false, status: status and return
169
+ rescue Exception => e
170
+ scoop_from_error e
171
+ end
172
+
173
+
38
174
  def index
39
- authorize resource_class
175
+ authorize resource_class, :index?
40
176
  respond_with resources
41
177
  rescue Exception => e
42
178
  scoop_from_error e
43
179
  end
44
180
 
45
181
  def create
46
- @resource = resource_class.new(resource_params)
47
182
  authorize resource
48
- flash[:notice] = t('.success.created', resource: resource_class.to_s ) if resource.save
49
- respond_with(resource)
183
+ respond_with(resource, location: redirect_after_create ) do |format|
184
+ if resource.save && update_parenthood
185
+ flash[:notice] = t('.success.created', resource: resource_class.to_s )
186
+ else
187
+ format.html { render action: :new, status: :unprocessable_entity }
188
+ format.js { render action: :new, status: :unprocessable_entity }
189
+ end
190
+ end
50
191
  rescue Exception => e
51
192
  scoop_from_error e
52
193
  end
53
194
 
54
195
  def update
55
196
  authorize resource
56
- flash[:notice] = t('.success.updated', resource: resource_class.to_s ) if resource.update_attributes(resource_params)
57
- respond_with(resource)
197
+ respond_with(resource, location: redirect_after_update) do |format|
198
+ if resource.update_attributes(resource_params) && update_parenthood
199
+ flash[:notice] = t('.success.updated', resource: resource_class.to_s )
200
+ else
201
+ format.html { render action: :edit, status: :unprocessable_entity }
202
+ format.js { render action: :edit, status: :unprocessable_entity }
203
+ end
204
+ end
58
205
  rescue Exception => e
59
206
  scoop_from_error e
60
207
  end
61
208
 
62
209
  def destroy
63
210
  authorize resource
64
- result = true if resource.destroy
211
+ result = true if resource.destroy && update_parenthood
65
212
  result ? (flash.now[:notice] = t('.success', resource: resource_class.to_s)) : (flash.now[:error] = t('.deleted.error',resource: resource_class.to_s))
66
213
  if result==true
67
214
  render layout:false, status: 200, locals: { result: true }
@@ -85,16 +232,57 @@ class AbstractResourcesController < ApplicationController
85
232
  resources
86
233
  end
87
234
 
235
+ def resource?
236
+ !(%w{NilClass TrueClass FalseClass}.include? @resource.class.to_s)
237
+ rescue Exception => e
238
+ scoop_from_error e
239
+ end
240
+
88
241
  def resource
89
- @resource ||= (params[:id].nil? ? resource_class.new : resource_class.find(params[:id]) ) rescue nil
242
+ @resource ||= (_id.nil? ? new_resource : resource_class.find(_id) )
243
+ return @resource if @resource.nil?
244
+ @resource.current_user = current_user || nil if @resource.respond_to? :current_user
245
+ @resource
246
+ rescue Exception => e
247
+ scoop_from_error e
248
+ end
249
+
250
+ # def resource=val
251
+ # @resource=val
252
+ # end
253
+
254
+ def new_resource
255
+ return nil if resource_class.nil?
256
+ return resource_class.new if resource_class.ancestors.include?( ActiveRecord::Base ) and !(params.include? resource_class.to_s.underscore) #[ 'create', 'update' ].include? params[:action]
257
+ return resource_class.new(resource_params.merge(current_user: current_user)) if resource_class.ancestors.include? ActiveRecord::Base
258
+ nil
259
+ rescue Exception => e
260
+ scoop_from_error e
261
+ end
262
+
263
+ def _id
264
+ return nil if !params[:id] || params[:id]=="0"
265
+ params[:id] || params["#{resource_class.to_s.downcase}_id".to_sym]
266
+ rescue Exception => e
267
+ scoop_from_error e
90
268
  end
91
269
 
92
- def resource_name
93
- resource_class.to_s.underscore.pluralize
270
+ def resource_name options={}
271
+ resource_class.table_name
272
+ rescue Exception => e
273
+ scoop_from_error e
274
+ # resource_class.to_s.underscore.pluralize
94
275
  end
95
276
 
96
277
  def resource_class
97
- @resource_class ||= params[:controller].singularize.classify.constantize rescue nil
278
+ return @resource_class if resource?
279
+ @resource_class ||= params[:controller].singularize.classify.constantize
280
+ rescue Exception => e
281
+ scoop_from_error e
282
+ end
283
+
284
+ def resource_class= val
285
+ @resource_class = val
98
286
  end
99
287
 
100
288
  def parent
@@ -106,8 +294,12 @@ class AbstractResourcesController < ApplicationController
106
294
  @parent_class ||= @parent.class
107
295
  end
108
296
 
297
+ def parent_class= val
298
+ @parent_class = val
299
+ end
300
+
109
301
  def parent?
110
- !(%w{NilClass TrueClass FalseClass}.include? @parent.class.to_s)
302
+ !(%w{NilClass TrueClass FalseClass}.include? parent.class.to_s)
111
303
  end
112
304
 
113
305
  #
@@ -128,6 +320,8 @@ class AbstractResourcesController < ApplicationController
128
320
  else ''
129
321
  end
130
322
  parent? ? ("%s/%s%s%s" % [parent_url,resource_name,action,options]) : ("/%s%s%s" % [resource_name,action,options])
323
+ rescue Exception => e
324
+ scoop_from_error e
131
325
  end
132
326
 
133
327
 
@@ -135,156 +329,301 @@ class AbstractResourcesController < ApplicationController
135
329
  # returns the url for the resources - /employees or /employees/1/events
136
330
  def resources_url options={}
137
331
  options = resource_options(options)
138
- "%s/%s" % [ parent_url, resource_name ]
332
+ r = "%s_path" % resource_name
333
+ r = send(r)
334
+ [ parent_url, r ].join("/").gsub /\/\//,'/'
335
+ rescue Exception => e
336
+ scoop_from_error e
139
337
  end
140
338
 
141
339
  #
142
340
  # parent_url returns the parent url - /employees/1
143
- def parent_url
341
+ def parent_url options={}
144
342
  parent? ? ( "/%s/%s" % [ @parent.class.table_name, @parent.id ] ) : ""
343
+ rescue Exception => e
344
+ scoop_from_error e
145
345
  end
146
346
 
147
347
 
148
348
  private
149
349
 
150
- #
151
- # use views/../$action.html+mobile.erb if request originates from an iPad
152
- #
153
- def set_variant_template
154
- request.variant = :mobile if request.user_agent =~ /iPad/
155
- end
350
+ # you can override this on your controller
351
+ def redirect_after_create
352
+ resources_url {}
353
+ end
156
354
 
157
- def resource_options options
158
- options.merge! params.except( "id", "controller", "action" )
159
- options = (options.empty? ? "" : "?" + options.collect{ |k,v| "#{k}=#{v}" }.join("&"))
160
- end
355
+ # you can override this on your controller
356
+ def redirect_after_update
357
+ resources_url {}
358
+ end
161
359
 
162
- #
163
- # find the resources collection
164
- def find_resources options
360
+ #
361
+ # print_resources will try to add a print_job
362
+ # return error code
363
+ def print_resources
364
+ if resource_class == PrintJob
365
+ resources.each do |res|
366
+ return NOQUEUE unless Delayed::Job.enqueue res, :queue => 'printing'
367
+ end
368
+ return PRINTSUCCESS
369
+ else
370
+ return NOUSER unless current_user
371
+ params[:user] = current_user
372
+ if params[:print_list].nil?
373
+ #
374
+ # print something specific?
375
+ if params[:print_cmd].nil?
376
+ resources.each do |res|
377
+ return PRINTRECERROR unless res.print_record params: params, context: self
378
+ end
379
+ else
380
+ resources.each do |res|
381
+ return PRINTCMDERROR unless res.send(params[:print_cmd],params)
382
+ end
383
+ end
384
+ else
385
+ params[:resources] = resources
386
+ return PRINTLISTERROR unless resource_class.print_list( params )
387
+ end
388
+ end
165
389
 
166
- params[:ids] ||= []
167
- params[:ids] << params[:id] unless params[:id].nil?
390
+ return PRINTSUCCESS
168
391
 
169
- if params[:ids].compact.any?
170
- policy_scope(resource_class).where(id: params[:ids].compact.split(",").flatten)
171
- else
172
- if params[:q].nil? or params[:q]=="" #or params[:q]=="undefined"
173
- r = parent? ? parent.send(resource_name) : (resource_class.nil? ? nil : policy_scope(resource_class))
392
+
393
+ rescue Exception => err
394
+ return PRINTEXCEPTION
395
+ end
396
+
397
+ #
398
+ # use views/../$action.html+mobile.erb if request originates from an iPad
399
+ #
400
+ def set_variant_template
401
+ request.variant = :mobile if request.user_agent =~ /iPad/
402
+ end
403
+
404
+ def resource_options options
405
+ options.merge! params.except( "id", "controller", "action" )
406
+ options = (options.empty? ? "" : "?" + options.collect{ |k,v| "#{k}=#{v}" }.join("&"))
407
+ end
408
+
409
+ #
410
+ # find the resources collection
411
+ def find_resources options
412
+
413
+ # return [] unless resource_class.ancestors.include? ActiveRecord::Base
414
+ params[:ids] ||= []
415
+ params[:ids] << params[:id] unless params[:id].nil?
416
+
417
+ if params[:ids].compact.any?
418
+ policy_scope(resource_class).where(id: params[:ids].compact.split(",").flatten)
174
419
  else
175
- r = find_resources_queried options
420
+ if params[:q].blank? #or params[:q]=="undefined"
421
+ r = parent? ? parent.send(resource_name) : (resource_class.nil? ? nil : find_all_resources(options))
422
+ else
423
+ r = find_resources_queried options
424
+ end
425
+ if (r.respond_to?( :page)) && (params[:format].nil? or params[:format]=='html' or params[:scrolling])
426
+ params[:perpage] ||= 20
427
+ params[:page] ||= 1
428
+ return r.page(params[:page]).per(params[:perpage])
429
+ else
430
+ return r
431
+ end
432
+
433
+ # (params[:format].nil? or params[:format]=='html') ? r.page(params[:page]).per(params[:perpage]) : r
176
434
  end
435
+ end
177
436
 
178
- return r #if params[:print_list]
179
- # params[:perpage] ||= 20
180
- # (params[:format].nil? or params[:format]=='html') ? r.page(params[:page]).per(params[:perpage]) : r
437
+ #
438
+ # find queried resources collection - implement on each controller to customize
439
+ # raise an exception
440
+ def find_all_resources options
441
+ policy_scope(resource_class)
181
442
  end
182
443
 
183
- end
444
+ #
445
+ # find queried resources collection - implement on each controller to customize
446
+ # raise an exception
447
+ def find_resources_queried options
448
+ case params[:f]
449
+ when nil
450
+ if parent?
451
+ policy_scope(resource_class).tags_included?( params[:q].split(" ") ).where( options )
452
+ else
453
+ policy_scope(resource_class).tags_included?( params[:q].split(" ") )
454
+ end
455
+ else
456
+ policy_scope(resource_class)
457
+ end
458
+ end
184
459
 
185
- #
186
- # find queried resources collection - implement on each controller to customize
187
- # raise an exception
188
- def find_resources_queried options
189
- case params[:f]
190
- when nil
191
- if parent?
192
- policy_scope(resource_class).tags_included?( params[:q].split(" ") ).where( options )
460
+
461
+ #
462
+ # build options for fixed action button - implement on each controller to customize
463
+ # raise an exception
464
+ def set_fab_button_options
465
+ opt = { items: {}}
466
+ case params[:action]
467
+ when 'nothing'; opt = opt
468
+ # when 'new'; #opt[:items].merge! print: { ajax: 'get', icon: 'print', class: 'blue lighten-2', url: '/stock_items/print?print_list=true', browser: 'new' }
469
+ # when 'edit'; #opt[:items].merge! print: { ajax: 'get', icon: 'print', class: 'blue lighten-2', url: '/stock_items/print?print_list=true', browser: 'new' }
470
+ # when 'show'; opt[:items].merge! print: { ajax: 'get', icon: 'print', class: 'blue lighten-2', url: '/stock_items/print', browser: 'new' }
471
+ # when 'index'; opt[:items].merge! print: { ajax: 'get', icon: 'print', class: 'blue lighten-2', url: '/stock_items/print?print_list=true', browser: 'new' }
472
+ end
473
+
474
+ # = build_print_link(f.object, list: false, print_options: "print_cmd=print_label", button: 'icon-tag', text: 'Udskriv dæk label')
475
+ @fab_button_options = opt
476
+ end
477
+
478
+ #
479
+ #
480
+ # /employees/1/teams
481
+ # /employees/1/teams/5
482
+ # /employees/1/teams/5/attach
483
+ # /theatres/2/contacts/5/uris.js
484
+ def find_parent path=nil, parms=nil
485
+ path ||= request.path
486
+ parms ||= params
487
+ if parms[:parent].nil? #or params[:parent_id].nil?
488
+ paths=path.split("/")
489
+ paths.pop if %w{new edit show create update delete index}.include? paths[-1]
490
+ return nil if (paths.size < 3) #or (paths.size==4 and %w{edit new}.include?( parms[:action]))
491
+ recognise_path paths.join("/")
193
492
  else
194
- policy_scope(resource_class).tags_included?( params[:q].split(" ") )
493
+ parms[:parent].classify.constantize.find(parms[:parent_id])
195
494
  end
196
- else
197
- policy_scope(resource_class)
198
495
  end
199
- end
200
- #
201
- #
202
- # /employees/1/teams
203
- # /employees/1/teams/5
204
- # /employees/1/teams/5/attach
205
- def find_parent
206
- if params[:parent].nil?
207
- return nil if (request.path.split("/").size < 4) or (request.path.split("/").size==4 and %w{edit new}.include?( params[:action]))
208
- dummy, parent_cls, parent_id, resource_cls, resource_id, action = request.path.split("/")
209
- parent_cls.singularize.classify.constantize.find(parent_id) rescue nil
210
- else
211
- params[:parent].constantize.find(params[:parent_id])
496
+ #
497
+ # ['theatres','5','contacts','2','uris.js']
498
+ def recognise_path path
499
+ path_elements = Rails.application.routes.recognize_path path.gsub /\..*$/,'' # "/admin/users/2/printers/3/attach" => {:controller=>"printers", :action=>"attach", :user_id=>"2", :id=>"3"}
500
+ recognise_parent( recognise_resource( path_elements ) )
501
+
502
+ rescue Exception => e
503
+ nil
504
+ # return [ nil, nil, false ] if e.class.to_s == "ActionController::RoutingError"
505
+
212
506
  end
213
- end
214
- #
215
- # # /employees/1/teams/new
216
- # # /employees/1/teams/1/edit
217
- # # /employees/1/teams/1/delete
218
- # def manage_parenthood
219
- # if params[:parent] and params[:parent_id]
220
- # parent = params[:parent].classify.constantize.find(params[:parent_id])
221
- # unless parent.blank?
222
- # case params[:action]
223
- # when "create"
224
- # child = eval("@#{resource_class.to_s.underscore}")
225
- # children = eval("parent.#{resource_name}")
226
- # children << child
227
- # when "edit"
228
- # when "delete"
229
- # child = eval("@#{resource_class.to_s.underscore}")
230
- # children = eval("parent.#{resource_name}")
231
- # children >> child
232
- # end
233
- # end
234
- # end
235
- # end
236
- #
237
- #
238
507
 
239
- def scoop_from_error e
240
- logger.debug "AbstractResourcesController##{params[:action]}: #{e.class}"
241
- case e.class.to_s
242
- when "Pundit::NotAuthorizedError"
243
- flash.now[:error] = flash[:error] = t('.fail.authorized', resource: resource)
244
- result = false
245
- status = 401
246
- when "ActiveRecord::StatementInvalid" # Mysql2::Error
247
- flash.now[:error] = flash[:error] = t('fail.mysql_error', mysql: e.to_s)
248
- result= false
249
- status = 409
250
- else
251
- flash.now[:error] = flash[:error] = "An error occured - please refer to log for details!"
252
- render head: 412
508
+ # {:controller=>"printers", :action=>"attach", :user_id=>"2", :id=>"3"}
509
+ def recognise_resource elems
510
+ resource_class = elems.delete(:controller).singularize.classify.constantize
511
+ resource = resource_class.find( elems.delete(:id) )
512
+ elems
513
+ rescue Exception => e
514
+ return elems if e.class.to_s == "ActiveRecord::RecordNotFound"
515
+ resource_class = nil
516
+ elems
253
517
  end
254
518
 
519
+ # { :action=>"attach", :user_id=>"2" }
520
+ def recognise_parent elems
521
+ elems.delete :action
522
+ arr = elems.keys.first.to_s.split("_")
523
+ return nil unless arr.include? "id"
524
+ arr[0].singularize.classify.constantize.find(elems.values.first)
525
+ rescue
526
+ nil
527
+ end
255
528
 
256
- respond_to do |format|
257
- case params[:action]
258
- when 'new'
259
- format.html { flash.keep(:error) ; redirect_to resources_url }
260
- format.js { render layout: false, status: status, locals: { result: result} }
261
- format.json { render json: resources, status: status }
262
- when 'create'
263
- format.html { render :new }
264
- format.js { render layout: false, status: status, locals: { result: result} }
265
- format.json { render json: resource.errors, status: status }
266
- when 'show'
267
- format.html { flash.keep(:error) ; redirect_to resources_url }
268
- format.js { render layout: false, status: status, locals: { result: result} }
269
- format.json { render json: resources, status: status }
270
- when 'edit'
271
- format.html { flash.keep(:error) ; redirect_to resources_url }
272
- format.js { render layout: false, status: status, locals: { result: result} }
273
- format.json { render json: resources, status: status }
274
- when 'update'
275
- format.html { render :edit }
276
- format.js { render layout: false, status: status, locals: { result: result} }
277
- format.json { render json: resource.errors, status: status }
278
- when 'index', 'destroy'
279
- # we should render index - but an error here will not make us happy
280
- # format.html { render :index }
281
- #
282
- format.html { redirect_to root_path, alert: flash[:error] }
283
- format.js { render layout: false, status: status, locals: { result: result} }
284
- format.json { render json: resources, status: status }
529
+ #
530
+ # # /employees/1/teams/new
531
+ # # /employees/1/teams/1/edit
532
+ # # /employees/1/teams/1/delete
533
+ def update_parenthood
534
+ if params[:parent] and params[:parent_id]
535
+ # raise "Ups - is this ready for prime time yet?"
536
+ parent = params[:parent].classify.constantize.find(params[:parent_id])
537
+ unless parent.blank?
538
+ case params[:action]
539
+ when "create"
540
+ children = eval("parent.#{resource_name}")
541
+ children << resource unless children.include? resource
542
+ # when "edit"
543
+ when "delete"
544
+ children = eval("parent.#{resource_name}")
545
+ children >> resource
546
+ end
547
+ end
285
548
  end
549
+ true
550
+ rescue
551
+ false
286
552
  end
553
+ #
554
+ #
555
+
556
+ def scoop_from_error e
557
+ raise e if Rails.env=='development'
558
+ logger.debug "AbstractResourcesController##{params[:action]}: #{e.class}"
559
+ a_url = root_path
560
+
561
+ case e.class.to_s
562
+ when "Exceptions::AuthenticationError"
563
+ flash.now[:error] = flash[:error] = "Access Problem: <br/><small>%s</small>" % e.message
564
+ result= false
565
+ status = 412
566
+
567
+ when "ActiveRecord::RecordNotFound"
568
+ flash.now[:error] = flash[:error] = t('.fail.record_not_found')
569
+ result = false
570
+ status = 301
571
+ a_url = resources_url
572
+
573
+ when "Pundit::NotAuthorizedError"
574
+ flash.now[:error] = flash[:error] = t('.fail.authorized', resource: resource)
575
+ result = false
576
+ status = 401
577
+
578
+ when "ActiveRecord::StatementInvalid" # Mysql2::Error
579
+ flash.now[:error] = flash[:error] = t('fail.mysql_error', mysql: e.to_s)
580
+ result= false
581
+ status = 409
582
+ when "ActionView::Template::Error"
583
+ flash.now[:error] = flash[:error] = "A template error occured - please call ALCO with: <br/><small>%s</small>" % e.message
584
+ result= false
585
+ status = 301
586
+ else
587
+ raise e
588
+ # flash.now[:error] = flash[:error] = "An error occured - please refer to log for details!"
589
+ # render :error, layout: false, status: 412 and return
590
+ end
287
591
 
288
- end
592
+ respond_to do |format|
593
+ case params[:action]
594
+ when 'new'
595
+ format.html { flash.keep(:error) ; redirect_to resources_url }
596
+ format.js { render :error, layout: false, status: status, locals: { result: result} }
597
+ format.json { render json: resources, status: status }
598
+ when 'create'
599
+ format.html { render :new }
600
+ format.js { render :error, layout: false, status: status, locals: { result: result} }
601
+ format.json { render json: resource.errors, status: status }
602
+ when 'show'
603
+ format.html { flash.keep(:error) ; redirect_to resources_url }
604
+ format.js { render :error, layout: false, status: status, locals: { result: result} }
605
+ format.json { render json: resources, status: status }
606
+ when 'edit'
607
+ format.html { flash.keep(:error) ; redirect_to resources_url }
608
+ format.js { render :error, layout: false, status: status, locals: { result: result} }
609
+ format.json { render json: resources, status: status }
610
+ when 'update'
611
+ format.html { render :edit }
612
+ format.js { render :error, layout: false, status: status, locals: { result: result} }
613
+ format.json { render json: resource.errors, status: status }
614
+ when 'index', 'destroy'
615
+ # we should render index - but an error here will not make us happy
616
+ # format.html { render :index }
617
+ #
618
+ format.html { redirect_to root_path, alert: flash[:error] }
619
+ format.js { render :error, layout: false, status: status, locals: { result: result} }
620
+ format.json { render json: resources, status: status }
621
+ else
622
+ format.html { redirect_to a_url and return }
623
+ format.js { render :error, layout:false, status: status, locals: { result: result } }
624
+ end
625
+ end
626
+
627
+ end
289
628
 
290
629
  end