glib-web 4.39.2 → 4.41.0

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.
@@ -3,85 +3,94 @@ json.title 'Timeline Panels'
3
3
  page = json_ui_page json
4
4
  render "#{@path_prefix}/nav_menu", json: json, page: page
5
5
 
6
- page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
7
- timeline_items = [
8
- { icon: 'place', color: '#4BB543' },
9
- { icon: 'check_circle', color: 'blue' },
10
- { icon: 'hourglass_empty', color: 'blue', text: 'Pending' },
11
- { icon: 'radio_button_unchecked' },
12
- { icon: 'radio_button_unchecked' },
6
+ page.scroll(
7
+ padding: glib_json_padding_body,
8
+ childViews: ->(scroll) do
9
+ timeline_items = [
10
+ { icon: 'place', color: '#4BB543' },
11
+ { icon: 'check_circle', color: 'blue' },
12
+ { icon: 'hourglass_empty', color: 'blue', text: 'Pending' },
13
+ { icon: 'radio_button_unchecked' },
14
+ { icon: 'radio_button_unchecked' },
13
15
  ]
14
-
15
- scroll.h2 text: 'Basic timeline'
16
- scroll.panels_timeline \
17
- events: timeline_items,
18
- childViews: ->(timeline) do
19
- timeline.label styleClass: 'mt-2', text: 'Order submitted'
20
-
21
- timeline.label styleClass: 'mt-2', text: 'Finding you a driver'
22
-
23
- timeline.panels_vertical styleClass: 'mt-2', childViews: ->(vertical) do
24
- vertical.h4 text: 'Driver found, picking you up..'
25
- vertical.spacer height: 16
26
- render 'json_ui/garage/panels/timeline_content', tview: vertical
16
+ scroll.h2 text: 'Basic timeline'
17
+ scroll.panels_timeline(
18
+ events: timeline_items,
19
+ childViews: ->(timeline) do
20
+ timeline.label styleClass: 'mt-2', text: 'Order submitted'
21
+ timeline.label styleClass: 'mt-2', text: 'Finding you a driver'
22
+ timeline.panels_vertical(
23
+ styleClass: 'mt-2',
24
+ childViews: ->(vertical) do
25
+ vertical.h4 text: 'Driver found, picking you up..'
26
+ vertical.spacer height: 16
27
+ render 'json_ui/garage/panels/timeline_content', tview: vertical
28
+ end
29
+ )
30
+ timeline.label styleClass: 'mt-2', text: 'On the way'
31
+ timeline.label styleClass: 'mt-2', text: 'Arrived'
27
32
  end
28
-
29
- timeline.label styleClass: 'mt-2', text: 'On the way'
30
-
31
- timeline.label styleClass: 'mt-2', text: 'Arrived'
32
- end
33
-
34
- timeline_items = [
35
- { icon: 'place', color: '#4BB543', styleClasses: ['outlined'] },
36
- { icon: 'check_circle', color: 'blue', styleClasses: ['outlined'] },
37
- { icon: 'check_circle', color: 'blue', styleClasses: ['outlined'] },
38
- { icon: 'check_circle', color: 'blue', styleClasses: ['outlined'] },
39
- { icon: 'flag', color: '#FFA500', styleClasses: ['outlined'] },
33
+ )
34
+ timeline_items = [
35
+ { icon: 'place', color: '#4BB543', styleClasses: ['outlined'] },
36
+ { icon: 'check_circle', color: 'blue', styleClasses: ['outlined'] },
37
+ { icon: 'check_circle', color: 'blue', styleClasses: ['outlined'] },
38
+ { icon: 'check_circle', color: 'blue', styleClasses: ['outlined'] },
39
+ { icon: 'flag', color: '#FFA500', styleClasses: ['outlined'] },
40
40
  ]
41
-
42
- scroll.h2 text: 'Timeline with outlined dots'
43
- scroll.panels_timeline \
44
- events: timeline_items,
45
- childViews: ->(timeline) do
46
- timeline.panels_vertical childViews: ->(vertical) do
47
- vertical.h4 text: 'Order submitted'
48
- vertical.spacer height: 2
49
- vertical.label text: '15 minutes ago'
50
- end
51
-
52
- timeline.panels_vertical childViews: ->(vertical) do
53
- vertical.h4 text: 'Finding you a driver'
54
- vertical.spacer height: 2
55
- vertical.label text: '15 minutes ago'
56
- end
57
-
58
- timeline.panels_vertical childViews: ->(vertical) do
59
- vertical.h4 text: 'Driver found'
60
- vertical.spacer height: 2
61
- vertical.label text: '12 minutes ago'
62
- end
63
-
64
- timeline.panels_vertical childViews: ->(vertical) do
65
- vertical.h4 text: 'On the way'
66
- vertical.spacer height: 2
67
- vertical.label text: 'Duration: 11 minutes'
41
+ timeline_events = [
42
+ { title: 'Order submitted', time: '15 minutes ago' },
43
+ { title: 'Finding you a driver', time: '15 minutes ago' },
44
+ { title: 'Driver found', time: '12 minutes ago' },
45
+ { title: 'On the way', time: 'Duration: 11 minutes' },
46
+ { title: 'Arrived', time: '1 minute ago' }
47
+ ]
48
+ scroll.spacer height: 32
49
+ scroll.h2 text: 'Timeline with outlined dots'
50
+ scroll.panels_timeline(
51
+ events: timeline_items,
52
+ childViews: ->(timeline) do
53
+ timeline_events.each do |event|
54
+ timeline.panels_vertical(
55
+ childViews: ->(vertical) do
56
+ vertical.h4 text: event[:title]
57
+ vertical.spacer height: 2
58
+ vertical.label text: event[:time]
59
+ end
60
+ )
61
+ end
68
62
  end
63
+ )
69
64
 
70
- timeline.panels_vertical childViews: ->(vertical) do
71
- vertical.h4 text: 'Arrived'
72
- vertical.spacer height: 2
73
- vertical.label text: '1 minute ago'
65
+ scroll.spacer height: 32
66
+ scroll.h2 text: 'Timeline horizontal'
67
+ scroll.panels_timeline(
68
+ events: timeline_items,
69
+ direction: 'horizontal',
70
+ side: 'end',
71
+ childViews: ->(timeline) do
72
+ timeline_events.each do |event|
73
+ timeline.panels_vertical(
74
+ childViews: ->(vertical) do
75
+ vertical.h4 text: event[:title]
76
+ vertical.spacer height: 2
77
+ vertical.label text: event[:time]
78
+ end
79
+ )
80
+ end
74
81
  end
75
- end
82
+ )
76
83
 
77
- timeline_items = [
78
- { backgroundColor: 'blue', styleClasses: ['small'] },
79
- { backgroundColor: 'blue', styleClasses: ['x-small'] },
80
- { backgroundColor: 'blue', color: 'white', text: '3' },
81
- { backgroundColor: 'white', icon: 'radio_button_unchecked', styleClasses: ['small'] },
82
- { backgroundColor: 'white', icon: 'radio_button_unchecked', styleClasses: ['small'] },
84
+ scroll.spacer height: 32
85
+ timeline_items = [
86
+ { backgroundColor: 'blue', styleClasses: ['small'] },
87
+ { backgroundColor: 'blue', styleClasses: ['x-small'] },
88
+ { backgroundColor: 'blue', color: 'white', text: '3' },
89
+ { backgroundColor: 'white', icon: 'radio_button_unchecked', styleClasses: ['small'] },
90
+ { backgroundColor: 'white', icon: 'radio_button_unchecked', styleClasses: ['small'] },
83
91
  ]
92
+ scroll.h2 text: 'Timeline without content'
93
+ scroll.panels_timeline truncateLine: 'both', events: timeline_items
84
94
 
85
- scroll.h2 text: 'Timeline without content'
86
- scroll.panels_timeline truncateLine: 'both', events: timeline_items
87
- end
95
+ end
96
+ )
@@ -9,6 +9,9 @@ page.on load: ->(action) do
9
9
  end,
10
10
  reRender: ->(action) do
11
11
  action.snackbars_alert message: 'page.onRerender'
12
+ end,
13
+ foreground: ->(action) do
14
+ action.snackbars_alert message: 'page.onForeground'
12
15
  end
13
16
 
14
17
  page.body childViews: ->(body) do
data/lib/glib/snapshot.rb CHANGED
@@ -23,17 +23,25 @@ module Glib
23
23
  return true if changed?
24
24
 
25
25
  associations_for_snapshot.each do |association_name|
26
- if (association = self.class.reflect_on_association(association_name))
27
- case association.macro
28
- when :has_many
29
- public_send(association_name).each do |record|
30
- return true if record.changed?
31
- end
32
- when :has_one, :belongs_to
33
- return true if public_send(association_name).changed?
26
+ association = self.class.reflect_on_association(association_name)
27
+ association_value = public_send(association_name)
28
+
29
+ if active_storage_association?(association, association_value)
30
+ active_storage_records(association_value).each do |record|
31
+ return true if record.changed?
34
32
  end
35
- else
36
- raise "Invalid association: #{association_name}"
33
+ next
34
+ end
35
+
36
+ raise "Invalid association: #{association_name}" if association.nil?
37
+
38
+ case association.macro
39
+ when :has_many
40
+ association_value.each do |record|
41
+ return true if record.changed?
42
+ end
43
+ when :has_one, :belongs_to
44
+ return true if association_value&.changed?
37
45
  end
38
46
  end
39
47
 
@@ -134,7 +142,7 @@ module Glib
134
142
  end
135
143
 
136
144
  # always watch column with name *id
137
- ignore_keys.filter! { |key| !key.ends_with?('id') || key != 'id' }
145
+ ignore_keys.reject! { |key| key == 'id' || key.ends_with?('_id') }
138
146
 
139
147
  if snapshot.present?
140
148
  item, associations = snapshot.fetch_reified_items
@@ -147,15 +155,18 @@ module Glib
147
155
  'item' => ::Hashdiff.diff(item.attributes.except(*ignore_keys), attributes.except(*ignore_keys))
148
156
  }
149
157
 
150
- obj['associations'] = associations_for_snapshot.reduce({}) do |prev, curr|
151
- first_record_off_same_collection = send(curr).first
158
+ obj['associations'] = associations_for_snapshot.reduce({}) do |prev, curr| # rubocop:disable Glib/MultilineMethodCallStyle
159
+ association_records = records_for_snapshot(curr)
160
+ first_record_off_same_collection = association_records.first
152
161
 
153
- if !first_record_off_same_collection.respond_to?(:watched_keys_for_snapshot) && !first_record_off_same_collection.nil?
162
+ if !first_record_off_same_collection.nil? && !active_storage_record?(first_record_off_same_collection) && !first_record_off_same_collection.respond_to?(:watched_keys_for_snapshot)
154
163
  raise NotImplementedError, "please add method 'watched_keys_for_snapshot' to #{first_record_off_same_collection.class}"
155
164
  end
156
165
 
157
166
  association_ignored_keys =
158
- if !first_record_off_same_collection.try(:watched_keys_for_snapshot).nil?
167
+ if active_storage_record?(first_record_off_same_collection)
168
+ default_ignored_keys
169
+ elsif !first_record_off_same_collection.try(:watched_keys_for_snapshot).nil?
159
170
  assoc_ignore_keys = first_record_off_same_collection.attributes.except(*first_record_off_same_collection.watched_keys_for_snapshot.map(&:to_s)).keys.map(&:to_s)
160
171
  (default_ignored_keys + assoc_ignore_keys).uniq
161
172
  else
@@ -163,13 +174,13 @@ module Glib
163
174
  end
164
175
 
165
176
  # always watch column with name *id
166
- association_ignored_keys.filter! { |key| !key.ends_with?('id') || key != 'id' }
177
+ association_ignored_keys.reject! { |key| key == 'id' || key.ends_with?('_id') }
167
178
 
168
179
  # attrs_before = (associations[curr] || []).map { |record| record.attributes.except(*association_ignored_keys) }
169
180
  # attrs_now = send(curr).order(id: :asc).map { |record| record.attributes.except(*association_ignored_keys) }
170
181
 
171
182
  before = (associations[curr] || [])
172
- now = send(curr).order(id: :asc)
183
+ now = association_records
173
184
 
174
185
  if before.blank?
175
186
  prev.merge(curr.to_s => ::Hashdiff.diff([], now.map { |record| record.attributes.except(*association_ignored_keys) }))
@@ -238,5 +249,52 @@ module Glib
238
249
  def max_snapshots
239
250
  10
240
251
  end
252
+
253
+ private
254
+ def active_storage_association?(association, association_value)
255
+ return true if association&.macro == :has_many_attached || association&.macro == :has_one_attached
256
+ return false if association_value.nil?
257
+
258
+ if defined?(ActiveStorage::Attached)
259
+ return true if association_value.is_a?(ActiveStorage::Attached::Many) || association_value.is_a?(ActiveStorage::Attached::One)
260
+ end
261
+
262
+ association_value.respond_to?(:attachments) || association_value.respond_to?(:attachment)
263
+ end
264
+
265
+ def active_storage_records(value)
266
+ if value.respond_to?(:attachments)
267
+ value.attachments
268
+ elsif value.respond_to?(:attachment)
269
+ Array(value.attachment).compact
270
+ else
271
+ []
272
+ end
273
+ end
274
+
275
+ def active_storage_record?(record)
276
+ return false if record.nil?
277
+
278
+ (defined?(ActiveStorage::Attachment) && record.is_a?(ActiveStorage::Attachment)) ||
279
+ record.class.name.start_with?('ActiveStorage::Attachment')
280
+ end
281
+
282
+ def records_for_snapshot(association_name)
283
+ association_value = public_send(association_name)
284
+
285
+ records = if active_storage_association?(self.class.reflect_on_association(association_name), association_value)
286
+ active_storage_records(association_value)
287
+ else
288
+ association_value
289
+ end
290
+
291
+ if records.respond_to?(:order)
292
+ records.order(id: :asc)
293
+ elsif records.respond_to?(:sort_by)
294
+ records.sort_by { |record| record.try(:id) || 0 }
295
+ else
296
+ Array(records)
297
+ end
298
+ end
241
299
  end
242
300
  end
data/lib/tasks/db.rake CHANGED
@@ -63,7 +63,7 @@ namespace :db do
63
63
 
64
64
  entries.each do |a|
65
65
  attrs = Hash[a.attributes.sort]
66
- # attrs.delete_if { |k, v| v.nil? }
66
+ attrs.delete_if { |k, v| v.nil? }
67
67
 
68
68
  id = if attrs.include?('id')
69
69
  [a.id]
metadata CHANGED
@@ -1,11 +1,11 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glib-web
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.39.2
4
+ version: 4.41.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ''
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
  date: 2019-10-04 00:00:00.000000000 Z
@@ -136,7 +136,7 @@ dependencies:
136
136
  - - ">="
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
- description:
139
+ description:
140
140
  email: ''
141
141
  executables: []
142
142
  extensions: []
@@ -427,7 +427,6 @@ files:
427
427
  - lib/glib-web.rb
428
428
  - lib/glib/all_helpers.rb
429
429
  - lib/glib/crypt/utils.rb
430
- - lib/glib/doc_generator.rb
431
430
  - lib/glib/dynamic_text.rb
432
431
  - lib/glib/dynamic_text/config.rb
433
432
  - lib/glib/engine.rb
@@ -463,10 +462,10 @@ files:
463
462
  - lib/glib/version.rb
464
463
  - lib/tasks/db.rake
465
464
  - lib/tasks/docs.rake
466
- homepage:
465
+ homepage:
467
466
  licenses: []
468
467
  metadata: {}
469
- post_install_message:
468
+ post_install_message:
470
469
  rdoc_options: []
471
470
  require_paths:
472
471
  - lib
@@ -482,7 +481,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
482
481
  version: '0'
483
482
  requirements: []
484
483
  rubygems_version: 3.4.6
485
- signing_key:
484
+ signing_key:
486
485
  specification_version: 4
487
486
  summary: ''
488
487
  test_files: []