alchemy_cms 6.0.0.pre.rc3 → 6.0.0.pre.rc6

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.

Potentially problematic release.


This version of alchemy_cms might be problematic. Click here for more details.

Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +0 -7
  3. data/CHANGELOG.md +26 -0
  4. data/alchemy_cms.gemspec +1 -1
  5. data/app/assets/javascripts/alchemy/admin.js +0 -2
  6. data/app/assets/javascripts/alchemy/alchemy.dialog.js.coffee +6 -1
  7. data/app/assets/javascripts/alchemy/alchemy.gui.js.coffee +2 -2
  8. data/app/assets/stylesheets/alchemy/_extends.scss +4 -4
  9. data/app/assets/stylesheets/alchemy/flatpickr.scss +182 -232
  10. data/app/assets/stylesheets/alchemy/sitemap.scss +7 -1
  11. data/app/controllers/alchemy/admin/base_controller.rb +9 -3
  12. data/app/controllers/alchemy/admin/pages_controller.rb +1 -3
  13. data/app/models/alchemy/page.rb +9 -3
  14. data/app/services/alchemy/tag_validations.rb +21 -0
  15. data/app/views/alchemy/admin/pages/_sitemap.html.erb +8 -8
  16. data/app/views/alchemy/admin/pages/edit.html.erb +1 -1
  17. data/app/views/alchemy/admin/pages/fold.js.erb +1 -1
  18. data/app/views/alchemy/admin/pages/update.js.erb +0 -5
  19. data/config/locales/alchemy.en.yml +0 -1
  20. data/config/routes.rb +0 -1
  21. data/db/migrate/20200226213334_alchemy_four_point_four.rb +30 -30
  22. data/db/migrate/20200423073425_create_alchemy_essence_nodes.rb +1 -1
  23. data/db/migrate/20200504210159_remove_site_id_from_nodes.rb +1 -1
  24. data/db/migrate/20200505215518_add_language_id_foreign_key_to_alchemy_pages.rb +1 -1
  25. data/db/migrate/20200511113603_add_menu_type_to_alchemy_nodes.rb +1 -1
  26. data/db/migrate/20200514091507_make_page_layoutpage_null_false.rb +1 -1
  27. data/db/migrate/20200519073500_remove_visible_from_alchemy_pages.rb +1 -1
  28. data/db/migrate/20200617110713_create_alchemy_picture_thumbs.rb +1 -1
  29. data/db/migrate/20200907111332_remove_tri_state_booleans.rb +1 -1
  30. data/db/migrate/20201207131309_create_page_versions.rb +1 -1
  31. data/db/migrate/20201207135820_add_page_version_id_to_alchemy_elements.rb +1 -1
  32. data/lib/alchemy/engine.rb +5 -4
  33. data/lib/alchemy/error_tracking.rb +14 -0
  34. data/lib/alchemy/version.rb +1 -1
  35. data/lib/alchemy_cms.rb +1 -0
  36. data/package/admin.js +7 -1
  37. data/package/src/datepicker.js +39 -0
  38. data/package/src/page_publication_fields.js +27 -0
  39. data/package/src/sitemap.js +133 -0
  40. data/package.json +2 -1
  41. metadata +11 -8
  42. data/app/assets/javascripts/alchemy/alchemy.datepicker.js.coffee +0 -29
  43. data/app/assets/javascripts/alchemy/alchemy.sitemap.js.coffee +0 -119
@@ -23,7 +23,7 @@ $sitemap-url-xlarge-width: 350px;
23
23
 
24
24
  #sitemap-wrapper {
25
25
  position: relative;
26
- min-height: calc(100vh - 96px);
26
+ min-height: calc(100vh - 148px);
27
27
  }
28
28
 
29
29
  .sitemap_pagename_link {
@@ -154,6 +154,8 @@ $sitemap-url-xlarge-width: 350px;
154
154
  position: absolute;
155
155
  left: -23px;
156
156
  top: 0;
157
+ width: 16px;
158
+ height: $sitemap-line-height;
157
159
  }
158
160
 
159
161
  .placeholder {
@@ -258,3 +260,7 @@ $sitemap-url-xlarge-width: 350px;
258
260
  }
259
261
  }
260
262
  }
263
+
264
+ #search_field_clear {
265
+ cursor: pointer;
266
+ }
@@ -40,9 +40,7 @@ module Alchemy
40
40
  def exception_handler(error)
41
41
  exception_logger(error)
42
42
  show_error_notice(error)
43
- if defined?(Airbrake)
44
- notify_airbrake(error) unless Rails.env.development? || Rails.env.test?
45
- end
43
+ notify_error_tracker(error)
46
44
  end
47
45
 
48
46
  # Displays an error notice in the Alchemy backend.
@@ -146,6 +144,14 @@ module Alchemy
146
144
  site
147
145
  end
148
146
  end
147
+
148
+ def notify_error_tracker(exception)
149
+ if ::Alchemy::ErrorTracking.notification_handler.respond_to?(:call)
150
+ ::Alchemy::ErrorTracking.notification_handler.call(exception)
151
+ else
152
+ Rails.logger.warn("To use the Alchemy::ErrorTracking.notification_handler, it must respond to #call.")
153
+ end
154
+ end
149
155
  end
150
156
  end
151
157
  end
@@ -123,8 +123,6 @@ module Alchemy
123
123
  # * fetches page via before filter
124
124
  #
125
125
  def update
126
- # stores old page_layout value, because unfurtunally rails @page.changes does not work here.
127
- @old_page_layout = @page.page_layout
128
126
  if @page.update(page_params)
129
127
  @notice = Alchemy.t("Page saved", name: @page.name)
130
128
  @while_page_edit = request.referer.include?("edit")
@@ -133,7 +131,7 @@ module Alchemy
133
131
  @tree = serialized_page_tree
134
132
  end
135
133
  else
136
- configure
134
+ render :configure
137
135
  end
138
136
  end
139
137
 
@@ -144,7 +144,7 @@ module Alchemy
144
144
  after_update :create_legacy_url,
145
145
  if: :saved_change_to_urlname?
146
146
 
147
- after_update -> { nodes.update_all(updated_at: Time.current) }
147
+ after_update :touch_nodes
148
148
 
149
149
  # Concerns
150
150
  include PageScopes
@@ -245,8 +245,8 @@ module Alchemy
245
245
 
246
246
  def copy_and_paste(source, new_parent, new_name)
247
247
  page = copy(source, {
248
- parent_id: new_parent.id,
249
- language: new_parent.language,
248
+ parent: new_parent,
249
+ language: new_parent&.language,
250
250
  name: new_name,
251
251
  title: new_name,
252
252
  })
@@ -448,6 +448,7 @@ module Alchemy
448
448
  next if child == new_parent
449
449
 
450
450
  new_child = Page.copy(child, {
451
+ parent_id: new_parent.id,
451
452
  language_id: new_parent.language_id,
452
453
  language_code: new_parent.language_code,
453
454
  })
@@ -603,5 +604,10 @@ module Alchemy
603
604
  def create_legacy_url
604
605
  legacy_urls.find_or_create_by(urlname: urlname_before_last_save)
605
606
  end
607
+
608
+ def touch_nodes
609
+ ids = node_ids + nodes.flat_map { |n| n.ancestors.pluck(:id) }
610
+ Node.where(id: ids).touch_all
611
+ end
606
612
  end
607
613
  end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Alchemy
4
+ class TagValidations
5
+ def self.call(klass)
6
+ new(klass).call
7
+ end
8
+
9
+ def initialize(klass)
10
+ @klass = klass
11
+ end
12
+
13
+ def call
14
+ klass.validates :name, presence: true, uniqueness: { case_sensitive: true }
15
+ end
16
+
17
+ private
18
+
19
+ attr_reader :klass
20
+ end
21
+ end
@@ -1,11 +1,10 @@
1
- <div id="sitemap-wrapper">
2
- <h4 id="sitemap_heading">
3
- <span class="page_name"><%= Alchemy::Page.human_attribute_name(:name) %></span>
4
- <span class="page_urlname"><%= Alchemy::Page.human_attribute_name(:urlname) %></span>
5
- <span class="page_status"><%= Alchemy.t(:page_status) %></span>
6
- </h4>
1
+ <h4 id="sitemap_heading">
2
+ <span class="page_name"><%= Alchemy::Page.human_attribute_name(:name) %></span>
3
+ <span class="page_urlname"><%= Alchemy::Page.human_attribute_name(:urlname) %></span>
4
+ <span class="page_status"><%= Alchemy.t(:page_status) %></span>
5
+ </h4>
7
6
 
8
- <p class="loading"></p>
7
+ <div id="sitemap-wrapper">
9
8
  </div>
10
9
 
11
10
  <script id="sitemap-template" type="text/x-handlebars-template">
@@ -22,7 +21,7 @@
22
21
 
23
22
  <script type="text/javascript">
24
23
  $(function() {
25
- Alchemy.Sitemap.init({
24
+ Alchemy.currentSitemap = new Alchemy.Sitemap({
26
25
  url: '<%= alchemy.tree_admin_pages_path %>',
27
26
  page_root_id: <%= @page_root.id %>,
28
27
  full: <%= full %>
@@ -32,5 +31,6 @@
32
31
  }
33
32
  <% end %>
34
33
  });
34
+ Alchemy.PagePublicationFields();
35
35
  });
36
36
  </script>
@@ -154,7 +154,7 @@
154
154
  if (!not_dirty) Alchemy.pleaseWaitOverlay(false);
155
155
  return not_dirty;
156
156
  });
157
- Alchemy.Sitemap.watchPagePublicationState();
157
+ Alchemy.PagePublicationFields();
158
158
  Alchemy.PageLeaveObserver();
159
159
  Alchemy.ElementsWindow.init('<%= alchemy.admin_elements_path(page_version_id: @page_version.id) %>', {
160
160
  texts: {
@@ -1,2 +1,2 @@
1
1
  $('#fold_button_<%= @page.id %>').css('background', 'none');
2
- Alchemy.Sitemap.fetch(<%= @page.id %>);
2
+ Alchemy.currentSitemap.reload(<%= @page.id %>);
@@ -1,11 +1,6 @@
1
1
  (function() {
2
2
  var page = document.querySelector('#page_<%= @page.id %>');
3
3
 
4
- <% if @old_page_layout != @page.page_layout -%>
5
- Alchemy.ElementsWindow.reload();
6
- Alchemy.growl('<%= j Alchemy.t(:page_layout_changed_notice) %>');
7
- <% end -%>
8
-
9
4
  <% if @while_page_edit -%>
10
5
 
11
6
  Alchemy.reloadPreview();
@@ -534,7 +534,6 @@ en:
534
534
  or_replace_it_with_an_existing_tag: 'Or replace it with an existing tag'
535
535
  "Page created": "Page: '%{name}' created."
536
536
  page_infos: 'Page info'
537
- page_layout_changed_notice: "Page type was changed. Elements not usable anymore have been hided."
538
537
  page_properties: "Page properties"
539
538
  page_public: "published"
540
539
  page_published: "Published page"
data/config/routes.rb CHANGED
@@ -124,7 +124,6 @@ Alchemy::Engine.routes.draw do
124
124
 
125
125
  resources :messages, only: [:index, :new, :create]
126
126
  resources :elements, only: :show
127
- resources :contents, only: :show
128
127
 
129
128
  namespace :api, defaults: { format: "json" } do
130
129
  resources :contents, only: [:index, :show]
@@ -1,23 +1,23 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class AlchemyFourPointFour < ActiveRecord::Migration[5.2]
3
+ class AlchemyFourPointFour < ActiveRecord::Migration[6.0]
4
4
  def up
5
5
  unless table_exists?("alchemy_attachments")
6
- create_table "alchemy_attachments", force: :cascade do |t|
6
+ create_table "alchemy_attachments" do |t|
7
7
  t.string "name"
8
8
  t.string "file_name"
9
9
  t.string "file_mime_type"
10
10
  t.integer "file_size"
11
11
  t.references "creator"
12
12
  t.references "updater"
13
- t.timestamps null: false
13
+ t.timestamps
14
14
  t.string "file_uid"
15
15
  t.index ["file_uid"], name: "index_alchemy_attachments_on_file_uid"
16
16
  end
17
17
  end
18
18
 
19
19
  unless table_exists?("alchemy_contents")
20
- create_table "alchemy_contents", force: :cascade do |t|
20
+ create_table "alchemy_contents" do |t|
21
21
  t.string "name"
22
22
  t.references "essence", null: false, polymorphic: true, index: { unique: true }
23
23
  t.references "element", null: false
@@ -25,14 +25,14 @@ class AlchemyFourPointFour < ActiveRecord::Migration[5.2]
25
25
  end
26
26
 
27
27
  unless table_exists?("alchemy_elements")
28
- create_table "alchemy_elements", force: :cascade do |t|
28
+ create_table "alchemy_elements" do |t|
29
29
  t.string "name"
30
30
  t.integer "position"
31
31
  t.references "page", null: false, index: false
32
32
  t.boolean "public", default: true
33
33
  t.boolean "folded", default: false
34
34
  t.boolean "unique", default: false
35
- t.timestamps null: false
35
+ t.timestamps
36
36
  t.references "creator"
37
37
  t.references "updater"
38
38
  t.references "parent_element", index: false
@@ -44,27 +44,27 @@ class AlchemyFourPointFour < ActiveRecord::Migration[5.2]
44
44
  end
45
45
 
46
46
  unless table_exists?("alchemy_elements_alchemy_pages")
47
- create_table "alchemy_elements_alchemy_pages", id: false, force: :cascade do |t|
47
+ create_table "alchemy_elements_alchemy_pages", id: false do |t|
48
48
  t.references "element"
49
49
  t.references "page"
50
50
  end
51
51
  end
52
52
 
53
53
  unless table_exists?("alchemy_essence_booleans")
54
- create_table "alchemy_essence_booleans", force: :cascade do |t|
54
+ create_table "alchemy_essence_booleans" do |t|
55
55
  t.boolean "value"
56
56
  t.index ["value"], name: "index_alchemy_essence_booleans_on_value"
57
57
  end
58
58
  end
59
59
 
60
60
  unless table_exists?("alchemy_essence_dates")
61
- create_table "alchemy_essence_dates", force: :cascade do |t|
61
+ create_table "alchemy_essence_dates" do |t|
62
62
  t.datetime "date"
63
63
  end
64
64
  end
65
65
 
66
66
  unless table_exists?("alchemy_essence_files")
67
- create_table "alchemy_essence_files", force: :cascade do |t|
67
+ create_table "alchemy_essence_files" do |t|
68
68
  t.references "attachment"
69
69
  t.string "title"
70
70
  t.string "css_class"
@@ -73,13 +73,13 @@ class AlchemyFourPointFour < ActiveRecord::Migration[5.2]
73
73
  end
74
74
 
75
75
  unless table_exists?("alchemy_essence_htmls")
76
- create_table "alchemy_essence_htmls", force: :cascade do |t|
76
+ create_table "alchemy_essence_htmls" do |t|
77
77
  t.text "source"
78
78
  end
79
79
  end
80
80
 
81
81
  unless table_exists?("alchemy_essence_links")
82
- create_table "alchemy_essence_links", force: :cascade do |t|
82
+ create_table "alchemy_essence_links" do |t|
83
83
  t.string "link"
84
84
  t.string "link_title"
85
85
  t.string "link_target"
@@ -88,13 +88,13 @@ class AlchemyFourPointFour < ActiveRecord::Migration[5.2]
88
88
  end
89
89
 
90
90
  unless table_exists?("alchemy_essence_pages")
91
- create_table "alchemy_essence_pages", force: :cascade do |t|
91
+ create_table "alchemy_essence_pages" do |t|
92
92
  t.references "page"
93
93
  end
94
94
  end
95
95
 
96
96
  unless table_exists?("alchemy_essence_pictures")
97
- create_table "alchemy_essence_pictures", force: :cascade do |t|
97
+ create_table "alchemy_essence_pictures" do |t|
98
98
  t.references "picture"
99
99
  t.string "caption"
100
100
  t.string "title"
@@ -111,7 +111,7 @@ class AlchemyFourPointFour < ActiveRecord::Migration[5.2]
111
111
  end
112
112
 
113
113
  unless table_exists?("alchemy_essence_richtexts")
114
- create_table "alchemy_essence_richtexts", force: :cascade do |t|
114
+ create_table "alchemy_essence_richtexts" do |t|
115
115
  t.text "body"
116
116
  t.text "stripped_body"
117
117
  t.boolean "public"
@@ -119,14 +119,14 @@ class AlchemyFourPointFour < ActiveRecord::Migration[5.2]
119
119
  end
120
120
 
121
121
  unless table_exists?("alchemy_essence_selects")
122
- create_table "alchemy_essence_selects", force: :cascade do |t|
122
+ create_table "alchemy_essence_selects" do |t|
123
123
  t.string "value"
124
124
  t.index ["value"], name: "index_alchemy_essence_selects_on_value"
125
125
  end
126
126
  end
127
127
 
128
128
  unless table_exists?("alchemy_essence_texts")
129
- create_table "alchemy_essence_texts", force: :cascade do |t|
129
+ create_table "alchemy_essence_texts" do |t|
130
130
  t.text "body"
131
131
  t.string "link"
132
132
  t.string "link_title"
@@ -137,7 +137,7 @@ class AlchemyFourPointFour < ActiveRecord::Migration[5.2]
137
137
  end
138
138
 
139
139
  unless table_exists?("alchemy_folded_pages")
140
- create_table "alchemy_folded_pages", force: :cascade do |t|
140
+ create_table "alchemy_folded_pages" do |t|
141
141
  t.references "page", null: false, index: false
142
142
  t.references "user", null: false, index: false
143
143
  t.boolean "folded", default: false
@@ -146,13 +146,13 @@ class AlchemyFourPointFour < ActiveRecord::Migration[5.2]
146
146
  end
147
147
 
148
148
  unless table_exists?("alchemy_languages")
149
- create_table "alchemy_languages", force: :cascade do |t|
149
+ create_table "alchemy_languages" do |t|
150
150
  t.string "name"
151
151
  t.string "language_code"
152
152
  t.string "frontpage_name"
153
153
  t.string "page_layout", default: "intro"
154
154
  t.boolean "public", default: false
155
- t.timestamps null: false
155
+ t.timestamps
156
156
  t.references "creator"
157
157
  t.references "updater"
158
158
  t.boolean "default", default: false
@@ -165,16 +165,16 @@ class AlchemyFourPointFour < ActiveRecord::Migration[5.2]
165
165
  end
166
166
 
167
167
  unless table_exists?("alchemy_legacy_page_urls")
168
- create_table "alchemy_legacy_page_urls", force: :cascade do |t|
168
+ create_table "alchemy_legacy_page_urls" do |t|
169
169
  t.string "urlname", null: false
170
170
  t.references "page", null: false
171
- t.timestamps null: false
171
+ t.timestamps
172
172
  t.index ["urlname"], name: "index_alchemy_legacy_page_urls_on_urlname"
173
173
  end
174
174
  end
175
175
 
176
176
  unless table_exists?("alchemy_nodes")
177
- create_table "alchemy_nodes", force: :cascade do |t|
177
+ create_table "alchemy_nodes" do |t|
178
178
  t.string "name"
179
179
  t.string "title"
180
180
  t.string "url"
@@ -189,7 +189,7 @@ class AlchemyFourPointFour < ActiveRecord::Migration[5.2]
189
189
  t.references "language", null: false
190
190
  t.references "creator"
191
191
  t.references "updater"
192
- t.timestamps null: false
192
+ t.timestamps
193
193
  t.references "site", null: false
194
194
  t.index ["lft"], name: "index_alchemy_nodes_on_lft"
195
195
  t.index ["rgt"], name: "index_alchemy_nodes_on_rgt"
@@ -197,7 +197,7 @@ class AlchemyFourPointFour < ActiveRecord::Migration[5.2]
197
197
  end
198
198
 
199
199
  unless table_exists?("alchemy_pages")
200
- create_table "alchemy_pages", force: :cascade do |t|
200
+ create_table "alchemy_pages" do |t|
201
201
  t.string "name"
202
202
  t.string "urlname"
203
203
  t.string "title"
@@ -217,7 +217,7 @@ class AlchemyFourPointFour < ActiveRecord::Migration[5.2]
217
217
  t.boolean "robot_follow", default: true
218
218
  t.boolean "sitemap", default: true
219
219
  t.boolean "layoutpage", default: false
220
- t.timestamps null: false
220
+ t.timestamps
221
221
  t.references "creator"
222
222
  t.references "updater"
223
223
  t.references "language"
@@ -234,12 +234,12 @@ class AlchemyFourPointFour < ActiveRecord::Migration[5.2]
234
234
  end
235
235
 
236
236
  unless table_exists?("alchemy_pictures")
237
- create_table "alchemy_pictures", force: :cascade do |t|
237
+ create_table "alchemy_pictures" do |t|
238
238
  t.string "name"
239
239
  t.string "image_file_name"
240
240
  t.integer "image_file_width"
241
241
  t.integer "image_file_height"
242
- t.timestamps null: false
242
+ t.timestamps
243
243
  t.references "creator"
244
244
  t.references "updater"
245
245
  t.string "upload_hash"
@@ -250,10 +250,10 @@ class AlchemyFourPointFour < ActiveRecord::Migration[5.2]
250
250
  end
251
251
 
252
252
  unless table_exists?("alchemy_sites")
253
- create_table "alchemy_sites", force: :cascade do |t|
253
+ create_table "alchemy_sites" do |t|
254
254
  t.string "host"
255
255
  t.string "name"
256
- t.timestamps null: false
256
+ t.timestamps
257
257
  t.boolean "public", default: false
258
258
  t.text "aliases"
259
259
  t.boolean "redirect_to_primary_host"
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class CreateAlchemyEssenceNodes < ActiveRecord::Migration[5.2]
3
+ class CreateAlchemyEssenceNodes < ActiveRecord::Migration[6.0]
4
4
  def change
5
5
  create_table :alchemy_essence_nodes do |t|
6
6
  t.references "node"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- class RemoveSiteIdFromNodes < ActiveRecord::Migration[5.2]
2
+ class RemoveSiteIdFromNodes < ActiveRecord::Migration[6.0]
3
3
  def up
4
4
  remove_foreign_key :alchemy_nodes, :alchemy_sites
5
5
  remove_index :alchemy_nodes, :site_id
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class AddLanguageIdForeignKeyToAlchemyPages < ActiveRecord::Migration[5.2]
3
+ class AddLanguageIdForeignKeyToAlchemyPages < ActiveRecord::Migration[6.0]
4
4
  def change
5
5
  add_foreign_key :alchemy_pages, :alchemy_languages, column: :language_id
6
6
  change_column_null :alchemy_pages, :language_id, false, Alchemy::Language.default&.id
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- class AddMenuTypeToAlchemyNodes < ActiveRecord::Migration[5.2]
2
+ class AddMenuTypeToAlchemyNodes < ActiveRecord::Migration[6.0]
3
3
  class LocalNode < ActiveRecord::Base
4
4
  self.table_name = :alchemy_nodes
5
5
  acts_as_nested_set scope: :language_id
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- class MakePageLayoutpageNullFalse < ActiveRecord::Migration[5.2]
2
+ class MakePageLayoutpageNullFalse < ActiveRecord::Migration[6.0]
3
3
  def change
4
4
  change_column_null :alchemy_pages, :layoutpage, false, false
5
5
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
- class RemoveVisibleFromAlchemyPages < ActiveRecord::Migration[5.2]
2
+ class RemoveVisibleFromAlchemyPages < ActiveRecord::Migration[6.0]
3
3
  class LocalPage < ActiveRecord::Base
4
4
  self.table_name = "alchemy_pages"
5
5
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class CreateAlchemyPictureThumbs < ActiveRecord::Migration[5.2]
3
+ class CreateAlchemyPictureThumbs < ActiveRecord::Migration[6.0]
4
4
  def up
5
5
  return if table_exists?(:alchemy_picture_thumbs)
6
6
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class RemoveTriStateBooleans < ActiveRecord::Migration[5.2]
3
+ class RemoveTriStateBooleans < ActiveRecord::Migration[6.0]
4
4
  def change
5
5
  change_column_null :alchemy_elements, :public, false, false
6
6
  change_column_default :alchemy_elements, :public, true
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class CreatePageVersions < ActiveRecord::Migration[5.2]
3
+ class CreatePageVersions < ActiveRecord::Migration[6.0]
4
4
  def change
5
5
  create_table :alchemy_page_versions do |t|
6
6
  t.references :page,
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- class AddPageVersionIdToAlchemyElements < ActiveRecord::Migration[5.2]
3
+ class AddPageVersionIdToAlchemyElements < ActiveRecord::Migration[6.0]
4
4
  class LocalPage < ActiveRecord::Base
5
5
  self.table_name = :alchemy_pages
6
6
  has_many :elements, class_name: "LocalElement", inverse_of: :page
@@ -19,11 +19,12 @@ module Alchemy
19
19
  NonStupidDigestAssets.whitelist += [/^tinymce\//]
20
20
  end
21
21
 
22
- # Gutentag downcases all tgas before save.
23
- # We support having tags with uppercase characters.
24
- # The Gutentag search is case insensitive.
25
- initializer "alchemy.gutentag_normalizer" do
22
+ # Gutentag downcases all tags before save
23
+ # and Gutentag validations are not case sensitive.
24
+ # But we support having tags with uppercase characters.
25
+ config.to_prepare do
26
26
  Gutentag.normaliser = ->(value) { value.to_s }
27
+ Gutentag.tag_validations = Alchemy::TagValidations
27
28
  end
28
29
 
29
30
  # Custom Ransack sort arrows
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Alchemy
4
+ module ErrorTracking
5
+ class BaseHandler
6
+ def self.call(exception)
7
+ # implement your own notification method
8
+ end
9
+ end
10
+
11
+ mattr_accessor :notification_handler
12
+ @@notification_handler = BaseHandler
13
+ end
14
+ end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Alchemy
4
- VERSION = "6.0.0-rc3"
4
+ VERSION = "6.0.0-rc6"
5
5
 
6
6
  def self.version
7
7
  VERSION
data/lib/alchemy_cms.rb CHANGED
@@ -37,6 +37,7 @@ require_relative "alchemy/controller_actions"
37
37
  require_relative "alchemy/deprecation"
38
38
  require_relative "alchemy/element_definition"
39
39
  require_relative "alchemy/elements_finder"
40
+ require_relative "alchemy/error_tracking"
40
41
  require_relative "alchemy/errors"
41
42
  require_relative "alchemy/essence"
42
43
  require_relative "alchemy/filetypes"
data/package/admin.js CHANGED
@@ -5,6 +5,9 @@ import fileEditors from "./src/file_editors"
5
5
  import pictureEditors from "./src/picture_editors"
6
6
  import ImageLoader from "./src/image_loader"
7
7
  import ImageCropper from "./src/image_cropper"
8
+ import Datepicker from "./src/datepicker"
9
+ import Sitemap from "./src/sitemap"
10
+ import PagePublicationFields from "./src/page_publication_fields.js"
8
11
 
9
12
  // Global Alchemy object
10
13
  if (typeof window.Alchemy === "undefined") {
@@ -20,5 +23,8 @@ Object.assign(Alchemy, {
20
23
  fileEditors,
21
24
  pictureEditors,
22
25
  ImageLoader: ImageLoader.init,
23
- ImageCropper
26
+ ImageCropper,
27
+ Datepicker,
28
+ Sitemap,
29
+ PagePublicationFields
24
30
  })
@@ -0,0 +1,39 @@
1
+ import flatpickr from "flatpickr"
2
+
3
+ export default function Datepicker(scope = document) {
4
+ if (scope === "") {
5
+ scope = document
6
+ } else if (scope instanceof String) {
7
+ scope = document.querySelectorAll(scope)
8
+ }
9
+
10
+ const datepickerInputs = scope.querySelectorAll("input[data-datepicker-type]")
11
+
12
+ // Initializes the datepickers on the text inputs and sets the proper type
13
+ // to enable browsers default datepicker if the current OS is iOS.
14
+ if (Alchemy.isiOS) {
15
+ datepickerInputs.forEach((input) => {
16
+ input.attributes.type = input.dataset.datepickerType
17
+ })
18
+ } else {
19
+ datepickerInputs.forEach((input) => {
20
+ const type = input.dataset.datepickerType
21
+ const options = {
22
+ // alchemy_i18n supports `zh_CN` etc., but flatpickr only has two-letter codes (`zh`)
23
+ locale: Alchemy.locale.slice(0, 2),
24
+ altInput: true,
25
+ altFormat: Alchemy.t(`formats.${type}`),
26
+ altInputClass: "flatpickr-input",
27
+ enableTime: /time/.test(type),
28
+ noCalendar: type === "time",
29
+ time_24hr: Alchemy.t("formats.time_24hr"),
30
+ onValueUpdate(_selectedDates, _dateStr, instance) {
31
+ return Alchemy.setElementDirty(
32
+ instance.element.closest(".element-editor")
33
+ )
34
+ }
35
+ }
36
+ flatpickr(input, options)
37
+ })
38
+ }
39
+ }