matestack-ui-bootstrap 1.5.1 → 3.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (112) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +17 -5
  3. data/README.md +36 -60
  4. data/lib/matestack/ui/bootstrap/base_component.rb +11 -0
  5. data/lib/matestack/ui/bootstrap/base_vue_js_component.rb +11 -0
  6. data/{app/concepts → lib}/matestack/ui/bootstrap/components/accordion.rb +18 -16
  7. data/lib/matestack/ui/bootstrap/components/alert.js +58 -0
  8. data/lib/matestack/ui/bootstrap/components/alert.rb +43 -0
  9. data/lib/matestack/ui/bootstrap/components/avatar.rb +27 -0
  10. data/lib/matestack/ui/bootstrap/components/badge.rb +32 -0
  11. data/{app/concepts → lib}/matestack/ui/bootstrap/components/breadcrumb.rb +12 -10
  12. data/lib/matestack/ui/bootstrap/components/button.rb +71 -0
  13. data/lib/matestack/ui/bootstrap/components/button_group.rb +36 -0
  14. data/lib/matestack/ui/bootstrap/components/card.rb +105 -0
  15. data/lib/matestack/ui/bootstrap/components/carousel.js +84 -0
  16. data/lib/matestack/ui/bootstrap/components/carousel.rb +103 -0
  17. data/{app/concepts → lib}/matestack/ui/bootstrap/components/close.rb +10 -9
  18. data/lib/matestack/ui/bootstrap/components/collapse.js +89 -0
  19. data/lib/matestack/ui/bootstrap/components/collapse.rb +54 -0
  20. data/lib/matestack/ui/bootstrap/components/dropdown.js +19 -0
  21. data/{app/concepts → lib}/matestack/ui/bootstrap/components/dropdown.rb +29 -25
  22. data/lib/matestack/ui/bootstrap/components/icon.rb +21 -0
  23. data/{app/concepts → lib}/matestack/ui/bootstrap/components/list_group.rb +32 -29
  24. data/{app/concepts → lib}/matestack/ui/bootstrap/components/modal.js +32 -28
  25. data/lib/matestack/ui/bootstrap/components/modal.rb +121 -0
  26. data/{app/concepts → lib}/matestack/ui/bootstrap/components/navbar.rb +39 -30
  27. data/{app/concepts → lib}/matestack/ui/bootstrap/components/page_heading.rb +7 -5
  28. data/{app/concepts → lib}/matestack/ui/bootstrap/components/pagination.rb +11 -9
  29. data/lib/matestack/ui/bootstrap/components/popover.js +30 -0
  30. data/{app/concepts → lib}/matestack/ui/bootstrap/components/popover.rb +25 -21
  31. data/{app/concepts → lib}/matestack/ui/bootstrap/components/progress.rb +19 -19
  32. data/lib/matestack/ui/bootstrap/components/scrollspy.rb +50 -0
  33. data/lib/matestack/ui/bootstrap/components/section_card.rb +33 -0
  34. data/lib/matestack/ui/bootstrap/components/spinner.rb +35 -0
  35. data/lib/matestack/ui/bootstrap/components/tab_nav.rb +79 -0
  36. data/lib/matestack/ui/bootstrap/components/tab_nav_content.rb +35 -0
  37. data/lib/matestack/ui/bootstrap/components/toast.js +89 -0
  38. data/lib/matestack/ui/bootstrap/components/toast.rb +113 -0
  39. data/{app/concepts → lib}/matestack/ui/bootstrap/components/tooltip.js +9 -6
  40. data/{app/concepts → lib}/matestack/ui/bootstrap/components/tooltip.rb +20 -18
  41. data/{app/concepts → lib}/matestack/ui/bootstrap/content/figure.rb +4 -2
  42. data/{app/concepts → lib}/matestack/ui/bootstrap/content/smart_collection/collection.rb +22 -16
  43. data/{app/concepts → lib}/matestack/ui/bootstrap/content/smart_collection/collection.scss +0 -0
  44. data/{app/concepts → lib}/matestack/ui/bootstrap/content/smart_collection/content.rb +38 -21
  45. data/{app/concepts → lib}/matestack/ui/bootstrap/content/smart_collection/filter.rb +6 -2
  46. data/{app/concepts → lib}/matestack/ui/bootstrap/content/smart_collection/paginate.rb +16 -11
  47. data/lib/matestack/ui/bootstrap/form/checkbox.rb +88 -0
  48. data/lib/matestack/ui/bootstrap/form/input.rb +116 -0
  49. data/lib/matestack/ui/bootstrap/form/radio.rb +55 -0
  50. data/{app/concepts → lib}/matestack/ui/bootstrap/form/select.rb +18 -10
  51. data/lib/matestack/ui/bootstrap/form/submit.rb +20 -0
  52. data/lib/matestack/ui/bootstrap/form/switch.rb +30 -0
  53. data/lib/matestack/ui/bootstrap/form/textarea.rb +47 -0
  54. data/lib/matestack/ui/bootstrap/index.js +40 -0
  55. data/lib/matestack/ui/bootstrap/initialize.rb +3 -0
  56. data/lib/matestack/ui/bootstrap/layout/column.rb +49 -0
  57. data/{app/concepts → lib}/matestack/ui/bootstrap/layout/container.rb +12 -9
  58. data/lib/matestack/ui/bootstrap/layout/row.rb +25 -0
  59. data/{app/concepts → lib}/matestack/ui/bootstrap/layout/sidebar.js +10 -6
  60. data/lib/matestack/ui/bootstrap/layout/sidebar.rb +43 -0
  61. data/{app/concepts → lib}/matestack/ui/bootstrap/layout/sidebar.scss +0 -0
  62. data/{app/concepts/matestack/ui/bootstrap/apps → lib/matestack/ui/bootstrap/layouts}/admin_template.rb +18 -13
  63. data/lib/matestack/ui/bootstrap/registry.rb +173 -0
  64. data/{app/javascript/matestack-ui-bootstrap → lib/matestack/ui/bootstrap}/stylesheets/matestack-ui-bootstrap.scss +0 -0
  65. data/lib/matestack/ui/bootstrap/version.rb +1 -1
  66. data/lib/matestack/ui/bootstrap.rb +99 -17
  67. metadata +85 -80
  68. data/app/assets/images/avatar-placeholder.png +0 -0
  69. data/app/assets/images/icons/bootstrap-icons.svg +0 -1
  70. data/app/concepts/matestack/ui/bootstrap/components/alert.js +0 -53
  71. data/app/concepts/matestack/ui/bootstrap/components/alert.rb +0 -34
  72. data/app/concepts/matestack/ui/bootstrap/components/avatar.rb +0 -27
  73. data/app/concepts/matestack/ui/bootstrap/components/badge.rb +0 -30
  74. data/app/concepts/matestack/ui/bootstrap/components/button.rb +0 -69
  75. data/app/concepts/matestack/ui/bootstrap/components/button_group.rb +0 -36
  76. data/app/concepts/matestack/ui/bootstrap/components/card.rb +0 -100
  77. data/app/concepts/matestack/ui/bootstrap/components/carousel.js +0 -79
  78. data/app/concepts/matestack/ui/bootstrap/components/carousel.rb +0 -86
  79. data/app/concepts/matestack/ui/bootstrap/components/collapse.js +0 -84
  80. data/app/concepts/matestack/ui/bootstrap/components/collapse.rb +0 -43
  81. data/app/concepts/matestack/ui/bootstrap/components/dropdown.js +0 -14
  82. data/app/concepts/matestack/ui/bootstrap/components/icon.rb +0 -19
  83. data/app/concepts/matestack/ui/bootstrap/components/modal.rb +0 -106
  84. data/app/concepts/matestack/ui/bootstrap/components/popover.js +0 -26
  85. data/app/concepts/matestack/ui/bootstrap/components/scrollspy.rb +0 -48
  86. data/app/concepts/matestack/ui/bootstrap/components/section_card.rb +0 -31
  87. data/app/concepts/matestack/ui/bootstrap/components/spinner.rb +0 -31
  88. data/app/concepts/matestack/ui/bootstrap/components/tab_nav.rb +0 -83
  89. data/app/concepts/matestack/ui/bootstrap/components/tab_nav_content.rb +0 -32
  90. data/app/concepts/matestack/ui/bootstrap/components/toast.js +0 -85
  91. data/app/concepts/matestack/ui/bootstrap/components/toast.rb +0 -99
  92. data/app/concepts/matestack/ui/bootstrap/form/checkbox.rb +0 -99
  93. data/app/concepts/matestack/ui/bootstrap/form/input.rb +0 -112
  94. data/app/concepts/matestack/ui/bootstrap/form/radio.rb +0 -57
  95. data/app/concepts/matestack/ui/bootstrap/form/submit.rb +0 -21
  96. data/app/concepts/matestack/ui/bootstrap/form/switch.rb +0 -99
  97. data/app/concepts/matestack/ui/bootstrap/layout/column.rb +0 -47
  98. data/app/concepts/matestack/ui/bootstrap/layout/row.rb +0 -15
  99. data/app/concepts/matestack/ui/bootstrap/layout/sidebar.rb +0 -45
  100. data/app/concepts/matestack/ui/bootstrap/pages/devise/sign_in.rb +0 -40
  101. data/app/concepts/matestack/ui/bootstrap/registry.rb +0 -61
  102. data/app/helpers/matestack/ui/bootstrap/application_helper.rb +0 -17
  103. data/app/javascript/matestack-ui-bootstrap/index.js +0 -24
  104. data/app/javascript/packs/matestack-ui-bootstrap.js +0 -2
  105. data/app/matestack/bootstrap/form/submit.rb +0 -20
  106. data/config/routes.rb +0 -2
  107. data/config/webpack/development.js +0 -5
  108. data/config/webpack/environment.js +0 -29
  109. data/config/webpack/production.js +0 -33
  110. data/config/webpack/test.js +0 -5
  111. data/config/webpacker.yml +0 -96
  112. data/lib/matestack/ui/bootstrap/engine.rb +0 -26
@@ -1,32 +1,34 @@
1
- class Matestack::Ui::Bootstrap::Components::Tooltip < Matestack::Ui::VueJsComponent
2
- vue_js_component_name "matestack-ui-bootstrap-tooltip"
1
+ require_relative "../base_vue_js_component"
2
+
3
+ class Matestack::Ui::Bootstrap::Components::Tooltip < Matestack::Ui::Bootstrap::BaseVueJsComponent
4
+ vue_name "matestack-ui-bootstrap-tooltip"
3
5
 
4
6
  DATA_ALIAS_ATTRIBUTES = %i[container delay selector html template fallback_placement]
5
7
 
6
8
  DATA_ALIAS_ATTRIBUTES.each do |attribute|
7
- optional "#{attribute}": { as: :"bs_#{attribute}"}
9
+ optional :"#{attribute}"
8
10
  end
9
11
 
10
12
  # TODO:
11
13
  # for security reasons the sanitize, sanitizeFn and whiteList options cannot be supplied using data attributes.
12
14
  # sanitize sanitize_fn white_list
13
15
  # optional :content
14
- requires :tooltip_title
16
+ required :tooltip_title
15
17
  optional :tag
16
- optional class: { as: :bs_class }
17
- optional id: { as: :bs_id }
18
+ optional class: { as: :bs_class }
19
+ optional :id
18
20
  DATA_ATTRIBUTES = %i[text variant animation placement tabindex trigger boundary offset popper_config]
19
21
  optional *DATA_ATTRIBUTES
20
22
 
21
23
  def response
22
- case tag
24
+ case context.tag
23
25
  when :div
24
26
  div tooltip_attributes do
25
- yield_components
27
+ yield if block_given?
26
28
  end
27
29
  else
28
30
  span tooltip_attributes do
29
- yield_components
31
+ yield if block_given?
30
32
  end
31
33
  end
32
34
  end
@@ -36,28 +38,28 @@ class Matestack::Ui::Bootstrap::Components::Tooltip < Matestack::Ui::VueJsCompon
36
38
  def tooltip_attributes
37
39
  attributes = {}.tap do |hash|
38
40
  hash[:class] = tooltip_classes
39
- hash[:text] = text if text.present?
41
+ hash[:text] = context.text if context.text.present?
40
42
  hash[:data] = {}.tap do |hash|
41
43
  DATA_ALIAS_ATTRIBUTES.each do |attribute|
42
- hash["bs-#{attribute}"] = self.send(:"bs_#{attribute}") if self.send(:"bs_#{attribute}")
44
+ hash["bs-#{attribute}"] = context.send("#{attribute}") if context.send("#{attribute}")
43
45
  end
44
46
  DATA_ATTRIBUTES.each do |attribute|
45
- hash["bs-#{attribute}"] = self.send(:"#{attribute}") if self.send(:"#{attribute}")
47
+ hash["bs-#{attribute}"] = context.send("#{attribute}") if context.send("#{attribute}")
46
48
  end
47
49
  hash["bs-toggle"] = "tooltip"
48
- hash["bs-type"] = tag
49
- hash["bs-placement"] = "auto" if placement.nil?
50
- hash["bs-title"] = tooltip_title
50
+ hash["bs-type"] = context.tag
51
+ hash["bs-placement"] = "auto" if context.placement.nil?
52
+ hash["bs-title"] = context.tooltip_title
51
53
  end
52
54
  end
53
- html_attributes.merge(
54
- attributes
55
+ options.merge(
56
+ attributes || {}
55
57
  )
56
58
  end
57
59
 
58
60
  def tooltip_classes
59
61
  [].tap do |classes|
60
- classes << bs_class
62
+ classes << context.bs_class
61
63
  end.join(' ').strip
62
64
  end
63
65
 
@@ -1,7 +1,9 @@
1
- class Matestack::Ui::Bootstrap::Content::Figure < Matestack::Ui::Component
1
+ require_relative "../base_component"
2
+
3
+ class Matestack::Ui::Bootstrap::Content::Figure < Matestack::Ui::Bootstrap::BaseComponent
2
4
 
3
5
  def response
4
6
  # provide a bootstrap figure
5
7
  end
6
8
 
7
- end
9
+ end
@@ -1,11 +1,17 @@
1
- class Matestack::Ui::Bootstrap::Content::SmartCollection::Collection < Matestack::Ui::Component
2
- include Matestack::Ui::Core::Collection::Helper
1
+ require_relative "../../base_component"
2
+
3
+ require_relative "./content"
4
+ require_relative "./filter"
5
+ require_relative "./paginate"
6
+
7
+ class Matestack::Ui::Bootstrap::Content::SmartCollection::Collection < Matestack::Ui::Bootstrap::BaseComponent
8
+ include Matestack::Ui::VueJs::Components::Collection::Helper
3
9
  include Matestack::Ui::Bootstrap::Content::SmartCollection::Content
4
10
  include Matestack::Ui::Bootstrap::Content::SmartCollection::Filter
5
11
  include Matestack::Ui::Bootstrap::Content::SmartCollection::Paginate
6
12
 
7
13
  # html attributes
8
- optional id: { as: :bs_id }
14
+ optional :id
9
15
 
10
16
  # table configuration
11
17
  optional :items
@@ -16,7 +22,7 @@ class Matestack::Ui::Bootstrap::Content::SmartCollection::Collection < Matestack
16
22
  optional :rerender_on
17
23
  optional :item_actions_proc
18
24
  optional :collection_rendering_proc
19
- optional :slots
25
+
20
26
 
21
27
  # bootstrap settings
22
28
  optional :responsive
@@ -29,7 +35,7 @@ class Matestack::Ui::Bootstrap::Content::SmartCollection::Collection < Matestack
29
35
  attr_accessor :processed_filters
30
36
 
31
37
  def response
32
- div id: bs_id, class: "smart-collection" do
38
+ div id: context.id, class: "smart-collection" do
33
39
  filter_partial
34
40
  content
35
41
  end
@@ -41,11 +47,11 @@ class Matestack::Ui::Bootstrap::Content::SmartCollection::Collection < Matestack
41
47
  def collection
42
48
  return @collection if @collection
43
49
  settings = {}.tap do |h|
44
- h[:id] = bs_id || "smartcollection"
50
+ h[:id] = context.id || "smartcollection"
45
51
  h[:data] = filtered_query
46
- h[:base_count] = items.count
47
- h[:init_limit] = paginate if paginate
48
- h[:filtered_count] = filtered_query.count if paginate
52
+ h[:base_count] = context.items.count
53
+ h[:init_limit] = context.paginate if context.paginate
54
+ h[:filtered_count] = filtered_query.count if context.paginate
49
55
  end
50
56
  @collection = set_collection(settings)
51
57
  end
@@ -56,9 +62,9 @@ class Matestack::Ui::Bootstrap::Content::SmartCollection::Collection < Matestack
56
62
 
57
63
  def filtered_query
58
64
  return @filtered_query if @filtered_query
59
- @filtered_query = items
60
- unless filters.nil?
61
- filters.select { |key, value| '.'.in? key.to_s }.each do |key, value|
65
+ @filtered_query = context.items
66
+ unless context.filters.nil?
67
+ context.filters.select { |key, value| '.'.in? key.to_s }.each do |key, value|
62
68
  associated_name = key.to_s.split(".").first
63
69
  @filtered_query = @filtered_query.joins(associated_name.to_sym).all
64
70
  if value.is_a?(Hash)
@@ -66,7 +72,7 @@ class Matestack::Ui::Bootstrap::Content::SmartCollection::Collection < Matestack
66
72
  @filtered_query = add_query_filter(@filtered_query, associated_name, key, value)
67
73
  end
68
74
  end
69
- filters.reject { |key, value| '.'.in? key.to_s }.each do |key, value|
75
+ context.filters.reject { |key, value| '.'.in? key.to_s }.each do |key, value|
70
76
  if value.is_a?(Hash)
71
77
  processed_filters[key] = value
72
78
  @filtered_query = add_query_filter(@filtered_query, nil, key, value)
@@ -80,10 +86,10 @@ class Matestack::Ui::Bootstrap::Content::SmartCollection::Collection < Matestack
80
86
  value = get_collection_filter(collection_id)[key.to_sym]
81
87
  if value.present?
82
88
  if associated_name.present?
83
- table_name = items.klass.reflections[associated_name].table_name
89
+ table_name = context.items.klass.reflections[associated_name].table_name
84
90
  key = key.to_s.gsub(associated_name, table_name)
85
91
  else
86
- table_name = items.klass.table_name
92
+ table_name = context.items.klass.table_name
87
93
  key = key.to_s
88
94
  end
89
95
  case filter_config[:match]
@@ -103,7 +109,7 @@ class Matestack::Ui::Bootstrap::Content::SmartCollection::Collection < Matestack
103
109
  end
104
110
 
105
111
  def head_columns
106
- columns.map { |key, value| value.is_a?(Hash) ? value[:heading] : value }
112
+ context.columns.map { |key, value| value.is_a?(Hash) ? value[:heading] : value }
107
113
  end
108
114
 
109
115
  def processed_filters
@@ -3,12 +3,12 @@ module Matestack::Ui::Bootstrap::Content::SmartCollection::Content
3
3
  def content
4
4
  bs_row class: 'smart-collection-content' do
5
5
  bs_col do
6
- async id: "#{collection_id}-async", rerender_on: "#{collection_id}-update, #{rerender_on} " do
6
+ async id: "#{collection_id}-async", rerender_on: "#{collection_id}-update, #{context.rerender_on} " do
7
7
  collection_content collection.config do
8
8
  div class: responsive_class do
9
9
  if slots && slots[:collection_rendering]
10
- slot slots[:collection_rendering].call(collection.paginated_data)
11
- elsif columns
10
+ slot :collection_rendering, collection.paginated_data
11
+ elsif context.columns
12
12
  div class: "table-responsive" do
13
13
  table table_attributes do
14
14
  table_head
@@ -18,7 +18,7 @@ module Matestack::Ui::Bootstrap::Content::SmartCollection::Content
18
18
  end
19
19
  end
20
20
  end
21
- paginate_partial if paginate.present?
21
+ paginate_partial if context.paginate.present?
22
22
  end
23
23
  end
24
24
  end
@@ -28,8 +28,10 @@ module Matestack::Ui::Bootstrap::Content::SmartCollection::Content
28
28
  def table_head
29
29
  thead do
30
30
  tr do
31
- columns&.each do |key, value|
32
- th text: value.is_a?(Hash) ? value[:heading] : value, class: cell_class(value), attributes: { scope: :col }
31
+ context.columns&.each do |key, value|
32
+ th class: cell_class(value), scope: :col do
33
+ plain value.is_a?(Hash) ? value[:heading] : value
34
+ end
33
35
  end
34
36
  th if slots && slots[:table_item_actions]
35
37
  end
@@ -40,12 +42,12 @@ module Matestack::Ui::Bootstrap::Content::SmartCollection::Content
40
42
  tbody do
41
43
  collection.paginated_data.each_with_index do |data, index|
42
44
  tr class: 'align-middle' do
43
- columns.each do |key, value|
45
+ context.columns.each do |key, value|
44
46
  cell(data, key, value)
45
47
  end
46
48
  if slots && slots[:table_item_actions]
47
49
  td class: 'text-end' do
48
- slot slots[:table_item_actions].call(data)
50
+ slot :table_item_actions, data
49
51
  end
50
52
  end
51
53
  end
@@ -56,17 +58,23 @@ module Matestack::Ui::Bootstrap::Content::SmartCollection::Content
56
58
  def table_footer
57
59
  tfoot do
58
60
  tr do
59
- footer&.each do |value|
60
- td text: value
61
+ context.footer&.each do |value|
62
+ td value
61
63
  end
62
64
  end
63
- end if footer
65
+ end if context.footer
64
66
  end
65
67
 
66
68
  private
67
69
 
68
70
  def cell(data, key, value)
69
- td text: cell_text(data, key, value), class: cell_class(value)
71
+ td class: cell_class(value) do
72
+ if value.is_a?(Hash) && value[:slot]
73
+ value[:slot].call(data)
74
+ else
75
+ plain cell_text(data, key, value)
76
+ end
77
+ end
70
78
  end
71
79
 
72
80
  def cell_class(value)
@@ -77,25 +85,34 @@ module Matestack::Ui::Bootstrap::Content::SmartCollection::Content
77
85
  end
78
86
 
79
87
  def cell_text(data, key, value)
80
- text = data.instance_eval(key.to_s)
81
- text = value[:format].call(text) if value.is_a?(Hash) && value[:format]
88
+ if value.is_a?(Hash)
89
+ if value[:attribute].present?
90
+ text = data.instance_eval(value[:attribute].to_s)
91
+ else
92
+ text = data.instance_eval(key.to_s)
93
+ end
94
+ text = value[:format].call(text) if value[:format].present?
95
+ else
96
+ text = data.instance_eval(key.to_s)
97
+ end
98
+
82
99
  text
83
100
  end
84
101
 
85
102
  def table_attributes
86
103
  klass = ['table'].tap do |classes|
87
- classes << "table-#{variant}" if variant
88
- classes << "table-striped" if striped
89
- classes << "table-hover" if hoverable
90
- classes << "table-bordered border-#{border_variant}" if border_variant
91
- classes << "table-borderless" if borderless
104
+ classes << "table-#{context.variant}" if context.variant
105
+ classes << "table-striped" if context.striped
106
+ classes << "table-hover" if context.hoverable
107
+ classes << "table-bordered border-#{context.border_variant}" if context.border_variant
108
+ classes << "table-borderless" if context.borderless
92
109
  end.join(' ').strip
93
110
  { id: collection_id, class: klass }
94
111
  end
95
112
 
96
113
  def responsive_class
97
- return unless responsive
98
- responsive === true ? 'table-responsive' : "table-responsive-#{responsive}"
114
+ return unless context.responsive
115
+ responsive === true ? 'table-responsive' : "table-responsive-#{context.responsive}"
99
116
  end
100
117
 
101
118
  end
@@ -18,15 +18,19 @@ module Matestack::Ui::Bootstrap::Content::SmartCollection::Filter
18
18
 
19
19
  def filter_input(key, config)
20
20
  attributes = {
21
+ id: key,
21
22
  key: key,
22
23
  type: :text,
23
24
  placeholder: config[:placeholder] || key.to_s,
25
+ label: config[:label]
24
26
  }
25
27
  case config[:type]
26
28
  when :select
27
- collection_filter_select attributes.merge(id: key, class: 'form-select', options: config[:options])
29
+ bs_form_select attributes.merge(options: config[:options])
30
+ when :checkbox
31
+ bs_form_checkbox attributes.merge(options: config[:options])
28
32
  else
29
- collection_filter_input attributes.merge(id: key, class: 'form-control smart-collection-filter')
33
+ bs_form_input attributes.merge(class: 'smart-collection-filter')
30
34
  end
31
35
  end
32
36
 
@@ -3,9 +3,9 @@ module Matestack::Ui::Bootstrap::Content::SmartCollection::Paginate
3
3
  def paginate_partial
4
4
  div class: "current-pagination-state ps-2" do
5
5
  small do
6
- plain "showing #{@collection.from}"
7
- plain "to #{@collection.to}"
8
- plain "of #{@collection.filtered_count}"
6
+ plain "showing #{@collection.from} "
7
+ plain "to #{@collection.to} "
8
+ plain "of #{@collection.filtered_count} "
9
9
  if (@collection.base_count - @collection.filtered_count) > 0
10
10
  plain "(#{@collection.base_count - @collection.filtered_count} hidden by filter)"
11
11
  end
@@ -15,7 +15,7 @@ module Matestack::Ui::Bootstrap::Content::SmartCollection::Paginate
15
15
  end
16
16
 
17
17
  def pagination_nav_partial
18
- nav class: "table-responsive", attributes: { style: "display: -webkit-box;" } do
18
+ nav class: "table-responsive", style: "display: -webkit-box;" do
19
19
  ul class: ul_classes do
20
20
  li class: "page-item previous #{ 'disabled' if current_page == 1 }" do
21
21
  collection_content_previous class: 'page-link' do
@@ -30,7 +30,7 @@ module Matestack::Ui::Bootstrap::Content::SmartCollection::Paginate
30
30
  end
31
31
  unless current_page == 6
32
32
  li class: "page-item disabled" do
33
- link class: 'page-link', path: "#" do
33
+ a class: 'page-link', path: "#" do
34
34
  plain "..."
35
35
  end
36
36
  end
@@ -48,7 +48,7 @@ module Matestack::Ui::Bootstrap::Content::SmartCollection::Paginate
48
48
  if @collection.pages.count >= 9 && last_page-current_page > 4
49
49
  unless current_page == last_page-5
50
50
  li class: "page-item disabled" do
51
- link class: 'page-link', path: "#" do
51
+ a class: 'page-link', path: "#" do
52
52
  plain "..."
53
53
  end
54
54
  end
@@ -77,15 +77,20 @@ module Matestack::Ui::Bootstrap::Content::SmartCollection::Paginate
77
77
  end
78
78
 
79
79
  def current_page
80
- current_offset = params["#{bs_id}-offset"].try(:to_i)
81
- (current_offset/paginate)+1 if current_offset && paginate.present?
80
+ current_offset = params["#{context.id}-offset"].try(:to_i)
81
+ if current_offset && context.paginate.present?
82
+ (current_offset/context.paginate)+1
83
+ elsif context.paginate.present?
84
+ 1
85
+ end
82
86
  end
87
+
83
88
 
84
89
  def last_page
85
- if @collection.filtered_count%paginate == 0
86
- (@collection.filtered_count/paginate)
90
+ if @collection.filtered_count%context.paginate == 0
91
+ (@collection.filtered_count/context.paginate)
87
92
  else
88
- (@collection.filtered_count/paginate)+1
93
+ (@collection.filtered_count/context.paginate)+1
89
94
  end
90
95
  end
91
96
 
@@ -0,0 +1,88 @@
1
+ class Matestack::Ui::Bootstrap::Form::Checkbox < Matestack::Ui::VueJs::Components::Form::Checkbox
2
+
3
+ vue_name "matestack-ui-core-form-checkbox"
4
+
5
+ optional :form_text
6
+ optional :disabled
7
+ optional :variant
8
+
9
+ def response
10
+ div class: "matestack-ui-bootstrap-form-checkbox" do
11
+ label input_label, class: "form-label", ":for": id if input_label && multiple?
12
+ render_options
13
+ render_errors
14
+ render_form_text unless context.form_text.nil? # otherwise renders empty div
15
+ end
16
+ end
17
+
18
+ private
19
+
20
+ def bootstrap_attributes
21
+ classes = 'form-check-input'
22
+ classes = [options[:class], classes].join(' ')
23
+ {
24
+ class: classes,
25
+ disabled: context.disabled
26
+ }
27
+ end
28
+
29
+ def multiple?
30
+ checkbox_options.present?
31
+ end
32
+
33
+ def render_options
34
+ # multiple
35
+ if multiple?
36
+ checkbox_options.to_a.each do |item|
37
+ checkbox_wrapper do
38
+ input options.merge(checkbox_attributes(item)).merge(bootstrap_attributes)
39
+ bootstrap_label text: item_label(item), for_input: item_id(item)
40
+ end
41
+ end
42
+ # checked/unchecked checkbox (true/false checkbox)
43
+ else
44
+ checkbox_wrapper do
45
+ input true_false_checkbox_attributes.merge(type: :hidden, id: nil, value: 0)
46
+ input true_false_checkbox_attributes.merge(type: :checkbox, ":id": item_id(1)).merge(bootstrap_attributes)
47
+
48
+ bootstrap_label text: input_label, for_input: item_id(1)
49
+ end
50
+ end
51
+ end
52
+
53
+ def checkbox_wrapper(options = {}, &block)
54
+ wrapper_attributes = (options[:attributes] || {}).merge({
55
+ class: "form-check #{'form-check-inline' if context.variant == :inline}"
56
+ })
57
+ div wrapper_attributes do
58
+ yield if block_given?
59
+ end
60
+ end
61
+
62
+ def bootstrap_label(text:, for_input:)
63
+ label text, ":for": for_input, class: 'form-check-label'
64
+ end
65
+
66
+ def render_errors
67
+ if display_errors?
68
+ div class: 'invalid-feedback', 'v-for': "error in #{error_key}", style: "display: block;" do
69
+ plain '{{ error }}'
70
+ end
71
+ end
72
+ end
73
+
74
+ def error_class
75
+ 'is-invalid'
76
+ end
77
+
78
+ def checkbox_options
79
+ super || {}
80
+ end
81
+
82
+ def render_form_text
83
+ div class: "form-text form-text-for-#{attribute_key}" do
84
+ plain context.form_text
85
+ end
86
+ end
87
+
88
+ end
@@ -0,0 +1,116 @@
1
+ class Matestack::Ui::Bootstrap::Form::Input < Matestack::Ui::VueJs::Components::Form::Input
2
+
3
+ vue_name "matestack-ui-core-form-input"
4
+
5
+ optional :form_text
6
+ optional :disabled
7
+ optional :browse_button_text
8
+ optional :placeholder
9
+ optional :variant
10
+ optional :min
11
+ optional :max
12
+ optional :step
13
+ optional :show_value
14
+
15
+ def response
16
+ div class: "matestack-ui-bootstrap-input" do
17
+ label input_label, ":for": id, class: "form-label" if input_label
18
+ case context.type
19
+ when :range
20
+ input options.merge(input_attributes).merge(bootstrap_range_attributes)
21
+ if context.show_value
22
+ div class: "form-text form-text-for-#{attribute_key}" do
23
+ plain "{{ data['#{attribute_key}'] }}"
24
+ end
25
+ end
26
+ when :file
27
+ file_input
28
+ else
29
+ input options.merge(input_attributes).merge(bootstrap_input_attributes)
30
+ render_errors
31
+ end
32
+ render_form_text if context.form_text
33
+ end
34
+ end
35
+
36
+ def bootstrap_input_attributes
37
+ {
38
+ class: (options[:class] || "") << (" form-control"),
39
+ disabled: context.disabled,
40
+ min: context.min,
41
+ max: context.max,
42
+ step: context.step
43
+ }
44
+ end
45
+
46
+ def bootstrap_range_attributes
47
+ {
48
+ class: (options[:class] || "") << (" form-range"),
49
+ disabled: context.disabled,
50
+ min: context.min,
51
+ max: context.max,
52
+ step: context.step
53
+ }
54
+ end
55
+
56
+ def bootstrap_file_input_attributes
57
+ {
58
+ class: (options[:class] || "") << (" form-file-input"),
59
+ disabled: context.disabled
60
+ }
61
+ end
62
+
63
+ def form_file_wrapper_class
64
+ case context.variant
65
+ when :lg
66
+ (options[:class] || "") << (" form-file form-file-lg")
67
+ when :sm
68
+ (options[:class] || "") << (" form-file form-file-sm")
69
+ else
70
+ (options[:class] || "") << (" form-file")
71
+ end
72
+ end
73
+
74
+ def file_input
75
+ div class: form_file_wrapper_class do
76
+ input options.merge(input_attributes).merge(bootstrap_file_input_attributes)
77
+ label class: "form-file-label", for: attribute_key do
78
+ span class: "form-file-text", "v-if": "data['#{attribute_key}']" do
79
+ if context.multiple
80
+ span "v-for": "file in data['#{attribute_key}']" do
81
+ plain "{{ file['name'] }}"
82
+ end
83
+ else
84
+ plain "{{ data['#{attribute_key}']['name'] }}"
85
+ end
86
+ end
87
+ span class: "form-file-text", "v-if": "!data['#{attribute_key}']" do
88
+ plain context.placeholder || "Choose file"
89
+ end
90
+ span class: "form-file-button" do
91
+ plain context.browse_button_text || "Browse"
92
+ end
93
+ end
94
+ render_errors
95
+ end
96
+ end
97
+
98
+ def render_errors
99
+ if display_errors?
100
+ div class: 'invalid-feedback', 'v-for': "error in #{error_key}" do
101
+ plain '{{ error }}'
102
+ end
103
+ end
104
+ end
105
+
106
+ def input_error_class
107
+ 'is-invalid'
108
+ end
109
+
110
+ def render_form_text
111
+ div class: "form-text form-text-for-#{attribute_key}" do
112
+ plain context.form_text
113
+ end
114
+ end
115
+
116
+ end
@@ -0,0 +1,55 @@
1
+ class Matestack::Ui::Bootstrap::Form::Radio < Matestack::Ui::VueJs::Components::Form::Radio
2
+
3
+ vue_name "matestack-ui-core-form-radio"
4
+
5
+ optional :form_text
6
+ optional :disabled
7
+ optional :variant
8
+
9
+ def response
10
+ div class: "matestack-ui-bootstrap-radio" do
11
+ label input_label, class: "form-label", ":for": id if input_label
12
+
13
+ radio_options.to_a.each_with_index do |item, index|
14
+ div class: "form-check #{'form-check-inline' if context.variant == :inline}" do
15
+ input options.merge(radio_attributes(item)).merge(bootstrap_radio_attributes)
16
+ label item_label(item), class: "form-check-label", ":for": item_id(item_value(item))
17
+ if index == radio_options.to_a.size - 1
18
+ render_errors
19
+ end
20
+ end
21
+ end
22
+ render_form_text if context.form_text
23
+ end
24
+
25
+ end
26
+
27
+ private
28
+
29
+ def bootstrap_radio_attributes
30
+ classes = 'form-check-input'
31
+ {
32
+ class: (options[:class] || "") << classes,
33
+ disabled: context.disabled
34
+ }
35
+ end
36
+
37
+ def render_form_text
38
+ div class: "form-text form-text-for-#{attribute_key}" do
39
+ plain context.form_text
40
+ end
41
+ end
42
+
43
+ def render_errors
44
+ if display_errors?
45
+ div class: 'invalid-feedback', 'v-for': "error in #{error_key}", style: "display: block;" do
46
+ plain '{{ error }}'
47
+ end
48
+ end
49
+ end
50
+
51
+ def input_error_class
52
+ 'is-invalid'
53
+ end
54
+
55
+ end