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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d404f99ae7ff7d1e309c9bedca7b93145bc5331281c64308daa033b9ae6b4524
4
- data.tar.gz: 2f89659ddffb2206989074678c6388176aad57dd872f9b14c43149c51b9e91b5
3
+ metadata.gz: f339d19fc2b321412b8c6677939a2aa4d68c4a7d542c7fb0f6e77975593003c7
4
+ data.tar.gz: acd6bbbde7c0631b3d8105e6fb796968184a7f3ac3104ddb22ef5c1881fe1d89
5
5
  SHA512:
6
- metadata.gz: de7bad6075a55452237fa31c44ad4a0405b6048fa84959385fe12003b1b37b53fc64576c59e658391b4c1efcb3608c62f772a1cffe050b6c2afacd87c86500ea
7
- data.tar.gz: 418db2e1fdf0af1838af518595b4eea273bfe5fd140676870f1a84c3fe8788e585f1701beb23861b84a7b2ade8206d0aed535256eecc5e6669ff69bfbc603749
6
+ metadata.gz: 6ba9dd32fcbb17c785e56e806e9b55d283b8ae7db19a75cfbe223b2b357b57d6fdb022d21a403dd24d994fc3c110abe0182178e65cea7ce18b0917ef79f7c19b
7
+ data.tar.gz: 6b6aeddb28afa1afd684bf3d142bc923fbb86257009548bedc1889f966e5876a23c4548f738f6ebdd76acde196fd20570e11fef9205122dfc74bfaee529729b7
@@ -3,6 +3,7 @@ class Glib::JsonUi::ActionBuilder
3
3
  class AbstractHttp < Action
4
4
  string :url, cache: true
5
5
  bool :silent
6
+ int :retryLimit
6
7
 
7
8
  def formData(hash)
8
9
  form_data = {}
@@ -152,6 +152,14 @@ class Glib::JsonUi::ViewBuilder
152
152
  end
153
153
 
154
154
  class Hidden < Text
155
+
156
+ def created
157
+ # no need to auto translate this
158
+ @label = ''
159
+ @placeholder = ''
160
+
161
+ super
162
+ end
155
163
  end
156
164
 
157
165
  class Timer < Text
@@ -520,6 +520,8 @@ class Glib::JsonUi::ViewBuilder
520
520
 
521
521
  views :childViews
522
522
 
523
+ string :align
524
+
523
525
  # required :innerPadding
524
526
  end
525
527
 
@@ -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
- # 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
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
- # TODO: Fix. Crawler test is failing.
25
- # f.shareButton \
26
- # network: 'email',
27
- # url: '',
28
- # text: 'Email',
29
- # onClick: ->(action) do
30
- # action.windows_openWeb url: 'mailto://test@email.com'
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
 
@@ -5,7 +5,8 @@ module Glib
5
5
  @http = http
6
6
 
7
7
  if (url = args['url'])
8
- json = @http.get(url, action, args.except('url'))
8
+ params = args.except('url').merge('format' => 'json')
9
+ json = @http.get(url, action, params)
9
10
 
10
11
  unless json.nil?
11
12
  @http.router.begin_page(json, url)
@@ -65,7 +65,9 @@ module Glib
65
65
  end
66
66
 
67
67
  if args.is_a?(Hash) && args['rel'] != 'nofollow'
68
- if (on_click = args.fetch('onClick', nil))
68
+ on_click = args.fetch('onClick', nil)
69
+
70
+ if on_click && !args['disabled']
69
71
  process_action(http, on_click)
70
72
  end
71
73
  end
@@ -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
@@ -1,5 +1,8 @@
1
1
  require 'glib/version'
2
- require 'glib/engine' if defined?(::Rails)
2
+ if defined?(::Rails)
3
+ require 'glib/engine'
4
+ require 'glib/snapshot'
5
+ end
3
6
  require 'glib/value'
4
7
  require 'glib/json_crawler'
5
8
 
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.31.1
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: []