alchemy_cms 7.1.13 → 7.2.0.b

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 (316) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +132 -39
  3. data/Gemfile +2 -11
  4. data/LICENSE +1 -1
  5. data/README.md +5 -6
  6. data/SECURITY.md +1 -1
  7. data/alchemy_cms.gemspec +3 -4
  8. data/app/assets/javascripts/alchemy/admin.js +0 -9
  9. data/app/assets/javascripts/alchemy/alchemy.dialog.js.coffee +5 -15
  10. data/app/assets/javascripts/alchemy/alchemy.image_overlay.coffee +5 -4
  11. data/app/assets/javascripts/alchemy/templates/index.js +0 -1
  12. data/app/assets/javascripts/alchemy/templates/node_folder.hbs +1 -1
  13. data/app/assets/javascripts/alchemy/templates/page_folder.hbs +1 -1
  14. data/app/assets/javascripts/tinymce/plugins/alchemy_link/plugin.min.js +20 -7
  15. data/app/assets/stylesheets/alchemy/_custom-properties.scss +12 -0
  16. data/app/assets/stylesheets/alchemy/_mixins.scss +10 -6
  17. data/app/assets/stylesheets/alchemy/_variables.scss +3 -0
  18. data/app/assets/stylesheets/alchemy/admin.scss +2 -2
  19. data/app/assets/stylesheets/alchemy/archive.scss +4 -3
  20. data/app/assets/stylesheets/alchemy/attachment-select.scss +19 -0
  21. data/app/assets/stylesheets/alchemy/base.scss +31 -18
  22. data/app/assets/stylesheets/alchemy/buttons.scss +3 -4
  23. data/app/assets/stylesheets/alchemy/dashboard.scss +1 -1
  24. data/app/assets/stylesheets/alchemy/dialogs.scss +2 -5
  25. data/app/assets/stylesheets/alchemy/elements.scss +74 -42
  26. data/app/assets/stylesheets/alchemy/flash.scss +20 -70
  27. data/app/assets/stylesheets/alchemy/forms.scss +41 -36
  28. data/app/assets/stylesheets/alchemy/frame.scss +12 -3
  29. data/app/assets/stylesheets/alchemy/icons.scss +34 -2
  30. data/app/assets/stylesheets/alchemy/image_library.scss +18 -9
  31. data/app/assets/stylesheets/alchemy/{filter_field.scss → list_filter.scss} +8 -7
  32. data/app/assets/stylesheets/alchemy/lists.scss +1 -1
  33. data/app/assets/stylesheets/alchemy/navigation.scss +9 -12
  34. data/app/assets/stylesheets/alchemy/node-select.scss +1 -1
  35. data/app/assets/stylesheets/alchemy/nodes.scss +15 -13
  36. data/app/assets/stylesheets/alchemy/notices.scss +56 -39
  37. data/app/assets/stylesheets/alchemy/page-select.scss +1 -4
  38. data/app/assets/stylesheets/alchemy/pagination.scss +11 -1
  39. data/app/assets/stylesheets/alchemy/preview_window.scss +3 -3
  40. data/app/assets/stylesheets/alchemy/search.scss +4 -4
  41. data/app/assets/stylesheets/alchemy/selects.scss +13 -7
  42. data/app/assets/stylesheets/alchemy/shoelace.scss +33 -2
  43. data/app/assets/stylesheets/alchemy/sitemap.scss +155 -159
  44. data/app/assets/stylesheets/alchemy/tables.scss +49 -12
  45. data/app/assets/stylesheets/alchemy/tags.scss +17 -11
  46. data/app/assets/stylesheets/alchemy/toolbar.scss +2 -2
  47. data/app/assets/stylesheets/alchemy/typography.scss +41 -22
  48. data/app/assets/stylesheets/alchemy/upload.scss +5 -4
  49. data/app/components/alchemy/admin/attachment_select.rb +39 -0
  50. data/app/components/alchemy/admin/icon.rb +72 -0
  51. data/app/components/alchemy/admin/link_dialog/anchor_tab.rb +41 -0
  52. data/app/components/alchemy/admin/link_dialog/base_tab.rb +75 -0
  53. data/app/components/alchemy/admin/link_dialog/external_tab.rb +42 -0
  54. data/app/components/alchemy/admin/link_dialog/file_tab.rb +45 -0
  55. data/app/components/alchemy/admin/link_dialog/internal_tab.rb +66 -0
  56. data/app/components/alchemy/admin/link_dialog/tabs.rb +33 -0
  57. data/app/components/alchemy/admin/list_filter.rb +42 -0
  58. data/app/components/alchemy/admin/message.rb +19 -0
  59. data/app/components/alchemy/admin/tags_autocomplete.rb +25 -0
  60. data/app/components/alchemy/admin/toolbar_button.rb +111 -0
  61. data/app/components/alchemy/ingredients/datetime_view.rb +2 -3
  62. data/app/components/alchemy/ingredients/link_view.rb +1 -7
  63. data/app/components/alchemy/ingredients/picture_view.rb +2 -2
  64. data/app/components/alchemy/ingredients/text_view.rb +1 -2
  65. data/app/controllers/alchemy/admin/base_controller.rb +3 -27
  66. data/app/controllers/alchemy/admin/elements_controller.rb +4 -2
  67. data/app/controllers/alchemy/admin/ingredients_controller.rb +2 -0
  68. data/app/controllers/alchemy/admin/languages_controller.rb +2 -2
  69. data/app/controllers/alchemy/admin/layoutpages_controller.rb +0 -19
  70. data/app/controllers/alchemy/admin/legacy_page_urls_controller.rb +12 -4
  71. data/app/controllers/alchemy/admin/nodes_controller.rb +26 -0
  72. data/app/controllers/alchemy/admin/pages_controller.rb +16 -79
  73. data/app/controllers/alchemy/admin/picture_descriptions_controller.rb +15 -0
  74. data/app/controllers/alchemy/admin/pictures_controller.rb +18 -1
  75. data/app/controllers/alchemy/admin/resources_controller.rb +16 -11
  76. data/app/controllers/alchemy/api/attachments_controller.rb +44 -0
  77. data/app/controllers/alchemy/api/pages_controller.rb +10 -6
  78. data/app/controllers/alchemy/base_controller.rb +2 -2
  79. data/app/controllers/alchemy/messages_controller.rb +3 -3
  80. data/app/controllers/alchemy/pages_controller.rb +8 -6
  81. data/app/controllers/concerns/alchemy/admin/current_language.rb +1 -11
  82. data/app/controllers/concerns/alchemy/legacy_page_redirects.rb +1 -1
  83. data/app/decorators/alchemy/element_editor.rb +2 -2
  84. data/app/helpers/alchemy/admin/base_helper.rb +8 -60
  85. data/app/helpers/alchemy/admin/elements_helper.rb +1 -1
  86. data/app/helpers/alchemy/admin/ingredients_helper.rb +1 -1
  87. data/app/helpers/alchemy/base_helper.rb +9 -91
  88. data/app/helpers/alchemy/elements_helper.rb +3 -3
  89. data/app/helpers/alchemy/pages_helper.rb +16 -9
  90. data/app/javascript/alchemy_admin/components/attachment_select.js +24 -0
  91. data/app/javascript/alchemy_admin/components/button.js +3 -0
  92. data/app/javascript/alchemy_admin/components/clipboard_button.js +3 -2
  93. data/app/javascript/alchemy_admin/components/dialog_link.js +10 -7
  94. data/app/javascript/alchemy_admin/components/dom_id_select.js +69 -0
  95. data/app/javascript/alchemy_admin/components/element_editor/delete_element_button.js +42 -0
  96. data/app/javascript/alchemy_admin/components/element_editor/publish_element_button.js +4 -2
  97. data/app/javascript/alchemy_admin/components/element_editor.js +21 -13
  98. data/app/javascript/alchemy_admin/components/elements_window.js +87 -0
  99. data/app/javascript/alchemy_admin/components/growl.js +13 -0
  100. data/app/javascript/alchemy_admin/components/icon.js +51 -0
  101. data/app/javascript/alchemy_admin/components/index.js +24 -0
  102. data/app/javascript/alchemy_admin/components/ingredient_group.js +6 -0
  103. data/app/javascript/alchemy_admin/components/link_buttons/link_button.js +21 -11
  104. data/app/javascript/alchemy_admin/components/link_buttons/unlink_button.js +2 -1
  105. data/app/javascript/alchemy_admin/components/link_buttons.js +1 -0
  106. data/app/javascript/alchemy_admin/components/list_filter.js +68 -0
  107. data/app/javascript/alchemy_admin/components/message.js +69 -0
  108. data/app/javascript/alchemy_admin/components/node_select.js +1 -1
  109. data/app/javascript/alchemy_admin/components/overlay.js +6 -6
  110. data/app/javascript/alchemy_admin/components/page_select.js +3 -7
  111. data/app/javascript/alchemy_admin/components/preview_window.js +121 -0
  112. data/app/javascript/alchemy_admin/components/remote_select.js +4 -1
  113. data/app/javascript/alchemy_admin/components/select.js +37 -1
  114. data/app/javascript/alchemy_admin/components/tags_autocomplete.js +57 -0
  115. data/app/javascript/alchemy_admin/components/uploader/file_upload.js +4 -3
  116. data/app/javascript/alchemy_admin/components/uploader/progress.js +1 -1
  117. data/app/javascript/alchemy_admin/confirm_dialog.js +133 -0
  118. data/app/javascript/alchemy_admin/dirty.js +19 -14
  119. data/app/javascript/alchemy_admin/fixed_elements.js +24 -0
  120. data/app/javascript/alchemy_admin/growler.js +15 -0
  121. data/app/javascript/alchemy_admin/gui.js +2 -4
  122. data/app/javascript/alchemy_admin/hotkeys.js +60 -0
  123. data/app/javascript/alchemy_admin/image_loader.js +2 -2
  124. data/app/javascript/alchemy_admin/ingredient_anchor_link.js +2 -3
  125. data/app/javascript/alchemy_admin/initializer.js +1 -8
  126. data/app/javascript/alchemy_admin/link_dialog.js +131 -0
  127. data/app/javascript/alchemy_admin/locales/en.js +3 -0
  128. data/app/javascript/alchemy_admin/node_tree.js +4 -3
  129. data/app/javascript/alchemy_admin/page_sorter.js +23 -14
  130. data/app/javascript/alchemy_admin/picture_editors.js +6 -5
  131. data/app/javascript/alchemy_admin/shoelace_theme.js +60 -0
  132. data/app/javascript/alchemy_admin/sitemap.js +9 -3
  133. data/app/javascript/alchemy_admin/sortable_elements.js +4 -6
  134. data/app/javascript/alchemy_admin.js +18 -42
  135. data/app/models/alchemy/current.rb +26 -0
  136. data/app/models/alchemy/element.rb +1 -1
  137. data/app/models/alchemy/ingredients/audio.rb +0 -11
  138. data/app/models/alchemy/ingredients/datetime.rb +1 -1
  139. data/app/models/alchemy/ingredients/headline.rb +8 -1
  140. data/app/models/alchemy/ingredients/picture.rb +6 -0
  141. data/app/models/alchemy/ingredients/video.rb +0 -12
  142. data/app/models/alchemy/language.rb +8 -6
  143. data/app/models/alchemy/node.rb +2 -2
  144. data/app/models/alchemy/page/page_elements.rb +8 -8
  145. data/app/models/alchemy/page/page_layouts.rb +3 -3
  146. data/app/models/alchemy/page/page_natures.rb +13 -9
  147. data/app/models/alchemy/page/page_scopes.rb +2 -2
  148. data/app/models/alchemy/page/publisher.rb +1 -0
  149. data/app/models/alchemy/page.rb +16 -31
  150. data/app/models/alchemy/picture.rb +8 -0
  151. data/app/models/alchemy/picture_description.rb +8 -0
  152. data/app/models/alchemy/picture_variant.rb +1 -1
  153. data/app/models/alchemy/site.rb +10 -7
  154. data/app/models/concerns/alchemy/picture_thumbnails.rb +5 -4
  155. data/app/serializers/alchemy/attachment_serializer.rb +8 -0
  156. data/app/serializers/alchemy/page_node_serializer.rb +9 -0
  157. data/app/views/alchemy/_menubar.html.erb +1 -1
  158. data/app/views/alchemy/_preview_mode_code.html.erb +1 -1
  159. data/app/views/alchemy/admin/attachments/_tag_list.html.erb +2 -2
  160. data/app/views/alchemy/admin/attachments/archive_overlay.js.erb +0 -1
  161. data/app/views/alchemy/admin/attachments/edit.html.erb +3 -4
  162. data/app/views/alchemy/admin/clipboard/clear.js.erb +1 -1
  163. data/app/views/alchemy/admin/clipboard/index.html.erb +1 -1
  164. data/app/views/alchemy/admin/clipboard/insert.js.erb +1 -1
  165. data/app/views/alchemy/admin/clipboard/remove.js.erb +1 -1
  166. data/app/views/alchemy/admin/dashboard/_locked_pages.html.erb +1 -1
  167. data/app/views/alchemy/admin/dashboard/_sites.html.erb +1 -1
  168. data/app/views/alchemy/admin/dashboard/help.html.erb +48 -12
  169. data/app/views/alchemy/admin/dashboard/index.html.erb +1 -1
  170. data/app/views/alchemy/admin/dashboard/info.html.erb +5 -8
  171. data/app/views/alchemy/admin/elements/_add_nested_element_form.html.erb +1 -1
  172. data/app/views/alchemy/admin/elements/_element.html.erb +5 -5
  173. data/app/views/alchemy/admin/elements/_footer.html.erb +1 -1
  174. data/app/views/alchemy/admin/elements/_header.html.erb +6 -2
  175. data/app/views/alchemy/admin/elements/_toolbar.html.erb +8 -6
  176. data/app/views/alchemy/admin/elements/create.js.erb +0 -5
  177. data/app/views/alchemy/admin/elements/index.html.erb +70 -34
  178. data/app/views/alchemy/admin/ingredients/_file_fields.html.erb +1 -2
  179. data/app/views/alchemy/admin/ingredients/_picture_fields.html.erb +3 -5
  180. data/app/views/alchemy/admin/languages/_language.html.erb +1 -1
  181. data/app/views/alchemy/admin/languages/index.html.erb +2 -2
  182. data/app/views/alchemy/admin/layoutpages/_layoutpage.html.erb +18 -18
  183. data/app/views/alchemy/admin/layoutpages/edit.html.erb +4 -5
  184. data/app/views/alchemy/admin/layoutpages/index.html.erb +2 -2
  185. data/app/views/alchemy/admin/legacy_page_urls/_legacy_page_url.html.erb +10 -11
  186. data/app/views/alchemy/admin/legacy_page_urls/_new.html.erb +15 -17
  187. data/app/views/alchemy/admin/legacy_page_urls/_table.html.erb +16 -0
  188. data/app/views/alchemy/admin/legacy_page_urls/_update.turbo_stream.erb +12 -0
  189. data/app/views/alchemy/admin/legacy_page_urls/create.turbo_stream.erb +8 -0
  190. data/app/views/alchemy/admin/legacy_page_urls/destroy.turbo_stream.erb +1 -0
  191. data/app/views/alchemy/admin/legacy_page_urls/edit.html.erb +27 -0
  192. data/app/views/alchemy/admin/legacy_page_urls/show.html.erb +1 -0
  193. data/app/views/alchemy/admin/legacy_page_urls/update.turbo_stream.erb +1 -0
  194. data/app/views/alchemy/admin/nodes/_form.html.erb +12 -11
  195. data/app/views/alchemy/admin/nodes/_label.html.erb +1 -0
  196. data/app/views/alchemy/admin/nodes/_node.html.erb +19 -19
  197. data/app/views/alchemy/admin/nodes/_page_nodes.html.erb +48 -0
  198. data/app/views/alchemy/admin/nodes/_update.turbo_stream.erb +9 -0
  199. data/app/views/alchemy/admin/nodes/create.turbo_stream.erb +1 -0
  200. data/app/views/alchemy/admin/nodes/destroy.turbo_stream.erb +1 -0
  201. data/app/views/alchemy/admin/nodes/index.html.erb +3 -3
  202. data/app/views/alchemy/admin/pages/_form.html.erb +3 -4
  203. data/app/views/alchemy/admin/pages/_legacy_urls.html.erb +4 -15
  204. data/app/views/alchemy/admin/pages/_page.html.erb +39 -39
  205. data/app/views/alchemy/admin/pages/_table_row.html.erb +3 -3
  206. data/app/views/alchemy/admin/pages/_toolbar.html.erb +2 -2
  207. data/app/views/alchemy/admin/pages/configure.html.erb +6 -0
  208. data/app/views/alchemy/admin/pages/edit.html.erb +15 -62
  209. data/app/views/alchemy/admin/pages/unlock.js.erb +3 -3
  210. data/app/views/alchemy/admin/partials/_autocomplete_tag_list.html.erb +3 -1
  211. data/app/views/alchemy/admin/partials/_flash_notices.html.erb +4 -2
  212. data/app/views/alchemy/admin/partials/_language_tree_select.html.erb +1 -1
  213. data/app/views/alchemy/admin/partials/_main_navigation_entry.html.erb +5 -2
  214. data/app/views/alchemy/admin/partials/_remote_search_form.html.erb +2 -2
  215. data/app/views/alchemy/admin/partials/_search_form.html.erb +2 -2
  216. data/app/views/alchemy/admin/partials/_site_select.html.erb +1 -1
  217. data/app/views/alchemy/admin/picture_descriptions/_form.html.erb +11 -0
  218. data/app/views/alchemy/admin/picture_descriptions/edit.html.erb +6 -0
  219. data/app/views/alchemy/admin/pictures/_form.html.erb +4 -3
  220. data/app/views/alchemy/admin/pictures/_infos.html.erb +1 -1
  221. data/app/views/alchemy/admin/pictures/_picture_description_field.html.erb +29 -0
  222. data/app/views/alchemy/admin/pictures/_tag_list.html.erb +2 -2
  223. data/app/views/alchemy/admin/pictures/archive_overlay.js.erb +0 -2
  224. data/app/views/alchemy/admin/pictures/edit_multiple.html.erb +3 -3
  225. data/app/views/alchemy/admin/pictures/show.html.erb +3 -3
  226. data/app/views/alchemy/admin/resources/_form.html.erb +3 -4
  227. data/app/views/alchemy/admin/resources/_per_page_select.html.erb +1 -1
  228. data/app/views/alchemy/admin/resources/_tag_list.html.erb +2 -2
  229. data/app/views/alchemy/admin/resources/index.html.erb +2 -2
  230. data/app/views/alchemy/admin/sites/index.html.erb +1 -1
  231. data/app/views/alchemy/admin/styleguide/index.html.erb +29 -24
  232. data/app/views/alchemy/admin/tags/_tag.html.erb +1 -1
  233. data/app/views/alchemy/admin/tags/edit.html.erb +1 -1
  234. data/app/views/alchemy/admin/tags/index.html.erb +1 -1
  235. data/app/views/alchemy/base/500.html.erb +7 -18
  236. data/app/views/alchemy/base/error_notice.html.erb +3 -1
  237. data/app/views/alchemy/ingredients/_boolean_editor.html.erb +1 -1
  238. data/app/views/alchemy/ingredients/_datetime_editor.html.erb +2 -3
  239. data/app/views/alchemy/ingredients/_headline_editor.html.erb +13 -8
  240. data/app/views/alchemy/ingredients/_picture_editor.html.erb +1 -1
  241. data/app/views/alchemy/ingredients/shared/_picture_tools.html.erb +1 -1
  242. data/app/views/alchemy/language_links/_language.html.erb +1 -1
  243. data/app/views/kaminari/alchemy/_first_page.html.erb +2 -2
  244. data/app/views/kaminari/alchemy/_gap.html.erb +1 -1
  245. data/app/views/kaminari/alchemy/_last_page.html.erb +2 -2
  246. data/app/views/kaminari/alchemy/_next_page.html.erb +2 -2
  247. data/app/views/kaminari/alchemy/_prev_page.html.erb +2 -2
  248. data/app/views/layouts/alchemy/admin.html.erb +2 -1
  249. data/bundles/shoelace.js +3 -1
  250. data/config/locales/alchemy.en.yml +16 -3
  251. data/config/routes.rb +4 -2
  252. data/db/migrate/20240314105244_create_alchemy_picture_descriptions.rb +11 -0
  253. data/lib/alchemy/configuration_methods.rb +1 -1
  254. data/lib/alchemy/controller_actions.rb +3 -3
  255. data/lib/alchemy/element_definition.rb +10 -6
  256. data/lib/alchemy/engine.rb +19 -2
  257. data/lib/alchemy/page_layout.rb +10 -6
  258. data/lib/alchemy/permissions.rb +4 -3
  259. data/lib/alchemy/resource.rb +4 -14
  260. data/lib/alchemy/routing_constraints.rb +1 -1
  261. data/lib/alchemy/seeder.rb +2 -2
  262. data/lib/alchemy/test_support/capybara_helpers.rb +4 -0
  263. data/lib/alchemy/test_support/factories/language_factory.rb +1 -1
  264. data/lib/alchemy/test_support/shared_contexts.rb +8 -0
  265. data/lib/alchemy/tinymce.rb +2 -1
  266. data/lib/alchemy/version.rb +1 -1
  267. data/lib/alchemy.rb +36 -0
  268. data/lib/alchemy_cms.rb +0 -1
  269. data/lib/generators/alchemy/menus/templates/node.html.erb +2 -2
  270. data/lib/generators/alchemy/menus/templates/node.html.haml +2 -2
  271. data/lib/generators/alchemy/menus/templates/node.html.slim +2 -2
  272. data/lib/generators/alchemy/menus/templates/wrapper.html.erb +1 -1
  273. data/lib/generators/alchemy/menus/templates/wrapper.html.haml +1 -1
  274. data/lib/generators/alchemy/menus/templates/wrapper.html.slim +1 -1
  275. data/lib/tasks/alchemy/sitemap.rake +97 -0
  276. data/lib/tasks/alchemy/tidy.rake +1 -0
  277. data/package.json +8 -8
  278. data/vendor/assets/fonts/remixicon.symbol.svg +11 -0
  279. data/vendor/javascript/shoelace.min.js +333 -118
  280. data/vendor/javascript/sortable.min.js +1 -1
  281. data/vendor/javascript/tinymce.min.js +1 -1
  282. data/vendor/javascript/ungap-custom-elements.min.js +1 -1
  283. metadata +63 -55
  284. data/app/assets/javascripts/alchemy/alchemy.confirm_dialog.js.coffee +0 -85
  285. data/app/assets/javascripts/alchemy/alchemy.elements_window.js.coffee +0 -107
  286. data/app/assets/javascripts/alchemy/alchemy.file_progress.js.coffee +0 -66
  287. data/app/assets/javascripts/alchemy/alchemy.fixed_elements.js +0 -45
  288. data/app/assets/javascripts/alchemy/alchemy.growler.js.coffee +0 -24
  289. data/app/assets/javascripts/alchemy/alchemy.hotkeys.js.coffee +0 -49
  290. data/app/assets/javascripts/alchemy/alchemy.initializer.js.coffee +0 -0
  291. data/app/assets/javascripts/alchemy/alchemy.link_dialog.js.coffee +0 -230
  292. data/app/assets/javascripts/alchemy/alchemy.list_filter.js.coffee +0 -49
  293. data/app/assets/javascripts/alchemy/alchemy.preview_window.js.coffee +0 -82
  294. data/app/assets/javascripts/alchemy/alchemy.string_extension.js.coffee +0 -11
  295. data/app/assets/javascripts/alchemy/templates/page.hbs +0 -19
  296. data/app/javascript/alchemy_admin/tags_autocomplete.js +0 -46
  297. data/app/models/alchemy/tree_node.rb +0 -7
  298. data/app/views/alchemy/admin/elements/destroy.js.erb +0 -8
  299. data/app/views/alchemy/admin/legacy_page_urls/_form.html.erb +0 -5
  300. data/app/views/alchemy/admin/legacy_page_urls/create.js.erb +0 -9
  301. data/app/views/alchemy/admin/legacy_page_urls/destroy.js.erb +0 -6
  302. data/app/views/alchemy/admin/legacy_page_urls/update.js.erb +0 -2
  303. data/app/views/alchemy/admin/pages/_anchor_link.html.erb +0 -22
  304. data/app/views/alchemy/admin/pages/_external_link.html.erb +0 -31
  305. data/app/views/alchemy/admin/pages/_file_link.html.erb +0 -31
  306. data/app/views/alchemy/admin/pages/_internal_link.html.erb +0 -35
  307. data/app/views/alchemy/admin/pages/link.html.erb +0 -26
  308. data/app/views/alchemy/admin/partials/_flash.html.erb +0 -4
  309. data/app/views/alchemy/admin/partials/_toolbar_button.html.erb +0 -29
  310. data/lib/alchemy/test_support/current_language_shared_examples.rb +0 -33
  311. data/vendor/assets/fonts/remixicon.eot +0 -0
  312. data/vendor/assets/fonts/remixicon.svg +0 -7816
  313. data/vendor/assets/fonts/remixicon.ttf +0 -0
  314. data/vendor/assets/fonts/remixicon.woff +0 -0
  315. data/vendor/assets/fonts/remixicon.woff2 +0 -0
  316. data/vendor/assets/stylesheets/remixicon.scss +0 -10480
@@ -200,17 +200,19 @@ module Alchemy
200
200
  %w[name urlname title]
201
201
  end
202
202
 
203
- # Used to store the current page id previewed in the edit page template.
204
- #
203
+ # Used to store the current page previewed in the edit page template.
204
+ # @deprecated Use {Alchemy::Current#preview_page=} instead.
205
205
  def current_preview=(page)
206
- RequestStore.store[:alchemy_current_preview] = page&.id
206
+ Current.preview_page = page
207
207
  end
208
+ deprecate "current_preview=": :"Alchemy::Current.preview_page=", deprecator: Alchemy::Deprecation
208
209
 
209
- # Returns the current page id previewed in the edit page template.
210
- #
210
+ # Returns the current page previewed in the edit page template.
211
+ # @deprecated Use {Alchemy::Current#preview_page} instead.
211
212
  def current_preview
212
- RequestStore.store[:alchemy_current_preview]
213
+ Current.preview_page
213
214
  end
215
+ deprecate current_preview: :"Alchemy::Current.preview_page", deprecator: Alchemy::Deprecation
214
216
 
215
217
  # @return the language root page for given language id.
216
218
  # @param language_id [Fixnum]
@@ -271,8 +273,10 @@ module Alchemy
271
273
  options = [[Alchemy.t(:default, scope: "link_target_options"), ""]]
272
274
  link_target_options = Config.get(:link_target_options)
273
275
  link_target_options.each do |option|
276
+ # add an underscore to the options to provide the default syntax
277
+ # @link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/a#target
274
278
  options << [Alchemy.t(option, scope: "link_target_options",
275
- default: option.to_s.humanize), option]
279
+ default: option.to_s.humanize), "_#{option}"]
276
280
  end
277
281
  options
278
282
  end
@@ -375,7 +379,7 @@ module Alchemy
375
379
  #
376
380
  def unlock!
377
381
  if update_columns(locked_at: nil, locked_by: nil)
378
- Page.current_preview = nil
382
+ Current.preview_page = nil
379
383
  end
380
384
  end
381
385
 
@@ -444,25 +448,6 @@ module Alchemy
444
448
 
445
449
  delegate :public_until=, to: :public_version, allow_nil: true
446
450
 
447
- # Updates an Alchemy::Page based on a new ordering to be applied to it
448
- #
449
- # Note: Page's urls should not be updated (and a legacy URL created) if nesting is OFF
450
- # or if the URL is the same
451
- #
452
- # @param [TreeNode]
453
- # A tree node with new lft, rgt, depth, url, parent_id and restricted indexes to be updated
454
- #
455
- def update_node!(node)
456
- hash = {lft: node.left, rgt: node.right, parent_id: node.parent, depth: node.depth, restricted: node.restricted}
457
-
458
- if urlname != node.url
459
- LegacyPageUrl.create(page_id: id, urlname: urlname)
460
- hash[:urlname] = node.url
461
- end
462
-
463
- update_columns(hash)
464
- end
465
-
466
451
  # Holds an instance of +FixedAttributes+
467
452
  def fixed_attributes
468
453
  @_fixed_attributes ||= FixedAttributes.new(self)
@@ -506,7 +491,7 @@ module Alchemy
506
491
  # does not respond to +#name+ it returns +'unknown'+
507
492
  #
508
493
  def creator_name
509
- creator.try(:alchemy_display_name) || Alchemy.t("unknown")
494
+ creator.try(:name) || Alchemy.t("unknown")
510
495
  end
511
496
 
512
497
  # Returns the name of the last updater of this page.
@@ -515,7 +500,7 @@ module Alchemy
515
500
  # does not respond to +#name+ it returns +'unknown'+
516
501
  #
517
502
  def updater_name
518
- updater.try(:alchemy_display_name) || Alchemy.t("unknown")
503
+ updater.try(:name) || Alchemy.t("unknown")
519
504
  end
520
505
 
521
506
  # Returns the name of the user currently editing this page.
@@ -524,7 +509,7 @@ module Alchemy
524
509
  # does not respond to +#name+ it returns +'unknown'+
525
510
  #
526
511
  def locker_name
527
- locker.try(:alchemy_display_name) || Alchemy.t("unknown")
512
+ locker.try(:name) || Alchemy.t("unknown")
528
513
  end
529
514
 
530
515
  # Key hint translations by page layout, rather than the default name.
@@ -555,7 +540,7 @@ module Alchemy
555
540
  end
556
541
 
557
542
  def set_language
558
- self.language = parent&.language || Language.current
543
+ self.language = parent&.language || Current.language
559
544
  set_language_code
560
545
  end
561
546
 
@@ -55,6 +55,9 @@ module Alchemy
55
55
  has_many :elements, through: :picture_ingredients
56
56
  has_many :pages, through: :elements
57
57
  has_many :thumbs, class_name: "Alchemy::PictureThumb", dependent: :destroy
58
+ has_many :descriptions, class_name: "Alchemy::PictureDescription", dependent: :destroy
59
+
60
+ accepts_nested_attributes_for :descriptions, allow_destroy: true, reject_if: ->(attr) { attr[:text].blank? }
58
61
 
59
62
  # Raise error, if picture is in use (aka. assigned to an Picture ingredient)
60
63
  #
@@ -231,6 +234,11 @@ module Alchemy
231
234
  }
232
235
  end
233
236
 
237
+ # Returns the picture description for a given language.
238
+ def description_for(language)
239
+ descriptions.find_by(language: language)&.text
240
+ end
241
+
234
242
  # Returns an uri escaped name.
235
243
  #
236
244
  def urlname
@@ -0,0 +1,8 @@
1
+ module Alchemy
2
+ class PictureDescription < ActiveRecord::Base
3
+ belongs_to :picture, class_name: "Alchemy::Picture"
4
+ belongs_to :language, class_name: "Alchemy::Language"
5
+
6
+ validates_uniqueness_of :picture_id, scope: :language_id
7
+ end
8
+ end
@@ -43,7 +43,7 @@ module Alchemy
43
43
 
44
44
  @picture = picture
45
45
  @options = options
46
- @render_format = options[:format] || picture.default_render_format
46
+ @render_format = (options[:format] || picture.default_render_format).to_s
47
47
  end
48
48
 
49
49
  # Process a variant of picture
@@ -35,7 +35,7 @@ module Alchemy
35
35
 
36
36
  # Returns true if this site is the current site
37
37
  def current?
38
- self.class.current == self
38
+ Current.site == self
39
39
  end
40
40
 
41
41
  # Returns the path to site's view partial.
@@ -57,23 +57,26 @@ module Alchemy
57
57
  end
58
58
 
59
59
  class << self
60
+ # @deprecated Use {Alchemy::Current#site=} instead.
60
61
  def current=(site)
61
- RequestStore.store[:alchemy_current_site] = site
62
+ Current.site = site
62
63
  end
64
+ deprecate "current=": :"Alchemy::Current.site=", deprecator: Alchemy::Deprecation
63
65
 
66
+ # @deprecated Use {Alchemy::Current#site} instead.
64
67
  def current
65
- RequestStore.store[:alchemy_current_site] || default
68
+ Current.site
66
69
  end
70
+ deprecate current: :"Alchemy::Current.site", deprecator: Alchemy::Deprecation
67
71
 
68
- def default
69
- Site.first
70
- end
72
+ alias_method :default, :first
73
+ deprecate default: :first, deprecator: Alchemy::Deprecation
71
74
 
72
75
  def find_for_host(host)
73
76
  # These are split up into two separate queries in order to run the
74
77
  # fastest query first (selecting the domain by its primary host name).
75
78
  #
76
- find_by(host: host) || find_in_aliases(host) || default
79
+ find_by(host: host) || find_in_aliases(host) || first
77
80
  end
78
81
 
79
82
  def find_in_aliases(host)
@@ -102,10 +102,11 @@ module Alchemy
102
102
 
103
103
  # Show image cropping link for ingredient
104
104
  def allow_image_cropping?
105
- settings[:crop] && picture&.can_be_cropped_to?(
106
- settings[:size],
107
- settings[:upsample]
108
- ) && !!picture.image_file
105
+ settings[:crop] && picture &&
106
+ picture.can_be_cropped_to?(
107
+ settings[:size],
108
+ settings[:upsample]
109
+ ) && !!picture.image_file
109
110
  end
110
111
 
111
112
  private
@@ -7,8 +7,16 @@ module Alchemy
7
7
  :file_name,
8
8
  :file_mime_type,
9
9
  :file_size,
10
+ :icon_css_class,
10
11
  :tag_list,
11
12
  :created_at,
12
13
  :updated_at
14
+
15
+ attribute :url do
16
+ Alchemy::Engine.routes.url_helpers.download_attachment_path(
17
+ id: object.id,
18
+ name: object.file_name
19
+ )
20
+ end
13
21
  end
14
22
  end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Alchemy
4
+ class PageNodeSerializer < ActiveModel::Serializer
5
+ attributes :id,
6
+ :url_path,
7
+ :parent_id
8
+ end
9
+ end
@@ -1,4 +1,4 @@
1
- <% if !@preview_mode && @page && can?(:edit_content, @page) %>
1
+ <% if !Alchemy::Current.preview_page? && @page && can?(:edit_content, @page) %>
2
2
  <alchemy-menubar>
3
3
  <template>
4
4
  <%= stylesheet_link_tag("alchemy/menubar") %>
@@ -1,4 +1,4 @@
1
- <% if @preview_mode %>
1
+ <% if Alchemy::Current.preview_page? %>
2
2
  <script type="text/javascript">
3
3
  Alchemy = { locale: "<%= session[:alchemy_locale] %>" };
4
4
  </script>
@@ -1,12 +1,12 @@
1
1
  <% if Alchemy::Attachment.tag_counts.any? %>
2
2
  <h3><%= Alchemy.t("Filter by tag") %></h3>
3
- <%= js_filter_field '.tag-list li' %>
3
+ <%= render Alchemy::Admin::ListFilter.new(".tag-list li") %>
4
4
  <ul>
5
5
  <%= render_tag_list('Alchemy::Attachment') %>
6
6
  </ul>
7
7
  <% if search_filter_params[:tagged_with].present? %>
8
8
  <%= link_to(
9
- render_icon(:times, size: 'xs') + Alchemy.t('Remove tag filter'),
9
+ render_icon(:times, size: '1x') + Alchemy.t('Remove tag filter'),
10
10
  url_for(search_filter_params.except(:tagged_with)),
11
11
  remote: request.xhr?,
12
12
  class: 'secondary button small with_icon'
@@ -1,5 +1,4 @@
1
1
  (function() {
2
2
  var dialog = Alchemy.currentDialog();
3
3
  dialog.dialog_body.html('<%= j render("archive_overlay") %>');
4
- Alchemy.ListFilter(dialog.dialog_body);
5
4
  })();
@@ -2,9 +2,8 @@
2
2
  url: {action: :update, q: search_filter_params[:q], page: params[:page]}) do |f| -%>
3
3
  <%= f.input :name, input_html: {autofocus: true} %>
4
4
  <%= f.input :file_name, input_html: {autofocus: true}, hint: Alchemy.t(:attachment_filename_notice) %>
5
- <div class="input string autocomplete_tag_list">
6
- <%= f.label :tag_list %>
7
- <%= render 'alchemy/admin/partials/autocomplete_tag_list', f: f %>
8
- </div>
5
+ <%= render Alchemy::Admin::TagsAutocomplete.new do %>
6
+ <%= f.input :tag_list, input_html: { value: f.object.tag_list.join(",") } %>
7
+ <% end %>
9
8
  <%= f.submit Alchemy.t(:save) %>
10
9
  <% end %>
@@ -1,3 +1,3 @@
1
1
  $("#clipboard_items").replaceWith("<%= j render_message { Alchemy.t('No items in your clipboard') } -%>");
2
- $('#clipboard_button .icon').removeClass('ri-clipboard-fill').addClass('ri-clipboard-line');
2
+ $('#clipboard_button alchemy-icon').attr('icon-style', 'line');
3
3
  Alchemy.pleaseWaitOverlay(false);
@@ -12,7 +12,7 @@
12
12
  <%= render_icon(:file) %>
13
13
  <%= truncate(item.name, length: 50) %>
14
14
  <% else %>
15
- <%= render_icon(:draggable, style: nil) %>
15
+ <%= render_icon(:draggable, style: false) %>
16
16
  <%= truncate(item.display_name_with_preview_text(50), length: 50) %>
17
17
  <% end %>
18
18
  <span class="float_right">
@@ -13,7 +13,7 @@
13
13
  <% else -%>
14
14
  Alchemy.growl('<%= j Alchemy.t("item copied to clipboard", name: @item.class.name == "Alchemy::Element" ? @item.display_name_with_preview_text : @item.name) %>')
15
15
  <% end -%>
16
- $('#clipboard_button .icon').removeClass('ri-clipboard-line').addClass('ri-clipboard-fill');
16
+ $('#clipboard_button alchemy-icon').attr('icon-style', 'fill');
17
17
 
18
18
  <%# Update add nested element forms for any elements that accept ONLY this as a nested element %>
19
19
  <% if @item.class == Alchemy::Element %>
@@ -3,7 +3,7 @@
3
3
  $("#clipboard_item_<%= @item.id -%>").remove();
4
4
  Alchemy.growl('<%= Alchemy.t("item removed from clipboard", :name => @item.class.to_s == "Element" ? @item.display_name_with_preview_text : @item.name) -%>');
5
5
  <%- if @clipboard.blank? -%>
6
- $('#clipboard_button .icon').removeClass('fa-paste').addClass('fa-clipboard');
6
+ $('#clipboard_button alchemy-icon').attr('icon-style', 'line');
7
7
  $("#clipboard_items").replaceWith("<%= j render_message { Alchemy.t('No items in your clipboard') } %>");
8
8
  <%- end -%>
9
9
 
@@ -36,7 +36,7 @@
36
36
  <% end %>
37
37
  </td>
38
38
  <td>
39
- <% if (current_alchemy_user.id == page.locked_by) || can?(:manage, Alchemy::Site.current) %>
39
+ <% if (current_alchemy_user.id == page.locked_by) || can?(:manage, Alchemy::Current.site) %>
40
40
  <%= form_tag(alchemy.unlock_admin_page_path(page, :redirect_to => alchemy.admin_dashboard_url)) do %>
41
41
  <button class="icon_button small" title="<%= Alchemy.t(:explain_unlocking) %>">
42
42
  <%= render_icon(:close, size: '1x') %>
@@ -7,7 +7,7 @@
7
7
  <tr class="<%= cycle('even', 'odd', name: 'sites') %>">
8
8
  <td>
9
9
  <% if alchemy.respond_to?(:login_url) %>
10
- <%= link_to_unless site == Alchemy::Site.current,
10
+ <%= link_to_unless site == Alchemy::Current.site,
11
11
  site.name,
12
12
  alchemy.login_url(
13
13
  protocol: 'http://',
@@ -1,21 +1,57 @@
1
1
  <h2><%= Alchemy.t('Global shortcuts') %></h2>
2
2
  <ul class="shortcuts">
3
- <li><kbd>?</kbd><%= Alchemy.t('Open help window', scope: 'help.shortcuts') %></li>
4
- <li><kbd>esc</kbd><%= Alchemy.t('Close current dialog', scope: 'help.shortcuts') %></li>
5
- <li><kbd>alt</kbd><kbd>q</kbd><%= Alchemy.t('Open logout dialog', scope: 'help.shortcuts') %></li>
6
- <li><kbd>alt</kbd><kbd>f</kbd><%= Alchemy.t('Focus search field', scope: 'help.shortcuts') %></li>
7
- <li><kbd>alt</kbd><kbd>n</kbd><%= Alchemy.t('Create a new record', scope: 'help.shortcuts') %></li>
3
+ <li>
4
+ <kbd>?</kbd>
5
+ <%= Alchemy.t('Open help window', scope: 'help.shortcuts') %>
6
+ </li>
7
+ <li>
8
+ <kbd>esc</kbd>
9
+ <%= Alchemy.t('Close current dialog', scope: 'help.shortcuts') %>
10
+ </li>
11
+ <li>
12
+ <kbd>alt</kbd><kbd>q</kbd>
13
+ <%= Alchemy.t('Open logout dialog', scope: 'help.shortcuts') %>
14
+ </li>
15
+ <li>
16
+ <kbd>alt</kbd><kbd>f</kbd>
17
+ <%= Alchemy.t('Focus search field', scope: 'help.shortcuts') %>
18
+ </li>
19
+ <li>
20
+ <kbd>alt</kbd><kbd>n</kbd>
21
+ <%= Alchemy.t('Create a new record', scope: 'help.shortcuts') %>
22
+ </li>
8
23
  </ul>
9
24
  <h2><%= Alchemy.t('Page edit shortcuts') %></h2>
10
25
  <ul class="shortcuts">
11
- <li><kbd>alt</kbd><kbd>i</kbd><%= Alchemy.t('Show page infos', scope: 'help.shortcuts') %></li>
12
- <li><kbd>alt</kbd><kbd>n</kbd><%= Alchemy.t('Create new element', scope: 'help.shortcuts') %></li>
13
- <li><kbd>alt</kbd><kbd>e</kbd><%= Alchemy.t('Edit page properties', scope: 'help.shortcuts') %></li>
14
- <li><kbd>alt</kbd><kbd>r</kbd><%= Alchemy.t('Reload the preview', scope: 'help.shortcuts') %></li>
15
- <li><kbd>alt</kbd><kbd>x</kbd><%= Alchemy.t('Leave the page', scope: 'help.shortcuts') %></li>
26
+ <li>
27
+ <kbd>alt</kbd><kbd>i</kbd>
28
+ <%= Alchemy.t('Show page infos', scope: 'help.shortcuts') %>
29
+ </li>
30
+ <li>
31
+ <kbd>alt</kbd><kbd>n</kbd>
32
+ <%= Alchemy.t('Create new element', scope: 'help.shortcuts') %>
33
+ </li>
34
+ <li>
35
+ <kbd>alt</kbd><kbd>e</kbd>
36
+ <%= Alchemy.t('Edit page properties', scope: 'help.shortcuts') %>
37
+ </li>
38
+ <li>
39
+ <kbd>alt</kbd><kbd>r</kbd>
40
+ <%= Alchemy.t('Reload the preview', scope: 'help.shortcuts') %>
41
+ </li>
42
+ <li>
43
+ <kbd>alt</kbd><kbd>x</kbd>
44
+ <%= Alchemy.t('Leave the page', scope: 'help.shortcuts') %>
45
+ </li>
16
46
  </ul>
17
47
  <h2><%= Alchemy.t('Library shortcuts') %></h2>
18
48
  <ul class="shortcuts">
19
- <li><kbd>alt</kbd><kbd>n</kbd><%= Alchemy.t('Open upload form', scope: 'help.shortcuts') %></li>
20
- <li><kbd>alt</kbd><kbd>a</kbd><%= Alchemy.t('Select all pictures', scope: 'help.shortcuts') %></li>
49
+ <li>
50
+ <kbd>alt</kbd><kbd>n</kbd>
51
+ <%= Alchemy.t('Open upload form', scope: 'help.shortcuts') %>
52
+ </li>
53
+ <li>
54
+ <kbd>alt</kbd><kbd>a</kbd>
55
+ <%= Alchemy.t('Select all pictures', scope: 'help.shortcuts') %>
56
+ </li>
21
57
  </ul>
@@ -1,6 +1,6 @@
1
1
  <%= content_for :toolbar do %>
2
2
  <div class="toolbar_buttons">
3
- <%= toolbar_button(
3
+ <%= render Alchemy::Admin::ToolbarButton.new(
4
4
  icon: 'information',
5
5
  label: Alchemy.t(:info),
6
6
  url: alchemy.dashboard_info_path,
@@ -43,22 +43,19 @@
43
43
  <p><%= Alchemy.t('Alchemy is open software and itself uses open software and free resources:') %></p>
44
44
  <ul>
45
45
  <li>
46
- <a href="http://rubyonrails.org" target="_blank">RubyOnRails</a>
46
+ <a href="https://rubyonrails.org" target="_blank">Ruby on Rails</a>
47
47
  </li>
48
48
  <li>
49
- <a href="http://jquery.com" target="_blank">jQuery Javascript Library</a>
49
+ <a href="https://jquery.com" target="_blank">jQuery Javascript Library</a>
50
50
  </li>
51
51
  <li>
52
- <a href="http://jqueryui.com" target="_blank">jQuery UI Javascript GUI Library</a>
52
+ <a href="https://shoelace.style" target="_blank">Shoelace Web Components Library</a>
53
53
  </li>
54
54
  <li>
55
- <a href="http://tinymce.moxiecode.com" target="_blank">TinyMCE - Javascript WYSIWYG Editor</a>
55
+ <a href="https://www.tiny.cloud" target="_blank">TinyMCE - Javascript WYSIWYG Editor</a>
56
56
  </li>
57
57
  <li>
58
- <a href="http://blueimp.github.io/jQuery-File-Upload/" target="_blank">jQuery File Upload</a>
59
- </li>
60
- <li>
61
- <a href="https://remixicon.com" target="_blank">Remix Icon</a>
58
+ <a href="https://remixicon.com" target="_blank">Remix Icons</a>
62
59
  </li>
63
60
  </ul>
64
61
  <% end %>
@@ -8,7 +8,7 @@
8
8
  <%= f.hidden_field :name %>
9
9
  <%= f.hidden_field :page_version_id, value: element.page_version_id %>
10
10
  <%= f.hidden_field :parent_element_id, value: element.id %>
11
- <button class="add-nestable-element-button" is="alchemy-button">
11
+ <button class="add-nestable-element-button" is="alchemy-button" data-turbo="false">
12
12
  <%= Alchemy.t(:add_nested_element, name: Alchemy.t(nestable_element.to_sym, scope: 'element_names')) %>
13
13
  </button>
14
14
  <% end %>
@@ -2,7 +2,7 @@
2
2
  id="element_<%= element.id %>"
3
3
  data-element-id="<%= element.id %>"
4
4
  data-element-name="<%= element.name %>"
5
- class="<%= element.css_classes %>"
5
+ class="<%= element.css_classes.join(" ") %>"
6
6
  <%= element.compact? ? "compact" : nil %>
7
7
  <%= element.fixed? ? "fixed" : nil %>
8
8
  >
@@ -44,7 +44,7 @@
44
44
  <%= content_tag :details, class: "ingredient-group", id: "element_#{element.id}_ingredient_group_#{group.parameterize.underscore}", is: "alchemy-ingredient-group" do %>
45
45
  <summary>
46
46
  <%= element.translated_group group %>
47
- <i class="ingredient-group-expand icon ri-fw ri-arrow-left-s-line"></i>
47
+ <%= render_icon "arrow-left-s" %>
48
48
  </summary>
49
49
  <%= render ingredients, element_form: f %>
50
50
  <% end %>
@@ -53,10 +53,10 @@
53
53
  <% end %>
54
54
 
55
55
  <% if element.taggable? %>
56
- <div class="autocomplete_tag_list">
56
+ <%= render Alchemy::Admin::TagsAutocomplete.new do %>
57
57
  <%= f.label :tag_list %>
58
- <%= render 'alchemy/admin/partials/autocomplete_tag_list', f: f %>
59
- </div>
58
+ <%= f.text_field :tag_list, value: f.object.tag_list.join(",") %>
59
+ <% end %>
60
60
  <% end %>
61
61
  <% end %>
62
62
 
@@ -5,7 +5,7 @@
5
5
  </p>
6
6
  <% end %>
7
7
 
8
- <button type="submit" form="element_<%= element.id %>_form" is="alchemy-button">
8
+ <button type="submit" form="element_<%= element.id %>_form" is="alchemy-button" data-turbo="false">
9
9
  <%= Alchemy.t(:save) %>
10
10
  </button>
11
11
  </div>
@@ -5,7 +5,7 @@
5
5
  <% elsif element.deprecated? %>
6
6
  <%= hint_with_tooltip element.deprecation_notice %>
7
7
  <% else %>
8
- <%= render_icon('draggable', style: nil, class: 'element', fixed_width: false) %>
8
+ <%= render_icon('draggable', style: false, class: 'element', fixed_width: false) %>
9
9
  <% end %>
10
10
  </span>
11
11
  <span class="element-title">
@@ -24,6 +24,10 @@
24
24
  title: Alchemy.t(element.folded? ? :show_element_content : :hide_element_content),
25
25
  class: "element-toggle"
26
26
  }) do %>
27
- <%= render_icon element.folded? ? 'arrow-left-s' : 'arrow-down-s' %>
27
+ <% if element.compact? %>
28
+ <%= render_icon "more-2" %>
29
+ <% else %>
30
+ <%= render_icon element.folded? ? "arrow-left-s" : "arrow-down-s" %>
31
+ <% end %>
28
32
  <% end %>
29
33
  </div>
@@ -19,12 +19,14 @@
19
19
  ) %>
20
20
  </sl-tooltip>
21
21
  <sl-tooltip content="<%= Alchemy.t("Delete element") %>">
22
- <%= link_to_confirm_dialog(
23
- render_icon('delete-bin-2'),
24
- Alchemy.t(:confirm_to_delete_element),
25
- alchemy.admin_element_path(element),
26
- class: "icon_button"
27
- ) -%>
22
+ <alchemy-delete-element-button
23
+ href="<%= alchemy.admin_element_path(element) %>"
24
+ message="<%= Alchemy.t(:confirm_to_delete_element) %>"
25
+ >
26
+ <button type="button" class="icon_button" data-turbo="false">
27
+ <%= render_icon('delete-bin-2') %>
28
+ </button>
29
+ </alchemy-delete-element-button>
28
30
  </sl-tooltip>
29
31
  <sl-tooltip content="<%= element.public? ? Alchemy.t(:hide_element) : Alchemy.t(:show_element) %>" placement="top-end">
30
32
  <alchemy-publish-element-button>
@@ -7,9 +7,6 @@
7
7
  <%- end -%>
8
8
 
9
9
  <% if @element.fixed? %>
10
- if ($('#fixed-elements').length == 0) {
11
- Alchemy.FixedElements.buildTabs('<%= Alchemy.t(:main_content) %>');
12
- }
13
10
  Alchemy.FixedElements.createTab('<%= @element.id %>', '<%= @element.display_name %>');
14
11
  $element_area = $('[name="fixed-element-<%= @element.id %>"]');
15
12
  <% elsif @element.parent_element %>
@@ -24,8 +21,6 @@
24
21
  $element_area.append(element_html);
25
22
  <%- end -%>
26
23
 
27
- Alchemy.SortableElements('[data-element-id="<%= @element.id %>"] .nested-elements');
28
-
29
24
  Alchemy.growl('<%= Alchemy.t(:successfully_added_element) %>');
30
25
  Alchemy.closeCurrentDialog();
31
26
  Alchemy.reloadPreview();