glib-web 4.31.1 → 4.32.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/http.rb +1 -0
- data/app/helpers/glib/json_ui/view_builder/fields.rb +8 -0
- data/app/helpers/glib/json_ui/view_builder/panels.rb +2 -0
- data/app/views/json_ui/garage/actions/_detects.json.jbuilder +3 -1
- data/app/views/json_ui/garage/actions/_dialogs_show.json.jbuilder +23 -1
- data/app/views/json_ui/garage/actions/_http.json.jbuilder +18 -0
- data/app/views/json_ui/garage/panels/flow.json.jbuilder +17 -17
- data/app/views/json_ui/garage/views/shareButton.json.jbuilder +7 -8
- data/lib/glib/json_crawler/action_crawlers/windows_open.rb +2 -1
- data/lib/glib/json_crawler/router.rb +3 -1
- data/lib/glib/snapshot.rb +145 -0
- data/lib/glib-web.rb +4 -1
- metadata +35 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f339d19fc2b321412b8c6677939a2aa4d68c4a7d542c7fb0f6e77975593003c7
|
4
|
+
data.tar.gz: acd6bbbde7c0631b3d8105e6fb796968184a7f3ac3104ddb22ef5c1881fe1d89
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6ba9dd32fcbb17c785e56e806e9b55d283b8ae7db19a75cfbe223b2b357b57d6fdb022d21a403dd24d994fc3c110abe0182178e65cea7ce18b0917ef79f7c19b
|
7
|
+
data.tar.gz: 6b6aeddb28afa1afd684bf3d142bc923fbb86257009548bedc1889f966e5876a23c4548f738f6ebdd76acde196fd20570e11fef9205122dfc74bfaee529729b7
|
@@ -10,7 +10,9 @@ section.rows builder: ->(template) do
|
|
10
10
|
end
|
11
11
|
template.thumbnail title: 'Detect Country', onClick: ->(action) do
|
12
12
|
action.browsers_detectCountry onDetect: ->(detect) do
|
13
|
-
detect.http_post url: json_ui_garage_url(path: 'forms/generic_post_all')
|
13
|
+
detect.http_post url: json_ui_garage_url(path: 'forms/generic_post_all'), formData: {
|
14
|
+
message: 'hello'
|
15
|
+
}
|
14
16
|
end
|
15
17
|
end
|
16
18
|
end
|
@@ -3,7 +3,29 @@ markdown = '## Emphasis' + "\n" +
|
|
3
3
|
"\n" +
|
4
4
|
'*This is italic text*' + "\n" +
|
5
5
|
"\n" +
|
6
|
-
'~~Strikethrough~~' + "\n"
|
6
|
+
'~~Strikethrough~~' + "\n" + "
|
7
|
+
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
|
8
|
+
Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.
|
9
|
+
It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged.
|
10
|
+
It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages,
|
11
|
+
and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
|
12
|
+
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
|
13
|
+
Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.
|
14
|
+
It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged.
|
15
|
+
It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages,
|
16
|
+
and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
|
17
|
+
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
|
18
|
+
Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.
|
19
|
+
It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged.
|
20
|
+
It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages,
|
21
|
+
and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
|
22
|
+
Lorem Ipsum is simply dummy text of the printing and typesetting industry.
|
23
|
+
Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.
|
24
|
+
It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged.
|
25
|
+
It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages,
|
26
|
+
and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.
|
27
|
+
"
|
28
|
+
|
7
29
|
|
8
30
|
options = {}
|
9
31
|
if (update_existing = local_assigns[:update_existing])
|
@@ -10,15 +10,33 @@ section.rows builder: ->(template) do
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
+
template.thumbnail title: 'http/post (error page)', onClick: ->(action) do
|
14
|
+
action.auth_saveCsrfToken token: form_authenticity_token, onSave: ->(subaction) do
|
15
|
+
subaction.http_post retryLimit: 5, url: json_ui_garage_url(path: SecureRandom.hex(3)), formData: { user: { name: { first: 'New', last: 'Joe' } } }
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
13
19
|
template.thumbnail title: 'http/patch', onClick: ->(action) do
|
14
20
|
action.auth_saveCsrfToken token: form_authenticity_token, onSave: ->(subaction) do
|
15
21
|
subaction.http_patch url: json_ui_garage_url(path: 'forms/basic_post'), formData: { 'user[name]' => 'Edit Joe' }
|
16
22
|
end
|
17
23
|
end
|
18
24
|
|
25
|
+
template.thumbnail title: 'http/patch (error page)', onClick: ->(action) do
|
26
|
+
action.auth_saveCsrfToken token: form_authenticity_token, onSave: ->(subaction) do
|
27
|
+
subaction.http_patch url: json_ui_garage_url(path: SecureRandom.hex(3)), formData: { 'user[name]' => 'Edit Joe' }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
19
31
|
template.thumbnail title: 'http/delete', onClick: ->(action) do
|
20
32
|
action.auth_saveCsrfToken token: form_authenticity_token, onSave: ->(subaction) do
|
21
33
|
subaction.http_delete url: json_ui_garage_url(path: 'forms/basic_post'), formData: { 'user[name]' => 'Delete Joe' }
|
22
34
|
end
|
23
35
|
end
|
36
|
+
|
37
|
+
template.thumbnail title: 'http/delete (error page)', onClick: ->(action) do
|
38
|
+
action.auth_saveCsrfToken token: form_authenticity_token, onSave: ->(subaction) do
|
39
|
+
subaction.http_delete url: json_ui_garage_url(path: SecureRandom.hex(3)), formData: { 'user[name]' => 'Delete Joe' }
|
40
|
+
end
|
41
|
+
end
|
24
42
|
end
|
@@ -60,21 +60,21 @@ page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
|
|
60
60
|
panel.button text: '5'
|
61
61
|
end
|
62
62
|
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
63
|
+
scroll.label text: "\n"
|
64
|
+
scroll.h1 text: 'Alignments'
|
65
|
+
scroll.panels_horizontal align: 'top', childViews: ->(panel) do
|
66
|
+
panel.button height: 50, text: 'Button'
|
67
|
+
panel.spacer width: 10
|
68
|
+
panel.label text: 'top'
|
69
|
+
end
|
70
|
+
scroll.panels_horizontal align: 'middle', childViews: ->(panel) do
|
71
|
+
panel.button height: 50, text: 'Button'
|
72
|
+
panel.spacer width: 10
|
73
|
+
panel.label text: 'middle'
|
74
|
+
end
|
75
|
+
scroll.panels_horizontal align: 'bottom', childViews: ->(panel) do
|
76
|
+
panel.button height: 50, text: 'Button'
|
77
|
+
panel.spacer width: 10
|
78
|
+
panel.label text: 'bottom'
|
79
|
+
end
|
80
80
|
end
|
@@ -21,14 +21,13 @@ page.scroll padding: glib_json_padding_body, childViews: ->(scroll) do
|
|
21
21
|
|
22
22
|
f.spacer width: 10
|
23
23
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
# end
|
24
|
+
f.shareButton \
|
25
|
+
network: 'email',
|
26
|
+
url: '',
|
27
|
+
text: 'Email',
|
28
|
+
onClick: ->(action) do
|
29
|
+
action.windows_openWeb url: 'mailto:test@email.com'
|
30
|
+
end
|
32
31
|
|
33
32
|
f.spacer width: 10
|
34
33
|
|
@@ -0,0 +1,145 @@
|
|
1
|
+
require 'active_snapshot'
|
2
|
+
require 'hashdiff'
|
3
|
+
|
4
|
+
module Glib
|
5
|
+
module Snapshot
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
include ::ActiveSnapshot
|
10
|
+
|
11
|
+
attr_accessor :snapshot_changed
|
12
|
+
attr_accessor :attributes_before_save
|
13
|
+
|
14
|
+
before_save do
|
15
|
+
self.attributes_before_save = attributes_in_database
|
16
|
+
self.snapshot_changed = changed?
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# information need to be store:
|
21
|
+
# - action: create, update, destroy
|
22
|
+
# - track changes
|
23
|
+
def glib_create_snapshot!(user, action)
|
24
|
+
known_actions = ['create', 'update', 'destroy']
|
25
|
+
|
26
|
+
raise 'unknown action' if !known_actions.include?(action.to_s)
|
27
|
+
|
28
|
+
result = nil
|
29
|
+
with_lock do
|
30
|
+
version = last_version + 1
|
31
|
+
metadata = {
|
32
|
+
action: action,
|
33
|
+
diff: diff,
|
34
|
+
version: version
|
35
|
+
}
|
36
|
+
|
37
|
+
# dont create version if same as before
|
38
|
+
if !same_as_before?
|
39
|
+
|
40
|
+
result = create_snapshot!(
|
41
|
+
identifier: "#{self.class.to_s.underscore}_#{id}_version_#{version}",
|
42
|
+
user: user,
|
43
|
+
metadata: metadata
|
44
|
+
)
|
45
|
+
|
46
|
+
remove_old_snapshot if result.present?
|
47
|
+
end
|
48
|
+
end
|
49
|
+
result
|
50
|
+
end
|
51
|
+
|
52
|
+
def glib_revert_snapshot!(version)
|
53
|
+
snapshot = snapshots.find_by(identifier: "#{self.class.to_s.underscore}_#{id}_version_#{version}")
|
54
|
+
snapshot.restore!
|
55
|
+
end
|
56
|
+
|
57
|
+
def interval_from_prev_version
|
58
|
+
updated_at - snapshot_prev.created_at
|
59
|
+
end
|
60
|
+
|
61
|
+
def diff(snapshot = snapshot_prev)
|
62
|
+
default_ignored_keys = ['updated_at', 'created_at']
|
63
|
+
ignore_keys = default_ignored_keys
|
64
|
+
|
65
|
+
if !try(:watched_keys_for_snapshot).nil?
|
66
|
+
ignored_keys_for_snapshot = attributes.except(*watched_keys_for_snapshot).keys
|
67
|
+
ignore_keys = (default_ignored_keys + ignored_keys_for_snapshot.map(&:to_s)).uniq
|
68
|
+
end
|
69
|
+
|
70
|
+
if snapshot.present?
|
71
|
+
item, associations = snapshot.fetch_reified_items
|
72
|
+
else
|
73
|
+
item = OpenStruct.new(attributes: attributes_before_save || {})
|
74
|
+
associations = {}
|
75
|
+
end
|
76
|
+
|
77
|
+
obj = {
|
78
|
+
'item' => ::Hashdiff.diff(item.attributes.except(*ignore_keys), attributes.except(*ignore_keys))
|
79
|
+
}
|
80
|
+
|
81
|
+
obj['associations'] = associations_for_snapshot.reduce({}) do |prev, curr|
|
82
|
+
first_record_off_same_collection = send(curr).first
|
83
|
+
association_ignored_keys =
|
84
|
+
if !first_record_off_same_collection.try(:watched_keys_for_snapshot).nil?
|
85
|
+
assoc_ignore_keys = first_record_off_same_collection.attributes.except(*first_record_off_same_collection.watched_keys_for_snapshot).keys.map(&:to_s)
|
86
|
+
(default_ignored_keys + assoc_ignore_keys).uniq
|
87
|
+
else
|
88
|
+
default_ignored_keys
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
attrs_before = (associations[curr] || []).map { |record| record.attributes.except(*association_ignored_keys) }
|
93
|
+
attrs_now = send(curr).order(id: :asc).map { |record| record.attributes.except(*association_ignored_keys) }
|
94
|
+
|
95
|
+
prev.merge(
|
96
|
+
curr.to_s => ::Hashdiff.diff(
|
97
|
+
attrs_before,
|
98
|
+
attrs_now
|
99
|
+
)
|
100
|
+
)
|
101
|
+
end
|
102
|
+
|
103
|
+
obj
|
104
|
+
end
|
105
|
+
|
106
|
+
def snapshot_prev
|
107
|
+
snapshots.order(id: :asc).last
|
108
|
+
end
|
109
|
+
|
110
|
+
def same_as_before?
|
111
|
+
return !snapshot_changed if snapshot_prev.blank?
|
112
|
+
|
113
|
+
result = diff['item'].blank?
|
114
|
+
|
115
|
+
result &&= diff['associations'].reduce(true) { |prev, (_k, v)| v.blank? && prev } if diff['associations'].present?
|
116
|
+
|
117
|
+
result
|
118
|
+
end
|
119
|
+
|
120
|
+
def last_version
|
121
|
+
return 0 if snapshot_prev.blank?
|
122
|
+
|
123
|
+
snapshot_prev.metadata['version']
|
124
|
+
end
|
125
|
+
|
126
|
+
def remove_old_snapshot
|
127
|
+
newest_ids = snapshots.order(id: :desc).limit(max_snapshots).ids
|
128
|
+
return unless newest_ids.size >= max_snapshots
|
129
|
+
|
130
|
+
snapshots.where.not(id: newest_ids).destroy_all
|
131
|
+
end
|
132
|
+
|
133
|
+
def watched_keys_for_snapshot
|
134
|
+
nil
|
135
|
+
end
|
136
|
+
|
137
|
+
def associations_for_snapshot
|
138
|
+
children_to_snapshot.keys.filter { |key| respond_to?(key) }
|
139
|
+
end
|
140
|
+
|
141
|
+
def max_snapshots
|
142
|
+
10
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
data/lib/glib-web.rb
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.32.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
|
@@ -80,6 +80,34 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '3.11'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: hashdiff
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: active_snapshot
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
83
111
|
- !ruby/object:Gem::Dependency
|
84
112
|
name: rubocop
|
85
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -94,7 +122,7 @@ dependencies:
|
|
94
122
|
- - ">="
|
95
123
|
- !ruby/object:Gem::Version
|
96
124
|
version: '0'
|
97
|
-
description:
|
125
|
+
description:
|
98
126
|
email: ''
|
99
127
|
executables: []
|
100
128
|
extensions: []
|
@@ -389,16 +417,17 @@ files:
|
|
389
417
|
- lib/glib/json_crawler/http.rb
|
390
418
|
- lib/glib/json_crawler/router.rb
|
391
419
|
- lib/glib/mailer_tester.rb
|
420
|
+
- lib/glib/snapshot.rb
|
392
421
|
- lib/glib/test_helpers.rb
|
393
422
|
- lib/glib/time_freezable_mailer.rb
|
394
423
|
- lib/glib/time_returning_mailer.rb
|
395
424
|
- lib/glib/value.rb
|
396
425
|
- lib/glib/version.rb
|
397
426
|
- lib/tasks/db.rake
|
398
|
-
homepage:
|
427
|
+
homepage:
|
399
428
|
licenses: []
|
400
429
|
metadata: {}
|
401
|
-
post_install_message:
|
430
|
+
post_install_message:
|
402
431
|
rdoc_options: []
|
403
432
|
require_paths:
|
404
433
|
- lib
|
@@ -414,7 +443,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
414
443
|
version: '0'
|
415
444
|
requirements: []
|
416
445
|
rubygems_version: 3.4.6
|
417
|
-
signing_key:
|
446
|
+
signing_key:
|
418
447
|
specification_version: 4
|
419
448
|
summary: ''
|
420
449
|
test_files: []
|