alchemy_cms 5.1.0.beta1 → 5.1.2

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 (51) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ci.yml +126 -0
  3. data/CHANGELOG.md +29 -1
  4. data/Gemfile +2 -2
  5. data/README.md +1 -1
  6. data/alchemy_cms.gemspec +1 -1
  7. data/app/assets/javascripts/alchemy/admin.js +0 -1
  8. data/app/assets/javascripts/alchemy/alchemy.element_editors.js.coffee +1 -4
  9. data/app/assets/javascripts/alchemy/alchemy.preview.js.coffee +0 -3
  10. data/app/assets/javascripts/alchemy/alchemy.preview_window.js.coffee +29 -4
  11. data/app/assets/stylesheets/alchemy/_variables.scss +7 -0
  12. data/app/assets/stylesheets/alchemy/admin.scss +0 -1
  13. data/app/assets/stylesheets/alchemy/buttons.scss +26 -15
  14. data/app/assets/stylesheets/alchemy/elements.scss +58 -19
  15. data/app/assets/stylesheets/alchemy/frame.scss +0 -1
  16. data/app/assets/stylesheets/alchemy/hints.scss +2 -1
  17. data/app/assets/stylesheets/alchemy/search.scss +1 -1
  18. data/app/assets/stylesheets/alchemy/selects.scss +26 -20
  19. data/app/assets/stylesheets/alchemy/tables.scss +38 -9
  20. data/app/controllers/alchemy/admin/pages_controller.rb +58 -8
  21. data/app/decorators/alchemy/element_editor.rb +1 -0
  22. data/app/models/alchemy/legacy_page_url.rb +1 -1
  23. data/app/models/alchemy/page.rb +8 -0
  24. data/app/models/alchemy/site/layout.rb +30 -2
  25. data/app/serializers/alchemy/page_tree_serializer.rb +4 -4
  26. data/app/views/alchemy/admin/elements/_element_toolbar.html.erb +1 -1
  27. data/app/views/alchemy/admin/elements/publish.js.erb +1 -0
  28. data/app/views/alchemy/admin/pages/_create_language_form.html.erb +19 -29
  29. data/app/views/alchemy/admin/pages/_new_page_form.html.erb +10 -1
  30. data/app/views/alchemy/admin/pages/_page_layout_filter.html.erb +29 -0
  31. data/app/views/alchemy/admin/pages/_table.html.erb +27 -0
  32. data/app/views/alchemy/admin/pages/_table_row.html.erb +107 -0
  33. data/app/views/alchemy/admin/pages/_toolbar.html.erb +77 -0
  34. data/app/views/alchemy/admin/pages/edit.html.erb +9 -1
  35. data/app/views/alchemy/admin/pages/index.html.erb +41 -74
  36. data/app/views/alchemy/admin/pages/list/_table.html.erb +31 -0
  37. data/app/views/alchemy/admin/pages/unlock.js.erb +2 -2
  38. data/app/views/alchemy/admin/pages/update.js.erb +19 -10
  39. data/app/views/alchemy/admin/resources/_filter_bar.html.erb +13 -11
  40. data/config/locales/alchemy.en.yml +6 -4
  41. data/lib/alchemy.rb +66 -0
  42. data/lib/alchemy/admin/preview_url.rb +2 -0
  43. data/lib/alchemy/engine.rb +0 -4
  44. data/lib/alchemy/permissions.rb +1 -0
  45. data/lib/alchemy/test_support/integration_helpers.rb +0 -7
  46. data/lib/alchemy/version.rb +1 -1
  47. data/lib/alchemy_cms.rb +2 -4
  48. data/vendor/assets/javascripts/jquery_plugins/select2.js +3729 -0
  49. data/vendor/assets/stylesheets/alchemy_admin/select2.scss +740 -0
  50. metadata +30 -29
  51. data/.travis.yml +0 -48
@@ -60,6 +60,7 @@
60
60
  max-width: 85%;
61
61
  margin-left: $default-margin;
62
62
  text-overflow: ellipsis;
63
+ transition: color $transition-duration;
63
64
 
64
65
  .has-hint & {
65
66
  max-width: 80%;
@@ -73,7 +74,6 @@
73
74
 
74
75
  .preview_text_element_name {
75
76
  font-size: $small-font-size;
76
- text-shadow: #efefef 1px 1px 1px;
77
77
  font-weight: bold;
78
78
  line-height: 15px;
79
79
  }
@@ -106,6 +106,7 @@
106
106
  height: 16px;
107
107
  right: 8px;
108
108
  top: 10px;
109
+ transition: none;
109
110
 
110
111
  .error_icon {
111
112
  float: left;
@@ -126,6 +127,32 @@
126
127
  margin-bottom: 2*$default-margin;
127
128
  transition: box-shadow $transition-duration;
128
129
 
130
+ &.hidden {
131
+ display: block;
132
+ border-style: dashed;
133
+ opacity: 0.5;
134
+ transition: opacity $transition-duration;
135
+
136
+ > .element-header {
137
+ background-color: transparent;
138
+ background-image: linear-gradient(
139
+ 45deg,
140
+ $light-gray 25%,
141
+ $medium-gray 25%,
142
+ $medium-gray 50%,
143
+ $light-gray 50%,
144
+ $light-gray 75%,
145
+ $medium-gray 75%,
146
+ $medium-gray 100%
147
+ );
148
+ background-size: 28.28px 28.28px;
149
+ }
150
+
151
+ &:hover {
152
+ opacity: 1;
153
+ }
154
+ }
155
+
129
156
  &.is-fixed {
130
157
  border-width: 0;
131
158
  border-radius: 0;
@@ -143,9 +170,17 @@
143
170
  }
144
171
  }
145
172
 
146
- &.selected:not(.is-fixed) {
147
- border-color: #c3c3c3;
148
- box-shadow: 0 2px 8px rgba(#9b9b9b, 0.75);
173
+ &.selected:not(.is-fixed), &:hover {
174
+ &:not(.hidden) {
175
+ box-shadow: 0 2px 8px rgba(#9b9b9b, 0.75);
176
+ }
177
+ }
178
+
179
+ &.selected:not(.is-fixed):not(.folded):not(.dirty):not(.hidden) {
180
+ > .element-header {
181
+ background-color: $element-header-active-bg-color;
182
+ color: $element-header-active-color;
183
+ }
149
184
  }
150
185
 
151
186
  &.folded {
@@ -221,21 +256,10 @@
221
256
  }
222
257
  }
223
258
 
224
- .element_tools {
225
- display: flex;
226
- width: 100%;
227
- justify-content: space-between;
228
- margin-left: 0;
229
- }
230
-
231
259
  .element-content {
232
260
  margin: 4px 8px;
233
261
  }
234
262
 
235
- .button_with_label {
236
- margin: 0 4px;
237
- }
238
-
239
263
  .content_editor,
240
264
  .picture_thumbnail {
241
265
  width: 100%;
@@ -313,7 +337,18 @@
313
337
  background-color: $element-header-bg-color;
314
338
  @extend .disable-user-select;
315
339
  cursor: pointer;
316
- @include border-top-radius($default-border-radius);
340
+ border-radius: $default-border-radius;
341
+ transition: background-color $transition-duration;
342
+
343
+ .expanded & {
344
+ border-bottom-left-radius: 0;
345
+ border-bottom-right-radius: 0;
346
+ }
347
+
348
+ .icon {
349
+ color: inherit;
350
+ transition: color $transition-duration;
351
+ }
317
352
 
318
353
  >.hint-with-icon {
319
354
  position: absolute;
@@ -338,10 +373,14 @@
338
373
  padding: $default-padding 0;
339
374
  height: $element-toolbar-height;
340
375
  border-bottom: 1px solid $medium-gray;
376
+ }
341
377
 
342
- .element_tools {
343
- float: left;
344
- margin-left: -$default-margin;
378
+ .element_tools {
379
+ display: flex;
380
+ width: 100%;
381
+
382
+ .button_with_label {
383
+ margin: 0 2px;
345
384
  }
346
385
  }
347
386
 
@@ -74,7 +74,6 @@ div#overlay_text_box {
74
74
 
75
75
  .page_name {
76
76
  display: inline-block;
77
- max-width: 100px;
78
77
  margin-right: $default-margin;
79
78
  line-height: $header-height;
80
79
  white-space: nowrap;
@@ -27,7 +27,8 @@
27
27
 
28
28
  > .hint-bubble {
29
29
  visibility: hidden;
30
- background: $light_yellow;
30
+ background-color: $hint-background-color;
31
+ color: $hint-text-color;
31
32
  border-radius: $default-border-radius;
32
33
  box-shadow: 0px 4px 8px rgba(0, 0, 0, .3);
33
34
  position: absolute;
@@ -54,7 +54,7 @@
54
54
 
55
55
  .search_input_field {
56
56
  width: 0;
57
- height: inherit;
57
+ height: 100%;
58
58
  border: none;
59
59
  background-color: transparentize($form-field-background-color, 0.25);
60
60
  transition:
@@ -1,15 +1,16 @@
1
- $medium-select-box-width: 90px;
1
+ @import "alchemy_admin/select2";
2
2
 
3
3
  select {
4
4
  @include button-defaults(
5
5
  $background-color: $form-field-background-color,
6
6
  $hover-color: $form-field-background-color,
7
7
  $hover-border-color: darken($default-border-color, 10%),
8
- $padding: 0 2*$default-padding,
8
+ $padding: 0 2 * $default-padding,
9
9
  $border: 1px solid $default-border-color,
10
10
  $box-shadow: none,
11
11
  $color: $text-color,
12
- $margin: 0);
12
+ $margin: 0
13
+ );
13
14
  height: $form-field-height;
14
15
  padding: 0.4em 0.6em;
15
16
  max-width: 100%;
@@ -34,7 +35,8 @@ select {
34
35
  $border: 1px solid $default-border-color,
35
36
  $box-shadow: none,
36
37
  $color: $text-color,
37
- $margin: 0);
38
+ $margin: 0
39
+ );
38
40
  background-image: none;
39
41
  display: block;
40
42
  font-weight: normal;
@@ -76,15 +78,18 @@ select {
76
78
  width: $medium-select-box-width;
77
79
  }
78
80
 
79
- &.select2-container-active {
81
+ &.large {
82
+ width: $large-select-box-width;
83
+ }
80
84
 
81
- .select2-choice, .select2-choices {
85
+ &.select2-container-active {
86
+ .select2-choice,
87
+ .select2-choices {
82
88
  @include default-focus-style($box-shadow: 0 0 0 1px $focus-color);
83
89
  }
84
90
  }
85
91
 
86
92
  &.select2-container-disabled {
87
-
88
93
  &:hover {
89
94
  + .with-hint > .hint-bubble {
90
95
  @include hint-hover-style;
@@ -96,7 +101,8 @@ select {
96
101
  top: 0;
97
102
  }
98
103
 
99
- .select2-choice, .select2-choice:hover {
104
+ .select2-choice,
105
+ .select2-choice:hover {
100
106
  background-image: none;
101
107
  background-color: $light-gray;
102
108
  box-shadow: none;
@@ -106,7 +112,9 @@ select {
106
112
  .select2-arrow {
107
113
  border-color: $border-inset-color;
108
114
 
109
- b { color: $border-inset-color; }
115
+ b {
116
+ color: $border-inset-color;
117
+ }
110
118
  }
111
119
  }
112
120
  }
@@ -140,7 +148,6 @@ select {
140
148
  margin-top: 0 !important;
141
149
 
142
150
  &.select2-container-active {
143
-
144
151
  .select2-choices {
145
152
  @include default-focus-style($box-shadow: 0 0 0 1px $focus-color);
146
153
  }
@@ -212,7 +219,8 @@ select {
212
219
  }
213
220
  }
214
221
 
215
- .select2-no-results, .select2-searching {
222
+ .select2-no-results,
223
+ .select2-searching {
216
224
  padding: 8px;
217
225
  margin: 0;
218
226
  }
@@ -233,41 +241,39 @@ select {
233
241
 
234
242
  .select2-more-results,
235
243
  .select2-ajax-error {
236
- padding: 2*$default-padding;
244
+ padding: 2 * $default-padding;
237
245
  margin-bottom: 0;
238
246
  }
239
247
  }
240
248
 
241
- .window_form, #filter_bar {
242
-
249
+ .window_form,
250
+ #filter_bar {
243
251
  .select2-container {
244
252
  width: 100%;
245
253
  }
246
254
  }
247
255
 
248
256
  .select_with_label {
249
- margin: 0 3*$default-margin;
257
+ margin: 0 3 * $default-margin;
250
258
  display: inline-block;
251
259
  vertical-align: middle;
252
260
 
253
261
  label {
254
262
  display: inline-block;
255
263
  vertical-align: middle;
256
- margin-right: 2*$default-margin;
264
+ margin-right: 2 * $default-margin;
257
265
  }
258
266
  }
259
267
 
260
268
  // overriding important of select2 default style for retina screens
261
269
  @media only screen and (-webkit-min-device-pixel-ratio: 1.5),
262
- only screen and (min-resolution: 2dppx) {
263
-
270
+ only screen and (min-resolution: 2dppx) {
264
271
  #alchemy {
265
-
266
272
  .select2-search input,
267
273
  .select2-search-choice-close,
268
274
  .select2-container .select2-choice abbr,
269
275
  .select2-container .select2-choice .select2-arrow b {
270
- background-image: none !important;
276
+ background-image: none !important;
271
277
  }
272
278
  }
273
279
  }
@@ -6,7 +6,8 @@ table {
6
6
  width: 100%;
7
7
 
8
8
  &.list .tools {
9
- button, a {
9
+ button,
10
+ a {
10
11
  display: inline-block;
11
12
  width: 18px;
12
13
  height: 18px;
@@ -22,8 +23,9 @@ table {
22
23
  }
23
24
  }
24
25
 
25
- .list td, .list th {
26
- padding: 2*$default-padding;
26
+ .list td,
27
+ .list th {
28
+ padding: 2 * $default-padding;
27
29
  vertical-align: top;
28
30
  line-height: 18px;
29
31
  border-right: 1px solid $medium-gray;
@@ -93,9 +95,10 @@ td.heading {
93
95
  background-color: $table-row-hover-color;
94
96
  }
95
97
 
96
- td, th {
97
-
98
- &.center, &.boolean {
98
+ td,
99
+ th {
100
+ &.center,
101
+ &.boolean {
99
102
  text-align: center;
100
103
  }
101
104
 
@@ -105,7 +108,6 @@ td, th {
105
108
  }
106
109
 
107
110
  td {
108
-
109
111
  &.file_name {
110
112
  word-break: break-all;
111
113
  }
@@ -118,7 +120,8 @@ td {
118
120
  width: 80px;
119
121
  }
120
122
 
121
- &.date, &.datetime {
123
+ &.date,
124
+ &.datetime {
122
125
  width: 150px;
123
126
  }
124
127
 
@@ -137,9 +140,35 @@ td {
137
140
  &.rights {
138
141
  width: 60px;
139
142
  }
143
+
144
+ &.page_layout {
145
+ width: 160px;
146
+ }
147
+
148
+ &.status {
149
+ width: 80px;
150
+
151
+ .page_status {
152
+ margin: 0 $default-margin;
153
+ }
154
+ }
155
+
156
+ &.tags {
157
+ width: 180px;
158
+
159
+ .tag {
160
+ margin: 0;
161
+ padding: 0 2 + $default-padding;
162
+
163
+ &:before {
164
+ padding-right: $default-padding;
165
+ }
166
+ }
167
+ }
140
168
  }
141
169
 
142
- th.count, td.count {
170
+ th.count,
171
+ td.count {
143
172
  width: 120px;
144
173
  text-align: right;
145
174
  padding-right: 16px;
@@ -2,12 +2,12 @@
2
2
 
3
3
  module Alchemy
4
4
  module Admin
5
- class PagesController < Alchemy::Admin::BaseController
5
+ class PagesController < ResourcesController
6
6
  include OnPageLayout::CallbacksRunner
7
7
 
8
8
  helper "alchemy/pages"
9
9
 
10
- before_action :load_page, except: [:index, :flush, :new, :order, :create, :copy_language_tree, :link, :sort]
10
+ before_action :load_resource, except: [:index, :flush, :new, :order, :create, :copy_language_tree, :link, :sort]
11
11
 
12
12
  authorize_resource class: Alchemy::Page, except: [:index, :tree]
13
13
 
@@ -27,11 +27,33 @@ module Alchemy
27
27
  if: :run_on_page_layout_callbacks?,
28
28
  only: [:show]
29
29
 
30
+ before_action :load_languages_and_layouts,
31
+ unless: -> { @page_root },
32
+ only: [:index]
33
+
34
+ before_action :set_view, only: [:index]
35
+
30
36
  def index
31
- if !@page_root
32
- @language = @current_language
33
- @languages_with_page_tree = Language.on_current_site.with_root_page
34
- @page_layouts = PageLayout.layouts_for_select(@language.id)
37
+ @query = @current_language.pages.contentpages.ransack(search_filter_params[:q])
38
+
39
+ if @view == "list"
40
+ @query.sorts = default_sort_order if @query.sorts.empty?
41
+ items = @query.result
42
+
43
+ if search_filter_params[:tagged_with].present?
44
+ items = items.tagged_with(search_filter_params[:tagged_with])
45
+ end
46
+
47
+ if search_filter_params[:filter].present?
48
+ items = items.public_send(sanitized_filter_params)
49
+ end
50
+
51
+ if search_filter_params[:page_layout].present?
52
+ items = items.where(page_layout: search_filter_params[:page_layout])
53
+ end
54
+
55
+ items = items.page(params[:page] || 1).per(items_per_page)
56
+ @pages = items
35
57
  end
36
58
  end
37
59
 
@@ -85,7 +107,12 @@ module Alchemy
85
107
  elsif page_needs_lock?
86
108
  @page.lock_to!(current_alchemy_user)
87
109
  end
88
- @preview_url = Alchemy::Admin::PREVIEW_URL.url_for(@page)
110
+ @preview_urls = Alchemy.preview_sources.map do |klass|
111
+ [
112
+ klass.model_name.human,
113
+ klass.new(routes: Alchemy::Engine.routes).url_for(@page),
114
+ ]
115
+ end
89
116
  @layoutpage = @page.layoutpage?
90
117
  end
91
118
 
@@ -178,6 +205,10 @@ module Alchemy
178
205
  def publish
179
206
  # fetching page via before filter
180
207
  @page.publish!
208
+
209
+ # Send publish notification to all registered publish targets
210
+ Alchemy.publish_targets.each { |p| p.perform_later(@page) }
211
+
181
212
  flash[:notice] = Alchemy.t(:page_published, name: @page.name)
182
213
  redirect_back(fallback_location: admin_pages_path)
183
214
  end
@@ -220,6 +251,19 @@ module Alchemy
220
251
 
221
252
  private
222
253
 
254
+ def resource_handler
255
+ @_resource_handler ||= Alchemy::Resource.new(controller_path, alchemy_module, Alchemy::Page)
256
+ end
257
+
258
+ def common_search_filter_includes
259
+ super.push(:page_layout, :view)
260
+ end
261
+
262
+ def set_view
263
+ @view = params[:view] || session[:alchemy_pages_view] || "tree"
264
+ session[:alchemy_pages_view] = @view
265
+ end
266
+
223
267
  def copy_of_language_root
224
268
  Page.copy(
225
269
  language_root_to_copy_from,
@@ -301,7 +345,7 @@ module Alchemy
301
345
  { my_urlname: default_urlname, children_path: default_urlname }
302
346
  end
303
347
 
304
- def load_page
348
+ def load_resource
305
349
  @page = Page.find(params[:id])
306
350
  end
307
351
 
@@ -364,6 +408,12 @@ module Alchemy
364
408
  user: current_alchemy_user,
365
409
  full: params[:full] == "true")
366
410
  end
411
+
412
+ def load_languages_and_layouts
413
+ @language = @current_language
414
+ @languages_with_page_tree = Language.on_current_site.with_root_page
415
+ @page_layouts = PageLayout.layouts_for_select(@language.id)
416
+ end
367
417
  end
368
418
  end
369
419
  end