adminos 1.0.0.pre.rc.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 (288) hide show
  1. checksums.yaml +7 -0
  2. data/.editorconfig +14 -0
  3. data/.gitignore +25 -0
  4. data/.gitlab-ci.yml +18 -0
  5. data/.rspec +2 -0
  6. data/.rubocop.yml +120 -0
  7. data/.rubocop_todo.yml +58 -0
  8. data/Gemfile +25 -0
  9. data/Guardfile +70 -0
  10. data/LICENSE.txt +22 -0
  11. data/README.md +88 -0
  12. data/Rakefile +20 -0
  13. data/adminos.gemspec +37 -0
  14. data/adminos.png +0 -0
  15. data/app/assets/images/.keep +0 -0
  16. data/app/assets/images/apple-touch-icon.png +0 -0
  17. data/app/assets/images/favicon-16x16.png +0 -0
  18. data/app/assets/images/favicon-32x32.png +0 -0
  19. data/app/assets/images/favicon.ico +0 -0
  20. data/app/assets/images/safari-pinned-tab.svg +23 -0
  21. data/app/inputs/cropp_input.rb +45 -0
  22. data/bin/bundle +105 -0
  23. data/bin/gem +39 -0
  24. data/bin/rspec +29 -0
  25. data/exe/adminos +5 -0
  26. data/lib/adminos/cli.rb +71 -0
  27. data/lib/adminos/controllers/admin_extension.rb +34 -0
  28. data/lib/adminos/controllers/helpers.rb +24 -0
  29. data/lib/adminos/controllers/resource.rb +169 -0
  30. data/lib/adminos/extensions/globalize_actiontext.rb +28 -0
  31. data/lib/adminos/extensions/globalize_fields.rb +19 -0
  32. data/lib/adminos/extensions/nested_set.rb +27 -0
  33. data/lib/adminos/extensions/string.rb +5 -0
  34. data/lib/adminos/generators/gemfile_merge.rb +85 -0
  35. data/lib/adminos/generators/utilities.rb +87 -0
  36. data/lib/adminos/helpers/admin.rb +190 -0
  37. data/lib/adminos/helpers/bootstrap.rb +64 -0
  38. data/lib/adminos/helpers/models/apply_sortable_order.rb +10 -0
  39. data/lib/adminos/helpers/models/array_attrs.rb +17 -0
  40. data/lib/adminos/helpers/models/cropped.rb +20 -0
  41. data/lib/adminos/helpers/models/dom_id.rb +16 -0
  42. data/lib/adminos/helpers/models/flag_attrs.rb +43 -0
  43. data/lib/adminos/helpers/models/if_blank_set_to_nil_params.rb +19 -0
  44. data/lib/adminos/helpers/models/move_to.rb +17 -0
  45. data/lib/adminos/helpers/models/nested_set/duplication.rb +31 -0
  46. data/lib/adminos/helpers/models/nested_set/materialize_path.rb +50 -0
  47. data/lib/adminos/helpers/models/nested_set/place_to.rb +35 -0
  48. data/lib/adminos/helpers/models/nested_set/safe_destroy.rb +34 -0
  49. data/lib/adminos/helpers/models/recognizable.rb +28 -0
  50. data/lib/adminos/helpers/models/slugged.rb +20 -0
  51. data/lib/adminos/helpers/models/soft_destroy.rb +61 -0
  52. data/lib/adminos/helpers/models/wysiwyg.rb +105 -0
  53. data/lib/adminos/helpers/view.rb +137 -0
  54. data/lib/adminos/operations/check_environment.rb +18 -0
  55. data/lib/adminos/operations/extract_environment.rb +42 -0
  56. data/lib/adminos/operations/load_environment.rb +30 -0
  57. data/lib/adminos/stateful_link/action_any_of.rb +76 -0
  58. data/lib/adminos/stateful_link/helper.rb +31 -0
  59. data/lib/adminos.rb +42 -0
  60. data/lib/adminos_template.rb +15 -0
  61. data/lib/generators/adminos/adminos_generator.rb +164 -0
  62. data/lib/generators/adminos/ci_generator.rb +124 -0
  63. data/lib/generators/adminos/field_generator.rb +105 -0
  64. data/lib/generators/adminos/i18n_generator.rb +76 -0
  65. data/lib/generators/adminos/install_generator.rb +238 -0
  66. data/lib/generators/templates/adminos/adminos.ru.yml +15 -0
  67. data/lib/generators/templates/adminos/fields.slim +21 -0
  68. data/lib/generators/templates/adminos/locales/general_fields.slim +7 -0
  69. data/lib/generators/templates/adminos/locales/locale_fields.slim +10 -0
  70. data/lib/generators/templates/adminos/locales/migration.rb.erb +18 -0
  71. data/lib/generators/templates/adminos/locales/model.rb.erb +6 -0
  72. data/lib/generators/templates/adminos/sidebar.slim +2 -0
  73. data/lib/generators/templates/adminos/sorts/body.slim +3 -0
  74. data/lib/generators/templates/adminos/sorts/headers.slim +3 -0
  75. data/lib/generators/templates/adminos/types/default/controller.rb.erb +18 -0
  76. data/lib/generators/templates/adminos/types/default/migration.rb +5 -0
  77. data/lib/generators/templates/adminos/types/default/model.rb +20 -0
  78. data/lib/generators/templates/adminos/types/default/model_includes.rb +4 -0
  79. data/lib/generators/templates/adminos/types/default/views/index.slim +14 -0
  80. data/lib/generators/templates/adminos/types/section/controller.rb.erb +10 -0
  81. data/lib/generators/templates/adminos/types/section/migration.rb +12 -0
  82. data/lib/generators/templates/adminos/types/section/model.rb +62 -0
  83. data/lib/generators/templates/adminos/types/section/model_includes.rb +7 -0
  84. data/lib/generators/templates/adminos/types/section/views/_object.slim +24 -0
  85. data/lib/generators/templates/adminos/types/section/views/_objects.slim +6 -0
  86. data/lib/generators/templates/adminos/types/section/views/index.slim +7 -0
  87. data/lib/generators/templates/adminos/types/sortable/controller.rb.erb +10 -0
  88. data/lib/generators/templates/adminos/types/sortable/migration.rb +9 -0
  89. data/lib/generators/templates/adminos/types/sortable/model.rb +35 -0
  90. data/lib/generators/templates/adminos/types/sortable/model_includes.rb +6 -0
  91. data/lib/generators/templates/adminos/types/sortable/views/_object.slim +17 -0
  92. data/lib/generators/templates/adminos/types/sortable/views/_objects.slim +6 -0
  93. data/lib/generators/templates/adminos/types/sortable/views/index.slim +7 -0
  94. data/lib/generators/templates/adminos/types/table/controller.rb.erb +19 -0
  95. data/lib/generators/templates/adminos/types/table/views/index.slim +31 -0
  96. data/lib/generators/templates/ci/.gitlab-ci.yml +40 -0
  97. data/lib/generators/templates/ci/audit/Gemfile +3 -0
  98. data/lib/generators/templates/ci/lint/Gemfile +3 -0
  99. data/lib/generators/templates/ci/lint/rubocop.yml +116 -0
  100. data/lib/generators/templates/ci/rakelib/audit.rake +13 -0
  101. data/lib/generators/templates/ci/rakelib/lint.rake +13 -0
  102. data/lib/generators/templates/ci/spec/Gemfile +9 -0
  103. data/lib/generators/templates/field/locales/locale_fields.slim +4 -0
  104. data/lib/generators/templates/field/locales/migration.rb.erb +13 -0
  105. data/lib/generators/templates/field/locales/model.rb.erb +6 -0
  106. data/lib/generators/templates/i18n/Gemfile +1 -0
  107. data/lib/generators/templates/i18n/add_translation_table_to_page.rb +15 -0
  108. data/lib/generators/templates/i18n/auto/app/validators/locale_validator.rb +23 -0
  109. data/lib/generators/templates/i18n/auto/app/views/admin/base/_fields.slim +1 -0
  110. data/lib/generators/templates/i18n/auto/app/views/admin/base/_pills.slim +19 -0
  111. data/lib/generators/templates/i18n/auto/app/views/admin/pages/_general_fields.slim +8 -0
  112. data/lib/generators/templates/i18n/auto/app/views/admin/pages/_locale_fields.slim +13 -0
  113. data/lib/generators/templates/i18n/auto/config/initializers/globalize_fields.rb +1 -0
  114. data/lib/generators/templates/i18n/controller.rb +12 -0
  115. data/lib/generators/templates/i18n/devise/devise.ru.yml +60 -0
  116. data/lib/generators/templates/i18n/devise/views/_links.erb +25 -0
  117. data/lib/generators/templates/i18n/devise/views/confirmations/new.slim +8 -0
  118. data/lib/generators/templates/i18n/devise/views/mailer/confirmation_instructions.slim +4 -0
  119. data/lib/generators/templates/i18n/devise/views/mailer/reset_password_instructions.slim +5 -0
  120. data/lib/generators/templates/i18n/devise/views/mailer/unlock_instructions.slim +4 -0
  121. data/lib/generators/templates/i18n/devise/views/passwords/edit.slim +7 -0
  122. data/lib/generators/templates/i18n/devise/views/passwords/new.slim +5 -0
  123. data/lib/generators/templates/i18n/devise/views/registrations/edit.slim +25 -0
  124. data/lib/generators/templates/i18n/devise/views/registrations/new.slim +7 -0
  125. data/lib/generators/templates/i18n/devise/views/sessions/new.slim +22 -0
  126. data/lib/generators/templates/i18n/devise/views/unlocks/new.slim +11 -0
  127. data/lib/generators/templates/i18n/locales.slim +3 -0
  128. data/lib/generators/templates/i18n/page.rb +5 -0
  129. data/lib/generators/templates/install/.gitignore +11 -0
  130. data/lib/generators/templates/install/Gemfile +57 -0
  131. data/lib/generators/templates/install/Procfile +1 -0
  132. data/lib/generators/templates/install/_sidebar.slim.erb +44 -0
  133. data/lib/generators/templates/install/add_authentications/authentication.rb +7 -0
  134. data/lib/generators/templates/install/add_authentications/authentications_controller.rb +95 -0
  135. data/lib/generators/templates/install/add_authentications/authentications_migration.rb +12 -0
  136. data/lib/generators/templates/install/add_authentications/views/authentications/_form.slim +5 -0
  137. data/lib/generators/templates/install/add_authentications/views/authentications/_modal.slim +7 -0
  138. data/lib/generators/templates/install/add_pages/page.rb +116 -0
  139. data/lib/generators/templates/install/add_pages/pages_controller.rb +6 -0
  140. data/lib/generators/templates/install/add_pages/pages_migration.rb +25 -0
  141. data/lib/generators/templates/install/add_pages/views/pages/show.slim +4 -0
  142. data/lib/generators/templates/install/admin.slim +36 -0
  143. data/lib/generators/templates/install/admin_panel/pages/admin_pages_controller.rb +9 -0
  144. data/lib/generators/templates/install/admin_panel/pages/views/admin_pages/_fields.slim +26 -0
  145. data/lib/generators/templates/install/admin_panel/pages/views/admin_pages/_object.slim +25 -0
  146. data/lib/generators/templates/install/admin_panel/pages/views/admin_pages/_objects.slim +6 -0
  147. data/lib/generators/templates/install/admin_panel/pages/views/admin_pages/index.slim +7 -0
  148. data/lib/generators/templates/install/admin_panel/users/admin_users_controller.rb +29 -0
  149. data/lib/generators/templates/install/admin_panel/users/views/admin_users/_fields.slim +4 -0
  150. data/lib/generators/templates/install/admin_panel/users/views/admin_users/index.slim +33 -0
  151. data/lib/generators/templates/install/admin_panel/versions/admin_versions_controller.rb +29 -0
  152. data/lib/generators/templates/install/admin_panel/versions/views/admin_versions/index.slim +47 -0
  153. data/lib/generators/templates/install/admin_panel/versions/views/admin_versions/show.slim +18 -0
  154. data/lib/generators/templates/install/application.slim.erb +31 -0
  155. data/lib/generators/templates/install/auto/.editorconfig +14 -0
  156. data/lib/generators/templates/install/auto/.env.staging +2 -0
  157. data/lib/generators/templates/install/auto/Capfile +14 -0
  158. data/lib/generators/templates/install/auto/Guardfile +18 -0
  159. data/lib/generators/templates/install/auto/Procfile +1 -0
  160. data/lib/generators/templates/install/auto/Procfile.local +2 -0
  161. data/lib/generators/templates/install/auto/app/assets/javascripts/admin/application.js +3 -0
  162. data/lib/generators/templates/install/auto/app/assets/javascripts/admin/cocoon_fields.js +43 -0
  163. data/lib/generators/templates/install/auto/app/assets/javascripts/application.js +1 -0
  164. data/lib/generators/templates/install/auto/app/assets/stylesheets/admin/application.scss +1 -0
  165. data/lib/generators/templates/install/auto/app/controllers/admin/base_controller.rb +16 -0
  166. data/lib/generators/templates/install/auto/app/controllers/admin/helps_controller.rb +4 -0
  167. data/lib/generators/templates/install/auto/app/controllers/admin/settings_controller.rb +26 -0
  168. data/lib/generators/templates/install/auto/app/controllers/application_controller.rb +50 -0
  169. data/lib/generators/templates/install/auto/app/controllers/index_controller.rb +2 -0
  170. data/lib/generators/templates/install/auto/app/helpers/nested_helper.rb +75 -0
  171. data/lib/generators/templates/install/auto/app/helpers/versions_helper.rb +33 -0
  172. data/lib/generators/templates/install/auto/app/inputs/carrierwave_input.rb +52 -0
  173. data/lib/generators/templates/install/auto/app/inputs/checkbox_input.rb +13 -0
  174. data/lib/generators/templates/install/auto/app/inputs/rich_text_input.rb +9 -0
  175. data/lib/generators/templates/install/auto/app/mailers/notifier.rb +9 -0
  176. data/lib/generators/templates/install/auto/app/models/settings.rb +27 -0
  177. data/lib/generators/templates/install/auto/app/services/export_xlsx.rb +76 -0
  178. data/lib/generators/templates/install/auto/app/views/active_storage/blobs/_blob.html.erb +17 -0
  179. data/lib/generators/templates/install/auto/app/views/admin/base/_form.slim +33 -0
  180. data/lib/generators/templates/install/auto/app/views/admin/base/_object.slim +27 -0
  181. data/lib/generators/templates/install/auto/app/views/admin/base/_objects.slim +19 -0
  182. data/lib/generators/templates/install/auto/app/views/admin/base/drop.js.erb +1 -0
  183. data/lib/generators/templates/install/auto/app/views/admin/base/edit.slim +1 -0
  184. data/lib/generators/templates/install/auto/app/views/admin/base/index.slim +14 -0
  185. data/lib/generators/templates/install/auto/app/views/admin/base/new.slim +1 -0
  186. data/lib/generators/templates/install/auto/app/views/admin/helps/index.slim +29 -0
  187. data/lib/generators/templates/install/auto/app/views/admin/settings/edit.slim +27 -0
  188. data/lib/generators/templates/install/auto/app/views/kaminari/_first_page.slim +10 -0
  189. data/lib/generators/templates/install/auto/app/views/kaminari/_gap.slim +7 -0
  190. data/lib/generators/templates/install/auto/app/views/kaminari/_last_page.slim +10 -0
  191. data/lib/generators/templates/install/auto/app/views/kaminari/_next_page.slim +9 -0
  192. data/lib/generators/templates/install/auto/app/views/kaminari/_page.slim +10 -0
  193. data/lib/generators/templates/install/auto/app/views/kaminari/_paginator.slim +16 -0
  194. data/lib/generators/templates/install/auto/app/views/kaminari/_prev_page.slim +9 -0
  195. data/lib/generators/templates/install/auto/app/views/kaminari/admin/_first_page.slim +10 -0
  196. data/lib/generators/templates/install/auto/app/views/kaminari/admin/_gap.slim +8 -0
  197. data/lib/generators/templates/install/auto/app/views/kaminari/admin/_last_page.slim +10 -0
  198. data/lib/generators/templates/install/auto/app/views/kaminari/admin/_next_page.slim +10 -0
  199. data/lib/generators/templates/install/auto/app/views/kaminari/admin/_page.slim +10 -0
  200. data/lib/generators/templates/install/auto/app/views/kaminari/admin/_paginator.slim +16 -0
  201. data/lib/generators/templates/install/auto/app/views/kaminari/admin/_prev_page.slim +10 -0
  202. data/lib/generators/templates/install/auto/app/views/layouts/admin/base.slim +17 -0
  203. data/lib/generators/templates/install/auto/app/views/shared/admin/_back_button.slim +3 -0
  204. data/lib/generators/templates/install/auto/app/views/shared/admin/_footer.slim +3 -0
  205. data/lib/generators/templates/install/auto/app/views/shared/admin/_search_form.slim +6 -0
  206. data/lib/generators/templates/install/auto/app/views/shared/admin/_topbar.slim +11 -0
  207. data/lib/generators/templates/install/auto/app/views/shared/helpers/_alert_close.slim +1 -0
  208. data/lib/generators/templates/install/auto/app/views/shared/helpers/_contacts_page_link_tag.slim +1 -0
  209. data/lib/generators/templates/install/auto/app/views/shared/helpers/_link_button_to.slim +2 -0
  210. data/lib/generators/templates/install/auto/app/views/shared/helpers/_method_ajax_request_link_to.slim +2 -0
  211. data/lib/generators/templates/install/auto/app/views/shared/helpers/_method_link_to.slim +12 -0
  212. data/lib/generators/templates/install/auto/app/views/shared/helpers/_navigation_menu.html.slim +3 -0
  213. data/lib/generators/templates/install/auto/app/views/shared/helpers/_print_tag.slim +2 -0
  214. data/lib/generators/templates/install/auto/app/views/shared/helpers/_search_tag_for.slim +16 -0
  215. data/lib/generators/templates/install/auto/app/views/shared/helpers/_show_breadcrumbs.slim +7 -0
  216. data/lib/generators/templates/install/auto/app/views/shared/helpers/_show_flash_alert.slim +9 -0
  217. data/lib/generators/templates/install/auto/app/views/shared/helpers/_sortable_column.slim +3 -0
  218. data/lib/generators/templates/install/auto/app/views/shared/helpers/_span_link_to.slim +3 -0
  219. data/lib/generators/templates/install/auto/app/views/shared/helpers/_sub_navigation.slim +14 -0
  220. data/lib/generators/templates/install/auto/app/views/shared/helpers/admin/_batch_actions_tag.slim +16 -0
  221. data/lib/generators/templates/install/auto/app/views/shared/helpers/admin/_collection_button_new.slim +5 -0
  222. data/lib/generators/templates/install/auto/app/views/shared/helpers/admin/_collection_header.slim +4 -0
  223. data/lib/generators/templates/install/auto/app/views/shared/helpers/admin/_locked_sign.slim +3 -0
  224. data/lib/generators/templates/install/auto/app/views/shared/helpers/admin/_nav_published_sign.slim +1 -0
  225. data/lib/generators/templates/install/auto/app/views/shared/helpers/admin/_object_link_children.slim +2 -0
  226. data/lib/generators/templates/install/auto/app/views/shared/helpers/admin/_object_link_duplication.slim +1 -0
  227. data/lib/generators/templates/install/auto/app/views/shared/helpers/admin/_object_link_edit.slim +1 -0
  228. data/lib/generators/templates/install/auto/app/views/shared/helpers/admin/_object_link_new.slim +1 -0
  229. data/lib/generators/templates/install/auto/app/views/shared/helpers/admin/_page_header.slim +5 -0
  230. data/lib/generators/templates/install/auto/app/views/shared/helpers/admin/_published_sign.slim +1 -0
  231. data/lib/generators/templates/install/auto/app/views/shared/helpers/admin/_show_breadcrumbs.slim +6 -0
  232. data/lib/generators/templates/install/auto/app/views/shared/helpers/admin/_top_menu_item.slim +5 -0
  233. data/lib/generators/templates/install/auto/app/views/shared/helpers/admin/_unpublished_sign.slim +1 -0
  234. data/lib/generators/templates/install/auto/browserslist +3 -0
  235. data/lib/generators/templates/install/auto/config/deploy/shared/database.yml.erb +10 -0
  236. data/lib/generators/templates/install/auto/config/deploy/shared/nginx.conf.erb +28 -0
  237. data/lib/generators/templates/install/auto/config/deploy/shared/unicorn.rb.erb +35 -0
  238. data/lib/generators/templates/install/auto/config/deploy/staging.rb +12 -0
  239. data/lib/generators/templates/install/auto/config/environments/staging.rb +84 -0
  240. data/lib/generators/templates/install/auto/config/initializers/awesome_nested_set.rb +1 -0
  241. data/lib/generators/templates/install/auto/config/initializers/content_security_policy.rb +26 -0
  242. data/lib/generators/templates/install/auto/config/initializers/friendly_id.rb +1 -0
  243. data/lib/generators/templates/install/auto/config/initializers/kaminari_config.rb +15 -0
  244. data/lib/generators/templates/install/auto/config/initializers/simple_form.rb +238 -0
  245. data/lib/generators/templates/install/auto/config/initializers/slim.rb +2 -0
  246. data/lib/generators/templates/install/auto/config/locales/adminos.en.yml +164 -0
  247. data/lib/generators/templates/install/auto/config/locales/adminos.ru.yml +292 -0
  248. data/lib/generators/templates/install/auto/lib/capistrano/substitute_strings.rb +12 -0
  249. data/lib/generators/templates/install/auto/lib/capistrano/tasks/setup_config.cap +39 -0
  250. data/lib/generators/templates/install/auto/lib/capistrano/template.rb +33 -0
  251. data/lib/generators/templates/install/auto/public/404.html +26 -0
  252. data/lib/generators/templates/install/auto/public/500.html +25 -0
  253. data/lib/generators/templates/install/database.yml +19 -0
  254. data/lib/generators/templates/install/deploy.rb.erb +21 -0
  255. data/lib/generators/templates/install/install_devise/ability.rb +49 -0
  256. data/lib/generators/templates/install/install_devise/application.rb +7 -0
  257. data/lib/generators/templates/install/install_devise/prepare_users.rb +1 -0
  258. data/lib/generators/templates/install/install_devise/user.rb +21 -0
  259. data/lib/generators/templates/install/prepare_settings.rb +4 -0
  260. data/lib/generators/templates/install/routes/pages.rb +18 -0
  261. data/lib/generators/templates/install/routes.rb.erb +53 -0
  262. data/lib/generators/templates/install/settings_migration.rb +16 -0
  263. data/lib/generators/templates/install/webpack/custom.js +36 -0
  264. data/lib/generators/templates/install/webpack/environment.js +4 -0
  265. data/lib/generators/templates/install/webpack/javascript/admin/js/index.js +2 -0
  266. data/lib/generators/templates/install/webpack/javascript/admin/styles/admin.scss +2 -0
  267. data/lib/generators/templates/install/webpack/javascript/packs/admin.js +2 -0
  268. data/package-lock.json +3 -0
  269. data/spec/config/database.yml +2 -0
  270. data/spec/db/schema.rb +0 -0
  271. data/spec/lib/adminos/helpers/models/apply_sortable_order.rb +26 -0
  272. data/spec/lib/adminos/helpers/models/array_attrs_spec.rb +38 -0
  273. data/spec/lib/adminos/helpers/models/dom_id_spec.rb +41 -0
  274. data/spec/lib/adminos/helpers/models/flag_attrs_spec.rb +115 -0
  275. data/spec/lib/adminos/helpers/models/if_blank_set_to_nil_params_spec.rb +36 -0
  276. data/spec/lib/adminos/helpers/models/recognizable_spec.rb +40 -0
  277. data/spec/lib/adminos/helpers/models/slugged.rb +40 -0
  278. data/spec/lib/generators/adminos/adminos_generator_spec.rb +106 -0
  279. data/spec/lib/generators/adminos/ci_generator_spec.rb +88 -0
  280. data/spec/lib/generators/adminos/i18n_generator_spec.rb +31 -0
  281. data/spec/lib/generators/adminos/install_generator_rspec.rb +322 -0
  282. data/spec/spec_helper.rb +122 -0
  283. data/spec/support/ammeter.rb +14 -0
  284. data/spec/support/database.rb +29 -0
  285. data/spec/support/generators.rb +99 -0
  286. data/spec/support/post.rb +8 -0
  287. data/spec/support/shared/generator.rb +35 -0
  288. metadata +632 -0
@@ -0,0 +1,20 @@
1
+ module Adminos::Slugged
2
+ extend ActiveSupport::Concern
3
+
4
+ module ClassMethods
5
+ def slugged(*args)
6
+ options = args.extract_options!
7
+ sluggable_column = args.first || options.delete(:sluggable_column) || :name
8
+ slug_column = options.delete(:slug_column) || :slug
9
+ validate = options.fetch(:validates, true)
10
+
11
+ before_validation do |object|
12
+ if object.send sluggable_column
13
+ object[slug_column] = object.send(sluggable_column).parameterize
14
+ end
15
+ end
16
+
17
+ validates(slug_column, presence: true, format: { with: /\A[a-zA-Z0-9-]+\z/ }) if validate
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,61 @@
1
+ module Adminos::SoftDestroy
2
+ extend ActiveSupport::Concern
3
+
4
+ module ClassMethods
5
+ def with_soft_destroy(*args)
6
+ options = args.extract_options!
7
+ namespace = options.delete(:states_namespace) || :in_admin
8
+ publish_guard = options.delete(:publish_guard) || -> { true }
9
+ unpublish_guard = options.delete(:unpublish_guard) || -> { true }
10
+ soft_destroy_guard = options.delete(:soft_destroy_guard) || -> { true }
11
+
12
+ attr_accessible :published
13
+ attr_accessor :published
14
+
15
+ before_save do |object|
16
+ if object.published?
17
+ object.send("unpublish_#{namespace}") if object.published == false
18
+ else
19
+ object.send("publish_#{namespace}") if object.published == true
20
+ end
21
+ end
22
+
23
+ state_machine("#{namespace}_state", initial: :unpublished,
24
+ namespace: namespace) do
25
+ after_transition do |user, transition|
26
+ fail(ActiveRecord::RecordInvalid, user) unless user.valid?
27
+ user.update_attribute("#{namespace}_state_transition_at", Time.zone.now)
28
+ end
29
+
30
+ event :publish do
31
+ transition all - [:deleted, :published] => :published, :if => publish_guard
32
+ end
33
+
34
+ event :unpublish do
35
+ transition all - [:deleted, :unpublished] => :unpublished, :if => unpublish_guard
36
+ end
37
+
38
+ event :soft_destroy do
39
+ transition all - :deleted => :deleted, :if => soft_destroy_guard
40
+ end
41
+ end
42
+
43
+ scope :active, -> { where("#{namespace}_state != 'deleted'") }
44
+ scope :published, -> { where("#{namespace}_state" => 'published') }
45
+ scope :unpublished, -> { where("#{namespace}_state" => 'unpublished') }
46
+ scope :deleted, -> { where("#{namespace}_state" => 'deleted') }
47
+
48
+ define_method :published? do
49
+ self.send("#{namespace}_published?")
50
+ end
51
+
52
+ define_method :active? do
53
+ !self.send("#{namespace}_deleted?")
54
+ end
55
+
56
+ define_singleton_method :soft_destroy_each! do
57
+ each { |object| object.send("soft_destroy_#{namespace}!") }
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,105 @@
1
+ module Adminos::Wysiwyg
2
+ extend ActiveSupport::Concern
3
+ mattr_accessor :default, :strict, :strip_tags
4
+
5
+ @@default = \
6
+ {
7
+ elements: %w[
8
+ a b blockquote br caption dd dl
9
+ dt em h1 h2 h3 h4 h5 h6 hr i iframe img li
10
+ ol p s small span strike strong sub sup table tbody td
11
+ tfoot th thead tr u ul div map area section article noscript param object video source
12
+ ],
13
+
14
+ attributes: {
15
+ :all => ['lang', 'title', 'class', 'style', 'id', 'data-speed', 'data-delay', 'data-src', 'data-screenwidth', 'data-alt'],
16
+ 'a' => ['href', 'target', 'name'],
17
+ 'img' => ['alt', 'height', 'src', 'width', 'usemap'],
18
+ 'ol' => ['start'],
19
+ 'td' => ['colspan', 'rowspan'],
20
+ 'th' => ['colspan', 'rowspan'],
21
+ 'iframe' => ['title', 'type', 'width', 'height', 'src', 'frameborder', 'allowFullScreen'],
22
+ 'map' => ['name'],
23
+ 'area' => ['shape', 'href', 'class', 'coords', 'alt'],
24
+ 'object' => ['data', 'type', 'width', 'height'],
25
+ 'param' => ['name', 'value'],
26
+ 'video' => ['autoplay', 'controls', 'width', 'height', 'loop', 'poster'],
27
+ 'source' => ['src', 'type']
28
+ },
29
+
30
+ protocols: {
31
+ 'a' => { 'href' => ['ftp', 'http', 'https', 'mailto', :relative] },
32
+ 'blockquote' => { 'cite' => ['http', 'https', :relative] },
33
+ 'del' => { 'cite' => ['http', 'https', :relative] },
34
+ 'img' => { 'src' => ['http', 'https', :relative] },
35
+ 'ins' => { 'cite' => ['http', 'https', :relative] },
36
+ 'q' => { 'cite' => ['http', 'https', :relative] }
37
+ },
38
+
39
+ remove_contents: %w(style)
40
+ }
41
+
42
+ @@strict = \
43
+ {
44
+ elements: %w[
45
+ p h2 h3 h4 blockquote a b strong i em br hr iframe img ul ol li span sub sup
46
+ ],
47
+
48
+ attributes: {
49
+ :all => ['lang', 'title'],
50
+ 'a' => ['href', 'target'],
51
+ 'img' => ['alt', 'height', 'src', 'width', 'style'],
52
+ 'ol' => ['start'],
53
+ 'p' => [],
54
+ 'iframe' => ['type', 'width', 'height', 'src', 'frameborder', 'allowFullScreen']
55
+ },
56
+
57
+ protocols: {
58
+ 'a' => { 'href' => ['ftp', 'http', 'https', 'mailto', :relative] },
59
+ 'blockquote' => { 'cite' => ['http', 'https', :relative] },
60
+ 'del' => { 'cite' => ['http', 'https', :relative] },
61
+ 'img' => { 'src' => ['http', 'https', :relative] },
62
+ 'ins' => { 'cite' => ['http', 'https', :relative] },
63
+ 'q' => { 'cite' => ['http', 'https', :relative] }
64
+ },
65
+
66
+ remove_contents: %w(style)
67
+ }
68
+
69
+ @@strip_tags = { elements: nil }
70
+
71
+ module ClassMethods
72
+ def wysiwyg_sanitize(*args)
73
+ options = args.extract_options!
74
+ config = options.delete(:kind) || :default
75
+ kaya_content = options.delete(:kaya_content)
76
+
77
+ before_validation do
78
+ args.each do |f|
79
+ if kaya_content
80
+ self[f] = self.class.wysiwyg_clean_kaya self[f], send(config)
81
+ else
82
+ self[f] = self.class.wysiwyg_clean self[f], send(config)
83
+ end
84
+ end
85
+ end
86
+ end
87
+
88
+ def wysiwyg_clean_kaya(data, config)
89
+ kaya_data = JSON.parse(data)
90
+ kaya_data.map! do |block|
91
+ if block['type'] == 'text'
92
+ block['data']['text'] = wysiwyg_clean block['data']['text'], config
93
+ end
94
+ block
95
+ end
96
+ kaya_data.to_json
97
+ end
98
+
99
+ def wysiwyg_clean(text, config)
100
+ res = Sanitize.clean text, config
101
+ res = res.gsub(/^<br\s*(\/?)>\s*$/im, '') unless res.nil?
102
+ res
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,137 @@
1
+ module Adminos::Helpers::View
2
+ def inside_layout(l, &block)
3
+ content_for("#{l}_layout".to_sym, capture(&block))
4
+ render(template: "layouts/#{l}")
5
+ end
6
+
7
+ def show_title
8
+ return @title if @title.present?
9
+ title_default
10
+ end
11
+
12
+ def title(*args, &block)
13
+ return(@title = capture(&block)) if block_given?
14
+
15
+ t = args.first
16
+ t =
17
+ if t.respond_to?(:meta_title) && t.meta_title.present?
18
+ t.meta_title
19
+ elsif t.respond_to?(:name) && t.name.present?
20
+ t.name
21
+ else
22
+ t
23
+ end
24
+
25
+ @title = h(t)
26
+ end
27
+
28
+ def show_flash_alert(*args)
29
+ options = args.extract_options!
30
+
31
+ kind = options.delete(:kind) || :notice
32
+ message = args.first || options.delete(:message)
33
+ messages = { kind => message } if message.present?
34
+ messages ||= Hash[[:error, :notice, :alert].map { |kind| [kind, flash[kind]] }]
35
+ messages = messages.select { |key, value| value.present? }
36
+
37
+ css_class = options.delete(:class)
38
+ css_class = [css_class] unless css_class.is_a?(Array)
39
+ css_class = css_class + %w(alert alert-block)
40
+
41
+ style = options.delete(:style)
42
+
43
+ r = ''
44
+ messages.each do |kind, message|
45
+ r << capture do
46
+ render(partial: 'shared/helpers/show_flash_alert',
47
+ locals: { message: message, kind: kind, css_class: css_class,
48
+ style: style, options: options })
49
+ end
50
+ end
51
+
52
+ raw(r)
53
+ end
54
+
55
+ def alert_close
56
+ render partial: 'shared/helpers/alert_close'
57
+ end
58
+
59
+ def page_header(*args, &block)
60
+ options = args.extract_options!
61
+ opts = { value: args.first, block: (capture(&block) if block_given?) }.
62
+ merge(opts: options)
63
+ render partial: 'shared/helpers/page_header', locals: opts
64
+ end
65
+
66
+ def breadcrumbs(*args, &block)
67
+ options = args.extract_options!
68
+ opts = { url: request.path,
69
+ label: (block_given? ? capture(&block) : args.first) }.
70
+ merge(options)
71
+
72
+ @breadcrumbs ||= []
73
+ @breadcrumbs << Struct::Breadcrumb.new(opts[:label], opts[:url])
74
+ end
75
+ alias breadcrumbs_admin breadcrumbs
76
+
77
+ def show_breadcrumbs(*args)
78
+ return '' if @breadcrumbs.blank?
79
+
80
+ options = args.extract_options!
81
+
82
+ is_admin = options.delete(:admin)
83
+ divider = options.delete(:divider)
84
+ divider_tag =
85
+ if divider.present?
86
+ divider
87
+ elsif is_admin
88
+ content_tag :span, '/', class: :divider
89
+ end
90
+
91
+ @breadcrumbs.uniq!
92
+ @breadcrumbs.reverse! #breadcrumbs added to the beginning from the end
93
+
94
+ render(partial: "shared/helpers/#{'admin/' if is_admin}show_breadcrumbs",
95
+ locals: { breadcrumbs: @breadcrumbs, divider: divider_tag,
96
+ options: options })
97
+ end
98
+
99
+ def optional_cls(*args)
100
+ options = args.extract_options!
101
+ clsses = options.map { |cls, condition| cls if condition }.compact
102
+ [Array.wrap(args) + clsses].join(' ')
103
+ end
104
+
105
+ def nav_link_state(page)
106
+ return :active if page.absolute_path == controller.request.path &&
107
+ controller.request.request_method_symbol == :get
108
+
109
+ if controller.request.path.starts_with?(page.absolute_path)
110
+ :chosen
111
+ else
112
+ :inactive
113
+ end
114
+ end
115
+
116
+ def navigation_link(object, *args)
117
+ options = args.extract_options!
118
+ redirect = options.delete(:redirect)
119
+
120
+ name = object.nav_name
121
+ path =
122
+ if redirect && object.default_behavior? && object.children.present?
123
+ depth = object.descendants.published.uniq.maximum(:depth)
124
+ object.descendants.published.where(depth: depth).first
125
+ else
126
+ object
127
+ end .absolute_path
128
+ state = path == controller.request.path ? :active : nav_link_state(object)
129
+
130
+ stateful_link_to(
131
+ active: ('<li class="active"><span>' + name + '</span></li>').html_safe,
132
+ inactive: ('<li><a href="' + path + '">' + name + '</a></li>').html_safe,
133
+ chosen: ('<li class="active"><a href="' + path + '">' + name + '</a></li>').html_safe,
134
+ state: state
135
+ )
136
+ end
137
+ end
@@ -0,0 +1,18 @@
1
+ require 'pathname'
2
+
3
+ # @see Dotenv::Railtie
4
+ module Adminos
5
+ module Operations
6
+ class CheckEnvironment
7
+ EXPRESSION = /`(\.env.*)`/
8
+
9
+ def call
10
+ ENV.inject([]) do |result, (name, value)|
11
+ next result unless value =~ EXPRESSION
12
+
13
+ result << name
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,42 @@
1
+ require 'pathname'
2
+
3
+ module Adminos
4
+ module Operations
5
+ class ExtractEnvironment
6
+ OPTIONAL = %w[RAILS_ENV VERBOSE DISABLE_SPRING PORT WEB_CONCURRENCY]
7
+
8
+ def extensions
9
+ %w[ru thor rake rb yml ruby yaml erb builder markerb slim haml cap]
10
+ end
11
+
12
+ # @return [{String => <{path: Pathname, line: Integer}>}]
13
+ def call(globs = '*')
14
+ results = Hash.new { |hash, key| hash[key] = [] }
15
+
16
+ Array(globs).each do |glob|
17
+ Pathname.glob(glob).each do |item|
18
+ next results.merge!(call(item.join('*'))) if item.directory?
19
+
20
+ next unless extensions.detect { |ext| item.extname.to_s[ext] }
21
+
22
+ item.readlines.each_with_index do |line, ix|
23
+ capture_variables(line).each do |variable|
24
+ next if OPTIONAL.include?(variable)
25
+
26
+ results[variable] << { path: item, line: ix.succ }
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ Hash[results.sort_by(&:first)]
33
+ end
34
+
35
+ private
36
+
37
+ def capture_variables(line)
38
+ line.scan(/ENV(?:\[|\.fetch\()['"]([^'"]+)['"]/).flatten
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,30 @@
1
+ require 'pathname'
2
+ require 'dotenv'
3
+
4
+ # @see Dotenv::Railtie
5
+ module Adminos
6
+ module Operations
7
+ class LoadEnvironment
8
+ def initialize(root: Pathname.pwd, env: ENV.fetch('RAILS_ENV', 'development'))
9
+ @root = root
10
+ @env = env
11
+ end
12
+
13
+ attr_reader :root
14
+ attr_reader :env
15
+
16
+ def call
17
+ Dotenv.load(*dotenv_files)
18
+ end
19
+
20
+ def dotenv_files
21
+ [
22
+ root.join(".env.#{env}.local"),
23
+ (root.join(".env.local") unless env == 'test'),
24
+ root.join(".env.#{env}"),
25
+ root.join(".env")
26
+ ].compact
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,76 @@
1
+ # <https://github.com/gzigzigzeo/stateful_link>.
2
+ module Adminos::StatefulLink::ActionAnyOf#:doc:
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ helper_method :action_any_of?, :extract_controller_and_action, :action_state if respond_to?(:helper_method)
7
+ end
8
+
9
+ # Returns true if current controller and action names equals to any of passed.
10
+ # Asterik as action name matches all controller's action.
11
+ #
12
+ # Examples:
13
+ # <%= "we are in PostsController::index" if action_any_of?("posts#index") %>
14
+ #
15
+ # <%= "we are not in PostsController::index" unless action_any_of?("posts#index") %>
16
+ #
17
+ # <% if action_any_of?("posts#index", "messages#index") %>
18
+ # we are in PostsController or in MessagesController
19
+ # <% end %>
20
+ #
21
+ def action_any_of?(*actions)
22
+ actions.any? do |sub_ca|
23
+ if sub_ca.present?
24
+ sub_controller, sub_action = extract_controller_and_action(sub_ca)
25
+ ((self.controller_path == sub_controller) || (sub_controller.blank?)) && (self.action_name == sub_action || (sub_action == '' || sub_action == '*'))
26
+ end
27
+ end
28
+ end
29
+
30
+ # Extracts controller and action names from a string.
31
+ #
32
+ # Examples:
33
+ #
34
+ # extract_controller_and_action("posts#index") # ["posts", "index"]
35
+ # extract_controller_and_action("admin/posts#index") # ["admin/posts", "index"]
36
+ # extract_controller_and_action("admin/posts#index") # raises ArgumentError
37
+ #
38
+ def extract_controller_and_action(ca)
39
+ raise ArgumentError, "Pass the string" if ca.nil?
40
+ slash_pos = ca.rindex('#')
41
+ raise ArgumentError, "Invalid action: #{ca}" if slash_pos.nil?
42
+ controller = ca[0, slash_pos]
43
+ action = ca[slash_pos + 1..-1] || ""
44
+ raise ArgumentError, "Invalid action or controller" if action.nil?
45
+
46
+ [controller, action]
47
+ end
48
+
49
+ # Returns link state related to current controller and action: :inactive, :active or :chosen.
50
+ # A list of active actions is the first argument, chosen actions are the second argument.
51
+ #
52
+ # Examples:
53
+ # # :active for PostsController::index, :chosen for PostsController::* (except :index),
54
+ # # :inactive otherwise.
55
+ # action_state("posts#index", "posts#")
56
+ #
57
+ # # :active for PostsController::new and PostsController::create, :inactive otherwise.
58
+ # action_state(["posts#new", "posts#create"])
59
+ #
60
+ # # :active for PostsController::index, :chosen for MessagesController::* and
61
+ # # PostsController::* (except :index), :inactive otherwise.
62
+ # action_state("posts#index", ["posts#", "messages#"])
63
+ #
64
+ def action_state(active, chosen = nil)
65
+ active = active.is_a?(String) ? [active] : active
66
+ chosen = chosen.is_a?(String) ? [chosen] : chosen
67
+
68
+ if action_any_of?(*active)
69
+ :active
70
+ elsif !chosen.nil? && action_any_of?(*chosen)
71
+ :chosen
72
+ else
73
+ :inactive
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,31 @@
1
+ # <https://github.com/gzigzigzeo/stateful_link>.
2
+ module Adminos::StatefulLink::Helper#:doc:
3
+ # Generates stateful link to something.
4
+ #
5
+ # Options:
6
+ # :inactive - template of inactive state (block or string).
7
+ # :active - template of active state.
8
+ # :chosen - template of chosen state.
9
+ # :state - state (action_state called if none) - block, symbol or boolean
10
+ #
11
+ # Any option may be proc.
12
+ #
13
+ # Example:
14
+ # stateful_link_to("foos#index", "bars#index",
15
+ # :active => "<li class='active'>Good!</li>",
16
+ # :chosen => "<li class='chosen'>#{link_to(...)}</li>"
17
+ # )
18
+ #
19
+ def stateful_link_to(*args)
20
+ options = args.extract_options!
21
+ active = args.first
22
+ chosen = args.second
23
+ state = options[:state]
24
+ state = proc { action_state(active, chosen) } if state.nil?
25
+ state = state.is_a?(Proc) ? instance_exec(&state) : state
26
+ state = :active if state == true
27
+ state = :inactive if state == false
28
+ current = options[state]
29
+ current.is_a?(Proc) ? instance_exec(&current) : current
30
+ end
31
+ end
data/lib/adminos.rb ADDED
@@ -0,0 +1,42 @@
1
+ require 'path'
2
+ require 'rails'
3
+ require 'jquery-fileupload-rails'
4
+ require 'dotenv-rails'
5
+ require 'babosa'
6
+ require 'russian'
7
+ require 'devise'
8
+ require 'cancancan'
9
+ require 'cocoon'
10
+
11
+ module Adminos
12
+ Helpers = Module.new
13
+ NestedSet = Module.new
14
+ Controllers = Module.new
15
+ StatefulLink = Module.new
16
+
17
+ Path.require_tree 'adminos', except: %w[generators operations]
18
+
19
+ class Engine < ::Rails::Engine
20
+ initializer 'adminos.view_helpers' do
21
+ ActionView::Base.send :include, Helpers::View
22
+ ActionView::Base.send :include, Helpers::Admin
23
+ ActionView::Base.send :include, Helpers::Bootstrap
24
+ end
25
+
26
+ initializer 'adminos.controller_helpers' do
27
+ ActionController::Base.send :include, Controllers::Helpers
28
+ ActionController::Base.send :include, Controllers::Resource
29
+ end
30
+
31
+ initializer 'adminos.stateful_link' do
32
+ ActionView::Base.send :include, StatefulLink::Helper
33
+ ActionController::Base.send :include, StatefulLink::ActionAnyOf
34
+ end
35
+
36
+ initializer 'adminos.assets' do
37
+ Rails.application.config.assets.precompile += %w(apple-touch-icon.png favicon-32x32.png favicon-16x16.png safari-pinned-tab.svg favicon.ico)
38
+ end
39
+ end
40
+ end
41
+
42
+ require 'adminos/extensions/nested_set'
@@ -0,0 +1,15 @@
1
+ require 'adminos/generators/utilities'
2
+
3
+ extend Adminos::Generators::Utilities
4
+
5
+ commit_changes 'Generate Rails application'
6
+
7
+ gem 'adminos', source: 'https://gems.molinos.ru/'
8
+ run 'bundle install'
9
+ generate 'adminos:install'
10
+
11
+ commit_changes 'Set up Adminos'
12
+
13
+ after_bundle do
14
+ commit_changes 'Finish rails app setup'
15
+ end