effective_bootstrap 0.9.37 → 0.9.41

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b1772102ddc52f73871d564739ecf3ed9edd05d7213764f9820ffcaddddd5341
4
- data.tar.gz: 4767059a01a6d4b34eb6a325f5ab14c941e1de8cef6f01f8542fd9dda7956a2a
3
+ metadata.gz: 2b496c8193535d6f7bb0a74e49665dec14d0330b26682753c5b8721a00da0288
4
+ data.tar.gz: 20d00e39d97d38d350f81c69abb3fbe35a4e9950b5807108a1c5b819cf596545
5
5
  SHA512:
6
- metadata.gz: 26050084b30228053d8cd328e30d1f48668ed640a951074060d21db38d102560fc7fa4ae15f7b5bf16459fc65f0cccc552fd749546b9bf5054b2b30353249502
7
- data.tar.gz: 5e3c97e66bd4bf2f6288f302a94adb085a6723fdebd6a1ead7661e8602249048814d1fcaa54d6a60f9f94bc24eee287494de9fbc5e424eaedddf0add94b58504
6
+ metadata.gz: 4e8e3c0416424d8f2a675f704a7088b9a5edbc8cbb26d8d8853ad1b9c7d2dac98cf2c7a4352e23ad9a5fd6398c7713d7602cd552e9d95311cf74ea0fdc1b0e51
7
+ data.tar.gz: 5c5bd0a118f9a68b8901fab25692e95a1728ebdb9a00744a93567fe1185fc23f02d4948609906c75b949440e1340ceaa298fb053f5807cd24195bc825fc2666d
@@ -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
- ArticleEditor($element, options)
36
+ options['filelink'] = {
37
+ upload: (editor, data) -> uploadActiveStorage(editor, data)
38
+ }
39
+
40
+ editor = ArticleEditor($element, options)
41
+ editor.app.image.insertByDrop = insertUploadByDrop
@@ -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
@@ -1,4 +1,4 @@
1
+ @import './collapse';
1
2
  @import './forms';
2
3
  @import './icons';
3
4
  @import './overrides';
4
-
@@ -0,0 +1,7 @@
1
+ .effective-collapse-actions {
2
+ .collapse-label-expand { display: none; }
3
+ .collapse-label-collapse { display: inline-block; }
4
+
5
+ &.collapsed .collapse-label-expand { display: inline-block; }
6
+ &.collapsed .collapse-label-collapse { display: none; }
7
+ }
@@ -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 {
@@ -10,7 +10,7 @@ module EffectiveBootstrapHelper
10
10
  def accordion(options = nil, &block)
11
11
  (options ||= {})[:class] = "accordion #{options.delete(:class)}".strip
12
12
 
13
- id = "accordion-#{String.new.object_id}"
13
+ id = "accordion-#{effective_bootstrap_unique_id}"
14
14
 
15
15
  @_accordion_active = id
16
16
  content = content_tag(:div, capture(&block), options.merge(id: id))
@@ -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
 
65
- id = "collapse-#{String.new.object_id}"
108
+ return accordian_collapse(label, opts, &block) if @_accordion_active
109
+
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
- if @_accordion_active
75
- # Accordion collapse
76
- content_tag(:div, class: "card mb-0") do
77
- content_tag(:div, class: "card-header") do
78
- content_tag(:h2, class: "mb-0") do
79
- content_tag(:button, label, link_opts.merge(class: "btn btn-link"))
80
- end
81
- end +
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')
92
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)
142
+ end
143
+
144
+ link_tag + div_tag
93
145
  end
94
146
 
95
147
  # Button Dropdowns
@@ -259,7 +311,7 @@ module EffectiveBootstrapHelper
259
311
  def nav_dropdown(label, right: false, link_class: [], list_class: [], &block)
260
312
  raise 'expected a block' unless block_given?
261
313
 
262
- id = "dropdown-#{String.new.object_id}"
314
+ id = "dropdown-#{effective_bootstrap_unique_id}"
263
315
 
264
316
  content_tag(:li, class: 'nav-item dropdown') do
265
317
  content_tag(:a, class: 'nav-link dropdown-toggle', href: '#', id: id, role: 'button', 'data-toggle': 'dropdown', 'aria-haspopup': true, 'aria-expanded': false) do
@@ -436,7 +488,7 @@ module EffectiveBootstrapHelper
436
488
 
437
489
  @_tab_mode = :tablist
438
490
  @_tab_active = (active || :first)
439
- @_tab_unique = String.new.object_id if unique
491
+ @_tab_unique = effective_bootstrap_unique_id if unique
440
492
 
441
493
  content_tag(:ul, {class: 'nav nav-tabs', role: 'tablist'}.merge(list)) do
442
494
  yield # Yield to tab the first time
@@ -476,7 +528,7 @@ module EffectiveBootstrapHelper
476
528
 
477
529
  @_tab_mode = :tablist_vertical
478
530
  @_tab_active = (active || :first)
479
- @_tab_unique = String.new.object_id if unique
531
+ @_tab_unique = effective_bootstrap_unique_id if unique
480
532
 
481
533
  content_tag(:div, class: 'row border') do
482
534
  content_tag(:div, class: 'col-3 border-right') do
@@ -504,4 +556,15 @@ module EffectiveBootstrapHelper
504
556
  end
505
557
  end
506
558
 
559
+ def effective_bootstrap_unique_id
560
+ # Set the first unique value
561
+ @_effective_bootstrap_unique_id ||= Time.zone.now.to_i
562
+
563
+ # Everytime we access this function make a new one
564
+ @_effective_bootstrap_unique_id = @_effective_bootstrap_unique_id + 1
565
+
566
+ # Return the updated value
567
+ @_effective_bootstrap_unique_id
568
+ end
569
+
507
570
  end
@@ -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
- content_tag(:div, render_fields(content, (remove + reorder)), class: 'has-many-fields')
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
- raise('unsupported')
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,
@@ -1,3 +1,3 @@
1
1
  module EffectiveBootstrap
2
- VERSION = '0.9.37'.freeze
2
+ VERSION = '0.9.41'.freeze
3
3
  end
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.37
4
+ version: 0.9.41
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-07-26 00:00:00.000000000 Z
11
+ date: 2021-09-08 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