forest_cms 0.98.1

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 (411) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +204 -0
  4. data/Rakefile +37 -0
  5. data/app/assets/config/forest_manifest.js +2 -0
  6. data/app/assets/fonts/FontAwesome.otf +0 -0
  7. data/app/assets/fonts/fontawesome-webfont.eot +0 -0
  8. data/app/assets/fonts/fontawesome-webfont.svg +2671 -0
  9. data/app/assets/fonts/fontawesome-webfont.ttf +0 -0
  10. data/app/assets/fonts/fontawesome-webfont.woff +0 -0
  11. data/app/assets/fonts/fontawesome-webfont.woff2 +0 -0
  12. data/app/assets/images/forest/favicons/android-chrome-192x192.png +0 -0
  13. data/app/assets/images/forest/favicons/android-chrome-512x512.png +0 -0
  14. data/app/assets/images/forest/favicons/apple-touch-icon.png +0 -0
  15. data/app/assets/images/forest/favicons/browserconfig.xml +9 -0
  16. data/app/assets/images/forest/favicons/favicon-16x16.png +0 -0
  17. data/app/assets/images/forest/favicons/favicon-32x32.png +0 -0
  18. data/app/assets/images/forest/favicons/favicon.ico +0 -0
  19. data/app/assets/images/forest/favicons/manifest.json.erb +18 -0
  20. data/app/assets/images/forest/favicons/mstile-150x150.png +0 -0
  21. data/app/assets/images/forest/favicons/safari-pinned-tab.svg +21 -0
  22. data/app/assets/images/forest/forest-low.jpg +0 -0
  23. data/app/assets/images/forest/forest.jpg +0 -0
  24. data/app/assets/javascripts/forest/admin/lib/jquery_plugins.js +32 -0
  25. data/app/assets/javascripts/forest/admin/main.js +59 -0
  26. data/app/assets/javascripts/forest/admin/partials/add_block.js +22 -0
  27. data/app/assets/javascripts/forest/admin/partials/block_collapser.js +49 -0
  28. data/app/assets/javascripts/forest/admin/partials/block_errors.js +11 -0
  29. data/app/assets/javascripts/forest/admin/partials/block_selector_inputs.js +61 -0
  30. data/app/assets/javascripts/forest/admin/partials/cocoon_events.js +3 -0
  31. data/app/assets/javascripts/forest/admin/partials/cocoon_sortable_field_sets.js +55 -0
  32. data/app/assets/javascripts/forest/admin/partials/collage_inputs.js +286 -0
  33. data/app/assets/javascripts/forest/admin/partials/color_inputs.js +24 -0
  34. data/app/assets/javascripts/forest/admin/partials/datepicker_init.js +70 -0
  35. data/app/assets/javascripts/forest/admin/partials/documentation_sidebar_affix.js +22 -0
  36. data/app/assets/javascripts/forest/admin/partials/dropdown_block_selector.js +106 -0
  37. data/app/assets/javascripts/forest/admin/partials/edit_header.js +22 -0
  38. data/app/assets/javascripts/forest/admin/partials/file_upload_init.js +111 -0
  39. data/app/assets/javascripts/forest/admin/partials/forest_tables.js +42 -0
  40. data/app/assets/javascripts/forest/admin/partials/infinite_loader.js +89 -0
  41. data/app/assets/javascripts/forest/admin/partials/markdown_text_editor_init.js +89 -0
  42. data/app/assets/javascripts/forest/admin/partials/media_item_chooser_modal.js.erb +259 -0
  43. data/app/assets/javascripts/forest/admin/partials/menus.js +79 -0
  44. data/app/assets/javascripts/forest/admin/partials/multi_checkbox_selector.js +27 -0
  45. data/app/assets/javascripts/forest/admin/partials/persisted_value_warnings.js +38 -0
  46. data/app/assets/javascripts/forest/admin/partials/repeater_inputs.js +24 -0
  47. data/app/assets/javascripts/forest/admin/partials/select2_init.js +165 -0
  48. data/app/assets/javascripts/forest/admin/partials/select_tag_form_submitter.js +40 -0
  49. data/app/assets/javascripts/forest/admin/partials/sortable_gallery.js +45 -0
  50. data/app/assets/javascripts/forest/admin/partials/sortable_page_block_position_setter.js +37 -0
  51. data/app/assets/javascripts/forest/admin/partials/status_scheduler.js +16 -0
  52. data/app/assets/javascripts/forest/admin/partials/tab_templates.js +93 -0
  53. data/app/assets/javascripts/forest/admin/partials/tables.js +7 -0
  54. data/app/assets/javascripts/forest/admin/partials/tooltips.js +7 -0
  55. data/app/assets/javascripts/forest/admin/partials/turboform_form_submitter.js +15 -0
  56. data/app/assets/javascripts/forest/admin/vendor/imagesloaded.pkgd.min.js +7 -0
  57. data/app/assets/javascripts/forest/admin/vendor/jquery-ui-timepicker-addon.js +2291 -0
  58. data/app/assets/javascripts/forest/admin/vendor/jquery.ba-throttle-debounce.min.js +9 -0
  59. data/app/assets/javascripts/forest/admin/vendor/jquery.nestable.js +756 -0
  60. data/app/assets/javascripts/forest/admin/vendor/select2.full.min.js +3 -0
  61. data/app/assets/javascripts/forest/admin/vendor/simplemde.min.js +15 -0
  62. data/app/assets/javascripts/forest/application_admin.js +29 -0
  63. data/app/assets/javascripts/forest/application_admin_from_host_app.js +1 -0
  64. data/app/assets/javascripts/forest/application_public.js +19 -0
  65. data/app/assets/javascripts/forest/cable.js +13 -0
  66. data/app/assets/javascripts/forest/lib/jquery-3.3.1.min.js +2 -0
  67. data/app/assets/javascripts/forest/main.js +59 -0
  68. data/app/assets/javascripts/forest/public/partials/analytics.js +16 -0
  69. data/app/assets/stylesheets/forest/admin/_bootstrap-variables.scss +877 -0
  70. data/app/assets/stylesheets/forest/admin/_variables.scss +13 -0
  71. data/app/assets/stylesheets/forest/admin/base/_foundation.scss +17 -0
  72. data/app/assets/stylesheets/forest/admin/mixins/_breakpoints.scss +26 -0
  73. data/app/assets/stylesheets/forest/admin/mixins/_glyphicons.scss +278 -0
  74. data/app/assets/stylesheets/forest/admin/mixins/_layout.scss +13 -0
  75. data/app/assets/stylesheets/forest/admin/mixins/_links.scss +10 -0
  76. data/app/assets/stylesheets/forest/admin/mixins/_lists.scss +10 -0
  77. data/app/assets/stylesheets/forest/admin/mixins/_mixins.scss +6 -0
  78. data/app/assets/stylesheets/forest/admin/mixins/_triangles.scss +21 -0
  79. data/app/assets/stylesheets/forest/admin/partials/_admin.scss +57 -0
  80. data/app/assets/stylesheets/forest/admin/partials/_affix.scss +5 -0
  81. data/app/assets/stylesheets/forest/admin/partials/_block_errors.scss +15 -0
  82. data/app/assets/stylesheets/forest/admin/partials/_block_layout.scss +48 -0
  83. data/app/assets/stylesheets/forest/admin/partials/_block_type_edit_ui.scss +15 -0
  84. data/app/assets/stylesheets/forest/admin/partials/_bootstrap_customizations.scss +12 -0
  85. data/app/assets/stylesheets/forest/admin/partials/_collage_inputs.scss +122 -0
  86. data/app/assets/stylesheets/forest/admin/partials/_documentation.scss +7 -0
  87. data/app/assets/stylesheets/forest/admin/partials/_dropdown_block_selector.scss +19 -0
  88. data/app/assets/stylesheets/forest/admin/partials/_edit_header.scss +16 -0
  89. data/app/assets/stylesheets/forest/admin/partials/_file_upload.scss +3 -0
  90. data/app/assets/stylesheets/forest/admin/partials/_forest_tables.scss +20 -0
  91. data/app/assets/stylesheets/forest/admin/partials/_forms_and_inputs.scss +72 -0
  92. data/app/assets/stylesheets/forest/admin/partials/_helper_classes.scss +24 -0
  93. data/app/assets/stylesheets/forest/admin/partials/_infinite_loader.scss +8 -0
  94. data/app/assets/stylesheets/forest/admin/partials/_markdown_editor.scss +12 -0
  95. data/app/assets/stylesheets/forest/admin/partials/_media_item_chooser.scss +168 -0
  96. data/app/assets/stylesheets/forest/admin/partials/_media_library.scss +109 -0
  97. data/app/assets/stylesheets/forest/admin/partials/_pages.scss +6 -0
  98. data/app/assets/stylesheets/forest/admin/partials/_pagination.scss +5 -0
  99. data/app/assets/stylesheets/forest/admin/partials/_repeater_inputs.scss +57 -0
  100. data/app/assets/stylesheets/forest/admin/partials/_resizable_ui.scss +1 -0
  101. data/app/assets/stylesheets/forest/admin/partials/_select2_custom.scss +20 -0
  102. data/app/assets/stylesheets/forest/admin/partials/_sessions.scss +13 -0
  103. data/app/assets/stylesheets/forest/admin/partials/_slug_attributes.scss +9 -0
  104. data/app/assets/stylesheets/forest/admin/partials/_sortable_field_sets.scss +22 -0
  105. data/app/assets/stylesheets/forest/admin/partials/_sortable_select2.scss +18 -0
  106. data/app/assets/stylesheets/forest/admin/partials/_sortable_ui.scss +15 -0
  107. data/app/assets/stylesheets/forest/admin/partials/_status_indicators.scss +33 -0
  108. data/app/assets/stylesheets/forest/admin/partials/_status_scheduler.scss +9 -0
  109. data/app/assets/stylesheets/forest/admin/partials/_tooltips.scss +5 -0
  110. data/app/assets/stylesheets/forest/admin/partials/_turbolinks.scss +5 -0
  111. data/app/assets/stylesheets/forest/admin/partials/_typography.scss +19 -0
  112. data/app/assets/stylesheets/forest/admin/partials/_ui.scss +32 -0
  113. data/app/assets/stylesheets/forest/admin/sprockets/font-awesome.scss +2337 -0
  114. data/app/assets/stylesheets/forest/admin/sprockets/main_bootstrap.scss +3 -0
  115. data/app/assets/stylesheets/forest/admin/vendor/_jquery-ui-timepicker-addon.scss +30 -0
  116. data/app/assets/stylesheets/forest/admin/vendor/_nestable.scss +347 -0
  117. data/app/assets/stylesheets/forest/admin/vendor/_select2_1_core.scss +484 -0
  118. data/app/assets/stylesheets/forest/admin/vendor/_select2_2_bootstrap.scss +612 -0
  119. data/app/assets/stylesheets/forest/admin/vendor/_simplemde.min.scss +7 -0
  120. data/app/assets/stylesheets/forest/admin_overrides.scss +1 -0
  121. data/app/assets/stylesheets/forest/application_admin.css +23 -0
  122. data/app/assets/stylesheets/forest/application_public.css +16 -0
  123. data/app/assets/stylesheets/forest/main_admin.scss +16 -0
  124. data/app/assets/stylesheets/forest/main_public.scss +4 -0
  125. data/app/assets/stylesheets/forest/public/base/_admin_error_messages.scss +15 -0
  126. data/app/assets/stylesheets/forest/public/base/_foundation.scss +24 -0
  127. data/app/assets/stylesheets/forest/public/base/_images.scss +14 -0
  128. data/app/assets/stylesheets/forest/scaffolds.scss +87 -0
  129. data/app/assets/stylesheets/jquery.fileupload.scss +37 -0
  130. data/app/classes/forest/block_set.rb +26 -0
  131. data/app/classes/forest/error.rb +15 -0
  132. data/app/classes/forest/markdown_renderer.rb +31 -0
  133. data/app/classes/search_index_manager.rb +83 -0
  134. data/app/controllers/admin/block_kinds_controller.rb +31 -0
  135. data/app/controllers/admin/block_layouts_controller.rb +47 -0
  136. data/app/controllers/admin/cache_purge_controller.rb +11 -0
  137. data/app/controllers/admin/dashboard_controller.rb +6 -0
  138. data/app/controllers/admin/documentation_controller.rb +5 -0
  139. data/app/controllers/admin/errors_controller.rb +9 -0
  140. data/app/controllers/admin/forest_controller.rb +96 -0
  141. data/app/controllers/admin/imports_controller.rb +34 -0
  142. data/app/controllers/admin/media_items_controller.rb +107 -0
  143. data/app/controllers/admin/menus_controller.rb +69 -0
  144. data/app/controllers/admin/pages_controller.rb +105 -0
  145. data/app/controllers/admin/settings_controller.rb +66 -0
  146. data/app/controllers/admin/translations_controller.rb +58 -0
  147. data/app/controllers/admin/user_groups_controller.rb +69 -0
  148. data/app/controllers/admin/users_controller.rb +88 -0
  149. data/app/controllers/application_controller.rb +2 -0
  150. data/app/controllers/errors_controller.rb +26 -0
  151. data/app/controllers/forest_controller.rb +39 -0
  152. data/app/controllers/media_items_controller.rb +12 -0
  153. data/app/controllers/pages_controller.rb +39 -0
  154. data/app/controllers/public_controller.rb +5 -0
  155. data/app/helpers/admin_helper.rb +95 -0
  156. data/app/helpers/admin_info_helper.rb +12 -0
  157. data/app/helpers/admin_settings_helper.rb +16 -0
  158. data/app/helpers/application_helper.rb +2 -0
  159. data/app/helpers/block_helper.rb +25 -0
  160. data/app/helpers/cache_helper.rb +23 -0
  161. data/app/helpers/forest_errors_helper.rb +34 -0
  162. data/app/helpers/form_helper.rb +93 -0
  163. data/app/helpers/image_helper.rb +65 -0
  164. data/app/helpers/markdown_helper.rb +25 -0
  165. data/app/helpers/meta_helper.rb +238 -0
  166. data/app/helpers/navigation_helper.rb +18 -0
  167. data/app/helpers/status_indicator_helper.rb +7 -0
  168. data/app/inputs/block_selector_input.rb +16 -0
  169. data/app/inputs/collage_input.rb +63 -0
  170. data/app/inputs/color_input.rb +30 -0
  171. data/app/inputs/currency_input.rb +22 -0
  172. data/app/inputs/datepicker_input.rb +19 -0
  173. data/app/inputs/gallery_input.rb +67 -0
  174. data/app/inputs/grouped_collection_select_input.rb +19 -0
  175. data/app/inputs/image_input.rb +82 -0
  176. data/app/inputs/repeater_input.rb +58 -0
  177. data/app/jobs/forest/application_job.rb +4 -0
  178. data/app/mailers/forest/application_mailer.rb +6 -0
  179. data/app/models/application_record.rb +13 -0
  180. data/app/models/block_kind.rb +54 -0
  181. data/app/models/block_layout.rb +19 -0
  182. data/app/models/block_slot.rb +49 -0
  183. data/app/models/blocks/base_block.rb +134 -0
  184. data/app/models/cache_record.rb +2 -0
  185. data/app/models/concerns/attachable.rb +126 -0
  186. data/app/models/concerns/blockable.rb +65 -0
  187. data/app/models/concerns/filter_controller_scopes.rb +13 -0
  188. data/app/models/concerns/forest/cache_buster.rb +112 -0
  189. data/app/models/concerns/searchable.rb +200 -0
  190. data/app/models/concerns/sluggable.rb +70 -0
  191. data/app/models/concerns/statusable.rb +71 -0
  192. data/app/models/concerns/versionable.rb +13 -0
  193. data/app/models/forest/application_record.rb +111 -0
  194. data/app/models/import.rb +43 -0
  195. data/app/models/media_item.rb +136 -0
  196. data/app/models/menu.rb +65 -0
  197. data/app/models/page.rb +154 -0
  198. data/app/models/setting.rb +142 -0
  199. data/app/models/translation.rb +97 -0
  200. data/app/models/user.rb +45 -0
  201. data/app/models/user_group.rb +17 -0
  202. data/app/policies/application_policy.rb +71 -0
  203. data/app/policies/block_kind_policy.rb +2 -0
  204. data/app/policies/block_layout_policy.rb +2 -0
  205. data/app/policies/block_record_policy.rb +13 -0
  206. data/app/policies/dashboard_policy.rb +19 -0
  207. data/app/policies/media_item_policy.rb +5 -0
  208. data/app/policies/menu_policy.rb +2 -0
  209. data/app/policies/page_policy.rb +9 -0
  210. data/app/policies/setting_policy.rb +2 -0
  211. data/app/policies/translation_policy.rb +2 -0
  212. data/app/policies/user_group_policy.rb +2 -0
  213. data/app/policies/user_policy.rb +17 -0
  214. data/app/views/admin/_file_upload.html.erb +75 -0
  215. data/app/views/admin/_flash_notifications.html.erb +20 -0
  216. data/app/views/admin/_navigation.html.erb +61 -0
  217. data/app/views/admin/api/index/_header.json.jbuilder +2 -0
  218. data/app/views/admin/api/index/_records.json.jbuilder +6 -0
  219. data/app/views/admin/block_kinds/_form.html.erb +34 -0
  220. data/app/views/admin/block_kinds/edit.html.erb +3 -0
  221. data/app/views/admin/block_kinds/index.html.erb +31 -0
  222. data/app/views/admin/block_layouts/_form.html.erb +33 -0
  223. data/app/views/admin/block_layouts/edit.html.erb +3 -0
  224. data/app/views/admin/block_layouts/index.html.erb +29 -0
  225. data/app/views/admin/block_layouts/new.html.erb +3 -0
  226. data/app/views/admin/block_layouts/show.html.erb +24 -0
  227. data/app/views/admin/block_record/_block_layout.html.erb +67 -0
  228. data/app/views/admin/block_record/_block_slot_field_buttons.html.erb +15 -0
  229. data/app/views/admin/block_record/_block_slot_fields.html.erb +37 -0
  230. data/app/views/admin/block_record/_block_slot_fields_template.html.erb +50 -0
  231. data/app/views/admin/dashboard/_panel.html.erb +30 -0
  232. data/app/views/admin/dashboard/index.html.erb +18 -0
  233. data/app/views/admin/documentation/_body.html.erb +9 -0
  234. data/app/views/admin/documentation/_sidebar.html.erb +17 -0
  235. data/app/views/admin/documentation/index.html.erb +87 -0
  236. data/app/views/admin/form_inputs/_slug.html.erb +11 -0
  237. data/app/views/admin/form_inputs/_status.html.erb +20 -0
  238. data/app/views/admin/form_inputs/collage/_media_item_fields.html.erb +41 -0
  239. data/app/views/admin/headers/_edit.html.erb +68 -0
  240. data/app/views/admin/headers/_index.html.erb +61 -0
  241. data/app/views/admin/headers/_new.html.erb +14 -0
  242. data/app/views/admin/headers/_show.html.erb +37 -0
  243. data/app/views/admin/imports/edit.html.erb +60 -0
  244. data/app/views/admin/media_items/_form.html.erb +54 -0
  245. data/app/views/admin/media_items/_media_item_grid_layout.html.erb +23 -0
  246. data/app/views/admin/media_items/_media_item_list_layout.html.erb +32 -0
  247. data/app/views/admin/media_items/_modal.html.erb +62 -0
  248. data/app/views/admin/media_items/edit.html.erb +3 -0
  249. data/app/views/admin/media_items/index.html.erb +58 -0
  250. data/app/views/admin/media_items/index.json.jbuilder +2 -0
  251. data/app/views/admin/media_items/new.html.erb +3 -0
  252. data/app/views/admin/menus/_form.html.erb +92 -0
  253. data/app/views/admin/menus/_list_item.html.erb +39 -0
  254. data/app/views/admin/menus/edit.html.erb +3 -0
  255. data/app/views/admin/menus/index.html.erb +29 -0
  256. data/app/views/admin/menus/new.html.erb +3 -0
  257. data/app/views/admin/menus/show.html.erb +3 -0
  258. data/app/views/admin/navigation/_resources_dropdown.html.erb +12 -0
  259. data/app/views/admin/pages/_additional_inputs.html.erb +1 -0
  260. data/app/views/admin/pages/_form.html.erb +52 -0
  261. data/app/views/admin/pages/_table_row.html.erb +14 -0
  262. data/app/views/admin/pages/edit.html.erb +3 -0
  263. data/app/views/admin/pages/index.html.erb +33 -0
  264. data/app/views/admin/pages/index.json.jbuilder +2 -0
  265. data/app/views/admin/pages/new.html.erb +3 -0
  266. data/app/views/admin/pages/show.html.erb +3 -0
  267. data/app/views/admin/settings/_form.html.erb +25 -0
  268. data/app/views/admin/settings/edit.html.erb +3 -0
  269. data/app/views/admin/settings/index.html.erb +38 -0
  270. data/app/views/admin/settings/new.html.erb +3 -0
  271. data/app/views/admin/settings/show.html.erb +19 -0
  272. data/app/views/admin/settings/types/_boolean.html.erb +1 -0
  273. data/app/views/admin/settings/types/_image.html.erb +10 -0
  274. data/app/views/admin/settings/types/_integer.html.erb +5 -0
  275. data/app/views/admin/settings/types/_string.html.erb +5 -0
  276. data/app/views/admin/settings/types/_text.html.erb +5 -0
  277. data/app/views/admin/shared/_admin_head_additions.html.erb +1 -0
  278. data/app/views/admin/shared/navigation/_navbar.html.erb +8 -0
  279. data/app/views/admin/translations/_form.html.erb +31 -0
  280. data/app/views/admin/translations/edit.html.erb +3 -0
  281. data/app/views/admin/translations/index.html.erb +41 -0
  282. data/app/views/admin/translations/new.html.erb +3 -0
  283. data/app/views/admin/translations/show.html.erb +19 -0
  284. data/app/views/admin/user_groups/_form.html.erb +11 -0
  285. data/app/views/admin/user_groups/edit.html.erb +3 -0
  286. data/app/views/admin/user_groups/index.html.erb +29 -0
  287. data/app/views/admin/user_groups/new.html.erb +3 -0
  288. data/app/views/admin/user_groups/show.html.erb +9 -0
  289. data/app/views/admin/users/_form.html.erb +41 -0
  290. data/app/views/admin/users/edit.html.erb +3 -0
  291. data/app/views/admin/users/index.html.erb +35 -0
  292. data/app/views/admin/users/new.html.erb +3 -0
  293. data/app/views/admin/users/show.html.erb +4 -0
  294. data/app/views/blocks/_show.html.erb +21 -0
  295. data/app/views/devise/confirmations/new.html.erb +28 -0
  296. data/app/views/devise/mailer/confirmation_instructions.html.erb +5 -0
  297. data/app/views/devise/mailer/password_change.html.erb +3 -0
  298. data/app/views/devise/mailer/reset_password_instructions.html.erb +8 -0
  299. data/app/views/devise/mailer/unlock_instructions.html.erb +7 -0
  300. data/app/views/devise/passwords/edit.html.erb +31 -0
  301. data/app/views/devise/passwords/new.html.erb +27 -0
  302. data/app/views/devise/registrations/edit.html.erb +39 -0
  303. data/app/views/devise/registrations/new.html.erb +1 -0
  304. data/app/views/devise/sessions/_default_login.html.erb +25 -0
  305. data/app/views/devise/sessions/_first_time_login.html.erb +22 -0
  306. data/app/views/devise/sessions/new.html.erb +12 -0
  307. data/app/views/devise/shared/_flash_notifications.html.erb +3 -0
  308. data/app/views/devise/shared/_links.html.erb +25 -0
  309. data/app/views/devise/unlocks/new.html.erb +28 -0
  310. data/app/views/errors/internal_server_error.html.erb +2 -0
  311. data/app/views/errors/internal_server_error.json.jbuilder +4 -0
  312. data/app/views/errors/not_found.html.erb +2 -0
  313. data/app/views/errors/not_found.json.jbuilder +4 -0
  314. data/app/views/errors/unprocessable.html.erb +2 -0
  315. data/app/views/errors/unprocessable.json.jbuilder +4 -0
  316. data/app/views/forest/_analytics.html.erb +10 -0
  317. data/app/views/forest/_favicons.html.erb +7 -0
  318. data/app/views/kaminari/_first_page.html.erb +11 -0
  319. data/app/views/kaminari/_gap.html.erb +8 -0
  320. data/app/views/kaminari/_last_page.html.erb +11 -0
  321. data/app/views/kaminari/_next_page.html.erb +11 -0
  322. data/app/views/kaminari/_page.html.erb +12 -0
  323. data/app/views/kaminari/_paginator.html.erb +25 -0
  324. data/app/views/kaminari/_prev_page.html.erb +11 -0
  325. data/app/views/layouts/_shared_head.html.erb +48 -0
  326. data/app/views/layouts/admin.html.erb +19 -0
  327. data/app/views/layouts/application.html.erb +15 -0
  328. data/app/views/layouts/devise.html.erb +12 -0
  329. data/app/views/layouts/mailer.html.erb +13 -0
  330. data/app/views/layouts/mailer.text.erb +1 -0
  331. data/app/views/media_items/show.html.erb +29 -0
  332. data/app/views/pages/show.html.erb +1 -0
  333. data/app/views/public/index.html.erb +2 -0
  334. data/app/views/shared/_footer.html.erb +9 -0
  335. data/app/views/shared/_header.html.erb +9 -0
  336. data/app/views/shared/_header_colophon.html.erb +7 -0
  337. data/app/views/shared/_menu.html.erb +5 -0
  338. data/app/views/shared/_menu_item.html.erb +30 -0
  339. data/app/views/shared/_subnav.html.erb +7 -0
  340. data/config/initializers/aws.rb +17 -0
  341. data/config/initializers/devise.rb +275 -0
  342. data/config/initializers/forest.rb +5 -0
  343. data/config/initializers/paperclip.rb +1 -0
  344. data/config/initializers/rails_extensions.rb +6 -0
  345. data/config/initializers/simple_form.rb +164 -0
  346. data/config/initializers/simple_form/markdown.rb +21 -0
  347. data/config/initializers/simple_form/remote.rb +38 -0
  348. data/config/initializers/simple_form/sortable.rb +28 -0
  349. data/config/initializers/simple_form_bootstrap.rb +155 -0
  350. data/config/locales/devise.en.yml +62 -0
  351. data/config/locales/en.yml +24 -0
  352. data/config/locales/simple_form.en.yml +31 -0
  353. data/config/routes.rb +61 -0
  354. data/db/migrate/20161217191000_devise_create_users.rb +48 -0
  355. data/db/migrate/20161217200300_create_pages.rb +21 -0
  356. data/db/migrate/20161217205353_create_menus.rb +12 -0
  357. data/db/migrate/20161219033747_create_settings.rb +14 -0
  358. data/db/migrate/20161219231741_create_media_items.rb +18 -0
  359. data/db/migrate/20161225212203_create_user_groups.rb +10 -0
  360. data/db/migrate/20161225212258_create_join_table_user_groups_users.rb +8 -0
  361. data/db/migrate/20170109175932_create_block_kinds.rb +14 -0
  362. data/db/migrate/20170109180818_create_block_slots.rb +17 -0
  363. data/db/migrate/20170109185414_create_base_blocks.rb +8 -0
  364. data/db/migrate/20170818025124_create_block_layouts.rb +13 -0
  365. data/db/migrate/20170818025229_add_block_layout_to_block_slots.rb +5 -0
  366. data/db/migrate/20170818025500_remove_layout_from_block_slots.rb +5 -0
  367. data/db/migrate/20170821161755_add_unique_index_to_block_layouts.rb +6 -0
  368. data/db/migrate/20170826173346_create_translations.rb +12 -0
  369. data/db/migrate/20170910204934_index_attachment_content_type_on_media_items.rb +5 -0
  370. data/db/migrate/20180206035546_create_cache_records.rb +14 -0
  371. data/db/migrate/20180415034427_add_redirect_to_pages.rb +5 -0
  372. data/db/migrate/20180618190248_add_index_created_at_to_media_items.rb +5 -0
  373. data/db/migrate/20180625172226_add_blockable_metadata_to_pages.rb +6 -0
  374. data/db/migrate/20180626182949_remove_attachable_from_media_items.rb +7 -0
  375. data/db/migrate/20180712162414_add_media_item_status_to_media_items.rb +6 -0
  376. data/db/migrate/20190223155013_add_type_to_block_kinds.rb +6 -0
  377. data/db/migrate/20190423173909_add_seo_title_to_pages.rb +5 -0
  378. data/lib/forest.rb +9 -0
  379. data/lib/forest/engine.rb +51 -0
  380. data/lib/forest/migrations.rb +86 -0
  381. data/lib/forest/rails/active_record/has_many_ordered.rb +30 -0
  382. data/lib/forest/rails/active_record/has_repeatable.rb +19 -0
  383. data/lib/forest/rails/core_ext/enumerable.rb +17 -0
  384. data/lib/forest/version.rb +3 -0
  385. data/lib/generators/forest/block/USAGE +8 -0
  386. data/lib/generators/forest/block/block_generator.rb +103 -0
  387. data/lib/generators/forest/block/templates/_block.html.erb +2 -0
  388. data/lib/generators/forest/block/templates/_block.scss.erb +5 -0
  389. data/lib/generators/forest/block/templates/_block_edit_fields.html.erb +21 -0
  390. data/lib/generators/forest/block/templates/create_table_migration.rb +31 -0
  391. data/lib/generators/forest/block/templates/model.rb +41 -0
  392. data/lib/generators/forest/install/USAGE +2 -0
  393. data/lib/generators/forest/install/install_generator.rb +72 -0
  394. data/lib/generators/forest/scaffold/USAGE +8 -0
  395. data/lib/generators/forest/scaffold/scaffold_generator.rb +133 -0
  396. data/lib/generators/forest/scaffold/templates/admin_controller.rb +67 -0
  397. data/lib/generators/forest/scaffold/templates/controller.rb +20 -0
  398. data/lib/generators/forest/scaffold/templates/create_table_migration.rb +35 -0
  399. data/lib/generators/forest/scaffold/templates/model.rb +21 -0
  400. data/lib/generators/forest/scaffold/templates/policy.rb +2 -0
  401. data/lib/generators/forest/scaffold/templates/views/admin/_form.html.erb +56 -0
  402. data/lib/generators/forest/scaffold/templates/views/admin/edit.html.erb +3 -0
  403. data/lib/generators/forest/scaffold/templates/views/admin/index.html.erb +58 -0
  404. data/lib/generators/forest/scaffold/templates/views/admin/index.json.jbuilder +2 -0
  405. data/lib/generators/forest/scaffold/templates/views/admin/new.html.erb +3 -0
  406. data/lib/generators/forest/scaffold/templates/views/admin/show.html.erb +12 -0
  407. data/lib/generators/forest/scaffold/templates/views/public/index.html.erb +1 -0
  408. data/lib/generators/forest/scaffold/templates/views/public/show.html.erb +17 -0
  409. data/lib/tasks/forest_db_tasks.rake +176 -0
  410. data/lib/tasks/forest_elasticsearch_tasks.rake +22 -0
  411. metadata +719 -0
@@ -0,0 +1,11 @@
1
+ <% options = {} %>
2
+ <% options.merge!({ as: :hidden }) if local_assigns.fetch(:hidden, false).present? %>
3
+ <%= f.input :slug,
4
+ placeholder: 'Leave this blank. The slug will be generated automatically from the title.',
5
+ required: false,
6
+ wrapper_class: 'form-group slug-attribute-wrapper',
7
+ **options,
8
+ input_html: {
9
+ data: {
10
+ persisted_value: f.object.try(:slug),
11
+ persisted_value_warning: '<span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span> You are changing the slug. Make sure to update any references to the old slug to avoid broken links.' } } %>
@@ -0,0 +1,20 @@
1
+ <% if record.statusable? %>
2
+ <% date_label = local_assigns.fetch(:date_label, 'Published date') %>
3
+ <div class="status-scheduler form-group">
4
+ <%= f.input :status, as: :select, collection: record.class.statuses_for_select.collect { |k, v| [k.titleize, k] }, include_blank: false %>
5
+ <% if record.respond_to?(:published_date) %>
6
+ <%= f.input :published_date,
7
+ as: :datepicker,
8
+ hint: "Set the date of this record to a future date and it will be hidden until this time.",
9
+ input_html: { value: f.object.published_date.presence || Date.today },
10
+ label: date_label %>
11
+ <% elsif record.respond_to?(:scheduled_date) %>
12
+ <%= f.input :scheduled_date,
13
+ as: :string,
14
+ hint: "Set the date of this record to a future date and it will be hidden until this time.",
15
+ label: date_label,
16
+ wrapper_html: {
17
+ class: ('active' if record.scheduled?) } %>
18
+ <% end %>
19
+ </div>
20
+ <% end %>
@@ -0,0 +1,41 @@
1
+ <% classes = [] %>
2
+ <% classes << 'collage-input__item' %>
3
+ <% classes << "collage-input__item--#{f.object.media_item.present? ? 'with-image' : 'without-image'}" %>
4
+ <% classes << 'nested-fields' %>
5
+
6
+ <% styles = [] %>
7
+ <% styles << "left: #{f.object.collage_position_left}%" %>
8
+ <% styles << "top: #{f.object.collage_position_top}%" %>
9
+ <% styles << "width: #{f.object.collage_item_width}%" %>
10
+ <% styles << "z-index: #{f.object.collage_z_index}" %>
11
+
12
+ <%= content_tag :div, class: classes.join(' '), style: styles.join(';') do %>
13
+ <%= f.association :media_item, as: :image, label: false %>
14
+ <%# If you're host app view displays captions in the collage, you may want to show this css class in a admin css override in the host app. %>
15
+ <%= content_tag(:div, md(f.object.media_item.caption), class: 'collage-input__caption') if f.object.media_item.present? %>
16
+
17
+ <%= f.hidden_field :collage_position_left, class: 'collage-input__input--position-left' %>
18
+ <%= f.hidden_field :collage_position_top, class: 'collage-input__input--position-top' %>
19
+ <%= f.hidden_field :collage_z_index, class: 'collage-input__input--z-index' %>
20
+ <%= f.hidden_field :collage_item_width, class: 'collage-input__input--item-width' %>
21
+ <%= f.hidden_field :collage_item_height, class: 'collage-input__input--item-height' %>
22
+
23
+ <%= f.hidden_field :id %>
24
+
25
+ <% begin %>
26
+ <%# Add a partial named collage_fields to your block if you need to add additional fiels to the collage items %>
27
+ <%= capture do %>
28
+ <div class="collage-input__additional-fields">
29
+ <%= render "blocks/#{obj.model_name.singular}/collage_fields", f: f %>
30
+ </div>
31
+ <% end %>
32
+ <% rescue ActionView::MissingTemplate %>
33
+ <% end %>
34
+
35
+ <div class="media-item__buttons">
36
+ <% if f.object.media_item.present? %>
37
+ <%= content_tag :div, '', class: 'media-item__button media-item__buttons__edit glyphicon glyphicon-pencil', data: { path: edit_admin_media_item_path(f.object.media_item) } %>
38
+ <% end %>
39
+ <%= link_to_remove_association '', f, class: 'media-item__button media-item__buttons__remove glyphicon glyphicon-remove' %>
40
+ </div>
41
+ <% end %>
@@ -0,0 +1,68 @@
1
+ <% if record.try(:statusable?) && !record.try(:published?) %>
2
+ <div class="alert alert-danger" role="alert">
3
+ <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
4
+ <span class="sr-only">Error:</span>
5
+ This <%= record.model_name.human %> is currently <strong><%= record.status %></strong> and is not visible to the public.
6
+ </div>
7
+ <% end %>
8
+
9
+ <%= admin_header_tag(record) do %>
10
+ <div class="panel panel-default">
11
+ <div class="panel-heading">
12
+ <h3 class="panel-title">
13
+ <%= record.model_name.human.titleize %> <%= record.id %>
14
+ </h3>
15
+ </div>
16
+ <div class="panel-body">
17
+ <div class="row">
18
+ <div class="col-sm-8">
19
+ <h1>
20
+ <%= record_name record %>
21
+ </h1>
22
+ </div>
23
+ <div class="col-sm-4 text-right">
24
+ <div class="btn-group">
25
+ <% if try(:respond_to?, "new_admin_#{record.model_name.singular}_path") %>
26
+ <%= link_to "New", send("new_admin_#{record.model_name.singular}_path"), title: "Create a new #{record.model_name.human}", class: 'btn btn-default' %>
27
+ <% end %>
28
+ <%= link_to "All", send("admin_#{record.model_name.plural}_path"), title: "View all #{record.model_name.plural.titleize}", class: 'btn btn-default' %>
29
+ <% record_namespaces = record.model_name.collection.split('/') %>
30
+ <% record_namespaces = record_namespaces.take(record_namespaces.length - 1) %>
31
+ <% begin %>
32
+ <% if Rails.application.routes.recognize_path send("admin_#{record.model_name.singular}_path", record), method: :delete %>
33
+ <%= link_to "Destroy", [:admin, *record_namespaces, record].reject(&:blank?), method: :delete, title: "Destroy this #{record.model_name.human}", data: { confirm: "Are you sure you want to destroy this #{record.model_name.human}?" }, class: 'btn btn-default' %>
34
+ <% end %>
35
+ <% rescue Exception => e %>
36
+ <% logger.info { "[Forest] Admin edit header could not determine destroy path for #{record.model_name}." } %>
37
+ <% end %>
38
+ <% begin %>
39
+ <% if Rails.application.routes.recognize_path send("#{record.model_name.singular}_path", record.to_friendly_param) %>
40
+ <%= link_to "Show", send("#{record.model_name.singular}_path", record.to_friendly_param), title: "View this #{record.model_name.human}", class: 'btn btn-default', data: { turbolinks: false } %>
41
+ <% elsif Rails.application.routes.recognize_path send("admin_#{record.model_name.singular}_path", record) %>
42
+ <%= link_to "Show", send("admin_#{record.model_name.singular}_path", record), title: "View this #{record.model_name.human}", class: 'btn btn-default' %>
43
+ <% end %>
44
+ <% rescue Exception => e %>
45
+ <% logger.info { "[Forest] Admin edit header could not determine show path for #{record.model_name}." } %>
46
+ <% end %>
47
+ </div>
48
+ <% if try(:respond_to?, "update_admin_#{record.model_name.singular}_path") %>
49
+ <div class="btn btn-success update-record-button">Update <%= record.model_name.human %></div>
50
+ <% end %>
51
+ </div>
52
+ </div>
53
+ <% if record.try(:draft?) %>
54
+ <div class="row">
55
+ <br>
56
+ <div class="col-sm-6">
57
+ <p class="text-muted">
58
+ <span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
59
+ This <%= record.model_name.human %> is in Draft mode. You can make edits and update the <%= record.model_name.human %> and the changes will not be visible to the public.
60
+ You can preview the draft, and when you are ready to make the changes live, switch the status back to published.
61
+ </p>
62
+ </div>
63
+ </div>
64
+ <% end %>
65
+ </div>
66
+ </div>
67
+ <div class="btn btn-success update-record-button fixed-update-record-button" id="fixed-update-record-button">Update <%= record.model_name.human %></div>
68
+ <% end %>
@@ -0,0 +1,61 @@
1
+ <% model = model_name.constantize %>
2
+ <% model_names = model.model_name %>
3
+ <% should_paginate = local_assigns.fetch :paginate, true %>
4
+ <% pagination_collection = local_assigns.fetch :pagination_collection, records %>
5
+
6
+ <%= admin_header_tag(records) do %>
7
+ <div class="well">
8
+ <div class="row">
9
+ <div class="admin-header__item-group col-sm-8">
10
+ <h1 class="admin-header__item"><%= model_names.human.pluralize.titleize %> <span class="badge"><%= number_with_delimiter records.total_count %></span></h1>
11
+ <%= form_tag send("admin_#{model_names.plural}_path"), class: 'form-inline admin-header__item', method: :get, enforce_utf8: false, data: { turboform: true } do %>
12
+ <div class="form-group">
13
+ <%= text_field_tag :fuzzy_search, params[:fuzzy_search], class: 'form-control', placeholder: 'Search', autofocus: (true if params[:fuzzy_search].present?), data: { turboform: true } %>
14
+ <%= submit_tag 'Submit', name: nil, class: 'btn btn-default' %>
15
+ </div>
16
+ <% end %>
17
+ </div>
18
+ <div class="col-sm-4 text-right">
19
+ <div class="btn-group text-left">
20
+ <% if content_for? :index_header_button_group %>
21
+ <%= content_for :index_header_button_group %>
22
+ <% else %>
23
+ <% if try(:respond_to?, "new_admin_#{model_names.singular_route_key}_path") %>
24
+ <%= link_to "New #{model_names.human.titleize}", send("new_admin_#{model_names.singular_route_key}_path"), class: 'btn btn-success' %>
25
+ <button type="button" class="btn btn-success dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
26
+ <span class="caret"></span>
27
+ <span class="sr-only">Toggle Dropdown</span>
28
+ </button>
29
+ <ul class="dropdown-menu dropdown-menu--right">
30
+ <li>
31
+ <%= link_to edit_admin_import_path(model_names.singular) do %>
32
+ <span class="glyphicon glyphicon-import"></span>
33
+ Bulk import
34
+ <% end %>
35
+ </li>
36
+ </ul>
37
+ <% end %>
38
+ <% end %>
39
+ </div>
40
+ </div>
41
+ <%# TODO: this doesn't seem necessary %>
42
+ <% if I18n.exists?("forest.admin.index.#{model_names.singular}.description", locale) %>
43
+ <div class="col-sm-12">
44
+ <p class="text-muted">
45
+ <%= t(:description, scope: [:forest, :admin, :index, model_names.singular]) %>
46
+ </p>
47
+ </div>
48
+ <% end %>
49
+ <% if content_for? :index_header_body %>
50
+ <div class="admin-header__body col-sm-12">
51
+ <%= content_for :index_header_body %>
52
+ </div>
53
+ <% end %>
54
+ <% if should_paginate %>
55
+ <div class="col-sm-12">
56
+ <%= paginate pagination_collection %>
57
+ </div>
58
+ <% end %>
59
+ </div>
60
+ </div>
61
+ <% end %>
@@ -0,0 +1,14 @@
1
+ <%= admin_header_tag(record) do %>
2
+ <div class="well">
3
+ <div class="row">
4
+ <div class="col-sm-6">
5
+ <h1>New <%= record.class.model_name.human %></h1>
6
+ </div>
7
+ <div class="col-sm-6 text-right">
8
+ <%= link_to 'Back',
9
+ back_button(send("admin_#{record.class.model_name.route_key}_path")),
10
+ class: 'btn btn-default' %>
11
+ </div>
12
+ </div>
13
+ </div>
14
+ <% end %>
@@ -0,0 +1,37 @@
1
+ <%= admin_header_tag(record) do %>
2
+ <div class="panel panel-default">
3
+ <div class="panel-heading">
4
+ <h3 class="panel-title">
5
+ <%= record.class.model_name.human %> <%= record.id %>
6
+ </h3>
7
+ </div>
8
+ <div class="panel-body">
9
+ <div class="row">
10
+ <div class="col-sm-6">
11
+ <h1>
12
+ <%= record_name record %>
13
+ </h1>
14
+ </div>
15
+ <div class="col-sm-6 text-right">
16
+ <div class="btn-group">
17
+ <%= link_to "All #{record.class.model_name.plural.titleize}", send("admin_#{record.class.model_name.route_key}_path"), class: 'btn btn-default' %>
18
+ <%= link_to "New #{record.class.model_name.human}", send("new_admin_#{record.class.model_name.singular_route_key}_path"), class: 'btn btn-default' %>
19
+ <% if respond_to? "#{record.class.model_name.singular_route_key}_path" %>
20
+ <%= link_to "View #{record.class.model_name.human}", send("#{record.class.model_name.singular_route_key}_path", record.to_friendly_param), class: 'btn btn-default', data: { turbolinks: false } %>
21
+ <% else %>
22
+ <%= link_to "View #{record.class.model_name.human}", send("admin_#{record.class.model_name.singular_route_key}_path", record), class: 'btn btn-default' %>
23
+ <% end %>
24
+ <button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
25
+ <span class="caret"></span>
26
+ <span class="sr-only">Toggle Dropdown</span>
27
+ </button>
28
+ <ul class="dropdown-menu dropdown-menu--right">
29
+ <li><%= link_to "Destroy #{record.class.model_name.human}", [:admin, record], method: :delete, data: { confirm: 'Are you sure?' } %></li>
30
+ </ul>
31
+ </div>
32
+ <%= link_to "Edit #{record.class.model_name.human}", send("edit_admin_#{record.class.model_name.singular_route_key}_path", record), class: 'btn btn-primary' %>
33
+ </div>
34
+ </div>
35
+ </div>
36
+ </div>
37
+ <% end %>
@@ -0,0 +1,60 @@
1
+ <div class="admin-header">
2
+ <div class="well">
3
+ <div class="row">
4
+ <div class="col-sm-9">
5
+ <h1>
6
+ <%= @import.model_name.human %> Import
7
+ <small>Upload a CSV file matching the template below to bulk import records</small>
8
+ </h1>
9
+ </div>
10
+ <div class="col-sm-3 text-right">
11
+ <div class="btn-group">
12
+ <%= link_to "All #{@import.model_name.plural.titleize}", send("admin_#{@import.model_name.route_key}_path"), class: 'btn btn-default' %>
13
+ </div>
14
+ </div>
15
+ </div>
16
+ </div>
17
+ </div>
18
+
19
+ <div class="panel panel-default">
20
+ <div class="panel-heading">
21
+ <h3 class="panel-title">CSV template</h3>
22
+ </div>
23
+ <div class="panel-body">
24
+ <p class="text-muted">Download the CSV template and format your import to match the following template. Save the file as a CSV and and upload in the form.
25
+ Leave columns blank if you do not have data for it available or it doesn't make sense to import.</p>
26
+ <p class="text-muted">Not all resources are able to be imported by default. If you need a more custom import please request this.</p>
27
+ <table class="table table-condensed table-bordered">
28
+ <thead>
29
+ <tr>
30
+ <% @import.csv_columns.each do |column| %>
31
+ <th><%= column.titleize %></th>
32
+ <% end %>
33
+ </tr>
34
+ </thead>
35
+ <tbody>
36
+ <% @import.csv_columns.each_with_index do |column, index| %>
37
+ <td><%= @import.columns_hash[column].type %></td>
38
+ <% end %>
39
+ </tbody>
40
+ </table>
41
+
42
+ <%= link_to 'Download CSV template', edit_admin_import_path(@import, format: :csv), class: 'btn btn-default', download: '' %>
43
+ </div>
44
+ </div>
45
+
46
+ <div class="panel panel-default">
47
+ <div class="panel-heading">
48
+ <h3 class="panel-title">Bulk import</h3>
49
+ </div>
50
+ <div class="panel-body">
51
+ <%= simple_form_for 'import', url: admin_imports_path, html: { multipart: true } do |f| %>
52
+ <div class="form-group">
53
+ <%= f.input :file, as: :file, label: 'CSV File input', input_html: { accept: '.csv' } %>
54
+ <p class="help-block">Upload your CSV file matching the template here.</p>
55
+ </div>
56
+ <%= f.input :model_name, value: @import.model_name.name, as: :hidden %>
57
+ <%= f.button :submit, 'Submit', class: 'btn btn-primary' %>
58
+ <% end %>
59
+ </div>
60
+ </div>
@@ -0,0 +1,54 @@
1
+ <%= simple_form_for([:admin, @media_item]) do |f| %>
2
+ <%= f.error_notification %>
3
+
4
+ <div class="row">
5
+ <div class="col-sm-12">
6
+
7
+ <div class="panel panel-default" data-collapse-parent>
8
+ <div class="panel-heading">
9
+ <h3 class="panel-title">
10
+ Metadata
11
+ </h3>
12
+ </div>
13
+ <div class="panel-body" data-collapse-body>
14
+ <div class="form-inputs">
15
+ <div class="row">
16
+ <div class="col-sm-6">
17
+ <%= f.input :attachment, hint: 'Replace the file by uploading a new attachment.' %>
18
+ <%= f.input :title, placeholder: 'The title will be generated automatically from the file name if left blank.' %>
19
+ <%= render 'admin/form_inputs/slug', f: f %>
20
+ <%= f.input :alternative_text, hint: 'The alt attribute provides alternative information for an image if a user for some reason cannot view it (because of slow connection, an error in the src attribute, or if the user uses a screen reader).' %>
21
+ <%= f.input :caption, markdown: true %>
22
+ <%#= f.input :description %>
23
+ <%= f.button :submit, class: 'btn-success' %>
24
+ </div>
25
+ <div class="col-sm-6">
26
+ <% if @media_item.attachment.present? %>
27
+ <div class="form-group">
28
+ <% if @media_item.image? %>
29
+ <%= image_tag @media_item.attachment.url(:medium) %>
30
+ <% elsif @media_item.video? %>
31
+ <%= video_tag @media_item.attachment.url, controls: true %>
32
+ <% else %>
33
+ <%= link_to media_item.attachment.url, class: 'blank-link', target: '_blank' do %>
34
+ <%= content_tag :div, class: 'media-item-file img-rounded', title: 'Open file' do %>
35
+ <%= content_tag :span, '', class: "media-library-image--grid__icon glyphicon #{media_item.glyphicon}" %>
36
+ <%= content_tag :div, media_item.attachment_file_name, class: "media-library-image__label small well" %>
37
+ <% end %>
38
+ <% end %>
39
+ <% end %>
40
+ </div>
41
+ <div class="form-group">
42
+ <label class="control-label">Attachment URL</label>
43
+ <textarea class="form-control not-resizable" type="text" readonly><%= @media_item.attachment.url %></textarea>
44
+ </div>
45
+ <% end %>
46
+ </div>
47
+ </div>
48
+ </div>
49
+ </div>
50
+ </div>
51
+
52
+ </div>
53
+ </div>
54
+ <% end %>
@@ -0,0 +1,23 @@
1
+ <div class="media-item--grid col-xs-4 col-sm-3 col-md-2">
2
+ <% attachment_or_placeholder_url = media_item.attachment.exists? ? media_item.attachment.url(:small) : '' %>
3
+ <% attachment_or_placeholder_url_large = media_item.attachment.exists? ? media_item.attachment.url(:large) : '' %>
4
+ <% content = capture do %>
5
+ <% if media_item.file? %>
6
+ <%= content_tag :span, '', class: "media-library-image--grid__icon glyphicon #{media_item.glyphicon}" %>
7
+ <% end %>
8
+ <%= content_tag :div, media_item.title, class: "media-library-image__label small well", title: media_item.attachment_file_name %>
9
+ <% end %>
10
+ <%= link_to edit_admin_media_item_path(media_item),
11
+ class: "media-library-link #{media_item.file? ? 'media-library-link--file' : 'media-library-link--image'}",
12
+ data: {
13
+ media_item_id: media_item.id,
14
+ image_url: (image_url(attachment_or_placeholder_url) if media_item.image?),
15
+ image_url_large: (image_url(attachment_or_placeholder_url_large) if media_item.image?) } do %>
16
+ <%= content_tag :div, content, class: "media-library-image img-rounded #{'media-library-image--file' if media_item.file?}", style: "background-image: url(#{image_url(attachment_or_placeholder_url) if media_item.image?})" %>
17
+ <% end %>
18
+ <div class="media-item__buttons">
19
+ <%= content_tag :div, '', class: 'media-item__button media-item__buttons__edit glyphicon glyphicon-pencil', data: { path: edit_admin_media_item_path(media_item) } %>
20
+ <%# TODO: update delete icon to work in media library grid view? %>
21
+ <%= content_tag :div, '', class: 'media-item__button media-item__buttons__remove glyphicon glyphicon-remove' %>
22
+ </div>
23
+ </div>
@@ -0,0 +1,32 @@
1
+ <tr class="media-library__list-table-row">
2
+ <td><%= check_box_tag "selected[]", media_item.id %></td>
3
+ <td>
4
+ <div class="row">
5
+ <div class="media-library-image-row col-xs-4 col-sm-2">
6
+ <% attachment_or_placeholder_url = media_item.attachment.exists? ? media_item.attachment.url(:thumb) : '' %>
7
+ <% content = capture do %>
8
+ <% if media_item.file? %>
9
+ <%= content_tag :span, '', class: "media-library-image--list__icon glyphicon #{media_item.glyphicon}" %>
10
+ <% end %>
11
+ <% end %>
12
+ <%= link_to edit_admin_media_item_path(media_item), class: "media-library-link media-library-link--list #{media_item.file? ? 'media-library-link--file' : 'media-library-link--image'}", data: { media_item_id: media_item.id, image_url: (image_url(attachment_or_placeholder_url) if media_item.image?) } do %>
13
+ <%= content_tag :div, content, class: "media-library-image media-library-image--list img-rounded #{'media-library-image--file' if media_item.file?}", style: "background-image: url(#{image_url(attachment_or_placeholder_url) if media_item.image?})" %>
14
+ <% end %>
15
+ </div>
16
+ <div class="col-sm-8">
17
+ <%= link_to media_item.title.presence || media_item.slug, edit_admin_media_item_path(media_item) %>
18
+ <br>
19
+ <%= media_item.attachment_file_name %>
20
+ <br>
21
+ <div class="media-library__list-actions">
22
+ <%= link_to 'Edit', edit_admin_media_item_path(media_item) %>
23
+ <span class="text-light">|</span>
24
+ <%= link_to 'Delete Permanently', [:admin, media_item], method: :delete, class: 'text-danger', data: { confirm: 'Are you sure?' } %>
25
+ <span class="text-light">|</span>
26
+ <%= link_to 'View', admin_media_item_path(media_item) %>
27
+ </div>
28
+ </div>
29
+ </div>
30
+ </td>
31
+ <td><%= forest_date media_item.created_at %></td>
32
+ </tr>
@@ -0,0 +1,62 @@
1
+ <% cache ['modal', MediaItem.cache_key], expires_in: 4.weeks do %>
2
+ <div class="modal fade media-item-chooser" id="media-item-chooser" tabindex="-1" role="dialog" aria-labelledby="mediaItemChooser">
3
+ <div class="modal-dialog modal-fluid" role="document">
4
+ <div class="modal-content">
5
+ <div class="modal-header">
6
+ <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
7
+ <h4 class="media-item-chooser__modal-title modal-title" id="gridSystemModalLabel">
8
+ Media Library
9
+ <div id="media-item-chooser__modal-title__loading-indicator" class="media-item-chooser__modal-title__loading-indicator text-muted small"></div>
10
+ </h4>
11
+ <div class="row">
12
+ <div class="col-sm-12">
13
+ <div class="text-muted">
14
+ <span class="glyphicon glyphicon-info-sign" aria-hidden="true"></span>
15
+ Drag and drop images or files to upload new items.
16
+ </div>
17
+ <br>
18
+ </div>
19
+ <div class="col-sm-10">
20
+ <div class="row">
21
+ <div class="col-sm-4">
22
+ <%= form_tag admin_media_items_path, class: 'media-item-chooser__modal-search-form', method: :get, enforce_utf8: false do %>
23
+ <%= text_field_tag :fuzzy_search, params[:fuzzy_search], id: 'media_item_modal_fuzzy_search', class: 'media-item-chooser__modal-search-input form-control', placeholder: 'Search' %>
24
+ <% end %>
25
+ </div>
26
+ <div class="col-sm-4">
27
+ <%= dropdown_select_form url: admin_media_items_path,
28
+ id: 'by_date',
29
+ select_options: MediaItem.dates_for_filter,
30
+ title: 'All Dates',
31
+ remote_parent: '.modal',
32
+ remote_target: '.modal-body',
33
+ remote_response_target: '.media-library' %>
34
+ </div>
35
+ <div class="col-sm-4">
36
+ <%= dropdown_select_form url: admin_media_items_path,
37
+ id: 'by_content_type',
38
+ select_options: MediaItem.content_types_for_filter,
39
+ title: 'All Content Types',
40
+ remote_parent: '.modal',
41
+ remote_target: '.modal-body',
42
+ remote_response_target: '.media-library' %>
43
+ </div>
44
+ </div>
45
+ </div>
46
+ <div class="col-sm-2 text-right">
47
+ <button type="button" class="media-item-chooser__select-button btn btn-primary">Select</button>
48
+ </div>
49
+ </div>
50
+ </div>
51
+ <%= render 'admin/file_upload', klass: MediaItem, association: :attachment %>
52
+ <div class="modal-body">
53
+ Loading...
54
+ </div>
55
+ <div class="modal-footer">
56
+ <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
57
+ <button type="button" class="media-item-chooser__select-button btn btn-primary">Select</button>
58
+ </div>
59
+ </div>
60
+ </div>
61
+ </div>
62
+ <% end %>