biovision 0.0.200518.1 → 0.12.211124.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (345) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +105 -52
  3. data/app/assets/images/biovision/icons/back.svg +19 -0
  4. data/app/assets/images/biovision/icons/create.svg +19 -0
  5. data/app/assets/images/biovision/icons/destroy.svg +12 -0
  6. data/app/assets/images/biovision/icons/dropdown.svg +3 -0
  7. data/app/assets/images/biovision/icons/edit.svg +22 -0
  8. data/app/assets/images/biovision/icons/gear.svg +11 -0
  9. data/app/assets/images/biovision/icons/return.svg +25 -0
  10. data/app/assets/images/biovision/icons/world.svg +11 -0
  11. data/app/assets/stylesheets/biovision/admin/components/users.scss +20 -0
  12. data/app/assets/stylesheets/biovision/admin/components.scss +13 -1
  13. data/app/assets/stylesheets/biovision/admin/layout.scss +27 -12
  14. data/app/assets/stylesheets/biovision/biovision.scss +105 -26
  15. data/app/assets/stylesheets/biovision/components/breadcrumbs.scss +13 -0
  16. data/app/assets/stylesheets/biovision/components/buttons.scss +130 -0
  17. data/app/assets/stylesheets/biovision/components/filters.scss +39 -0
  18. data/app/assets/stylesheets/biovision/components/forms.scss +208 -1
  19. data/app/assets/stylesheets/biovision/components/lists.scss +6 -7
  20. data/app/assets/stylesheets/biovision/{biovision → components}/messages.scss +9 -0
  21. data/app/assets/stylesheets/biovision/components/pagination.scss +34 -0
  22. data/app/assets/stylesheets/biovision/components/quick_search.scss +24 -0
  23. data/app/assets/stylesheets/biovision/components/simple_image.scss +112 -0
  24. data/app/assets/stylesheets/biovision/components/toggleable.scss +71 -0
  25. data/app/assets/stylesheets/biovision/components.scss +7 -0
  26. data/app/assets/stylesheets/biovision/default.scss +4 -4
  27. data/app/assets/stylesheets/biovision/themes/default_theme/components/users/dashboard.scss +4 -0
  28. data/app/assets/stylesheets/biovision/themes/default_theme/components/users/form_tabs.scss +101 -0
  29. data/app/assets/stylesheets/biovision/themes/default_theme/components/users/profile.scss +77 -0
  30. data/app/assets/stylesheets/biovision/themes/default_theme/components/users.scss +3 -0
  31. data/app/assets/stylesheets/biovision/themes/default_theme/components.scss +2 -3
  32. data/app/assets/stylesheets/biovision/themes/default_theme/layout/footer.scss +3 -0
  33. data/app/assets/stylesheets/biovision/themes/default_theme/layout/header.scss +12 -0
  34. data/app/assets/stylesheets/biovision/themes/default_theme/layout.scss +8 -19
  35. data/app/assets/stylesheets/biovision/themes/default_theme.scss +0 -1
  36. data/app/assets/stylesheets/biovision/vars.scss +5 -0
  37. data/app/controllers/admin/biovision_components_controller.rb +10 -0
  38. data/app/controllers/admin/components_controller.rb +37 -97
  39. data/app/controllers/admin/dynamic_blocks_controller.rb +15 -0
  40. data/app/controllers/admin/dynamic_pages_controller.rb +15 -0
  41. data/app/controllers/admin/index_controller.rb +8 -2
  42. data/app/controllers/admin/navigation_groups_controller.rb +45 -0
  43. data/app/controllers/admin/tokens_controller.rb +15 -0
  44. data/app/controllers/admin/users_controller.rb +101 -0
  45. data/app/controllers/admin_controller.rb +2 -8
  46. data/app/controllers/authentication_controller.rb +6 -34
  47. data/app/controllers/concerns/authentication.rb +12 -12
  48. data/app/controllers/concerns/component_stories.rb +22 -0
  49. data/app/controllers/concerns/crud_entities.rb +140 -0
  50. data/app/controllers/concerns/entity_priority.rb +10 -0
  51. data/app/controllers/concerns/my_crud_entities.rb +146 -0
  52. data/app/controllers/concerns/processed_forms.rb +28 -0
  53. data/app/controllers/concerns/restricted_access.rb +37 -0
  54. data/app/controllers/concerns/toggleable_entity.rb +31 -0
  55. data/app/controllers/contact_controller.rb +49 -0
  56. data/app/controllers/errors_controller.rb +37 -0
  57. data/app/controllers/fallback_controller.rb +12 -0
  58. data/app/controllers/index_controller.rb +1 -0
  59. data/app/controllers/legal_controller.rb +14 -0
  60. data/app/controllers/my/components_controller.rb +26 -0
  61. data/app/controllers/my/confirmations_controller.rb +44 -0
  62. data/app/controllers/my/index_controller.rb +7 -1
  63. data/app/controllers/my/profiles_controller.rb +33 -16
  64. data/app/controllers/oembed_controller.rb +12 -0
  65. data/app/controllers/profile_controller.rb +14 -0
  66. data/app/controllers/users_controller.rb +63 -0
  67. data/app/helpers/biovision_components_helper.rb +7 -3
  68. data/app/helpers/biovision_helper.rb +170 -0
  69. data/app/helpers/entity_helper.rb +77 -0
  70. data/app/helpers/my_helper.rb +34 -0
  71. data/app/helpers/simple_image_helper.rb +125 -0
  72. data/app/jobs/application_job.rb +7 -0
  73. data/app/jobs/send_phone_confirmation_job.rb +16 -0
  74. data/app/lib/biovision/components/base/component_parameters.rb +55 -0
  75. data/app/lib/biovision/components/base/component_privileges.rb +75 -0
  76. data/app/lib/biovision/components/base/component_settings.rb +40 -0
  77. data/app/lib/biovision/components/base/component_stories.rb +30 -0
  78. data/app/lib/biovision/components/base/entity_links.rb +38 -0
  79. data/app/lib/biovision/components/base/image_handling.rb +33 -0
  80. data/app/lib/biovision/components/base_component.rb +63 -95
  81. data/app/lib/biovision/components/contact_component.rb +26 -0
  82. data/app/lib/biovision/components/content/oembed/receiver.rb +98 -0
  83. data/app/lib/biovision/components/content/oembed/twitter_receiver.rb +20 -0
  84. data/app/lib/biovision/components/content/oembed/vimeo_receiver.rb +20 -0
  85. data/app/lib/biovision/components/content/oembed/youtube_receiver.rb +20 -0
  86. data/app/lib/biovision/components/content_component.rb +65 -0
  87. data/app/lib/biovision/components/track_component.rb +3 -0
  88. data/app/lib/biovision/components/users/authentication.rb +15 -7
  89. data/app/lib/biovision/components/users/codes.rb +104 -0
  90. data/app/lib/biovision/components/users/flag_helpers.rb +72 -0
  91. data/app/lib/biovision/components/users/profile_handler.rb +111 -1
  92. data/app/lib/biovision/components/users/registration_handler.rb +40 -52
  93. data/app/lib/biovision/components/users/validation.rb +83 -0
  94. data/app/lib/biovision/components/users_component.rb +114 -19
  95. data/app/lib/biovision/helpers/data_helper.rb +70 -0
  96. data/app/lib/biovision/helpers/export_helper.rb +97 -0
  97. data/app/lib/biovision/migrations/component_migration.rb +56 -0
  98. data/app/lib/biovision/notifiers/base_notifier.rb +2 -2
  99. data/app/lib/biovision/notifiers/contact_notifier.rb +15 -0
  100. data/app/lib/biovision/stories/component_story.rb +55 -0
  101. data/app/lib/canonizer.rb +38 -0
  102. data/app/lib/carrier_wave/image_optim.rb +32 -0
  103. data/app/mailers/code_sender.rb +29 -0
  104. data/app/mailers/feedback_mailer.rb +14 -0
  105. data/app/models/agent.rb +4 -0
  106. data/app/models/biovision_component.rb +39 -3
  107. data/app/models/code.rb +31 -8
  108. data/app/models/concerns/checkable.rb +2 -1
  109. data/app/models/concerns/has_simple_image.rb +9 -0
  110. data/app/models/concerns/has_uploaded_file.rb +26 -0
  111. data/app/models/concerns/meta_texts.rb +25 -5
  112. data/app/models/concerns/simple_tag.rb +30 -0
  113. data/app/models/concerns/toggleable.rb +2 -1
  114. data/app/models/concerns/tree_structure.rb +75 -0
  115. data/app/models/contact_method.rb +47 -0
  116. data/app/models/contact_type.rb +27 -0
  117. data/app/models/dynamic_block.rb +43 -0
  118. data/app/models/dynamic_page.rb +73 -0
  119. data/app/models/feedback_message.rb +65 -0
  120. data/app/models/feedback_response.rb +50 -0
  121. data/app/models/group.rb +48 -0
  122. data/app/models/language.rb +4 -0
  123. data/app/models/metric.rb +4 -0
  124. data/app/models/navigation_group.rb +43 -0
  125. data/app/models/navigation_group_page.rb +23 -0
  126. data/app/models/oembed_domain.rb +25 -0
  127. data/app/models/oembed_link.rb +19 -0
  128. data/app/models/oembed_receiver.rb +15 -0
  129. data/app/models/role.rb +86 -0
  130. data/app/models/role_group.rb +13 -0
  131. data/app/models/simple_image.rb +49 -8
  132. data/app/models/simple_image_tag.rb +1 -16
  133. data/app/models/token.rb +6 -2
  134. data/app/models/uploaded_file.rb +62 -0
  135. data/app/models/uploaded_file_tag.rb +15 -0
  136. data/app/models/uploaded_file_tag_file.rb +13 -0
  137. data/app/models/user.rb +122 -29
  138. data/app/models/user_group.rb +20 -0
  139. data/app/models/user_role.rb +18 -0
  140. data/app/uploaders/simple_file_uploader.rb +23 -0
  141. data/app/uploaders/simple_image_uploader.rb +29 -20
  142. data/app/uploaders/uploaders/path_slug.rb +22 -0
  143. data/app/views/admin/agents/index.html.erb +1 -3
  144. data/app/views/admin/biovision_components/_nav_item.html.erb +6 -0
  145. data/app/views/admin/biovision_components/entity/_in_list.html.erb +12 -0
  146. data/app/views/admin/biovision_components/index.html.erb +11 -0
  147. data/app/views/admin/components/_image.jbuilder +18 -0
  148. data/app/views/admin/components/_list.html.erb +1 -1
  149. data/app/views/admin/components/entity/_links.html.erb +31 -21
  150. data/app/views/admin/components/image.jbuilder +1 -0
  151. data/app/views/admin/components/images.jbuilder +4 -0
  152. data/app/views/admin/components/links/_base.html.erb +1 -0
  153. data/app/views/admin/components/settings/_new_parameter.html.erb +4 -2
  154. data/app/views/admin/components/settings/_parameters.html.erb +8 -2
  155. data/app/views/admin/components/settings/_settings.html.erb +4 -4
  156. data/app/views/admin/components/settings.html.erb +2 -1
  157. data/app/views/admin/components/update_privileges.jbuilder +21 -0
  158. data/app/views/admin/dynamic_blocks/_form.html.erb +16 -0
  159. data/app/views/admin/dynamic_blocks/_nav_item.html.erb +6 -0
  160. data/app/views/admin/dynamic_blocks/entity/_in_list.html.erb +12 -0
  161. data/app/views/admin/dynamic_blocks/index.html.erb +17 -0
  162. data/app/views/admin/dynamic_blocks/show.html.erb +25 -0
  163. data/app/views/admin/dynamic_pages/_dynamic_page.jbuilder +18 -0
  164. data/app/views/admin/dynamic_pages/_form.html.erb +21 -0
  165. data/app/views/admin/dynamic_pages/_nav_item.html.erb +6 -0
  166. data/app/views/admin/dynamic_pages/entity/_in_list.html.erb +17 -0
  167. data/app/views/admin/dynamic_pages/entity/_in_search.html.erb +7 -0
  168. data/app/views/admin/dynamic_pages/index.html.erb +17 -0
  169. data/app/views/admin/dynamic_pages/search.jbuilder +4 -0
  170. data/app/views/admin/dynamic_pages/show.html.erb +28 -0
  171. data/app/views/admin/index/index.html.erb +7 -5
  172. data/app/views/admin/ip_addresses/index.html.erb +2 -4
  173. data/app/views/admin/navigation_group_pages/entity/_in_list.html.erb +26 -0
  174. data/app/views/admin/navigation_groups/_form.html.erb +15 -0
  175. data/app/views/admin/navigation_groups/_nav_item.html.erb +6 -0
  176. data/app/views/admin/navigation_groups/entity/_dynamic_pages.html.erb +38 -0
  177. data/app/views/admin/navigation_groups/entity/_in_list.html.erb +14 -0
  178. data/app/views/admin/navigation_groups/index.html.erb +17 -0
  179. data/app/views/admin/navigation_groups/show.html.erb +33 -0
  180. data/app/views/admin/tokens/_form.html.erb +31 -0
  181. data/app/views/admin/tokens/_nav_item.html.erb +6 -0
  182. data/app/views/admin/tokens/entity/_in_list.html.erb +27 -0
  183. data/app/views/admin/tokens/index.html.erb +11 -0
  184. data/app/views/admin/tokens/show.html.erb +26 -0
  185. data/app/views/admin/unauthorized.html.erb +2 -5
  186. data/app/views/admin/users/_form.html.erb +81 -0
  187. data/app/views/admin/users/_nav_item.html.erb +6 -0
  188. data/app/views/admin/users/_user.jbuilder +18 -0
  189. data/app/views/admin/users/entity/_fields.html.erb +53 -0
  190. data/app/views/admin/users/entity/_in_list.html.erb +38 -0
  191. data/app/views/admin/users/entity/_in_search.html.erb +18 -0
  192. data/app/views/admin/users/entity/_profile.html.erb +26 -0
  193. data/app/views/admin/users/entity/in_list/_additional_data.html.erb +0 -0
  194. data/app/views/admin/users/index.html.erb +24 -0
  195. data/app/views/admin/users/roles/_component.html.erb +22 -0
  196. data/app/views/admin/users/roles.html.erb +23 -0
  197. data/app/views/admin/users/search.jbuilder +4 -0
  198. data/app/views/admin/users/show.html.erb +62 -0
  199. data/app/views/admin/widgets/_filters.html.erb +20 -0
  200. data/app/views/admin/widgets/_quick_search.html.erb +13 -0
  201. data/app/views/admin/widgets/filters/_flag.html.erb +15 -0
  202. data/app/views/admin/widgets/filters/_text.html.erb +7 -0
  203. data/app/views/application/forbidden.html.erb +9 -0
  204. data/app/views/application/forbidden.jbuilder +4 -0
  205. data/app/views/application/not_found.html.erb +9 -0
  206. data/app/views/application/not_found.jbuilder +4 -0
  207. data/app/views/application/unauthorized.html.erb +19 -0
  208. data/app/views/application/unauthorized.jbuilder +4 -0
  209. data/app/views/authentication/new.html.erb +2 -8
  210. data/app/views/components/content/_dynamic_page.html.erb +17 -0
  211. data/app/views/components/content/_dynamic_page_content.html.erb +14 -0
  212. data/app/views/components/users/_form_tabs.html.erb +31 -0
  213. data/app/views/components/users/_join_form.html.erb +192 -0
  214. data/app/views/components/users/_login_form.html.erb +46 -0
  215. data/app/views/components/users/form/_image.html.erb +17 -0
  216. data/app/views/components/users/form/_profile_data.html.erb +54 -0
  217. data/app/views/contact/_form.html.erb +108 -0
  218. data/app/views/contact/create_feedback_message.js.erb +1 -0
  219. data/app/views/contact/feedback.html.erb +13 -0
  220. data/app/views/contact/index.html.erb +16 -0
  221. data/app/views/errors/error.html.erb +1 -0
  222. data/app/views/fallback/show.html.erb +6 -0
  223. data/app/views/feedback_mailer/new_feedback_request.html.erb +11 -0
  224. data/app/views/feedback_mailer/new_feedback_request.text.erb +6 -0
  225. data/app/views/index/index.html.erb +14 -0
  226. data/app/views/layouts/admin/_footer.html.erb +1 -1
  227. data/app/views/layouts/admin/_header.html.erb +7 -2
  228. data/app/views/layouts/admin.html.erb +0 -1
  229. data/app/views/layouts/application/_footer.html.erb +1 -1
  230. data/app/views/layouts/application/header/_authentication.html.erb +4 -1
  231. data/app/views/legal/privacy.html.erb +5 -0
  232. data/app/views/legal/tos.html.erb +5 -0
  233. data/app/views/my/components/index.html.erb +25 -0
  234. data/app/views/my/components/show.html.erb +21 -0
  235. data/app/views/my/confirmations/show.html.erb +62 -0
  236. data/app/views/my/index/_cards.html.erb +15 -0
  237. data/app/views/my/index/_email.html.erb +14 -0
  238. data/app/views/my/index/_navigation.html.erb +33 -0
  239. data/app/views/my/index/index.html.erb +12 -0
  240. data/app/views/my/profiles/_form.html.erb +10 -0
  241. data/app/views/my/profiles/check.jbuilder +4 -0
  242. data/app/views/my/profiles/edit.html.erb +14 -0
  243. data/app/views/my/profiles/form/_basic_parameters.html.erb +9 -0
  244. data/app/views/my/profiles/form/_sensitive_parameters.html.erb +68 -0
  245. data/app/views/my/profiles/new.html.erb +6 -8
  246. data/app/views/my/profiles/show.html.erb +36 -0
  247. data/app/views/my/recoveries/show.html.erb +0 -0
  248. data/app/views/shared/_flash_messages.html.erb +1 -1
  249. data/app/views/shared/_list_of_errors.html.erb +7 -0
  250. data/app/views/shared/admin/_breadcrumbs.html.erb +8 -0
  251. data/app/views/shared/admin/_list.html.erb +10 -19
  252. data/app/views/shared/admin/_list_with_priority.html.erb +10 -19
  253. data/app/views/shared/admin/_priority.html.erb +6 -0
  254. data/app/views/shared/admin/_toggle.html.erb +6 -0
  255. data/app/views/shared/entity/_date_field.html.erb +6 -0
  256. data/app/views/shared/entity/_formatted_text_field.html.erb +10 -0
  257. data/app/views/shared/entity/_image.html.erb +31 -0
  258. data/app/views/shared/entity/_language.html.erb +6 -0
  259. data/app/views/shared/entity/_linked_entity.html.erb +6 -0
  260. data/app/views/shared/entity/_list.html.erb +22 -0
  261. data/app/views/shared/entity/_list_with_priority.html.erb +22 -0
  262. data/app/views/shared/entity/_meta_texts.html.erb +16 -0
  263. data/app/views/shared/entity/_metadata.html.erb +18 -0
  264. data/app/views/shared/entity/_parent.html.erb +6 -0
  265. data/app/views/shared/entity/_priority.html.erb +4 -0
  266. data/app/views/shared/entity/_priority_icons.html.erb +8 -0
  267. data/app/views/shared/entity/_raw_text_field.html.erb +10 -0
  268. data/app/views/shared/entity/_simple_image.html.erb +10 -0
  269. data/app/views/shared/entity/_slug.html.erb +6 -0
  270. data/app/views/shared/entity/_text_field.html.erb +6 -0
  271. data/app/views/shared/entity/_text_fields.html.erb +9 -0
  272. data/app/views/shared/entity/_time_field.html.erb +6 -0
  273. data/app/views/shared/entity/_timestamps.html.erb +13 -0
  274. data/app/views/shared/entity/_toggle.html.erb +12 -0
  275. data/app/views/shared/entity/_track.html.erb +12 -0
  276. data/app/views/shared/entity/_tree_caches.html.erb +19 -0
  277. data/app/views/shared/entity/_uuid.html.erb +4 -0
  278. data/app/views/shared/entity/edit.html.erb +23 -0
  279. data/app/views/shared/entity/new.html.erb +16 -0
  280. data/app/views/shared/forms/_entity_flags.html.erb +15 -0
  281. data/app/views/shared/forms/_field.html.erb +50 -0
  282. data/app/views/shared/forms/_field_with_search.html.erb +17 -0
  283. data/app/views/shared/forms/_fields.html.erb +3 -0
  284. data/app/views/shared/forms/_language.html.erb +40 -0
  285. data/app/views/shared/forms/_meta_texts.html.erb +27 -0
  286. data/app/views/shared/forms/_priority.html.erb +13 -0
  287. data/app/views/shared/forms/_simple_entity_link.html.erb +14 -0
  288. data/app/views/shared/forms/_simple_image.html.erb +47 -0
  289. data/app/views/shared/forms/_state_container.html.erb +7 -0
  290. data/app/views/shared/forms/_text_area.html.erb +25 -0
  291. data/app/views/shared/forms/_text_field.html.erb +24 -0
  292. data/app/views/shared/forms/_text_fields.html.erb +3 -0
  293. data/app/views/shared/forms/check.jbuilder +4 -0
  294. data/app/views/shared/forms/errors.jbuilder +3 -0
  295. data/app/views/shared/forms/simple_image/_browse.html.erb +14 -0
  296. data/app/views/shared/forms/simple_image/_load_image.html.erb +38 -0
  297. data/app/views/shared/my/_list.html.erb +10 -0
  298. data/app/views/shared/my/_list_with_priority.html.erb +10 -0
  299. data/app/views/shared/my/entity/edit.html.erb +25 -0
  300. data/app/views/shared/my/entity/new.html.erb +18 -0
  301. data/app/views/simple_images/_simple_image.jbuilder +13 -0
  302. data/app/views/users/_profile.html.erb +30 -0
  303. data/app/views/users/profile/_data.html.erb +20 -0
  304. data/app/views/users/show.html.erb +21 -0
  305. data/config/locales/biovision-ru.yml +76 -1
  306. data/config/locales/components-ru.yml +55 -4
  307. data/config/locales/contact-ru.yml +110 -0
  308. data/config/locales/content-ru.yml +115 -0
  309. data/config/locales/users-ru.yml +142 -3
  310. data/config/routes.rb +99 -48
  311. data/db/migrate/20191228000000_create_biovision_components.rb +6 -5
  312. data/db/migrate/20200224000000_create_track_component.rb +9 -14
  313. data/db/migrate/20200224000010_create_users_component.rb +14 -83
  314. data/db/migrate/20200404000000_create_simple_images.rb +4 -3
  315. data/db/migrate/20210405000000_create_acl.rb +88 -0
  316. data/db/migrate/20210421000000_create_content_component.rb +80 -0
  317. data/db/migrate/20210421000010_create_contact_component.rb +74 -0
  318. data/db/migrate/20210616000000_create_uploaded_files.rb +52 -0
  319. data/db/migrate/amends/20210816060606_create_oembed_receivers.rb +21 -0
  320. data/db/migrate/amends/20210907070707_add_checksum_to_simple_images.rb +13 -0
  321. data/lib/biovision/base_methods.rb +17 -29
  322. data/lib/biovision/engine.rb +8 -13
  323. data/lib/biovision/version.rb +1 -1
  324. data/lib/tasks/components.rake +51 -0
  325. metadata +266 -27
  326. data/app/assets/images/biovision/placeholders/user.svg +0 -15
  327. data/app/helpers/users_helper.rb +0 -11
  328. data/app/lib/biovision/components/component_settings.rb +0 -30
  329. data/app/lib/biovision/components/privilege_handler.rb +0 -77
  330. data/app/lib/biovision/components/users/code_handler.rb +0 -23
  331. data/app/models/biovision_component_user.rb +0 -21
  332. data/app/models/foreign_site.rb +0 -34
  333. data/app/models/foreign_user.rb +0 -21
  334. data/app/uploaders/user_image_uploader.rb +0 -58
  335. data/app/views/admin/components/links/_track.html.erb +0 -2
  336. data/app/views/admin/components/links/_users.html.erb +0 -11
  337. data/app/views/admin/components/privileges/_component_user.html.erb +0 -17
  338. data/app/views/admin/components/privileges/_links.html.erb +0 -35
  339. data/app/views/admin/components/privileges/_privilege_flag.html.erb +0 -28
  340. data/app/views/admin/components/privileges/_users.html.erb +0 -23
  341. data/app/views/admin/components/privileges.html.erb +0 -20
  342. data/app/views/authentication/_form.html.erb +0 -40
  343. data/app/views/authentication/failed.js.erb +0 -3
  344. data/app/views/my/profiles/new/_form.html.erb +0 -147
  345. data/app/views/shared/admin/_toggleable.html.erb +0 -8
data/config/routes.rb CHANGED
@@ -5,71 +5,122 @@ Rails.application.routes.draw do
5
5
  post :check, on: :collection, defaults: { format: :json }
6
6
  end
7
7
 
8
+ concern :priority do
9
+ post :priority, on: :member, defaults: { format: :json }
10
+ end
11
+
8
12
  concern :toggle do
9
13
  post :toggle, on: :member, defaults: { format: :json }
10
14
  end
11
15
 
12
- concern :priority do
13
- post :priority, on: :member, defaults: { format: :json }
16
+ concern :search do
17
+ get :search, on: :collection
14
18
  end
15
19
 
16
- concern :removable_image do
17
- delete :image, action: :destroy_image, on: :member, defaults: { format: :json }
20
+ concern :stories do
21
+ post 'stories/:slug' => :story, on: :collection, as: :story
18
22
  end
19
23
 
20
- concern :lock do
21
- member do
22
- put :lock, defaults: { format: :json }
23
- delete :lock, action: :unlock, defaults: { format: :json }
24
- end
24
+ # Handling errors
25
+ match '/400' => 'errors#bad_request', via: :all
26
+ match '/401' => 'errors#unauthorized', via: :all
27
+ match '/403' => 'errors#forbidden', via: :all
28
+ match '/404' => 'errors#not_found', via: :all
29
+ match '/422' => 'errors#unprocessable_entity', via: :all
30
+ match '/500' => 'errors#internal_server_error', via: :all
31
+
32
+ # Contact component
33
+ scope 'contact', controller: :contact do
34
+ get '/' => :index, as: :contact
35
+ get 'feedback'
36
+ post 'feedback_messages' => :create_feedback_message
37
+ end
38
+
39
+ controller :legal do
40
+ get 'tos'
41
+ get 'privacy'
25
42
  end
26
43
 
27
- scope '(:locale)', constraints: { locale: /ru|en/ } do
28
- # Handling errors
29
- match '/400' => 'errors#bad_request', via: :all
30
- match '/401' => 'errors#unauthorized', via: :all
31
- match '/403' => 'errors#forbidden', via: :all
32
- match '/404' => 'errors#not_found', via: :all
33
- match '/422' => 'errors#unprocessable_entity', via: :all
34
- match '/500' => 'errors#internal_server_error', via: :all
35
-
36
- controller :authentication do
37
- get 'login' => :new
38
- post 'login' => :create
39
- delete 'logout' => :destroy
40
- get 'auth/:provider/callback' => :auth_callback, as: :auth_callback
44
+ # Users component
45
+ controller :authentication do
46
+ get 'login' => :new
47
+ post 'login' => :create
48
+ delete 'logout' => :destroy
49
+ end
50
+
51
+ scope 'u/:slug', controller: :users, constraints: { slug: %r{[^/]+} } do
52
+ get '/' => :show, as: :user
53
+ put 'follow' => :follow, as: :follow_user
54
+ delete 'follow' => :unfollow, as: nil
55
+ put 'ban' => :ban, as: :ban_user
56
+ delete 'ban' => :unban, as: nil
57
+ end
58
+
59
+ namespace :admin do
60
+ get '/' => 'index#index'
61
+
62
+ resources :biovision_components, only: :index, concerns: %i[priority toggle]
63
+
64
+ scope :components, controller: :components do
65
+ get '/' => :index, as: :components
66
+ scope ':slug' do
67
+ get '/' => :show, as: :component
68
+ get 'settings' => :settings, as: :component_settings
69
+ patch 'settings' => :update_settings, as: nil
70
+ patch 'parameters' => :update_parameter, as: :component_parameters
71
+ put 'administrators/:user_id' => :add_administrator, as: :component_administrators
72
+ delete 'administrators/:user_id' => :remove_administrator, as: nil
73
+ get 'images' => :images, as: :component_images
74
+ post 'images' => :create_image, as: nil
75
+ post 'ckeditor'
76
+ end
41
77
  end
42
78
 
43
- namespace :admin do
44
- get '/' => 'index#index'
45
-
46
- scope :components, controller: :components do
47
- get '/' => :index, as: :components
48
- scope ':slug' do
49
- get '/' => :show, as: :component
50
- get 'settings' => :settings, as: :component_settings
51
- patch 'settings' => :update_settings, as: nil
52
- patch 'parameters' => :update_parameter, as: :component_parameters
53
- get 'privileges' => :privileges, as: :component_privileges
54
- patch 'privileges' => :update_privileges, as: nil
55
- put 'administrators/:user_id' => :add_administrator, as: :component_administrators
56
- delete 'administrators/:user_id' => :remove_administrator, as: nil
57
- put 'users/:user_id/privileges/:privilege_slug' => :add_privilege, as: :component_privilege
58
- delete 'users/:user_id/privileges/:privilege_slug' => :remove_privilege, as: nil
59
- get 'images' => :images, as: :component_images
60
- post 'images' => :create_image, as: nil
61
- post 'ckeditor'
62
- end
79
+ # Track component
80
+ resources :agents, :ip_addresses, only: :index
81
+
82
+ # Content component
83
+ resources :dynamic_pages, :dynamic_blocks, concerns: %i[check search toggle]
84
+ resources :navigation_groups, concerns: :check do
85
+ member do
86
+ put 'dynamic_pages/:page_id' => :add_page, as: :dynamic_page
87
+ delete 'dynamic_pages/:page_id' => :remove_page
88
+ post 'dynamic_pages/:page_id/priority' => :page_priority, as: :page_priority
63
89
  end
90
+ end
64
91
 
65
- resources :agents, :ip_addresses, only: :index
92
+ # Users component
93
+ resources :users, concerns: %i[check search toggle] do
94
+ member do
95
+ get 'roles'
96
+ put 'roles/:role_id' => :add_role, as: :role
97
+ delete 'roles/:role_id' => :remove_role
98
+ post 'authenticate'
99
+ end
66
100
  end
101
+ resources :tokens, concerns: %i[toggle]
102
+ end
103
+
104
+ namespace :my do
105
+ get '/' => 'index#index'
67
106
 
68
- namespace :my do
69
- get '/' => 'index#index'
107
+ resource :profile, except: :destroy, concerns: :check
108
+ resource :confirmation, :recovery, only: %i[show create update]
70
109
 
71
- resource :profile, except: :destroy, concerns: :check
72
- resource :confirmation, :recovery, only: %i[show create update]
110
+ scope :components, controller: :components do
111
+ get '/' => :index, as: :components
112
+ scope ':slug' do
113
+ get '/' => :show, as: :component
114
+ get 'images' => :images, as: :component_images
115
+ post 'images' => :create_image, as: nil
116
+ post 'ckeditor'
117
+ end
73
118
  end
119
+ get 'dashboard' => 'components#index'
120
+ get 'dashboard/:slug' => 'components#show', as: :component_dashboard
74
121
  end
122
+
123
+ post 'oembed' => 'oembed#code'
124
+
125
+ get ':slug' => 'fallback#show', constraints: { slug: /.+/ }
75
126
  end
@@ -7,13 +7,14 @@ class CreateBiovisionComponents < ActiveRecord::Migration[6.0]
7
7
  create_metrics unless Metric.table_exists?
8
8
  create_metric_values unless MetricValue.table_exists?
9
9
  create_languages unless Language.table_exists?
10
+
11
+ Biovision::Components::BaseComponent.create
10
12
  end
11
13
 
12
14
  def down
13
- drop_table :languages if Language.table_exists?
14
- drop_table :metric_values if MetricValue.table_exists?
15
- drop_table :metrics if Metric.table_exists?
16
- drop_table :biovision_components if BiovisionComponent.table_exists?
15
+ [Language, MetricValue, Metric, BiovisionComponent].each do |model|
16
+ drop_table model.table_name if model.table_exists?
17
+ end
17
18
  end
18
19
 
19
20
  private
@@ -58,7 +59,7 @@ class CreateBiovisionComponents < ActiveRecord::Migration[6.0]
58
59
  end
59
60
 
60
61
  def create_languages
61
- create_table :languages, comment: 'Interface languages' do |t|
62
+ create_table :languages, comment: 'Interface and content languages' do |t|
62
63
  t.integer :priority, limit: 2, default: 1, null: false
63
64
  t.boolean :active, default: true, null: false
64
65
  t.integer :object_count, default: 0, null: false
@@ -1,26 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Create entry and tables for track component
4
- class CreateTrackComponent < ActiveRecord::Migration[6.0]
4
+ class CreateTrackComponent < ActiveRecord::Migration[6.1]
5
+ include Biovision::Migrations::ComponentMigration
6
+
5
7
  def up
6
- create_component
7
- create_browsers unless Browser.table_exists?
8
- create_agents unless Agent.table_exists?
9
- create_ip_addresses unless IpAddress.table_exists?
10
- end
8
+ component.create
9
+ component.dependent_models.each do |model|
10
+ next if model.table_exists?
11
11
 
12
- def down
13
- drop_table :ip_addresses if IpAddress.table_exists?
14
- drop_table :agents if Agent.table_exists?
15
- drop_table :browsers if Browser.table_exists?
12
+ message = "create_#{model.table_name}".to_sym
13
+ send(message) if respond_to?(message, true)
14
+ end
16
15
  end
17
16
 
18
17
  private
19
18
 
20
- def create_component
21
- BiovisionComponent.create(slug: Biovision::Components::TrackComponent.slug)
22
- end
23
-
24
19
  def create_browsers
25
20
  create_table :browsers, comment: 'Browsers' do |t|
26
21
  t.boolean :mobile, default: false, null: false
@@ -1,53 +1,21 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Create tables for Users component
4
- class CreateUsersComponent < ActiveRecord::Migration[6.0]
4
+ class CreateUsersComponent < ActiveRecord::Migration[6.1]
5
+ include Biovision::Migrations::ComponentMigration
6
+
5
7
  def up
6
- create_component
7
- create_users unless User.table_exists?
8
- create_tokens unless Token.table_exists?
9
- create_login_attempts unless LoginAttempt.table_exists?
10
- create_user_languages unless UserLanguage.table_exists?
11
- create_foreign_sites unless ForeignSite.table_exists?
12
- create_foreign_users unless ForeignUser.table_exists?
13
- create_component_links unless BiovisionComponentUser.table_exists?
14
- create_codes unless Code.table_exists?
15
- create_notifications unless Notification.table_exists?
16
- end
8
+ component.create
9
+ component.dependent_models.each do |model|
10
+ next if model.table_exists?
17
11
 
18
- def down
19
- drop_table :notifications if Notification.table_exists?
20
- drop_table :codes if Code.table_exists?
21
- drop_table :biovision_component_users if BiovisionComponentUser.table_exists?
22
- drop_table :foreign_users if ForeignUser.table_exists?
23
- drop_table :foreign_sites if ForeignSite.table_exists?
24
- drop_table :user_languages if UserLanguage.table_exists?
25
- drop_table :login_attempts if LoginAttempt.table_exists?
26
- drop_table :tokens if Token.table_exists?
27
- drop_table :users if User.table_exists?
28
- BiovisionComponent[Biovision::Components::UsersComponent.slug]&.destroy
12
+ message = "create_#{model.table_name}".to_sym
13
+ send(message) if respond_to?(message, true)
14
+ end
29
15
  end
30
16
 
31
17
  private
32
18
 
33
- def create_component
34
- slug = Biovision::Components::UsersComponent.slug
35
-
36
- settings = {
37
- registration_open: true,
38
- email_as_login: false,
39
- confirm_email: false,
40
- require_email: false,
41
- invite_only: false,
42
- use_invites: false,
43
- invite_count: 5,
44
- bounce_count: 10,
45
- bounce_timeout: 15
46
- }
47
-
48
- BiovisionComponent.create(slug: slug, settings: settings)
49
- end
50
-
51
19
  def create_users
52
20
  create_table :users, comment: 'Users' do |t|
53
21
  t.uuid :uuid, null: false
@@ -57,12 +25,10 @@ class CreateUsersComponent < ActiveRecord::Migration[6.0]
57
25
  t.timestamps
58
26
  t.integer :primary_id, index: true
59
27
  t.integer :inviter_id, index: true
60
- t.integer :balance, default: 0, null: false
61
28
  t.boolean :super_user, default: false, null: false
62
29
  t.boolean :banned, default: false, null: false
63
30
  t.boolean :bot, default: false, null: false
64
31
  t.boolean :deleted, default: false, null: false
65
- t.boolean :consent, default: false, null: false
66
32
  t.boolean :email_confirmed, default: false, null: false
67
33
  t.boolean :phone_confirmed, default: false, null: false
68
34
  t.boolean :allow_mail, default: true, null: false
@@ -76,7 +42,8 @@ class CreateUsersComponent < ActiveRecord::Migration[6.0]
76
42
  t.string :image
77
43
  t.string :notice
78
44
  t.string :referral_link
79
- t.jsonb :data, default: { profile: {} }, null: false
45
+ t.jsonb :data, default: {}, null: false
46
+ t.jsonb :profile, default: {}, null: false
80
47
  end
81
48
 
82
49
  add_foreign_key :users, :users, column: :inviter_id, on_update: :cascade, on_delete: :nullify
@@ -85,6 +52,7 @@ class CreateUsersComponent < ActiveRecord::Migration[6.0]
85
52
  add_index :users, :uuid, unique: true
86
53
  add_index :users, :slug, unique: true
87
54
  add_index :users, :data, using: :gin
55
+ add_index :users, :profile, using: :gin
88
56
  add_index :users, :referral_link, unique: true
89
57
  end
90
58
 
@@ -120,55 +88,18 @@ class CreateUsersComponent < ActiveRecord::Migration[6.0]
120
88
  end
121
89
  end
122
90
 
123
- def create_foreign_sites
124
- create_table :foreign_sites, comment: 'Sites for external authentication' do |t|
125
- t.string :slug, null: false
126
- t.string :name, null: false
127
- t.integer :foreign_users_count, default: 0, null: false
128
- end
129
-
130
- add_index :foreign_sites, :slug, unique: true
131
- end
132
-
133
- def create_foreign_users
134
- create_table :foreign_users, comment: 'Users from external sites' do |t|
135
- t.references :foreign_site, null: false, foreign_key: { on_update: :cascade, on_delete: :cascade }
136
- t.references :user, null: false, foreign_key: { on_update: :cascade, on_delete: :cascade }
137
- t.references :agent, foreign_key: { on_update: :cascade, on_delete: :nullify }
138
- t.references :ip_address, foreign_key: { on_update: :cascade, on_delete: :nullify }
139
- t.string :slug, null: false
140
- t.timestamps
141
- t.jsonb :data, default: {}, null: false
142
- end
143
-
144
- add_index :foreign_users, :data, using: :gin
145
- end
146
-
147
- def create_component_links
148
- create_table :biovision_component_users, comment: 'Privileges and settings for users in components' do |t|
149
- t.references :biovision_component, null: false, foreign_key: { on_update: :cascade, on_delete: :cascade }
150
- t.references :user, null: false, foreign_key: { on_update: :cascade, on_delete: :cascade }
151
- t.boolean :administrator, default: false, null: false
152
- t.timestamps
153
- t.jsonb :data, default: {}, null: false
154
- end
155
-
156
- add_index :biovision_component_users, :data, using: :gin
157
- end
158
-
159
91
  def create_codes
160
92
  create_table :codes, comment: 'Codes for different purposes' do |t|
161
93
  t.references :biovision_component, null: false, foreign_key: { on_update: :cascade, on_delete: :cascade }
162
- t.references :user, null: false, foreign_key: { on_update: :cascade, on_delete: :cascade }
94
+ t.references :user, foreign_key: { on_update: :cascade, on_delete: :cascade }
163
95
  t.references :agent, foreign_key: { on_update: :cascade, on_delete: :nullify }
164
96
  t.references :ip_address, foreign_key: { on_update: :cascade, on_delete: :nullify }
165
97
  t.integer :quantity, default: 1, null: false
166
- t.string :body, null: false
98
+ t.string :body, index: true, null: false
167
99
  t.timestamps
168
100
  t.jsonb :data, default: {}, null: false
169
101
  end
170
102
 
171
- add_index :codes, :body, unique: true
172
103
  add_index :codes, :data, using: :gin
173
104
  end
174
105
 
@@ -9,9 +9,9 @@ class CreateSimpleImages < ActiveRecord::Migration[6.0]
9
9
  end
10
10
 
11
11
  def down
12
- drop_table :simple_image_tag_images if SimpleImageTagImage.table_exists?
13
- drop_table :simple_image_tags if SimpleImageTag.table_exists?
14
- drop_table :simple_images if SimpleImage.table_exists?
12
+ [SimpleImageTagImage, SimpleImageTag, SimpleImage].each do |model|
13
+ drop_table model.table_name if model.table_exists?
14
+ end
15
15
  end
16
16
 
17
17
  private
@@ -30,6 +30,7 @@ class CreateSimpleImages < ActiveRecord::Migration[6.0]
30
30
  t.string :caption
31
31
  t.string :source_name
32
32
  t.string :source_link
33
+ t.string :checksum, index: true
33
34
  t.jsonb :data, default: {}, null: false
34
35
  end
35
36
 
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Create tables for access control
4
+ class CreateAcl < ActiveRecord::Migration[6.1]
5
+ def up
6
+ create_groups unless Group.table_exists?
7
+ create_roles unless Role.table_exists?
8
+ create_role_groups unless RoleGroup.table_exists?
9
+ create_user_groups unless UserGroup.table_exists?
10
+ create_user_roles unless UserRole.table_exists?
11
+
12
+ create_component_roles
13
+ end
14
+
15
+ def down
16
+ [UserRole, UserGroup, RoleGroup, Role, Group].each do |model|
17
+ drop_table model.table_name if model.table_exists?
18
+ end
19
+ end
20
+
21
+ private
22
+
23
+ def create_groups
24
+ create_table :groups, comment: 'ACL groups' do |t|
25
+ t.uuid :uuid, null: false
26
+ t.references :biovision_component, null: false, foreign_key: { on_update: :cascade, on_delete: :cascade }
27
+ t.integer :parent_id
28
+ t.integer :user_count, default: 0, null: false
29
+ t.string :slug, index: true, null: false
30
+ t.string :parents_cache, default: '', null: false
31
+ t.integer :children_cache, array: true, default: [], null: false
32
+ t.jsonb :data, default: {}, null: false
33
+ end
34
+
35
+ add_foreign_key :groups, :groups, column: :parent_id, on_update: :cascade, on_delete: :cascade
36
+ add_index :groups, :uuid, unique: true
37
+ add_index :groups, :data, using: :gin
38
+ end
39
+
40
+ def create_roles
41
+ create_table :roles, comment: 'ACL roles' do |t|
42
+ t.uuid :uuid, null: false
43
+ t.references :biovision_component, null: false, foreign_key: { on_update: :cascade, on_delete: :cascade }
44
+ t.integer :user_count, default: 0, null: false
45
+ t.string :slug, index: true, null: false
46
+ t.jsonb :data, default: {}, null: false
47
+ end
48
+
49
+ add_index :roles, :uuid, unique: true
50
+ add_index :roles, :data, using: :gin
51
+ end
52
+
53
+ def create_role_groups
54
+ create_table :role_groups, comment: 'ACL: roles in groups' do |t|
55
+ t.references :role, null: false, foreign_key: { on_update: :cascade, on_delete: :cascade }
56
+ t.references :group, null: false, foreign_key: { on_update: :cascade, on_delete: :cascade }
57
+ end
58
+ end
59
+
60
+ def create_user_groups
61
+ create_table :user_groups, comment: 'Users in ACL groups' do |t|
62
+ t.references :user, null: false, foreign_key: { on_update: :cascade, on_delete: :cascade }
63
+ t.references :group, null: false, foreign_key: { on_update: :cascade, on_delete: :cascade }
64
+ t.timestamps
65
+ end
66
+ end
67
+
68
+ def create_user_roles
69
+ create_table :user_roles, comment: 'Users with (and without) ACL roles' do |t|
70
+ t.references :user, null: false, foreign_key: { on_update: :cascade, on_delete: :cascade }
71
+ t.references :role, null: false, foreign_key: { on_update: :cascade, on_delete: :cascade }
72
+ t.timestamps
73
+ end
74
+ end
75
+
76
+ def create_component_roles
77
+ BiovisionComponent.pluck(:slug).each do |component|
78
+ next if component == Biovision::Components::BaseComponent.slug
79
+
80
+ Biovision::Components::BaseComponent.handler(component).create_roles
81
+ end
82
+
83
+ base_component = BiovisionComponent[Biovision::Components::BaseComponent]
84
+ %w[admin components.view].each do |role|
85
+ Role.create(biovision_component: base_component, slug: role)
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,80 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Create Content component and tables
4
+ class CreateContentComponent < ActiveRecord::Migration[6.1]
5
+ include Biovision::Migrations::ComponentMigration
6
+
7
+ private
8
+
9
+ def create_navigation_groups
10
+ create_table :navigation_groups, comment: 'Navigation groups' do |t|
11
+ t.timestamps
12
+ t.integer :dynamic_pages_count, default: 0, null: false
13
+ t.string :slug, null: false
14
+ t.string :name, null: false
15
+ end
16
+
17
+ add_index :navigation_groups, :slug, unique: true
18
+ end
19
+
20
+ def create_dynamic_pages
21
+ create_table :dynamic_pages, comment: 'Dynamic pages' do |t|
22
+ t.uuid :uuid, null: false
23
+ t.references :simple_image, foreign_key: { on_update: :cascade, on_delete: :nullify }
24
+ t.references :language, foreign_key: { on_update: :cascade, on_delete: :cascade }
25
+ t.timestamps
26
+ t.boolean :visible, default: true, null: false
27
+ t.string :slug, null: false
28
+ t.string :url, index: true
29
+ t.string :name
30
+ t.text :body, default: '', null: false
31
+ t.jsonb :data, default: {}, null: false
32
+ end
33
+
34
+ add_index :dynamic_pages, :uuid, unique: true
35
+ add_index :dynamic_pages, :data, using: :gin
36
+ end
37
+
38
+ def create_navigation_group_pages
39
+ create_table :navigation_group_pages, comment: 'Dynamic pages in navigation groups' do |t|
40
+ t.references :navigation_group, null: false, foreign_key: { on_update: :cascade, on_delete: :cascade }
41
+ t.references :dynamic_page, null: false, foreign_key: { on_update: :cascade, on_delete: :cascade }
42
+ t.integer :priority, limit: 2, default: 1, null: false
43
+ t.timestamps
44
+ end
45
+ end
46
+
47
+ def create_dynamic_blocks
48
+ create_table :dynamic_blocks, comment: 'Dynamic blocks' do |t|
49
+ t.string :slug, null: false
50
+ t.boolean :visible, default: true, null: false
51
+ t.timestamps
52
+ t.text :body
53
+ t.jsonb :data, default: {}, null: false
54
+ end
55
+
56
+ add_index :dynamic_blocks, :slug, unique: true
57
+ add_index :dynamic_blocks, :data, using: :gin
58
+ end
59
+
60
+ def create_oembed_receivers
61
+ create_table :oembed_receivers, comment: 'Receivers for OEmbed content' do |t|
62
+ t.string :slug, null: false, index: true
63
+ end
64
+ end
65
+
66
+ def create_oembed_domains
67
+ create_table :oembed_domains, comment: 'Supported domains for OEmbed' do |t|
68
+ t.references :oembed_receiver, foreign_key: { on_update: :cascade, on_delete: :nullify }
69
+ t.string :name, null: false, index: true
70
+ end
71
+ end
72
+
73
+ def create_oembed_links
74
+ create_table :oembed_links, comment: 'Embedded links' do |t|
75
+ t.string :url, null: false
76
+ t.text :code
77
+ t.timestamps
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,74 @@
1
+ # frozen_string_literal: true
2
+
3
+ # Create tables for contact component
4
+ class CreateContactComponent < ActiveRecord::Migration[6.1]
5
+ include Biovision::Migrations::ComponentMigration
6
+
7
+ private
8
+
9
+ def create_feedback_messages
10
+ create_table :feedback_messages, comment: 'Feedback messages from visitors' do |t|
11
+ t.uuid :uuid, null: false
12
+ t.references :language, foreign_key: { on_update: :cascade, on_delete: :nullify }
13
+ t.references :user, foreign_key: { on_update: :cascade, on_delete: :nullify }
14
+ t.references :ip_address, foreign_key: { on_update: :cascade, on_delete: :nullify }
15
+ t.references :agent, foreign_key: { on_update: :cascade, on_delete: :nullify }
16
+ t.timestamps
17
+ t.boolean :visible, default: false, null: false
18
+ t.boolean :processed, default: false, null: false
19
+ t.string :attachment
20
+ t.string :name
21
+ t.string :email
22
+ t.string :phone
23
+ t.text :comment
24
+ t.jsonb :data, default: {}, null: false
25
+ end
26
+
27
+ add_index :feedback_messages, :uuid, unique: true
28
+ add_index :feedback_messages, :data, using: :gin
29
+ end
30
+
31
+ def create_feedback_responses
32
+ create_table :feedback_responses, comment: 'Responses to feedback messages' do |t|
33
+ t.uuid :uuid, null: false
34
+ t.references :feedback_message, null: false, foreign_key: { on_update: :cascade, on_delete: :cascade }
35
+ t.references :user, foreign_key: { on_update: :cascade, on_delete: :nullify }
36
+ t.references :agent, foreign_key: { on_update: :cascade, on_delete: :nullify }
37
+ t.references :ip_address, foreign_key: { on_update: :cascade, on_delete: :nullify }
38
+ t.timestamps
39
+ t.boolean :visible, default: true, null: false
40
+ t.text :body
41
+ t.jsonb :data, default: {}, null: false
42
+ end
43
+
44
+ add_index :feedback_responses, :uuid, unique: true
45
+ add_index :feedback_responses, :data, using: :gin
46
+ end
47
+
48
+ def create_contact_types
49
+ create_table :contact_types, comment: 'Types of contact methods' do |t|
50
+ t.string :slug, null: false
51
+ end
52
+
53
+ add_index :contact_types, :slug, unique: true
54
+
55
+ %w[email phone address].each { |slug| ContactType.create(slug: slug) }
56
+ end
57
+
58
+ def create_contact_methods
59
+ create_table :contact_methods, comment: 'Contact methods for visitors' do |t|
60
+ t.uuid :uuid, null: false
61
+ t.references :language, foreign_key: { on_update: :cascade, on_delete: :nullify }
62
+ t.references :contact_type, null: false, foreign_key: { on_update: :cascade, on_delete: :cascade }
63
+ t.timestamps
64
+ t.boolean :visible, default: true, null: false
65
+ t.integer :priority, limit: 2, default: 1, null: false
66
+ t.string :name
67
+ t.string :value
68
+ t.jsonb :data, default: {}, null: false
69
+ end
70
+
71
+ add_index :contact_methods, :uuid, unique: true
72
+ add_index :contact_methods, :data, using: :gin
73
+ end
74
+ end