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.
- checksums.yaml +4 -4
- data/app/helpers/glib/json_ui/action_builder/dialogs.rb +3 -0
- data/app/helpers/glib/json_ui/page_helper.rb +6 -0
- data/app/helpers/glib/json_ui/view_builder/fields.rb +574 -35
- data/app/helpers/glib/json_ui/view_builder/panels.rb +5 -1
- data/app/views/json_ui/garage/actions/_dialogs.json.jbuilder +71 -17
- data/app/views/json_ui/garage/actions/_dialogs_show.json.jbuilder +10 -1
- data/app/views/json_ui/garage/forms/pickers.json.jbuilder +13 -0
- data/app/views/json_ui/garage/forms/text_validation.json.jbuilder +4 -0
- data/app/views/json_ui/garage/lists/edit_actions.json.jbuilder +96 -66
- data/app/views/json_ui/garage/lists/edit_mode.json.jbuilder +58 -41
- data/app/views/json_ui/garage/panels/timeline.json.jbuilder +82 -73
- data/app/views/json_ui/garage/test_page/lifecycle.json.jbuilder +3 -0
- data/lib/glib/snapshot.rb +75 -17
- data/lib/tasks/db.rake +1 -1
- metadata +6 -7
- data/lib/glib/doc_generator.rb +0 -386
|
@@ -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
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
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
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
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
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
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
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
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
|
-
|
|
82
|
+
)
|
|
76
83
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
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
|
-
|
|
86
|
-
|
|
87
|
-
end
|
|
95
|
+
end
|
|
96
|
+
)
|
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
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
-
|
|
36
|
-
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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
|
|
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.
|
|
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 =
|
|
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
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.
|
|
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: []
|