alchemy_cms 5.1.0.beta2 → 5.1.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +126 -0
- data/CHANGELOG.md +29 -1
- data/Gemfile +1 -1
- data/README.md +1 -1
- data/alchemy_cms.gemspec +1 -1
- data/app/assets/javascripts/alchemy/admin.js +0 -1
- data/app/assets/stylesheets/alchemy/_variables.scss +5 -0
- data/app/assets/stylesheets/alchemy/admin.scss +0 -1
- data/app/assets/stylesheets/alchemy/buttons.scss +26 -15
- data/app/assets/stylesheets/alchemy/elements.scss +58 -19
- data/app/assets/stylesheets/alchemy/frame.scss +0 -1
- data/app/assets/stylesheets/alchemy/hints.scss +2 -1
- data/app/assets/stylesheets/alchemy/search.scss +1 -1
- data/app/assets/stylesheets/alchemy/selects.scss +23 -19
- data/app/assets/stylesheets/alchemy/tables.scss +38 -9
- data/app/controllers/alchemy/admin/pages_controller.rb +48 -7
- data/app/decorators/alchemy/element_editor.rb +67 -0
- data/app/models/alchemy/legacy_page_url.rb +1 -1
- data/app/models/alchemy/page.rb +8 -0
- data/app/models/alchemy/site/layout.rb +30 -2
- data/app/serializers/alchemy/page_tree_serializer.rb +4 -4
- data/app/views/alchemy/admin/elements/_element.html.erb +1 -1
- data/app/views/alchemy/admin/elements/_element_toolbar.html.erb +1 -1
- data/app/views/alchemy/admin/elements/publish.js.erb +1 -0
- data/app/views/alchemy/admin/pages/_create_language_form.html.erb +19 -29
- data/app/views/alchemy/admin/pages/_new_page_form.html.erb +10 -1
- data/app/views/alchemy/admin/pages/_page_layout_filter.html.erb +29 -0
- data/app/views/alchemy/admin/pages/_table.html.erb +27 -0
- data/app/views/alchemy/admin/pages/_table_row.html.erb +107 -0
- data/app/views/alchemy/admin/pages/_toolbar.html.erb +77 -0
- data/app/views/alchemy/admin/pages/index.html.erb +41 -74
- data/app/views/alchemy/admin/pages/list/_table.html.erb +31 -0
- data/app/views/alchemy/admin/pages/unlock.js.erb +2 -2
- data/app/views/alchemy/admin/pages/update.js.erb +19 -10
- data/app/views/alchemy/admin/resources/_filter_bar.html.erb +13 -11
- data/config/locales/alchemy.en.yml +4 -4
- data/lib/alchemy/permissions.rb +1 -0
- data/lib/alchemy/resource.rb +5 -3
- data/lib/alchemy/test_support/integration_helpers.rb +0 -7
- data/lib/alchemy/version.rb +1 -1
- data/lib/alchemy_cms.rb +0 -1
- data/vendor/assets/javascripts/jquery_plugins/select2.js +3729 -0
- data/vendor/assets/stylesheets/alchemy_admin/select2.scss +740 -0
- metadata +29 -29
- data/.travis.yml +0 -48
@@ -27,7 +27,8 @@
|
|
27
27
|
|
28
28
|
> .hint-bubble {
|
29
29
|
visibility: hidden;
|
30
|
-
background: $
|
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;
|
@@ -1,13 +1,16 @@
|
|
1
|
+
@import "alchemy_admin/select2";
|
2
|
+
|
1
3
|
select {
|
2
4
|
@include button-defaults(
|
3
5
|
$background-color: $form-field-background-color,
|
4
6
|
$hover-color: $form-field-background-color,
|
5
7
|
$hover-border-color: darken($default-border-color, 10%),
|
6
|
-
$padding: 0 2
|
8
|
+
$padding: 0 2 * $default-padding,
|
7
9
|
$border: 1px solid $default-border-color,
|
8
10
|
$box-shadow: none,
|
9
11
|
$color: $text-color,
|
10
|
-
$margin: 0
|
12
|
+
$margin: 0
|
13
|
+
);
|
11
14
|
height: $form-field-height;
|
12
15
|
padding: 0.4em 0.6em;
|
13
16
|
max-width: 100%;
|
@@ -32,7 +35,8 @@ select {
|
|
32
35
|
$border: 1px solid $default-border-color,
|
33
36
|
$box-shadow: none,
|
34
37
|
$color: $text-color,
|
35
|
-
$margin: 0
|
38
|
+
$margin: 0
|
39
|
+
);
|
36
40
|
background-image: none;
|
37
41
|
display: block;
|
38
42
|
font-weight: normal;
|
@@ -79,14 +83,13 @@ select {
|
|
79
83
|
}
|
80
84
|
|
81
85
|
&.select2-container-active {
|
82
|
-
|
83
|
-
.select2-
|
86
|
+
.select2-choice,
|
87
|
+
.select2-choices {
|
84
88
|
@include default-focus-style($box-shadow: 0 0 0 1px $focus-color);
|
85
89
|
}
|
86
90
|
}
|
87
91
|
|
88
92
|
&.select2-container-disabled {
|
89
|
-
|
90
93
|
&:hover {
|
91
94
|
+ .with-hint > .hint-bubble {
|
92
95
|
@include hint-hover-style;
|
@@ -98,7 +101,8 @@ select {
|
|
98
101
|
top: 0;
|
99
102
|
}
|
100
103
|
|
101
|
-
.select2-choice,
|
104
|
+
.select2-choice,
|
105
|
+
.select2-choice:hover {
|
102
106
|
background-image: none;
|
103
107
|
background-color: $light-gray;
|
104
108
|
box-shadow: none;
|
@@ -108,7 +112,9 @@ select {
|
|
108
112
|
.select2-arrow {
|
109
113
|
border-color: $border-inset-color;
|
110
114
|
|
111
|
-
b {
|
115
|
+
b {
|
116
|
+
color: $border-inset-color;
|
117
|
+
}
|
112
118
|
}
|
113
119
|
}
|
114
120
|
}
|
@@ -142,7 +148,6 @@ select {
|
|
142
148
|
margin-top: 0 !important;
|
143
149
|
|
144
150
|
&.select2-container-active {
|
145
|
-
|
146
151
|
.select2-choices {
|
147
152
|
@include default-focus-style($box-shadow: 0 0 0 1px $focus-color);
|
148
153
|
}
|
@@ -214,7 +219,8 @@ select {
|
|
214
219
|
}
|
215
220
|
}
|
216
221
|
|
217
|
-
.select2-no-results,
|
222
|
+
.select2-no-results,
|
223
|
+
.select2-searching {
|
218
224
|
padding: 8px;
|
219
225
|
margin: 0;
|
220
226
|
}
|
@@ -235,41 +241,39 @@ select {
|
|
235
241
|
|
236
242
|
.select2-more-results,
|
237
243
|
.select2-ajax-error {
|
238
|
-
padding: 2
|
244
|
+
padding: 2 * $default-padding;
|
239
245
|
margin-bottom: 0;
|
240
246
|
}
|
241
247
|
}
|
242
248
|
|
243
|
-
.window_form,
|
244
|
-
|
249
|
+
.window_form,
|
250
|
+
#filter_bar {
|
245
251
|
.select2-container {
|
246
252
|
width: 100%;
|
247
253
|
}
|
248
254
|
}
|
249
255
|
|
250
256
|
.select_with_label {
|
251
|
-
margin: 0 3
|
257
|
+
margin: 0 3 * $default-margin;
|
252
258
|
display: inline-block;
|
253
259
|
vertical-align: middle;
|
254
260
|
|
255
261
|
label {
|
256
262
|
display: inline-block;
|
257
263
|
vertical-align: middle;
|
258
|
-
margin-right: 2
|
264
|
+
margin-right: 2 * $default-margin;
|
259
265
|
}
|
260
266
|
}
|
261
267
|
|
262
268
|
// overriding important of select2 default style for retina screens
|
263
269
|
@media only screen and (-webkit-min-device-pixel-ratio: 1.5),
|
264
|
-
|
265
|
-
|
270
|
+
only screen and (min-resolution: 2dppx) {
|
266
271
|
#alchemy {
|
267
|
-
|
268
272
|
.select2-search input,
|
269
273
|
.select2-search-choice-close,
|
270
274
|
.select2-container .select2-choice abbr,
|
271
275
|
.select2-container .select2-choice .select2-arrow b {
|
272
|
-
|
276
|
+
background-image: none !important;
|
273
277
|
}
|
274
278
|
}
|
275
279
|
}
|
@@ -6,7 +6,8 @@ table {
|
|
6
6
|
width: 100%;
|
7
7
|
|
8
8
|
&.list .tools {
|
9
|
-
button,
|
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,
|
26
|
-
|
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,
|
97
|
-
|
98
|
-
&.center,
|
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,
|
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,
|
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 <
|
5
|
+
class PagesController < ResourcesController
|
6
6
|
include OnPageLayout::CallbacksRunner
|
7
7
|
|
8
8
|
helper "alchemy/pages"
|
9
9
|
|
10
|
-
before_action :
|
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
|
-
|
32
|
-
|
33
|
-
|
34
|
-
@
|
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
|
|
@@ -229,6 +251,19 @@ module Alchemy
|
|
229
251
|
|
230
252
|
private
|
231
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
|
+
|
232
267
|
def copy_of_language_root
|
233
268
|
Page.copy(
|
234
269
|
language_root_to_copy_from,
|
@@ -310,7 +345,7 @@ module Alchemy
|
|
310
345
|
{ my_urlname: default_urlname, children_path: default_urlname }
|
311
346
|
end
|
312
347
|
|
313
|
-
def
|
348
|
+
def load_resource
|
314
349
|
@page = Page.find(params[:id])
|
315
350
|
end
|
316
351
|
|
@@ -373,6 +408,12 @@ module Alchemy
|
|
373
408
|
user: current_alchemy_user,
|
374
409
|
full: params[:full] == "true")
|
375
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
|
376
417
|
end
|
377
418
|
end
|
378
419
|
end
|
@@ -8,6 +8,17 @@ module Alchemy
|
|
8
8
|
"alchemy/admin/elements/element"
|
9
9
|
end
|
10
10
|
|
11
|
+
# Returns content editor instances for defined contents
|
12
|
+
#
|
13
|
+
# Creates contents on demand if the content is not yet present on the element
|
14
|
+
#
|
15
|
+
# @return Array<Alchemy::ContentEditor>
|
16
|
+
def contents
|
17
|
+
element.definition.fetch(:contents, []).map do |content|
|
18
|
+
Alchemy::ContentEditor.new(find_or_create_content(content[:name]))
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
11
22
|
# CSS classes for the element editor partial.
|
12
23
|
def css_classes
|
13
24
|
[
|
@@ -18,6 +29,7 @@ module Alchemy
|
|
18
29
|
folded ? "folded" : "expanded",
|
19
30
|
compact? ? "compact" : nil,
|
20
31
|
fixed? ? "is-fixed" : "not-fixed",
|
32
|
+
public? ? "visible" : "hidden",
|
21
33
|
].join(" ")
|
22
34
|
end
|
23
35
|
|
@@ -35,5 +47,60 @@ module Alchemy
|
|
35
47
|
|
36
48
|
super
|
37
49
|
end
|
50
|
+
|
51
|
+
# Returns a deprecation notice for elements marked deprecated
|
52
|
+
#
|
53
|
+
# You can either use localizations or pass a String as notice
|
54
|
+
# in the element definition.
|
55
|
+
#
|
56
|
+
# == Custom deprecation notices
|
57
|
+
#
|
58
|
+
# Use general element deprecation notice
|
59
|
+
#
|
60
|
+
# - name: old_element
|
61
|
+
# deprecated: true
|
62
|
+
#
|
63
|
+
# Add a translation to your locale file for a per element notice.
|
64
|
+
#
|
65
|
+
# en:
|
66
|
+
# alchemy:
|
67
|
+
# element_deprecation_notices:
|
68
|
+
# old_element: Foo baz widget is deprecated
|
69
|
+
#
|
70
|
+
# or use the global translation that apply to all deprecated elements.
|
71
|
+
#
|
72
|
+
# en:
|
73
|
+
# alchemy:
|
74
|
+
# element_deprecation_notice: Foo baz widget is deprecated
|
75
|
+
#
|
76
|
+
# or pass string as deprecation notice.
|
77
|
+
#
|
78
|
+
# - name: old_element
|
79
|
+
# deprecated: This element will be removed soon.
|
80
|
+
#
|
81
|
+
def deprecation_notice
|
82
|
+
case definition["deprecated"]
|
83
|
+
when String
|
84
|
+
definition["deprecated"]
|
85
|
+
when TrueClass
|
86
|
+
Alchemy.t(name,
|
87
|
+
scope: :element_deprecation_notices,
|
88
|
+
default: Alchemy.t(:element_deprecated))
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
def find_or_create_content(name)
|
95
|
+
find_content(name) || create_content(name)
|
96
|
+
end
|
97
|
+
|
98
|
+
def find_content(name)
|
99
|
+
element.contents.find { |content| content.name == name }
|
100
|
+
end
|
101
|
+
|
102
|
+
def create_content(name)
|
103
|
+
Alchemy::Content.create(element: element, name: name)
|
104
|
+
end
|
38
105
|
end
|
39
106
|
end
|
data/app/models/alchemy/page.rb
CHANGED
@@ -164,6 +164,14 @@ module Alchemy
|
|
164
164
|
@_url_path_class = klass
|
165
165
|
end
|
166
166
|
|
167
|
+
def alchemy_resource_filters
|
168
|
+
%w[published not_public restricted]
|
169
|
+
end
|
170
|
+
|
171
|
+
def searchable_alchemy_resource_attributes
|
172
|
+
%w[name urlname title]
|
173
|
+
end
|
174
|
+
|
167
175
|
# Used to store the current page previewed in the edit page template.
|
168
176
|
#
|
169
177
|
def current_preview=(page)
|