katalyst-content 0.2.0 → 0.2.1
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.
- checksums.yaml +4 -4
- data/app/assets/javascripts/controllers/content/editor/container_controller.js +36 -2
- data/app/assets/javascripts/controllers/content/editor/list_controller.js +6 -5
- data/app/assets/javascripts/controllers/content/editor/trix_controller.js +11 -1
- data/app/assets/javascripts/utils/content/editor/item.js +1 -20
- data/app/assets/javascripts/utils/content/editor/rules-engine.js +1 -1
- data/app/assets/stylesheets/katalyst/content/editor/_new-items.scss +1 -0
- data/app/controllers/katalyst/content/items_controller.rb +4 -4
- data/app/helpers/katalyst/content/editor/container.rb +6 -0
- data/app/helpers/katalyst/content/editor/errors.rb +24 -0
- data/app/helpers/katalyst/content/editor_helper.rb +6 -0
- data/app/models/concerns/katalyst/content/container.rb +5 -0
- data/app/models/concerns/katalyst/content/version.rb +10 -4
- data/app/models/katalyst/content/figure.rb +1 -1
- data/app/models/katalyst/content/item.rb +5 -1
- data/app/views/katalyst/content/columns/_column.html.erb +1 -1
- data/app/views/katalyst/content/figures/_figure.html+form.erb +4 -10
- data/config/locales/en.yml +2 -0
- data/lib/katalyst/content/version.rb +1 -1
- metadata +3 -4
- data/app/assets/javascripts/controllers/content/editor/image_field_controller.js +0 -90
- data/app/helpers/katalyst/content/editor/image_field.rb +0 -72
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5d759a4e97d9609138eba1c1d03ad9a081cc1badb65be59b5b200a23665909e7
|
4
|
+
data.tar.gz: 848034cbe45b3fb9c0550bd452c5424cccdf5c4a7e4e9b819abaef0bed9b24a3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 64f111753041dd647e73d863e011b23c3507cb930dcac40dd55f991d422802896cc6d515e998adf31be3a07962a38ac8b22e16490b3a56fcb3638441bd8d5d26
|
7
|
+
data.tar.gz: 24e97c6e52f38944a1947b50cb09347c3e5ebd457bcdb7bff0aff70aeac8412ed0a1ba8cfc85606d26886f30499c3981c4d4de414d2651c38d08f4104b362e79
|
@@ -26,6 +26,36 @@ export default class ContainerController extends Controller {
|
|
26
26
|
this.container.reset();
|
27
27
|
}
|
28
28
|
|
29
|
+
drop(event) {
|
30
|
+
this.container.reindex(); // set indexes before calculating previous
|
31
|
+
|
32
|
+
const item = getEventItem(event);
|
33
|
+
const previous = item.previousItem;
|
34
|
+
|
35
|
+
let delta = 0;
|
36
|
+
if (previous === undefined) {
|
37
|
+
// if previous does not exist, set depth to 0
|
38
|
+
delta = -item.depth;
|
39
|
+
} else if (
|
40
|
+
previous.isLayout &&
|
41
|
+
item.nextItem &&
|
42
|
+
item.nextItem.depth > previous.depth
|
43
|
+
) {
|
44
|
+
// if previous is a layout and next is a child of previous, make item a child of previous
|
45
|
+
delta = previous.depth - item.depth + 1;
|
46
|
+
} else {
|
47
|
+
// otherwise, make item a sibling of previous
|
48
|
+
delta = previous.depth - item.depth;
|
49
|
+
}
|
50
|
+
|
51
|
+
item.traverse((child) => {
|
52
|
+
child.depth += delta;
|
53
|
+
});
|
54
|
+
|
55
|
+
this.#update();
|
56
|
+
event.preventDefault();
|
57
|
+
}
|
58
|
+
|
29
59
|
remove(event) {
|
30
60
|
const item = getEventItem(event);
|
31
61
|
|
@@ -38,7 +68,9 @@ export default class ContainerController extends Controller {
|
|
38
68
|
nest(event) {
|
39
69
|
const item = getEventItem(event);
|
40
70
|
|
41
|
-
item.
|
71
|
+
item.traverse((child) => {
|
72
|
+
child.depth += 1;
|
73
|
+
});
|
42
74
|
|
43
75
|
this.#update();
|
44
76
|
event.preventDefault();
|
@@ -47,7 +79,9 @@ export default class ContainerController extends Controller {
|
|
47
79
|
deNest(event) {
|
48
80
|
const item = getEventItem(event);
|
49
81
|
|
50
|
-
item.
|
82
|
+
item.traverse((child) => {
|
83
|
+
child.depth -= 1;
|
84
|
+
});
|
51
85
|
|
52
86
|
this.#update();
|
53
87
|
event.preventDefault();
|
@@ -46,7 +46,7 @@ export default class ListController extends Controller {
|
|
46
46
|
}
|
47
47
|
|
48
48
|
drop(event) {
|
49
|
-
|
49
|
+
let item = this.dragItem();
|
50
50
|
|
51
51
|
if (!item) return;
|
52
52
|
|
@@ -55,17 +55,18 @@ export default class ListController extends Controller {
|
|
55
55
|
swap(this.dropTarget(event.target), item);
|
56
56
|
|
57
57
|
if (item.dataset.hasOwnProperty("newItem")) {
|
58
|
+
const placeholder = item;
|
58
59
|
const template = document.createElement("template");
|
59
60
|
template.innerHTML = event.dataTransfer.getData("text/html");
|
60
|
-
|
61
|
+
item = template.content.querySelector("li");
|
61
62
|
|
62
|
-
this.element.replaceChild(
|
63
|
+
this.element.replaceChild(item, placeholder);
|
63
64
|
setTimeout(() =>
|
64
|
-
|
65
|
+
item.querySelector("[role='button'][value='edit']").click()
|
65
66
|
);
|
66
67
|
}
|
67
68
|
|
68
|
-
this.
|
69
|
+
this.dispatch("drop", { target: item, bubbles: true, prefix: "content" });
|
69
70
|
}
|
70
71
|
|
71
72
|
dragend() {
|
@@ -25,7 +25,7 @@ delete Trix.config.blockAttributes.heading1;
|
|
25
25
|
* input does not permit. Uses a permissive regex pattern which is not suitable
|
26
26
|
* for untrusted use cases.
|
27
27
|
*/
|
28
|
-
const LINK_PATTERN = "(https
|
28
|
+
const LINK_PATTERN = "(https?|mailto:|tel:|/|#).*?";
|
29
29
|
|
30
30
|
/**
|
31
31
|
* Customize default toolbar:
|
@@ -76,3 +76,13 @@ Trix.config.toolbar.getDefaultHTML = () => {
|
|
76
76
|
</div>
|
77
77
|
`;
|
78
78
|
};
|
79
|
+
|
80
|
+
/**
|
81
|
+
* If the <trix-editor> element is in the HTML when Trix loads, then Trix will have already injected the toolbar content
|
82
|
+
* before our code gets a chance to run. Fix that now.
|
83
|
+
*
|
84
|
+
* Note: in Trix 2 this is likely to no longer be necessary.
|
85
|
+
*/
|
86
|
+
document.querySelectorAll("trix-toolbar").forEach((e) => {
|
87
|
+
e.innerHTML = Trix.config.toolbar.getDefaultHTML();
|
88
|
+
});
|
@@ -131,7 +131,7 @@ export default class Item {
|
|
131
131
|
|
132
132
|
callback(this);
|
133
133
|
this.#traverseCollapsed(callback);
|
134
|
-
expanded.forEach((item) =>
|
134
|
+
expanded.forEach((item) => item.#traverseCollapsed(callback));
|
135
135
|
}
|
136
136
|
|
137
137
|
/**
|
@@ -148,16 +148,6 @@ export default class Item {
|
|
148
148
|
});
|
149
149
|
}
|
150
150
|
|
151
|
-
/**
|
152
|
-
* Increase the depth of this item and its descendants.
|
153
|
-
* If this causes it to become a child of a collapsed item, then collapse this item.
|
154
|
-
*/
|
155
|
-
nest() {
|
156
|
-
this.traverse((child) => {
|
157
|
-
child.depth += 1;
|
158
|
-
});
|
159
|
-
}
|
160
|
-
|
161
151
|
/**
|
162
152
|
* Move the given item into this element's hidden children list.
|
163
153
|
* Assumes the list already exists.
|
@@ -168,15 +158,6 @@ export default class Item {
|
|
168
158
|
this.#childrenListElement.appendChild(item.node);
|
169
159
|
}
|
170
160
|
|
171
|
-
/**
|
172
|
-
* Decrease the depth of this item (and its descendants).
|
173
|
-
*/
|
174
|
-
deNest() {
|
175
|
-
this.traverse((child) => {
|
176
|
-
child.depth -= 1;
|
177
|
-
});
|
178
|
-
}
|
179
|
-
|
180
161
|
/**
|
181
162
|
* Collapses visible (logical) children into this element's hidden children
|
182
163
|
* list, creating it if it doesn't already exist.
|
@@ -59,7 +59,7 @@ export default class RulesEngine {
|
|
59
59
|
* First item can't have a parent, so its depth should always be 0
|
60
60
|
*/
|
61
61
|
firstItemDepthZero(item) {
|
62
|
-
if (item.index === 0 &&
|
62
|
+
if (item.index === 0 && item.depth !== 0) {
|
63
63
|
this.debug(`enforce depth on item ${item.index}: ${item.depth} => 0`);
|
64
64
|
|
65
65
|
item.depth = 0;
|
@@ -13,6 +13,10 @@ module Katalyst
|
|
13
13
|
render locals: { item: @container.items.build(item_params) }
|
14
14
|
end
|
15
15
|
|
16
|
+
def edit
|
17
|
+
render locals: { item: @item }
|
18
|
+
end
|
19
|
+
|
16
20
|
def create
|
17
21
|
@item = item = @container.items.build(item_params)
|
18
22
|
if item.save
|
@@ -22,10 +26,6 @@ module Katalyst
|
|
22
26
|
end
|
23
27
|
end
|
24
28
|
|
25
|
-
def edit
|
26
|
-
render locals: { item: @item }
|
27
|
-
end
|
28
|
-
|
29
29
|
def update
|
30
30
|
@item.attributes = item_params
|
31
31
|
|
@@ -6,6 +6,7 @@ module Katalyst
|
|
6
6
|
class Container < Base
|
7
7
|
ACTIONS = <<~ACTIONS.gsub(/\s+/, " ").freeze
|
8
8
|
submit->#{CONTAINER_CONTROLLER}#reindex
|
9
|
+
content:drop->#{CONTAINER_CONTROLLER}#drop
|
9
10
|
content:reindex->#{CONTAINER_CONTROLLER}#reindex
|
10
11
|
content:reset->#{CONTAINER_CONTROLLER}#reset
|
11
12
|
ACTIONS
|
@@ -13,12 +14,17 @@ module Katalyst
|
|
13
14
|
def build(options)
|
14
15
|
form_with(model: container, **default_options(id: container_form_id, **options)) do |form|
|
15
16
|
concat hidden_input
|
17
|
+
concat errors
|
16
18
|
concat(capture { yield form })
|
17
19
|
end
|
18
20
|
end
|
19
21
|
|
20
22
|
private
|
21
23
|
|
24
|
+
def errors
|
25
|
+
Editor::Errors.new(self, container).build
|
26
|
+
end
|
27
|
+
|
22
28
|
# Hidden input ensures that if the container is empty then the controller
|
23
29
|
# receives an empty array.
|
24
30
|
def hidden_input
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Katalyst
|
4
|
+
module Content
|
5
|
+
module Editor
|
6
|
+
class Errors < Base
|
7
|
+
def build(**options)
|
8
|
+
turbo_frame_tag dom_id(container, :errors) do
|
9
|
+
next unless container.errors.any?
|
10
|
+
|
11
|
+
tag.div(class: "content-errors", **options) do
|
12
|
+
tag.h2("Errors in content") +
|
13
|
+
tag.ul(class: "errors") do
|
14
|
+
container.errors.each do |error|
|
15
|
+
concat(tag.li(error.full_message))
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -25,6 +25,12 @@ module Katalyst
|
|
25
25
|
Editor::List.new(self, container).items(item)
|
26
26
|
end
|
27
27
|
|
28
|
+
# Generate a turbo stream fragment that will show structural errors to the user.
|
29
|
+
def content_editor_errors(container:, **options)
|
30
|
+
turbo_stream.replace(dom_id(container, :errors),
|
31
|
+
Editor::Errors.new(self, container).build(**options))
|
32
|
+
end
|
33
|
+
|
28
34
|
# Gene
|
29
35
|
def content_editor_new_item(item:, container: item.container, **options, &block)
|
30
36
|
Editor::NewItem.new(self, container).build(item, **options, &block)
|
@@ -95,6 +95,11 @@ module Katalyst
|
|
95
95
|
self
|
96
96
|
end
|
97
97
|
|
98
|
+
# Required for testing items validation
|
99
|
+
def items_attributes
|
100
|
+
draft_version&.nodes&.as_json
|
101
|
+
end
|
102
|
+
|
98
103
|
# Updates the current draft version with new structure. Attributes should be structural information about the
|
99
104
|
# items, e.g. `{index => {id:, depth:}` or `[{id:, depth:}]`.
|
100
105
|
#
|
@@ -13,6 +13,12 @@ module Katalyst
|
|
13
13
|
# rubocop:enable Rails/ReflectionClassName
|
14
14
|
|
15
15
|
attribute :nodes, Katalyst::Content::Types::NodesType.new, default: -> { [] }
|
16
|
+
|
17
|
+
validate :ensure_items_exists
|
18
|
+
end
|
19
|
+
|
20
|
+
def ensure_items_exists
|
21
|
+
parent.errors.add(:items, :missing_item) unless items.all?(&:present?)
|
16
22
|
end
|
17
23
|
|
18
24
|
def items
|
@@ -22,10 +28,10 @@ module Katalyst
|
|
22
28
|
|
23
29
|
items = parent.items.where(id: nodes.map(&:id)).index_by(&:id)
|
24
30
|
nodes.map do |node|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
31
|
+
items[node.id]&.tap do |item|
|
32
|
+
item.index = node.index
|
33
|
+
item.depth = node.depth
|
34
|
+
end
|
29
35
|
end
|
30
36
|
end
|
31
37
|
|
@@ -20,7 +20,7 @@ module Katalyst
|
|
20
20
|
# if image has changed, duplicate the change, otherwise attach the existing blob
|
21
21
|
if source.attachment_changes["image"]
|
22
22
|
self.image = source.attachment_changes["image"].attachable
|
23
|
-
elsif source.image.attached?
|
23
|
+
elsif source.image.attached? && !source.image.marked_for_destruction?
|
24
24
|
image.attach(source.image.blob)
|
25
25
|
end
|
26
26
|
end
|
@@ -11,7 +11,7 @@ module Katalyst
|
|
11
11
|
belongs_to :container, polymorphic: true
|
12
12
|
|
13
13
|
validates :heading, presence: true
|
14
|
-
validates :background, presence: true, inclusion: { in: config.backgrounds }
|
14
|
+
validates :background, presence: true, inclusion: { in: config.backgrounds }, if: :validate_background?
|
15
15
|
|
16
16
|
after_initialize :initialize_tree
|
17
17
|
|
@@ -43,6 +43,10 @@ module Katalyst
|
|
43
43
|
self.parent ||= nil
|
44
44
|
self.children ||= []
|
45
45
|
end
|
46
|
+
|
47
|
+
def validate_background?
|
48
|
+
true
|
49
|
+
end
|
46
50
|
end
|
47
51
|
end
|
48
52
|
end
|
@@ -2,16 +2,10 @@
|
|
2
2
|
<%= render "hidden_fields", form: form %>
|
3
3
|
<%= render "form_errors", form: form %>
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
<%= builder.preview class: "image-wrapper" %>
|
10
|
-
</div>
|
11
|
-
<%= form.file_field :image, **builder.file_input_options %>
|
12
|
-
<hint><%= builder.hint_text %></hint>
|
13
|
-
</div>
|
14
|
-
<% end %>
|
5
|
+
<div class="field">
|
6
|
+
<%= form.label :image %>
|
7
|
+
<%= form.file_field :image %>
|
8
|
+
</div>
|
15
9
|
|
16
10
|
<div class="field">
|
17
11
|
<%= form.label :heading %>
|
data/config/locales/en.yml
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: katalyst-content
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Katalyst Interactive
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-11-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: active_storage_validations
|
@@ -35,7 +35,6 @@ files:
|
|
35
35
|
- README.md
|
36
36
|
- app/assets/config/katalyst-content.js
|
37
37
|
- app/assets/javascripts/controllers/content/editor/container_controller.js
|
38
|
-
- app/assets/javascripts/controllers/content/editor/image_field_controller.js
|
39
38
|
- app/assets/javascripts/controllers/content/editor/item_controller.js
|
40
39
|
- app/assets/javascripts/controllers/content/editor/list_controller.js
|
41
40
|
- app/assets/javascripts/controllers/content/editor/new_item_controller.js
|
@@ -58,7 +57,7 @@ files:
|
|
58
57
|
- app/controllers/katalyst/content/items_controller.rb
|
59
58
|
- app/helpers/katalyst/content/editor/base.rb
|
60
59
|
- app/helpers/katalyst/content/editor/container.rb
|
61
|
-
- app/helpers/katalyst/content/editor/
|
60
|
+
- app/helpers/katalyst/content/editor/errors.rb
|
62
61
|
- app/helpers/katalyst/content/editor/item.rb
|
63
62
|
- app/helpers/katalyst/content/editor/list.rb
|
64
63
|
- app/helpers/katalyst/content/editor/new_item.rb
|
@@ -1,90 +0,0 @@
|
|
1
|
-
import { Controller } from "@hotwired/stimulus";
|
2
|
-
|
3
|
-
export default class ImageFieldController extends Controller {
|
4
|
-
static targets = ["preview"];
|
5
|
-
static values = {
|
6
|
-
mimeTypes: Array,
|
7
|
-
};
|
8
|
-
|
9
|
-
#counter = 0;
|
10
|
-
|
11
|
-
onUpload(event) {
|
12
|
-
this.previewTarget.classList.remove("hidden");
|
13
|
-
|
14
|
-
const reader = new FileReader();
|
15
|
-
|
16
|
-
reader.onload = (e) => {
|
17
|
-
this.imageTag.src = e.target.result;
|
18
|
-
};
|
19
|
-
|
20
|
-
reader.readAsDataURL(event.currentTarget.files[0]);
|
21
|
-
}
|
22
|
-
|
23
|
-
drop(event) {
|
24
|
-
event.preventDefault();
|
25
|
-
|
26
|
-
const file = fileForEvent(event, this.mimeTypesValue);
|
27
|
-
if (file) {
|
28
|
-
const dT = new DataTransfer();
|
29
|
-
dT.items.add(file);
|
30
|
-
this.fileInput.files = dT.files;
|
31
|
-
this.fileInput.dispatchEvent(new Event("change"));
|
32
|
-
}
|
33
|
-
|
34
|
-
this.#counter = 0;
|
35
|
-
this.element.classList.remove("droppable");
|
36
|
-
}
|
37
|
-
|
38
|
-
dragover(event) {
|
39
|
-
event.preventDefault();
|
40
|
-
}
|
41
|
-
|
42
|
-
dragenter(event) {
|
43
|
-
event.preventDefault();
|
44
|
-
|
45
|
-
if (this.#counter === 0) {
|
46
|
-
this.element.classList.add("droppable");
|
47
|
-
}
|
48
|
-
this.#counter++;
|
49
|
-
}
|
50
|
-
|
51
|
-
dragleave(event) {
|
52
|
-
event.preventDefault();
|
53
|
-
|
54
|
-
this.#counter--;
|
55
|
-
if (this.#counter === 0) {
|
56
|
-
this.element.classList.remove("droppable");
|
57
|
-
}
|
58
|
-
}
|
59
|
-
|
60
|
-
get fileInput() {
|
61
|
-
return this.element.querySelector("input[type='file']");
|
62
|
-
}
|
63
|
-
|
64
|
-
get imageTag() {
|
65
|
-
return this.previewTarget.querySelector("img");
|
66
|
-
}
|
67
|
-
}
|
68
|
-
|
69
|
-
/**
|
70
|
-
* Given a drop event, find the first acceptable file.
|
71
|
-
* @param event {DropEvent}
|
72
|
-
* @param mimeTypes {String[]}
|
73
|
-
* @returns {File}
|
74
|
-
*/
|
75
|
-
function fileForEvent(event, mimeTypes) {
|
76
|
-
const accept = (file) => mimeTypes.indexOf(file.type) > -1;
|
77
|
-
|
78
|
-
let file;
|
79
|
-
|
80
|
-
if (event.dataTransfer.items) {
|
81
|
-
const item = [...event.dataTransfer.items].find(accept);
|
82
|
-
if (item) {
|
83
|
-
file = item.getAsFile();
|
84
|
-
}
|
85
|
-
} else {
|
86
|
-
file = [...event.dataTransfer.files].find(accept);
|
87
|
-
}
|
88
|
-
|
89
|
-
return file;
|
90
|
-
}
|
@@ -1,72 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Katalyst
|
4
|
-
module Content
|
5
|
-
module Editor
|
6
|
-
class ImageField < Base
|
7
|
-
IMAGE_FIELD_CONTROLLER = "content--editor--image-field"
|
8
|
-
|
9
|
-
ACTIONS = <<~ACTIONS.gsub(/\s+/, " ").freeze
|
10
|
-
dragover->#{IMAGE_FIELD_CONTROLLER}#dragover
|
11
|
-
dragenter->#{IMAGE_FIELD_CONTROLLER}#dragenter
|
12
|
-
dragleave->#{IMAGE_FIELD_CONTROLLER}#dragleave
|
13
|
-
drop->#{IMAGE_FIELD_CONTROLLER}#drop
|
14
|
-
ACTIONS
|
15
|
-
|
16
|
-
attr_accessor :item, :method
|
17
|
-
|
18
|
-
def build(item, method, **options, &block)
|
19
|
-
self.item = item
|
20
|
-
self.method = method
|
21
|
-
|
22
|
-
tag.div **default_options(**options) do
|
23
|
-
concat(capture { yield self }) if block
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
def preview(**options)
|
28
|
-
add_option(options, :data, "#{IMAGE_FIELD_CONTROLLER}_target", "preview")
|
29
|
-
add_option(options, :class, "hidden") unless preview?
|
30
|
-
|
31
|
-
tag.div **options do
|
32
|
-
image_tag preview_url, class: "image-thumbnail"
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def file_input_options(options = {})
|
37
|
-
add_option(options, :accept, config.image_mime_types.join(","))
|
38
|
-
add_option(options, :data, :action, "change->#{IMAGE_FIELD_CONTROLLER}#onUpload")
|
39
|
-
|
40
|
-
options
|
41
|
-
end
|
42
|
-
|
43
|
-
def hint_text
|
44
|
-
t("views.katalyst.content.item.size_hint", max_size: number_to_human_size(config.max_image_size.megabytes))
|
45
|
-
end
|
46
|
-
|
47
|
-
def preview?
|
48
|
-
value&.attached? && value&.persisted?
|
49
|
-
end
|
50
|
-
|
51
|
-
def preview_url
|
52
|
-
preview? ? main_app.url_for(value) : ""
|
53
|
-
end
|
54
|
-
|
55
|
-
def value
|
56
|
-
item.send(method)
|
57
|
-
end
|
58
|
-
|
59
|
-
private
|
60
|
-
|
61
|
-
def default_options(**options)
|
62
|
-
add_option(options, :data, :controller, IMAGE_FIELD_CONTROLLER)
|
63
|
-
add_option(options, :data, :action, ACTIONS)
|
64
|
-
add_option(options, :data, :"#{IMAGE_FIELD_CONTROLLER}_mime_types_value",
|
65
|
-
config.image_mime_types.to_json)
|
66
|
-
|
67
|
-
options
|
68
|
-
end
|
69
|
-
end
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|