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

Sign up to get free protection for your applications and to get access to all the features.
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
+ }