effective_bootstrap 0.9.38 → 0.9.42
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/effective_article_editor/initialize.js.coffee +25 -2
- data/app/assets/javascripts/effective_bootstrap/confirm.js.coffee.erb +15 -7
- data/app/assets/javascripts/effective_file/initialize.js.coffee +6 -1
- data/app/assets/javascripts/effective_has_many/initialize.js.coffee +20 -1
- data/app/assets/stylesheets/effective_bootstrap/base.scss +1 -1
- data/app/assets/stylesheets/effective_bootstrap/collapse.scss +7 -0
- data/app/assets/stylesheets/effective_has_many/input.scss +4 -0
- data/app/helpers/effective_bootstrap_helper.rb +70 -18
- data/app/models/effective/form_inputs/article_editor.rb +2 -1
- data/app/models/effective/form_inputs/has_many.rb +71 -7
- data/lib/effective_bootstrap/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5bfd09a27598da184de3a2f8208d36db4ac3021c76946dc45f7c7c81ed0d0b1f
|
4
|
+
data.tar.gz: e62446f65854520af700752157415cf606d18b43ac631726394c26895a8df705
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2ca774aa86d286554166d8780d0a8ba4ddbe187f4decb5295e83728d63b5b5eb7723abd5bf1aa74881ca36c983c94d2fc8b88fb6ed58fbdc7759287ae7886a70
|
7
|
+
data.tar.gz: 9f15e36d568891a388fd9c788887f9fadd195d5bc81d06bf04ba899161a76a55a676850311f41efbb0ec55458b523091c36ca86ddfe430e282b9d402d875fdd7
|
@@ -6,7 +6,25 @@ uploadActiveStorage = (editor, data) ->
|
|
6
6
|
|
7
7
|
upload.create (error, blob) =>
|
8
8
|
url = '/rails/active_storage/blobs/redirect/' + blob.signed_id + '/' + blob.filename
|
9
|
-
editor.complete({ file: { url: url }}, data.e)
|
9
|
+
editor.complete({ file: { url: url, name: blob.filename, content_type: blob.content_type }}, data.e)
|
10
|
+
|
11
|
+
insertUploadByDrop = (response, e) ->
|
12
|
+
if @app.block.is()
|
13
|
+
instance = @app.block.get()
|
14
|
+
target = e.target
|
15
|
+
type = instance.getType()
|
16
|
+
|
17
|
+
if ((type == 'card' && target && target.tagName == 'IMG' && instance.hasImage()) || type == 'image')
|
18
|
+
return @change(response)
|
19
|
+
else if (e && type != 'card' && instance.isEditable())
|
20
|
+
@app.insertion.insertPoint(e)
|
21
|
+
|
22
|
+
content_type = (response.file.content_type || '')
|
23
|
+
|
24
|
+
unless content_type.startsWith('image') && @app.filelink
|
25
|
+
@app.filelink._insert(response)
|
26
|
+
else
|
27
|
+
@insert(response)
|
10
28
|
|
11
29
|
(this.EffectiveBootstrap || {}).effective_article_editor = ($element, options) ->
|
12
30
|
|
@@ -15,4 +33,9 @@ uploadActiveStorage = (editor, data) ->
|
|
15
33
|
upload: (editor, data) -> uploadActiveStorage(editor, data)
|
16
34
|
}
|
17
35
|
|
18
|
-
|
36
|
+
options['filelink'] = {
|
37
|
+
upload: (editor, data) -> uploadActiveStorage(editor, data)
|
38
|
+
}
|
39
|
+
|
40
|
+
editor = ArticleEditor($element, options)
|
41
|
+
editor.app.image.insertByDrop = insertUploadByDrop
|
@@ -4,19 +4,27 @@ if <%= !!EffectiveBootstrap.use_custom_data_confirm %> && (window.Rails || $.rai
|
|
4
4
|
$(document).on 'confirm', (event) ->
|
5
5
|
$obj = $(event.target)
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
7
|
+
# Already confirmed
|
8
|
+
return true if $obj.data('confirmed')
|
9
|
+
|
10
|
+
# Otherwise unconfirmed
|
11
|
+
$obj.data('confirm-original', $obj.html())
|
12
|
+
$obj.html($obj.data('confirm'))
|
13
|
+
$obj.data('confirmed', true)
|
14
|
+
|
15
|
+
# When using the direct to s3 active storage javascript library
|
16
|
+
$activeStorageUpload = $obj.closest('form').find('input[type=file][data-direct-upload-url]')
|
17
|
+
|
18
|
+
if $activeStorageUpload.length == 0
|
13
19
|
setTimeout(
|
14
20
|
(->
|
15
21
|
$obj.data('confirmed', false)
|
16
22
|
$obj.html($obj.data('confirm-original'))
|
17
23
|
)
|
18
24
|
, 4000)
|
19
|
-
|
25
|
+
|
26
|
+
# Do not display the confirmation dialog
|
27
|
+
false
|
20
28
|
|
21
29
|
if window.Rails
|
22
30
|
window.Rails.confirm = (message) -> true
|
@@ -13,7 +13,12 @@ $(document).on 'direct-upload:error', (event) ->
|
|
13
13
|
$("[data-direct-upload-id=#{event.detail.id}]").addClass('direct-upload--error').attr('title', event.detail.error)
|
14
14
|
|
15
15
|
$(document).on 'direct-upload:end', (event) ->
|
16
|
-
$("[data-direct-upload-id=#{event.detail.id}]")
|
16
|
+
$obj = $("[data-direct-upload-id=#{event.detail.id}]")
|
17
|
+
|
18
|
+
$obj.addClass('direct-upload--complete')
|
19
|
+
|
20
|
+
# Rails UJS fix
|
21
|
+
$obj.closest('form').find('[type=submit][data-confirm]').data('confirmed', true)
|
17
22
|
|
18
23
|
$(document).on 'change', "input[type='file'][data-click-submit]", (event) ->
|
19
24
|
$(event.currentTarget).closest('form').find('button[type=submit],input[type=submit]').first().click()
|
@@ -36,8 +36,27 @@ $(document).on 'click', '[data-effective-form-has-many-add]', (event) ->
|
|
36
36
|
template = atob($obj.data('effective-form-has-many-template')).replace(/HASMANYINDEX/g, uid)
|
37
37
|
|
38
38
|
$fields = $(template).hide().fadeIn('fast')
|
39
|
-
EffectiveBootstrap.initialize($fields)
|
40
39
|
$obj.closest('.has-many-links').before($fields)
|
40
|
+
EffectiveBootstrap.initialize($fields)
|
41
|
+
|
42
|
+
assignPositions($hasMany)
|
43
|
+
true
|
44
|
+
|
45
|
+
$(document).on 'click', '[data-effective-form-has-many-insert]', (event) ->
|
46
|
+
event.preventDefault()
|
47
|
+
|
48
|
+
$obj = $(event.currentTarget)
|
49
|
+
$hasMany = $obj.closest('.form-has-many')
|
50
|
+
return unless $hasMany.length > 0
|
51
|
+
|
52
|
+
$add = $hasMany.children('.has-many-links').find('[data-effective-form-has-many-template]')
|
53
|
+
|
54
|
+
uid = (new Date).valueOf()
|
55
|
+
template = atob($add.data('effective-form-has-many-template')).replace(/HASMANYINDEX/g, uid)
|
56
|
+
|
57
|
+
$fields = $(template).hide().fadeIn('fast')
|
58
|
+
$obj.closest('.has-many-fields').before($fields)
|
59
|
+
EffectiveBootstrap.initialize($fields)
|
41
60
|
|
42
61
|
assignPositions($hasMany)
|
43
62
|
true
|
@@ -3,12 +3,16 @@
|
|
3
3
|
.has-many-move { display: none; }
|
4
4
|
.has-many-remove-disabled { opacity: 0; cursor: default !important; }
|
5
5
|
|
6
|
+
.has-many-actions { margin-bottom: 0.75rem; }
|
6
7
|
.has-many-remove { margin-top: 1rem; }
|
7
8
|
.has-many-move { margin-top: 1.5rem; }
|
8
9
|
}
|
9
10
|
|
10
11
|
.form-has-many.reordering {
|
12
|
+
.has-many-actions { display: none; }
|
11
13
|
.has-many-move { display: inline-block; cursor: grab; }
|
14
|
+
|
15
|
+
.form-has-many { display: none; }
|
12
16
|
}
|
13
17
|
|
14
18
|
.form-has-many.tight {
|
@@ -18,6 +18,31 @@ module EffectiveBootstrapHelper
|
|
18
18
|
content
|
19
19
|
end
|
20
20
|
|
21
|
+
def accordion_collapse(label, opts = {}, &block)
|
22
|
+
raise 'expected a block' unless block_given?
|
23
|
+
|
24
|
+
id = "collapse-#{effective_bootstrap_unique_id}"
|
25
|
+
show = (opts.delete(:show) == true)
|
26
|
+
|
27
|
+
link_opts = { 'data-toggle': 'collapse', role: 'button', href: "##{id}", 'aria-controls': "##{id}", 'aria-expanded': show }
|
28
|
+
|
29
|
+
link_opts[:class] = opts.delete(:link_class) || 'btn btn-link'
|
30
|
+
div_class = opts.delete(:div_class)
|
31
|
+
card_class = opts.delete(:card_class) || 'card card-body my-2'
|
32
|
+
|
33
|
+
# Accordion collapse
|
34
|
+
content_tag(:div, class: "card mb-0") do
|
35
|
+
content_tag(:div, class: "card-header") do
|
36
|
+
content_tag(:h2, class: "mb-0") do
|
37
|
+
content_tag(:button, label, link_opts.merge(class: "btn btn-link"))
|
38
|
+
end
|
39
|
+
end +
|
40
|
+
content_tag(:div, id: id, class: ['collapse', div_class, ('show' if show)].compact.join(' '), "data-parent": "##{@_accordion_active}") do
|
41
|
+
content_tag(:div, capture(&block), class: "card-body")
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
21
46
|
# https://getbootstrap.com/docs/4.0/components/card/
|
22
47
|
# = card('title do')
|
23
48
|
# %p Stuff
|
@@ -56,40 +81,67 @@ module EffectiveBootstrapHelper
|
|
56
81
|
# = collapse('already expanded', show: true) do
|
57
82
|
# %p Something Expanded
|
58
83
|
|
84
|
+
# the word 'show' will automatically be replaced with hide and an icon added
|
85
|
+
# = collapse('show items') do
|
86
|
+
# %p Something Expanded
|
87
|
+
|
88
|
+
# Override the expand and collapse labels directly
|
89
|
+
# = collapse('show items', expand: "Show items" + icon('ok'), collapse: "Hide items" + icon('x')) do
|
90
|
+
# %p Something Expanded
|
91
|
+
|
59
92
|
# collapse(items.length, class: 'btn btn-primary', class: 'mt-2') do
|
60
93
|
# items.map { |item| content_tag(:div, item.to_s) }.join.html_safe
|
61
94
|
# end
|
95
|
+
|
96
|
+
COLLAPSE_SUBSTITUTIONS = {
|
97
|
+
'Show ' => 'Hide ',
|
98
|
+
'show ' => 'hide ',
|
99
|
+
'Expand ' => 'Collapse ',
|
100
|
+
'expand ' => 'collapse ',
|
101
|
+
' More' => ' Less',
|
102
|
+
' more' => ' less'
|
103
|
+
}
|
104
|
+
|
62
105
|
def collapse(label, opts = {}, &block)
|
63
106
|
raise 'expected a block' unless block_given?
|
64
107
|
|
108
|
+
return accordian_collapse(label, opts, &block) if @_accordion_active
|
109
|
+
|
65
110
|
id = "collapse-#{effective_bootstrap_unique_id}"
|
66
111
|
show = (opts.delete(:show) == true)
|
67
112
|
|
113
|
+
# Figure out all the button / link options
|
68
114
|
link_opts = { 'data-toggle': 'collapse', role: 'button', href: "##{id}", 'aria-controls': "##{id}", 'aria-expanded': show }
|
69
115
|
|
116
|
+
# Two link labels
|
117
|
+
label_expand = opts.delete(:expand) || label.to_s.tap do |label|
|
118
|
+
COLLAPSE_SUBSTITUTIONS.each { |show, hide| label.sub!(hide, show) }
|
119
|
+
end + icon('chevron-down')
|
120
|
+
|
121
|
+
label_collapse = opts.delete(:collapse) || label.to_s.tap do |label|
|
122
|
+
COLLAPSE_SUBSTITUTIONS.each { |show, hide| label.sub!(show, hide) }
|
123
|
+
end + icon('chevron-up')
|
124
|
+
|
125
|
+
# The link html classes
|
70
126
|
link_opts[:class] = opts.delete(:link_class) || 'btn btn-link'
|
127
|
+
link_opts[:class] += ' effective-collapse-actions hidden-print'
|
128
|
+
link_opts[:class] += ' collapsed' unless show
|
129
|
+
|
130
|
+
# The div and the card now
|
71
131
|
div_class = opts.delete(:div_class)
|
72
132
|
card_class = opts.delete(:card_class) || 'card card-body my-2'
|
73
133
|
|
74
|
-
|
75
|
-
|
76
|
-
content_tag(:div, class:
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
content_tag(:div, id: id, class: ['collapse', div_class, ('show' if show)].compact.join(' '), "data-parent": "##{@_accordion_active}") do
|
83
|
-
content_tag(:div, capture(&block), class: "card-body")
|
84
|
-
end
|
85
|
-
end
|
86
|
-
else
|
87
|
-
# Normal collapse
|
88
|
-
content_tag(:a, label, link_opts) +
|
89
|
-
content_tag(:div, id: id, class: ['collapse', div_class, ('show' if show)].compact.join(' ')) do
|
90
|
-
content_tag(:div, capture(&block), class: card_class)
|
91
|
-
end
|
134
|
+
# Normal collapse
|
135
|
+
link_tag = content_tag(:a, link_opts) do
|
136
|
+
content_tag(:div, label_expand.html_safe, class: 'collapse-label-expand') +
|
137
|
+
content_tag(:div, label_collapse.html_safe, class: 'collapse-label-collapse')
|
138
|
+
end
|
139
|
+
|
140
|
+
div_tag = content_tag(:div, id: id, class: ['effective-collapse collapse', div_class, ('show' if show)].compact.join(' ')) do
|
141
|
+
content_tag(:div, capture(&block), class: card_class)
|
92
142
|
end
|
143
|
+
|
144
|
+
link_tag + div_tag
|
93
145
|
end
|
94
146
|
|
95
147
|
# Button Dropdowns
|
@@ -14,6 +14,7 @@ module Effective
|
|
14
14
|
body: 'article-editor-body',
|
15
15
|
table: 'table'
|
16
16
|
},
|
17
|
+
filelink: nil,
|
17
18
|
grid: {
|
18
19
|
classname: 'row',
|
19
20
|
columns: 12,
|
@@ -40,7 +41,7 @@ module Effective
|
|
40
41
|
'12': 'col-sm-12'
|
41
42
|
}
|
42
43
|
},
|
43
|
-
plugins: ['blockcode', 'cellcolor', 'imageposition', 'imageresize', 'inlineformat', 'listitem', 'removeformat', 'reorder', 'style'],
|
44
|
+
plugins: ['blockcode', 'cellcolor', 'imageposition', 'imageresize', 'inlineformat', 'listitem', 'removeformat', 'reorder', 'style', 'filelink'],
|
44
45
|
quote: {
|
45
46
|
template: '<blockquote><p></p></blockquote>'
|
46
47
|
},
|
@@ -51,6 +51,20 @@ module Effective
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
+
# insert: false
|
55
|
+
def insert
|
56
|
+
return @insert unless @insert.nil?
|
57
|
+
|
58
|
+
@insert ||= begin
|
59
|
+
insert = options[:input].delete(:insert)
|
60
|
+
insert.nil? ? false : insert
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def insert?
|
65
|
+
!!insert
|
66
|
+
end
|
67
|
+
|
54
68
|
# errors: true
|
55
69
|
def errors?
|
56
70
|
return @errors unless @errors.nil?
|
@@ -62,7 +76,7 @@ module Effective
|
|
62
76
|
end
|
63
77
|
|
64
78
|
# remove: true
|
65
|
-
def remove
|
79
|
+
def remove
|
66
80
|
return @remove unless @remove.nil?
|
67
81
|
|
68
82
|
@remove ||= begin
|
@@ -77,6 +91,10 @@ module Effective
|
|
77
91
|
end
|
78
92
|
end
|
79
93
|
|
94
|
+
def remove?
|
95
|
+
!!remove
|
96
|
+
end
|
97
|
+
|
80
98
|
def can_remove_method
|
81
99
|
return @can_remove_method unless @can_remove_method.nil?
|
82
100
|
@can_remove_method = (options[:input].delete(:can_remove_method) || false)
|
@@ -114,6 +132,7 @@ module Effective
|
|
114
132
|
def render_resource(resource, block)
|
115
133
|
remove = BLANK
|
116
134
|
reorder = BLANK
|
135
|
+
insert = BLANK
|
117
136
|
can_remove = (can_remove_method.blank? || !!resource.send(can_remove_method))
|
118
137
|
|
119
138
|
content = @builder.fields_for(name, resource) do |form|
|
@@ -129,7 +148,11 @@ module Effective
|
|
129
148
|
remove += (can_remove || resource.new_record?) ? link_to_remove(resource) : disabled_link_to_remove(resource)
|
130
149
|
end
|
131
150
|
|
132
|
-
|
151
|
+
if insert?
|
152
|
+
insert = render_insert() if add? && reorder?
|
153
|
+
end
|
154
|
+
|
155
|
+
content_tag(:div, insert + render_fields(content, remove + reorder), class: 'has-many-fields')
|
133
156
|
end
|
134
157
|
|
135
158
|
def render_fields(content, remove)
|
@@ -141,12 +164,25 @@ module Effective
|
|
141
164
|
content_tag(:div, remove, class: 'col-auto')
|
142
165
|
end
|
143
166
|
when :cards
|
144
|
-
|
167
|
+
content_tag(:div, class: 'form-row mb-3') do
|
168
|
+
(reorder? ? content_tag(:div, has_many_move, class: 'col-auto') : BLANK) +
|
169
|
+
content_tag(:div, content, class: 'col mr-auto') do
|
170
|
+
content_tag(:div, class: 'card') do
|
171
|
+
content_tag(:div, class: 'card-body') do
|
172
|
+
content_tag(:div, remove, class: 'float-right') + content
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
145
177
|
else
|
146
178
|
content + remove
|
147
179
|
end
|
148
180
|
end
|
149
181
|
|
182
|
+
def render_insert()
|
183
|
+
content_tag(:div, link_to_insert(), class: 'has-many-actions')
|
184
|
+
end
|
185
|
+
|
150
186
|
def render_template(block)
|
151
187
|
resource = build_resource()
|
152
188
|
index = collection.length
|
@@ -176,6 +212,27 @@ module Effective
|
|
176
212
|
)
|
177
213
|
end
|
178
214
|
|
215
|
+
# f.has_many :things, insert: { label: (icon('plus-circle') + 'Insert Article') }
|
216
|
+
# f.has_many :things, insert: (icon('plus-circle') + 'Insert Article')
|
217
|
+
def link_to_insert
|
218
|
+
tag = (insert[:tag] if insert.kind_of?(Hash))
|
219
|
+
title = (insert[:title] || insert[:label] if insert.kind_of?(Hash))
|
220
|
+
html_class = (insert[:class] if insert.kind_of?(Hash))
|
221
|
+
|
222
|
+
label = (insert[:label] if insert.kind_of?(Hash))
|
223
|
+
label = insert if insert.kind_of?(String)
|
224
|
+
|
225
|
+
content_tag(
|
226
|
+
(tag || :button),
|
227
|
+
(label || (icon('plus-circle') + 'Insert Another')),
|
228
|
+
class: 'has-many-insert ' + (html_class || 'btn btn-secondary'),
|
229
|
+
title: (title || 'Insert Another'),
|
230
|
+
data: {
|
231
|
+
'effective-form-has-many-insert': true,
|
232
|
+
}
|
233
|
+
)
|
234
|
+
end
|
235
|
+
|
179
236
|
def link_to_reorder(block)
|
180
237
|
content_tag(
|
181
238
|
:button,
|
@@ -189,11 +246,18 @@ module Effective
|
|
189
246
|
end
|
190
247
|
|
191
248
|
def link_to_remove(resource)
|
249
|
+
tag = (remove[:tag] if remove.kind_of?(Hash))
|
250
|
+
title = (remove[:title] || remove[:label] if remove.kind_of?(Hash))
|
251
|
+
html_class = (remove[:class] if remove.kind_of?(Hash))
|
252
|
+
|
253
|
+
label = (remove[:label] if remove.kind_of?(Hash))
|
254
|
+
label = remove if remove.kind_of?(String)
|
255
|
+
|
192
256
|
content_tag(
|
193
|
-
:button,
|
194
|
-
icon('trash-2'),
|
195
|
-
class: 'has-many-remove btn btn-danger',
|
196
|
-
title: 'Remove',
|
257
|
+
(tag || :button),
|
258
|
+
(label || icon('trash-2')),
|
259
|
+
class: 'has-many-remove ' + (html_class || 'btn btn-danger'),
|
260
|
+
title: (title || 'Remove'),
|
197
261
|
data: {
|
198
262
|
'confirm': "Remove #{resource}?",
|
199
263
|
'effective-form-has-many-remove': true,
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: effective_bootstrap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.9.
|
4
|
+
version: 0.9.42
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Code and Effect
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-09-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rails
|
@@ -615,6 +615,7 @@ files:
|
|
615
615
|
- app/assets/stylesheets/effective_article_editor/input.scss
|
616
616
|
- app/assets/stylesheets/effective_bootstrap.scss
|
617
617
|
- app/assets/stylesheets/effective_bootstrap/base.scss
|
618
|
+
- app/assets/stylesheets/effective_bootstrap/collapse.scss
|
618
619
|
- app/assets/stylesheets/effective_bootstrap/forms.scss
|
619
620
|
- app/assets/stylesheets/effective_bootstrap/icons.scss
|
620
621
|
- app/assets/stylesheets/effective_bootstrap/overrides.scss
|