fae-railsz 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (328) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +5 -0
  3. data/Rakefile +37 -0
  4. data/app/assets/fonts/fae/icons.eot +0 -0
  5. data/app/assets/fonts/fae/icons.svg +56 -0
  6. data/app/assets/fonts/fae/icons.ttf +0 -0
  7. data/app/assets/fonts/fae/icons.woff +0 -0
  8. data/app/assets/fonts/fae/lato-bold-webfont.eot +0 -0
  9. data/app/assets/fonts/fae/lato-bold-webfont.svg +4551 -0
  10. data/app/assets/fonts/fae/lato-bold-webfont.ttf +0 -0
  11. data/app/assets/fonts/fae/lato-bold-webfont.woff +0 -0
  12. data/app/assets/fonts/fae/lato-light-webfont.eot +0 -0
  13. data/app/assets/fonts/fae/lato-light-webfont.svg +4241 -0
  14. data/app/assets/fonts/fae/lato-light-webfont.ttf +0 -0
  15. data/app/assets/fonts/fae/lato-light-webfont.woff +0 -0
  16. data/app/assets/fonts/fae/lato-regular-webfont.eot +0 -0
  17. data/app/assets/fonts/fae/lato-regular-webfont.svg +4241 -0
  18. data/app/assets/fonts/fae/lato-regular-webfont.ttf +0 -0
  19. data/app/assets/fonts/fae/lato-regular-webfont.woff +0 -0
  20. data/app/assets/fonts/fae/selection.json +1334 -0
  21. data/app/assets/images/fae/error_bg.jpg +0 -0
  22. data/app/assets/images/fae/error_sad_face.png +0 -0
  23. data/app/assets/images/fae/icons/alert.svg +9 -0
  24. data/app/assets/images/fae/icons/arrow_down.svg +8 -0
  25. data/app/assets/images/fae/icons/arrow_left.svg +9 -0
  26. data/app/assets/images/fae/icons/arrow_right.svg +9 -0
  27. data/app/assets/images/fae/icons/arrow_stacked.svg +8 -0
  28. data/app/assets/images/fae/icons/arrow_up.svg +8 -0
  29. data/app/assets/images/fae/icons/calendar.svg +17 -0
  30. data/app/assets/images/fae/icons/check.svg +7 -0
  31. data/app/assets/images/fae/icons/checkmark.svg +8 -0
  32. data/app/assets/images/fae/icons/chevron_down.svg +7 -0
  33. data/app/assets/images/fae/icons/chevron_left.svg +10 -0
  34. data/app/assets/images/fae/icons/chevron_right.svg +10 -0
  35. data/app/assets/images/fae/icons/chevron_up.svg +7 -0
  36. data/app/assets/images/fae/icons/delete.svg +8 -0
  37. data/app/assets/images/fae/icons/delete_x.svg +8 -0
  38. data/app/assets/images/fae/icons/edit.svg +11 -0
  39. data/app/assets/images/fae/icons/handle.svg +13 -0
  40. data/app/assets/images/fae/icons/home.svg +10 -0
  41. data/app/assets/images/fae/icons/logout.svg +12 -0
  42. data/app/assets/images/fae/icons/magnifying_glass.svg +10 -0
  43. data/app/assets/images/fae/icons/menu.svg +11 -0
  44. data/app/assets/images/fae/icons/offlink.svg +25 -0
  45. data/app/assets/images/fae/icons/plus.svg +8 -0
  46. data/app/assets/images/fae/icons/pulldown.svg +11 -0
  47. data/app/assets/images/fae/icons/search.svg +11 -0
  48. data/app/assets/images/fae/icons/settings.svg +12 -0
  49. data/app/assets/images/fae/icons/sort.svg +11 -0
  50. data/app/assets/images/fae/icons/support.svg +15 -0
  51. data/app/assets/images/fae/icons/trash.svg +10 -0
  52. data/app/assets/images/fae/icons/trumbowyg.svg +1 -0
  53. data/app/assets/images/fae/icons/user.svg +13 -0
  54. data/app/assets/images/fae/icons/users.svg +19 -0
  55. data/app/assets/images/fae/icons/zoom.svg +12 -0
  56. data/app/assets/images/fae/tutorial_model_location.png +0 -0
  57. data/app/assets/images/fae/youtube_helper.jpg +0 -0
  58. data/app/assets/javascripts/fae/_modals.js +60 -0
  59. data/app/assets/javascripts/fae/_tables.js +403 -0
  60. data/app/assets/javascripts/fae/admin.js.erb +11 -0
  61. data/app/assets/javascripts/fae/application.js +63 -0
  62. data/app/assets/javascripts/fae/fae_init.js +8 -0
  63. data/app/assets/javascripts/fae/form/_ajax.js +380 -0
  64. data/app/assets/javascripts/fae/form/_cancel.js +38 -0
  65. data/app/assets/javascripts/fae/form/_filtering.js +276 -0
  66. data/app/assets/javascripts/fae/form/_form.js +60 -0
  67. data/app/assets/javascripts/fae/form/_slugger.js.erb +100 -0
  68. data/app/assets/javascripts/fae/form/_validator.js +459 -0
  69. data/app/assets/javascripts/fae/form/fae_chosen.js +44 -0
  70. data/app/assets/javascripts/fae/form/fileinputer.js +178 -0
  71. data/app/assets/javascripts/fae/form/hinter.js +111 -0
  72. data/app/assets/javascripts/fae/form/inputs/_checkbox.js +27 -0
  73. data/app/assets/javascripts/fae/form/inputs/_color.js +42 -0
  74. data/app/assets/javascripts/fae/form/inputs/_dates.js +78 -0
  75. data/app/assets/javascripts/fae/form/inputs/_select.js +162 -0
  76. data/app/assets/javascripts/fae/form/inputs/_text.js +118 -0
  77. data/app/assets/javascripts/fae/navigation/_global_search.js +184 -0
  78. data/app/assets/javascripts/fae/navigation/_language.js +89 -0
  79. data/app/assets/javascripts/fae/navigation/_navigation.js +206 -0
  80. data/app/assets/javascripts/fae/navigation/_subnav_highlighter.js +81 -0
  81. data/app/assets/javascripts/fae/navigation/sticky.js +186 -0
  82. data/app/assets/javascripts/fae/vendor/chosen.jquery.min.js +2 -0
  83. data/app/assets/javascripts/fae/vendor/frob_core_helpers.js +587 -0
  84. data/app/assets/javascripts/fae/vendor/fryr.js +437 -0
  85. data/app/assets/javascripts/fae/vendor/jqColorPicker.min.js +4 -0
  86. data/app/assets/javascripts/fae/vendor/jquery.daterangepicker.js +1292 -0
  87. data/app/assets/javascripts/fae/vendor/jquery.multi-select.js +534 -0
  88. data/app/assets/javascripts/fae/vendor/jquery.simplemodal.1.4.4.js +719 -0
  89. data/app/assets/javascripts/fae/vendor/jquery.tablesorter.js +1901 -0
  90. data/app/assets/javascripts/fae/vendor/js.cookie.js +139 -0
  91. data/app/assets/javascripts/fae/vendor/moment.min.js +7 -0
  92. data/app/assets/javascripts/fae/vendor/simplemde.min.js +13 -0
  93. data/app/assets/javascripts/fae/vendor/touch_punch.js +11 -0
  94. data/app/assets/javascripts/fae/vendor/trumbowyg.js.erb +4 -0
  95. data/app/assets/javascripts/fae/vendor/trumbowyg/plugins/upload/trumbowyg.upload.js +223 -0
  96. data/app/assets/javascripts/fae/vendor/trumbowyg/trumbowyg.js +1603 -0
  97. data/app/assets/stylesheets/fae/application.css +8 -0
  98. data/app/assets/stylesheets/fae/base.scss +82 -0
  99. data/app/assets/stylesheets/fae/globals/_fonts.scss +43 -0
  100. data/app/assets/stylesheets/fae/globals/_icons.scss +15 -0
  101. data/app/assets/stylesheets/fae/globals/_plugins.scss +51 -0
  102. data/app/assets/stylesheets/fae/globals/_tags.scss +68 -0
  103. data/app/assets/stylesheets/fae/globals/imports/_extends.scss +53 -0
  104. data/app/assets/stylesheets/fae/globals/imports/_mixins.scss +58 -0
  105. data/app/assets/stylesheets/fae/globals/imports/_variables.scss +165 -0
  106. data/app/assets/stylesheets/fae/globals/imports/finescss/_fine.scss +7 -0
  107. data/app/assets/stylesheets/fae/globals/imports/finescss/_fine_functions.scss +88 -0
  108. data/app/assets/stylesheets/fae/globals/imports/finescss/_fine_mixins.scss +280 -0
  109. data/app/assets/stylesheets/fae/globals/imports/finescss/_fine_variables.scss +30 -0
  110. data/app/assets/stylesheets/fae/globals/layout/_base.scss +48 -0
  111. data/app/assets/stylesheets/fae/globals/layout/_breadcrumbs.scss +45 -0
  112. data/app/assets/stylesheets/fae/globals/layout/_content-header.scss +99 -0
  113. data/app/assets/stylesheets/fae/globals/legacy/_pre-1.3.scss +659 -0
  114. data/app/assets/stylesheets/fae/globals/navigation/_base.scss +22 -0
  115. data/app/assets/stylesheets/fae/globals/navigation/_footer.scss +50 -0
  116. data/app/assets/stylesheets/fae/globals/navigation/_header.scss +149 -0
  117. data/app/assets/stylesheets/fae/globals/navigation/_mobilenav.scss +149 -0
  118. data/app/assets/stylesheets/fae/globals/navigation/_search.scss +76 -0
  119. data/app/assets/stylesheets/fae/globals/navigation/_sidenav.scss +142 -0
  120. data/app/assets/stylesheets/fae/globals/navigation/_utility.scss +95 -0
  121. data/app/assets/stylesheets/fae/modules/_alerts.scss +50 -0
  122. data/app/assets/stylesheets/fae/modules/_buttons.scss +62 -0
  123. data/app/assets/stylesheets/fae/modules/_modal.scss +78 -0
  124. data/app/assets/stylesheets/fae/modules/_toggles.scss +48 -0
  125. data/app/assets/stylesheets/fae/modules/forms/_asset-actions.scss +83 -0
  126. data/app/assets/stylesheets/fae/modules/forms/_base.scss +100 -0
  127. data/app/assets/stylesheets/fae/modules/forms/_checkbox.scss +87 -0
  128. data/app/assets/stylesheets/fae/modules/forms/_colorpicker.scss +57 -0
  129. data/app/assets/stylesheets/fae/modules/forms/_date.scss +335 -0
  130. data/app/assets/stylesheets/fae/modules/forms/_hints.scss +40 -0
  131. data/app/assets/stylesheets/fae/modules/forms/_label.scss +57 -0
  132. data/app/assets/stylesheets/fae/modules/forms/_radio.scss +69 -0
  133. data/app/assets/stylesheets/fae/modules/forms/_select.scss +317 -0
  134. data/app/assets/stylesheets/fae/modules/forms/_simple-mde.scss +29 -0
  135. data/app/assets/stylesheets/fae/modules/forms/_text.scss +62 -0
  136. data/app/assets/stylesheets/fae/modules/forms/_textarea.scss +16 -0
  137. data/app/assets/stylesheets/fae/modules/forms/_validation.scss +63 -0
  138. data/app/assets/stylesheets/fae/modules/tables/_actions.scss +41 -0
  139. data/app/assets/stylesheets/fae/modules/tables/_base.scss +63 -0
  140. data/app/assets/stylesheets/fae/modules/tables/_collapsible.scss +76 -0
  141. data/app/assets/stylesheets/fae/modules/tables/_filters.scss +61 -0
  142. data/app/assets/stylesheets/fae/modules/tables/_image.scss +21 -0
  143. data/app/assets/stylesheets/fae/modules/tables/_pagination.scss +34 -0
  144. data/app/assets/stylesheets/fae/modules/tables/_sorting.scss +58 -0
  145. data/app/assets/stylesheets/fae/modules/tables/_sticky.scss +9 -0
  146. data/app/assets/stylesheets/fae/modules/tables/_tooltips.scss +24 -0
  147. data/app/assets/stylesheets/fae/pages/_error.scss +35 -0
  148. data/app/assets/stylesheets/fae/pages/_help.scss +28 -0
  149. data/app/assets/stylesheets/fae/pages/_home.scss +18 -0
  150. data/app/assets/stylesheets/fae/pages/_login.scss +137 -0
  151. data/app/assets/stylesheets/fae/vendor/chosen.css +377 -0
  152. data/app/assets/stylesheets/fae/vendor/daterangepicker.css +227 -0
  153. data/app/assets/stylesheets/fae/vendor/reset.css +48 -0
  154. data/app/assets/stylesheets/fae/vendor/simplemde.min.css +7 -0
  155. data/app/assets/stylesheets/fae/vendor/trumbowyg.css +584 -0
  156. data/app/controllers/concerns/fae/application_controller_concern.rb +1 -0
  157. data/app/controllers/concerns/fae/asset_cloner.rb +46 -0
  158. data/app/controllers/concerns/fae/cloneable.rb +136 -0
  159. data/app/controllers/fae/application_controller.rb +123 -0
  160. data/app/controllers/fae/base_controller.rb +117 -0
  161. data/app/controllers/fae/files_controller.rb +26 -0
  162. data/app/controllers/fae/images_controller.rb +37 -0
  163. data/app/controllers/fae/nested_base_controller.rb +100 -0
  164. data/app/controllers/fae/options_controller.rb +29 -0
  165. data/app/controllers/fae/pages_controller.rb +44 -0
  166. data/app/controllers/fae/setup_controller.rb +54 -0
  167. data/app/controllers/fae/static_pages_controller.rb +54 -0
  168. data/app/controllers/fae/users_controller.rb +71 -0
  169. data/app/controllers/fae/utilities_controller.rb +61 -0
  170. data/app/helpers/fae/application_helper.rb +114 -0
  171. data/app/helpers/fae/fae_helper.rb +6 -0
  172. data/app/helpers/fae/form_helper.rb +240 -0
  173. data/app/helpers/fae/nested_form_helper.rb +39 -0
  174. data/app/helpers/fae/view_helper.rb +175 -0
  175. data/app/inputs/date_range_input.rb +17 -0
  176. data/app/inputs/radio_collection_input.rb +17 -0
  177. data/app/inputs/symbol_input.rb +5 -0
  178. data/app/models/concerns/fae/assets_validatable.rb +12 -0
  179. data/app/models/concerns/fae/authorization_concern.rb +12 -0
  180. data/app/models/concerns/fae/base_model_concern.rb +105 -0
  181. data/app/models/concerns/fae/change_concern.rb +1 -0
  182. data/app/models/concerns/fae/file_concern.rb +1 -0
  183. data/app/models/concerns/fae/image_concern.rb +1 -0
  184. data/app/models/concerns/fae/navigation_concern.rb +10 -0
  185. data/app/models/concerns/fae/option_concern.rb +1 -0
  186. data/app/models/concerns/fae/page_validatable.rb +26 -0
  187. data/app/models/concerns/fae/paper_trailer.rb +8 -0
  188. data/app/models/concerns/fae/role_concern.rb +1 -0
  189. data/app/models/concerns/fae/sortable.rb +51 -0
  190. data/app/models/concerns/fae/static_page_concern.rb +1 -0
  191. data/app/models/concerns/fae/text_area_concern.rb +1 -0
  192. data/app/models/concerns/fae/text_field_concern.rb +1 -0
  193. data/app/models/concerns/fae/trackable.rb +124 -0
  194. data/app/models/concerns/fae/user_concern.rb +7 -0
  195. data/app/models/fae/authorization.rb +8 -0
  196. data/app/models/fae/change.rb +53 -0
  197. data/app/models/fae/file.rb +24 -0
  198. data/app/models/fae/image.rb +33 -0
  199. data/app/models/fae/navigation.rb +132 -0
  200. data/app/models/fae/option.rb +38 -0
  201. data/app/models/fae/role.rb +18 -0
  202. data/app/models/fae/static_page.rb +109 -0
  203. data/app/models/fae/text_area.rb +14 -0
  204. data/app/models/fae/text_field.rb +14 -0
  205. data/app/models/fae/user.rb +67 -0
  206. data/app/uploaders/fae/file_uploader.rb +26 -0
  207. data/app/uploaders/fae/image_uploader.rb +28 -0
  208. data/app/validators/fae/cross_model_uniqueness_validator.rb +14 -0
  209. data/app/views/devise/confirmations/new.html.slim +13 -0
  210. data/app/views/devise/mailer/confirmation_instructions.html.slim +3 -0
  211. data/app/views/devise/mailer/reset_password_instructions.html.slim +5 -0
  212. data/app/views/devise/mailer/unlock_instructions.html.slim +4 -0
  213. data/app/views/devise/passwords/edit.html.slim +10 -0
  214. data/app/views/devise/passwords/new.html.slim +10 -0
  215. data/app/views/devise/registrations/edit.html.slim +22 -0
  216. data/app/views/devise/registrations/new.html.slim +15 -0
  217. data/app/views/devise/sessions/new.html.slim +7 -0
  218. data/app/views/devise/shared/_links.slim +25 -0
  219. data/app/views/devise/unlocks/new.html.slim +13 -0
  220. data/app/views/fae/application/_breadcrumb.html.slim +19 -0
  221. data/app/views/fae/application/_content_form.html.slim +55 -0
  222. data/app/views/fae/application/_credit.slim +6 -0
  223. data/app/views/fae/application/_file_uploader.html.slim +36 -0
  224. data/app/views/fae/application/_flash_messages.slim +2 -0
  225. data/app/views/fae/application/_global_search_results.html.slim +37 -0
  226. data/app/views/fae/application/_header.slim +50 -0
  227. data/app/views/fae/application/_markdown_helper.slim +41 -0
  228. data/app/views/fae/application/_mobilenav.slim +66 -0
  229. data/app/views/fae/application/_sidenav.slim +23 -0
  230. data/app/views/fae/application/_user_log.html.slim +36 -0
  231. data/app/views/fae/images/_image_uploader.html.slim +66 -0
  232. data/app/views/fae/options/_form.html.slim +16 -0
  233. data/app/views/fae/options/edit.html.slim +1 -0
  234. data/app/views/fae/pages/activity_log.html.slim +32 -0
  235. data/app/views/fae/pages/disabled_environment.html.slim +4 -0
  236. data/app/views/fae/pages/error404.html.slim +7 -0
  237. data/app/views/fae/pages/help.html.slim +35 -0
  238. data/app/views/fae/pages/home.html.slim +36 -0
  239. data/app/views/fae/setup/first_user.html.slim +11 -0
  240. data/app/views/fae/shared/_errors.slim +4 -0
  241. data/app/views/fae/shared/_form_header.html.slim +40 -0
  242. data/app/views/fae/shared/_index_header.html.slim +26 -0
  243. data/app/views/fae/shared/_nested_table.html.slim +49 -0
  244. data/app/views/fae/shared/_recent_changes.html.slim +22 -0
  245. data/app/views/fae/shared/_shared_nested_table.html.slim +46 -0
  246. data/app/views/fae/static_pages/index.html.slim +13 -0
  247. data/app/views/fae/users/_form.html.slim +19 -0
  248. data/app/views/fae/users/edit.html.slim +1 -0
  249. data/app/views/fae/users/index.html.slim +23 -0
  250. data/app/views/fae/users/new.html.slim +1 -0
  251. data/app/views/fae/users/settings.html.slim +1 -0
  252. data/app/views/kaminari/fae/_gap.html.slim +8 -0
  253. data/app/views/kaminari/fae/_next_page.html.slim +9 -0
  254. data/app/views/kaminari/fae/_page.html.slim +15 -0
  255. data/app/views/kaminari/fae/_paginator.html.slim +15 -0
  256. data/app/views/kaminari/fae/_prev_page.html.slim +9 -0
  257. data/app/views/layouts/devise.html.slim +29 -0
  258. data/app/views/layouts/fae/application.html.slim +23 -0
  259. data/app/views/layouts/fae/error.html.slim +11 -0
  260. data/config/deploy.rb +73 -0
  261. data/config/deploy/dev.rb +19 -0
  262. data/config/deploy/prod.rb +19 -0
  263. data/config/deploy/stage.rb +19 -0
  264. data/config/initializers/assets.rb +1 -0
  265. data/config/initializers/carrierwave.rb +3 -0
  266. data/config/initializers/devise.rb +258 -0
  267. data/config/initializers/devise_monkeypatch.rb +11 -0
  268. data/config/initializers/fae_judge.rb +3 -0
  269. data/config/initializers/inflections.rb +16 -0
  270. data/config/initializers/kaminari_config.rb +10 -0
  271. data/config/initializers/simple_form.rb +147 -0
  272. data/config/initializers/time_formats.rb +3 -0
  273. data/config/locales/devise.en.yml +59 -0
  274. data/config/locales/devise.zh-CN.yml +59 -0
  275. data/config/locales/fae.en.yml +10 -0
  276. data/config/locales/fae.zh-CN.yml +10 -0
  277. data/config/locales/simple_form.en.yml +26 -0
  278. data/config/locales/simple_form.zh-CN.yml +26 -0
  279. data/config/routes.rb +46 -0
  280. data/db/migrate/20140809222030_add_user_table.rb +49 -0
  281. data/db/migrate/20140822224029_create_fae_roles.rb +10 -0
  282. data/db/migrate/20141008180718_create_fae_images_table.rb +19 -0
  283. data/db/migrate/20141017194616_create_fae_options.rb +16 -0
  284. data/db/migrate/20141021181327_create_fae_files.rb +17 -0
  285. data/db/migrate/20141021183047_create_fae_text_areas.rb +16 -0
  286. data/db/migrate/20141021184311_create_fae_pages.rb +13 -0
  287. data/db/migrate/20141105214814_create_fae_text_fields.rb +15 -0
  288. data/db/migrate/20150930224821_create_fae_changes.rb +17 -0
  289. data/lib/fae-rails.rb +6 -0
  290. data/lib/fae/concerns/models/base.rb +8 -0
  291. data/lib/fae/engine.rb +37 -0
  292. data/lib/fae/options.rb +35 -0
  293. data/lib/fae/validation_helper_collection.rb +76 -0
  294. data/lib/fae/version.rb +3 -0
  295. data/lib/file_size_validator.rb +71 -0
  296. data/lib/generators/fae/base_generator.rb +156 -0
  297. data/lib/generators/fae/controller_generator.rb +13 -0
  298. data/lib/generators/fae/install_generator.rb +61 -0
  299. data/lib/generators/fae/model_generator.rb +11 -0
  300. data/lib/generators/fae/nested_index_scaffold_generator.rb +36 -0
  301. data/lib/generators/fae/nested_scaffold_generator.rb +51 -0
  302. data/lib/generators/fae/page_generator.rb +65 -0
  303. data/lib/generators/fae/scaffold_generator.rb +15 -0
  304. data/lib/generators/fae/templates/assets/fae.js +6 -0
  305. data/lib/generators/fae/templates/assets/fae.scss +2 -0
  306. data/lib/generators/fae/templates/controllers/nested_index_scaffold_controller.rb +81 -0
  307. data/lib/generators/fae/templates/controllers/nested_scaffold_controller.rb +13 -0
  308. data/lib/generators/fae/templates/controllers/scaffold_controller.rb +13 -0
  309. data/lib/generators/fae/templates/controllers/static_pages_controller.rb +10 -0
  310. data/lib/generators/fae/templates/initializers/fae.rb +63 -0
  311. data/lib/generators/fae/templates/initializers/fae_fine.rb +51 -0
  312. data/lib/generators/fae/templates/initializers/judge.rb +6 -0
  313. data/lib/generators/fae/templates/models/concerns/authorization_concern.rb +27 -0
  314. data/lib/generators/fae/templates/models/concerns/navigation_concern.rb +33 -0
  315. data/lib/generators/fae/templates/models/pages_model.rb +14 -0
  316. data/lib/generators/fae/templates/tasks/fae_tasks.rake +19 -0
  317. data/lib/generators/fae/templates/views/_form.html.slim +18 -0
  318. data/lib/generators/fae/templates/views/_form_index_nested.html.slim +13 -0
  319. data/lib/generators/fae/templates/views/_form_nested.html.slim +17 -0
  320. data/lib/generators/fae/templates/views/edit.html.slim +1 -0
  321. data/lib/generators/fae/templates/views/edit_nested.html.slim +3 -0
  322. data/lib/generators/fae/templates/views/index.html.slim +35 -0
  323. data/lib/generators/fae/templates/views/index_nested.html.slim +8 -0
  324. data/lib/generators/fae/templates/views/new.html.slim +1 -0
  325. data/lib/generators/fae/templates/views/new_nested.html.slim +3 -0
  326. data/lib/generators/fae/templates/views/static_page_form.html.slim +15 -0
  327. data/lib/generators/fae/templates/views/table_nested.html.slim +4 -0
  328. metadata +692 -0
@@ -0,0 +1 @@
1
+ module Fae::ApplicationControllerConcern; end
@@ -0,0 +1,46 @@
1
+ module Fae
2
+ class AssetCloner
3
+ NoFileForOriginalResource = Class.new(StandardError)
4
+ UnknownStorage = Class.new(StandardError)
5
+
6
+ attr_reader :original_resource, :resource, :mount_point
7
+
8
+ def initialize(original_resource, resource, mount_point)
9
+ @mount_point = mount_point.to_sym
10
+ @original_resource = original_resource
11
+ @resource = resource
12
+ end
13
+
14
+ def set_file
15
+ if have_file?
16
+ case original_resource_mounter.send(:storage).class.name
17
+ when 'CarrierWave::Storage::File'
18
+ set_file_for_local_storage
19
+ when 'CarrierWave::Storage::Fog', 'CarrierWave::Storage::AWS'
20
+ set_file_for_remote_storage
21
+ else
22
+ raise UnknownStorage
23
+ end
24
+ else
25
+ raise NoFileForOriginalResource
26
+ end
27
+ end
28
+
29
+ def have_file?
30
+ original_resource_mounter.file.present? || original_resource_mounter.url
31
+ end
32
+
33
+ def set_file_for_remote_storage
34
+ resource.send(:"remote_#{mount_point.to_s}_url=", original_resource_mounter.url)
35
+ end
36
+
37
+ def set_file_for_local_storage
38
+ resource.send(:"#{mount_point.to_s}=", ::File.open(original_resource_mounter.file.file))
39
+ end
40
+
41
+ def original_resource_mounter
42
+ original_resource.send(mount_point)
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,136 @@
1
+ module Fae
2
+ module Cloneable
3
+ extend ActiveSupport::Concern
4
+
5
+ private
6
+
7
+ def create_from_existing(id)
8
+ @item = @klass.find(id)
9
+ @cloned_item = @item.dup
10
+ update_cloned_attributes(@cloned_item)
11
+ @cloned_item.on_prod = false if @item.respond_to?(:on_prod)
12
+
13
+ if @cloned_item.save
14
+ update_cloneable_associations
15
+ redirect_to @index_path + '/' + @cloned_item.id.to_s + '/edit'
16
+ else
17
+ build_assets
18
+ flash[:alert] = @cloned_item.errors.full_messages
19
+ render action: 'edit'
20
+ end
21
+ end
22
+
23
+ # array of symbols used for setting up associations on cloned object
24
+ def associations_for_cloning
25
+ []
26
+ end
27
+
28
+ # array of symbols used for cloning only specific attributes
29
+ def attributes_for_cloning
30
+ @klass.column_names
31
+ end
32
+
33
+ def update_cloned_attributes(item)
34
+ attribute_names = attributes_for_cloning.map(&:to_s) - ['id']
35
+ item.attributes.each do |attribute, value|
36
+ if attribute_names.include? attribute
37
+ rename_unique_attribute(item, attribute, value) if attr_is_unique?(item, attribute)
38
+ else
39
+ item.send("#{attribute}=", nil)
40
+ end
41
+ end
42
+ end
43
+
44
+ # set cloneable attributes and associations
45
+ def update_cloneable_associations
46
+ associations_for_cloning.each do |association|
47
+ type = @klass.reflect_on_association(association)
48
+ through_record = type.through_reflection
49
+
50
+ if through_record.present?
51
+ clone_join_relationships(through_record.plural_name)
52
+ else
53
+ clone_has_one_relationship(association,type) if type.macro == :has_one
54
+ clone_has_many_relationships(association) if type.macro == :has_many
55
+ end
56
+ end
57
+ end
58
+
59
+ def clone_has_one_relationship(association,type)
60
+ old_record = @item.send(association)
61
+
62
+ if old_record.present?
63
+ new_record = old_record.dup
64
+ if ['::Fae::Image','::Fae::File'].include?(type.options[:class_name])
65
+ new_record.send("#{type.options[:as]}_id" + '=', @cloned_item.id) if new_record.send("#{type.options[:as]}_id").present?
66
+ new_record.send("#{type.options[:as]}_type" + '=', @cloned_item.class.name) if new_record.send("#{type.options[:as]}_type").present?
67
+ Fae::AssetCloner.new(old_record, new_record, :asset).set_file if old_record.asset.present? && old_record.asset.url.present?
68
+ new_record.save
69
+ else
70
+ new_record.send("#{@klass_singular}_id" + '=', @cloned_item.id) if new_record.send("#{@klass_singular}_id").present?
71
+ end
72
+ new_record.attributes.each do |attribute, value|
73
+ rename_unique_attribute(new_record, attribute, value) if attr_is_unique?(new_record, attribute.first)
74
+ end
75
+ end
76
+ end
77
+
78
+ def clone_has_many_relationships(association)
79
+ if @item.send(association).present?
80
+ @item.send(association).reverse.each do |record|
81
+ new_record = association.to_s.classify.constantize.find_by_id(record.id).dup
82
+ new_record.send("#{@klass_singular}_id" + '=', @cloned_item.id) if new_record.send("#{@klass_singular}_id").present?
83
+ # check if associations have unique attributes
84
+ new_record.attributes.each do |attribute, value|
85
+ rename_unique_attribute(new_record, attribute, value) if attr_is_unique?(new_record, attribute.first)
86
+ end
87
+
88
+ @cloned_item.send(association) << new_record
89
+ end
90
+ end
91
+ end
92
+
93
+ def clone_join_relationships(object)
94
+ if @item.send(object.to_sym).present?
95
+ @item.send(object.to_sym).reverse.each do |record|
96
+ copied_join = object.classify.constantize.find_by_id(record.id).dup
97
+ copied_join.send("#{@klass_singular}_id" + '=', @cloned_item.id)
98
+ @cloned_item.send(object.to_sym) << copied_join
99
+ end
100
+ end
101
+ end
102
+
103
+ def rename_unique_attribute(item, attribute, value)
104
+ index = 2
105
+ symbol = attribute.to_sym
106
+ value = unique_name(item, attribute, value, index.to_s)
107
+
108
+ begin
109
+ record = item.class.where(symbol => value)
110
+ unless record.empty?
111
+ new_index = index + 1
112
+ value = value.chomp(index.to_s) + new_index.to_s
113
+ index = new_index
114
+ end
115
+ end while record.present?
116
+
117
+ item[symbol] = value
118
+ end
119
+
120
+ def attr_is_unique?(item, attribute)
121
+ item.class.validators_on(attribute.to_sym).map(&:class).include? ActiveRecord::Validations::UniquenessValidator
122
+ end
123
+
124
+ def unique_name(item, attribute, value, suffix)
125
+ item.class.validators_on(attribute.to_sym).each do |validator|
126
+ if validator.class.name.include?('LengthValidator') && validator.options[:maximum].present?
127
+ max_length = validator.options[:maximum] - (suffix.length + 1)
128
+ value = value[0...max_length]
129
+ break
130
+ end
131
+ end
132
+
133
+ "#{value}-#{suffix}"
134
+ end
135
+ end
136
+ end
@@ -0,0 +1,123 @@
1
+ module Fae
2
+ class ApplicationController < ActionController::Base
3
+ protect_from_forgery with: :exception
4
+
5
+ include Fae::ApplicationControllerConcern
6
+
7
+ helper Fae::ViewHelper
8
+ helper Fae::FormHelper
9
+ helper Fae::NestedFormHelper
10
+ helper Fae::FaeHelper
11
+
12
+ before_action :check_disabled_environment
13
+ before_action :first_user_redirect
14
+ before_action :authenticate_user!
15
+ before_action :build_nav
16
+ before_action :set_option
17
+ before_action :detect_cancellation
18
+ before_action :set_change_user
19
+ before_action :set_locale
20
+
21
+ private
22
+
23
+ def set_locale
24
+ I18n.locale = :en
25
+ end
26
+
27
+ def check_disabled_environment
28
+ disabled_envs = Fae.disabled_environments.map { |e| e.to_s }
29
+ return unless disabled_envs.include? Rails.env.to_s
30
+ render template: 'fae/pages/disabled_environment.html.slim', layout: 'fae/error.html.slim'
31
+ end
32
+
33
+ def super_admin_only
34
+ redirect_to fae.root_path, flash: { error: t('fae.unauthorized_error') } unless current_user.super_admin?
35
+ end
36
+
37
+ def admin_only
38
+ redirect_to fae.root_path, flash: { error: t('fae.unauthorized_error') } unless current_user.super_admin? || current_user.admin?
39
+ end
40
+
41
+ def show_404
42
+ render template: 'fae/pages/error404.html.slim', layout: 'fae/error.html.slim', status: :not_found
43
+ end
44
+
45
+ def set_option
46
+ @option = Fae::Option.instance
47
+ end
48
+
49
+ def detect_cancellation
50
+ flash.now[:warning] = 'Your changes were not saved.' if params[:cancelled].present? && params[:cancelled]== "true"
51
+ end
52
+
53
+ def build_nav
54
+ return unless current_user
55
+
56
+ # shameless green: if we continue to cache specific parts of Fae we should either:
57
+ # - create support methods to DRY this conditional logic
58
+ # - explore using `expires_in: 0` as a way to ignore caching
59
+ if Fae.use_cache
60
+ @fae_navigation = Rails.cache.fetch("fae_navigation_#{current_user.role.id}") do
61
+ Fae::Navigation.new(current_user)
62
+ end
63
+ else
64
+ @fae_navigation = Fae::Navigation.new(current_user)
65
+ end
66
+
67
+ raise_define_structure_error unless @fae_navigation.respond_to? :structure
68
+
69
+ @fae_topnav_items = @fae_navigation.items
70
+ @fae_sidenav_items = @fae_navigation.side_nav(request.path)
71
+ end
72
+
73
+ # redirect to login after sign out
74
+ def after_sign_out_path_for(resource_or_scope)
75
+ fae.new_user_session_path
76
+ end
77
+
78
+ # redirect to requested page after sign in
79
+ def after_sign_in_path_for(resource)
80
+ request.env['omniauth.origin'] || stored_location_for(resource) || fae.root_path
81
+ end
82
+
83
+ def first_user_redirect
84
+ redirect_to fae.first_user_path if Fae::User.live_super_admins.blank?
85
+ end
86
+
87
+ def set_change_user
88
+ Fae::Change.current_user = current_user.id if current_user.present?
89
+ end
90
+
91
+ def raise_define_structure_error
92
+ raise 'Fae::Navigation#structure is not defined, please define it in `app/models/concerns/fae/navigation_concern.rb`'
93
+ end
94
+
95
+ def all_models
96
+ if Fae.use_cache
97
+ Rails.cache.fetch('fae_all_models') do
98
+ load_and_filter_models
99
+ end
100
+ else
101
+ load_and_filter_models
102
+ end
103
+ end
104
+
105
+ def load_and_filter_models
106
+ # load of all models since Rails caches activerecord queries.
107
+ Rails.application.eager_load!
108
+ ActiveRecord::Base.descendants.map.reject { |m| m.name['Fae::'] || !m.instance_methods.include?(:fae_display_field) || Fae.dashboard_exclusions.include?(m.name) || !authorize_model(m) }
109
+ end
110
+
111
+ def authorize_model(model)
112
+ return false if current_user.blank? || current_user.role.blank? || current_user.role.name.blank?
113
+
114
+ users_role = current_user.role.name.downcase
115
+ tableized_model = model.name.tableize
116
+ role_group_for_model = Fae::Authorization.access_map[tableized_model]
117
+
118
+ return true if role_group_for_model.blank? || (role_group_for_model.present? && role_group_for_model.include?(users_role))
119
+ false
120
+ end
121
+
122
+ end
123
+ end
@@ -0,0 +1,117 @@
1
+ module Fae
2
+ class BaseController < ApplicationController
3
+ include Fae::Cloneable
4
+
5
+ before_action :set_class_variables
6
+ before_action :set_item, only: [:edit, :update, :destroy]
7
+ before_action :authorize_user
8
+
9
+ helper FormHelper
10
+
11
+ def index
12
+ if use_pagination
13
+ @items = @klass.for_fae_index.page(params[:page])
14
+ else
15
+ @items = @klass.for_fae_index
16
+ end
17
+ respond_to do |format|
18
+ format.html
19
+ format.csv { send_data @items.to_csv, filename: @items.name.parameterize + "." + Time.now.to_s(:filename) + '.csv' }
20
+ end
21
+ end
22
+
23
+ def new
24
+ @item = @klass.new
25
+ build_assets
26
+ end
27
+
28
+ def edit
29
+ build_assets
30
+ end
31
+
32
+ def create
33
+ return create_from_existing(params[:from_existing]) if params[:from_existing].present?
34
+
35
+ @item = @klass.new(item_params)
36
+
37
+ if @item.save
38
+ redirect_to @index_path, notice: t('fae.save_notice')
39
+ else
40
+ build_assets
41
+ flash[:alert] = t('fae.save_error')
42
+ render action: 'new'
43
+ end
44
+ end
45
+
46
+ def update
47
+ if @item.update(item_params)
48
+ redirect_to @index_path, notice: t('fae.save_notice')
49
+ else
50
+ build_assets
51
+ flash[:alert] = t('fae.save_error')
52
+ render action: 'edit'
53
+ end
54
+ end
55
+
56
+ def destroy
57
+ if @item.destroy
58
+ redirect_to @index_path, notice: t('fae.delete_notice')
59
+ else
60
+ redirect_to @index_path, flash: { error: t('fae.delete_error') }
61
+ end
62
+ end
63
+
64
+ def filter
65
+ if use_pagination
66
+ @items = @klass.filter(params).fae_sort(params).page(params[:page])
67
+ else
68
+ @items = @klass.filter(params).fae_sort(params)
69
+ end
70
+
71
+ render :index, layout: false
72
+ end
73
+
74
+ def show
75
+ # show action is hidden by default, override as needed
76
+ show_404
77
+ end
78
+
79
+ private
80
+
81
+ def set_class_variables(class_name = nil)
82
+ klass_base = params[:controller].split('/').last
83
+ @klass_name = class_name || klass_base # used in form views
84
+ @klass = klass_base.classify.constantize # used as class reference in this controller
85
+ @klass_singular = klass_base.singularize # used in index views
86
+ @klass_humanized = @klass_name.singularize.humanize # used in index views
87
+ @index_path = '/' + params[:controller] # used in form_header partial
88
+ @new_path = @index_path + '/new' # used in index_header partial
89
+ end
90
+
91
+ # use callbacks to share common setup or constraints between actions.
92
+ def set_item
93
+ @item = @klass.find(params[:id])
94
+ end
95
+
96
+ # only allow trusted parameters, override to white-list
97
+ def item_params
98
+ params.require(@klass_singular).permit!
99
+ end
100
+
101
+ # if model has images or files, build them here for nesting
102
+ def build_assets
103
+ end
104
+
105
+ def authorize_user
106
+ roles_for_controller = Fae::Authorization.access_map[params[:controller].gsub('admin/','')]
107
+ return if current_user.super_admin? || roles_for_controller.blank?
108
+ return show_404 unless roles_for_controller.include?(current_user.role.name)
109
+ end
110
+
111
+ # allows this controller to use pagination
112
+ def use_pagination
113
+ false
114
+ end
115
+
116
+ end
117
+ end
@@ -0,0 +1,26 @@
1
+ module Fae
2
+ class FilesController < ApplicationController
3
+ # ajax delete action
4
+ #
5
+ # post 'files/:id/delete_file' => 'files#delete_file', as: :delete_file
6
+ # here we just remove the asset from the attached file model, because if we deleted
7
+ # the model itself, re-uploading a new one would break.
8
+ def delete_file
9
+ file = Fae::File.find_by_id(params[:id])
10
+ file.remove_asset = true
11
+ file.save
12
+ render body: nil
13
+ end
14
+
15
+ private
16
+
17
+ # allow mass assignment
18
+ def file_params
19
+ if params[:file].present?
20
+ params.require(:file).permit!
21
+ else
22
+ nil
23
+ end
24
+ end
25
+ end
26
+ end