rollout-ui 0.2.0 → 0.5.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: e342dafb4fb3a868d96da458d3227d4d177d168a28e640d3ba6eb4e85caa3393
4
- data.tar.gz: f7d5778665b1da78012854c306b1df04797fe924fa5733d68de3bd1428ce8c84
3
+ metadata.gz: 8a1ec80944aa3ae6f4c7fc142dceb5b0f5f87d111a3a9cec771be3325d5996a8
4
+ data.tar.gz: df9d961f8306cdfd1bd377d6bb6629238c4e2f8ea901c796f27442f03bfa85c1
5
5
  SHA512:
6
- metadata.gz: b91d583fecd5e7b9ba6d0d1adfddec7e5a8894e943d80c9c258bb7399d40fc1687cdbe0b72129b111e5c3dfb162d1fc445784660e09c37adeaa8f95165956658
7
- data.tar.gz: cf24e7f1bb6b083bad9fd4e30f1838cef1b746f662eb3b94f5de28beb69485f2729a38f302b30a3b807505a22259eb951564ef24bf25bb075af56206b2b57ab2
6
+ metadata.gz: 952b01c7614a32d8f2ecd7b94f54f02fe8b0483314c1861065c93400ffa7abd6bba639e47639a0ce084fc173ae3b002944ad21bce9bc504273a3cb7c6fa2785e
7
+ data.tar.gz: 59bcfcb7bbfa61c371b16e692f14afe9b30b7b50b2072eede8849d8c9267b3d54012e1fd8db79571c009b55523f8bc450d13b125e766e9b7ed835c7bf28fc5cb
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 2.6.6
1
+ 3.1.0
data/README.md CHANGED
@@ -58,6 +58,15 @@ Rails.application.routes.draw do
58
58
  end
59
59
  ```
60
60
 
61
+ ## API Endpoints
62
+
63
+ The index and show routes can also respond with JSON data instead of HTML when the request's `Accept` header is
64
+ `application/json`
65
+
66
+ The index route also accepts query parameters to filter by user or group:
67
+ `/admin/rollout?user=someone`
68
+ `/admin/rollout?group=developers`
69
+
61
70
  ## Logging
62
71
 
63
72
  To get the most out of **rollout-ui**, we recommend you to turn on logging
@@ -84,5 +84,29 @@ module Rollout::UI
84
84
  value
85
85
  end
86
86
  end
87
+
88
+ def json_request?
89
+ request.env['HTTP_ACCEPT'] == 'application/json'
90
+ end
91
+
92
+ # Filters features by user and group if those params are provided
93
+ def filtered_features(rollout, feature_names)
94
+ feature_names.select do |feature_name|
95
+ feature = rollout.get(feature_name)
96
+ user_match = params[:user].nil? || feature.users.member?(params[:user])
97
+ group_match = params[:group].nil? || feature.groups.member?(params[:group].to_sym)
98
+ user_match && group_match
99
+ end
100
+ end
101
+
102
+ # Returns a hash of feature data to be rendered as json
103
+ def feature_to_hash(feature)
104
+ {
105
+ data: feature.data,
106
+ groups: feature.groups,
107
+ name: feature.name,
108
+ percentage: feature.percentage
109
+ }
110
+ end
87
111
  end
88
112
  end
@@ -1,5 +1,5 @@
1
1
  class Rollout
2
2
  module UI
3
- VERSION = "0.2.0"
3
+ VERSION = "0.5.0"
4
4
  end
5
5
  end
@@ -24,7 +24,7 @@ h2.font-semibold.text-xl.text-gray-500.pt-12.flex.items-center
24
24
  - @features.each do |feature_name|
25
25
  - feature = @rollout.get(feature_name)
26
26
  tr.border-b.border-gray-200
27
- td.py-2.whitespace-no-wrap
27
+ td.py-2
28
28
  a.text-blue-600(href=feature_path(feature.name) class='hover:text-blue-700 hover:underline')
29
29
  = feature_name
30
30
  div.text-gray-500.text-xs = feature.data['description']
@@ -5,64 +5,69 @@ h2.font-semibold.text-xl.text-gray-500.pt-12
5
5
  = @feature.name
6
6
 
7
7
  .w-8.h-1.bg-gray-300.my-10
8
+ main.p-6.bg-gray-100.max-w-lg.w-full.text-sm.rounded-sm
9
+ form#updateFormSubmit action=feature_path(@feature.name) method='POST'
10
+ .mb-5
11
+ label.block.text-gray-500.mb-2(for='description') Description
12
+ input.appearance-none.border.rounded-sm.w-full.py-2.px-4.text-gray-600.leading-relaxed.bg-white(
13
+ name='description'
14
+ id='description'
15
+ value=@feature.data['description']
16
+ class='hover:border-gray-500'
17
+ )
8
18
 
9
- form.p-6.bg-gray-100.max-w-lg.w-full.text-sm.rounded-sm action=feature_path(@feature.name) method='POST'
10
- .mb-5
11
- label.block.text-gray-500.mb-2(for='description') Description
12
- input.appearance-none.border.rounded-sm.w-full.py-2.px-4.text-gray-600.leading-relaxed.bg-white(
13
- name='description'
14
- id='description'
15
- value=@feature.data['description']
16
- class='hover:border-gray-500'
17
- )
18
-
19
- .mb-5
20
- label.block.text-gray-500.mb-2(for='groups')
21
- | Groups
22
- span.ml-1.text-gray-400
23
- | (multi-select)
24
- select.block.appearance-none.w-full.bg-white.border.border-gray-300.px-4.py-3.rounded-sm.leading-relaxed(name="groups[]" id='groups' multiple=true size=(@rollout.groups.count + 1))
25
- option.py-1.px-1(value='' selected=(@feature.groups.count == 0))
26
- = '(none)'
27
- - @rollout.groups.each do |group|
28
- option.py-1.px-1(
29
- value=group
30
- selected=@feature.groups.include?(group)
31
- )
32
- = group
33
-
34
- .mb-5
35
- label.block.text-gray-500.mb-2(for='percentage') Percentage
36
- input.appearance-none.border.rounded-sm.w-full.py-2.px-4.text-gray-600.leading-relaxed.bg-white(
37
- name='percentage'
38
- id='percentage'
39
- value=@feature.percentage
40
- class='hover:border-gray-500'
41
- type='number'
42
- step='0.1'
43
- )
44
-
45
- .mb-5
46
- label.block.text-gray-500.mb-2 Users
19
+ .mb-5
20
+ label.block.text-gray-500.mb-2(for='groups')
21
+ | Groups
22
+ span.ml-1.text-gray-400
23
+ | (multi-select)
24
+ select.block.appearance-none.w-full.bg-white.border.border-gray-300.px-4.py-3.rounded-sm.leading-relaxed(name="groups[]" id='groups' multiple=true size=(@rollout.groups.count + 1))
25
+ option.py-1.px-1(value='' selected=(@feature.groups.count == 0))
26
+ = '(none)'
27
+ - @rollout.groups.each do |group|
28
+ option.py-1.px-1(
29
+ value=group
30
+ selected=@feature.groups.include?(group)
31
+ )
32
+ = group
47
33
 
48
- - if @feature.users.count > 100
49
- .appearance-none.border.rounded-sm.w-full.py-2.px-4.text-gray-600.leading-relaxed.bg-gray-100
50
- = @feature.users.count
51
- - else
52
- textarea.appearance-none.border.rounded-sm.w-full.py-2.px-4.text-gray-600.leading-relaxed.bg-white(
53
- name='users'
54
- id='users'
55
- value=@feature.users.join(', ')
34
+ .mb-5
35
+ label.block.text-gray-500.mb-2(for='percentage') Percentage
36
+ input.appearance-none.border.rounded-sm.w-full.py-2.px-4.text-gray-600.leading-relaxed.bg-white(
37
+ name='percentage'
38
+ id='percentage'
39
+ value=@feature.percentage
56
40
  class='hover:border-gray-500'
57
- rows='2'
41
+ type='number'
42
+ step='0.1'
58
43
  )
59
- = @feature.users.join(', ')
44
+
45
+ .mb-5
46
+ label.block.text-gray-500.mb-2 Users
47
+
48
+ - if @feature.users.count > 150
49
+ .appearance-none.border.rounded-sm.w-full.py-2.px-4.text-gray-600.leading-relaxed.bg-gray-100
50
+ = @feature.users.count
51
+ - else
52
+ textarea.appearance-none.border.rounded-sm.w-full.py-2.px-4.text-gray-600.leading-relaxed.bg-white(
53
+ name='users'
54
+ id='users'
55
+ value=@feature.users.join(', ')
56
+ class='hover:border-gray-500'
57
+ rows='2'
58
+ )
59
+ = @feature.users.join(', ')
60
60
 
61
61
  .flex.items-center.justify-end
62
62
  form action=delete_feature_path(@feature.name) method='POST'
63
63
  button.mr-5.text-gray-600(class='hover:underline' type='submit' onclick="return confirm('Are you sure you want to delete #{@feature.name}?')")
64
- ' Delete
65
- button.py-4.px-5.bg-gray-700.text-gray-200.rounded-sm.font-bold.leading-none.transition-colors.duration-200(class='hover:bg-gray-800' type='submit') Update
64
+ | Delete
65
+ button.py-4.px-5.bg-gray-700.text-gray-200.rounded-sm.font-bold.leading-none.transition-colors.duration-200(
66
+ type='submit'
67
+ class='hover:bg-gray-800'
68
+ form='updateFormSubmit'
69
+ )
70
+ | Update
66
71
 
67
72
  - history_events = @rollout.respond_to?(:logging) ? @rollout.logging.events(@feature.name).reverse : []
68
73
 
@@ -1,4 +1,5 @@
1
1
  require "sinatra"
2
+ require "sinatra/json"
2
3
  require "rollout"
3
4
 
4
5
  require "rollout/ui/version"
@@ -15,8 +16,15 @@ module Rollout::UI
15
16
  get '/' do
16
17
  @rollout = config.get(:instance)
17
18
  @features = @rollout.features.sort_by(&:downcase)
18
-
19
- slim :'features/index'
19
+ if json_request?
20
+ json(
21
+ filtered_features(@rollout, @features).map do |feature|
22
+ feature_to_hash(@rollout.get(feature))
23
+ end
24
+ )
25
+ else
26
+ slim :'features/index'
27
+ end
20
28
  end
21
29
 
22
30
  get '/features/new' do
@@ -31,7 +39,11 @@ module Rollout::UI
31
39
  @rollout = config.get(:instance)
32
40
  @feature = @rollout.get(params[:feature_name])
33
41
 
34
- slim :'features/show'
42
+ if json_request?
43
+ json(feature_to_hash(@feature))
44
+ else
45
+ slim :'features/show'
46
+ end
35
47
  end
36
48
 
37
49
  post '/features/:feature_name' do
data/rollout-ui.gemspec CHANGED
@@ -24,10 +24,14 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  spec.add_dependency 'rollout', '~> 2.5'
26
26
  spec.add_dependency 'sinatra', '~> 2.0'
27
- spec.add_dependency 'slim', '~> 4.0'
27
+ spec.add_dependency 'sinatra-contrib', '~> 2.1'
28
+ spec.add_dependency 'slim', ['>= 3.0', '< 5.0']
28
29
 
29
- spec.add_development_dependency 'bundler', '~> 1.17'
30
+ spec.add_development_dependency 'bundler', '>= 1.17'
30
31
  spec.add_development_dependency 'rake', '~> 10.0'
31
32
  spec.add_development_dependency 'rspec', '~> 3.0'
32
33
  spec.add_development_dependency 'rerun', '~> 0.13'
34
+ spec.add_development_dependency 'rack-test'
35
+ spec.add_development_dependency 'puma'
36
+ spec.add_development_dependency 'pry'
33
37
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rollout-ui
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.5.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - FetLife
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-07-22 00:00:00.000000000 Z
11
+ date: 2022-09-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rollout
@@ -39,31 +39,51 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '2.0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: slim
42
+ name: sinatra-contrib
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '4.0'
47
+ version: '2.1'
48
48
  type: :runtime
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
52
  - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '4.0'
54
+ version: '2.1'
55
+ - !ruby/object:Gem::Dependency
56
+ name: slim
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '3.0'
62
+ - - "<"
63
+ - !ruby/object:Gem::Version
64
+ version: '5.0'
65
+ type: :runtime
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: '3.0'
72
+ - - "<"
73
+ - !ruby/object:Gem::Version
74
+ version: '5.0'
55
75
  - !ruby/object:Gem::Dependency
56
76
  name: bundler
57
77
  requirement: !ruby/object:Gem::Requirement
58
78
  requirements:
59
- - - "~>"
79
+ - - ">="
60
80
  - !ruby/object:Gem::Version
61
81
  version: '1.17'
62
82
  type: :development
63
83
  prerelease: false
64
84
  version_requirements: !ruby/object:Gem::Requirement
65
85
  requirements:
66
- - - "~>"
86
+ - - ">="
67
87
  - !ruby/object:Gem::Version
68
88
  version: '1.17'
69
89
  - !ruby/object:Gem::Dependency
@@ -108,6 +128,48 @@ dependencies:
108
128
  - - "~>"
109
129
  - !ruby/object:Gem::Version
110
130
  version: '0.13'
131
+ - !ruby/object:Gem::Dependency
132
+ name: rack-test
133
+ requirement: !ruby/object:Gem::Requirement
134
+ requirements:
135
+ - - ">="
136
+ - !ruby/object:Gem::Version
137
+ version: '0'
138
+ type: :development
139
+ prerelease: false
140
+ version_requirements: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ - !ruby/object:Gem::Dependency
146
+ name: puma
147
+ requirement: !ruby/object:Gem::Requirement
148
+ requirements:
149
+ - - ">="
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ type: :development
153
+ prerelease: false
154
+ version_requirements: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ - !ruby/object:Gem::Dependency
160
+ name: pry
161
+ requirement: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ requirements:
170
+ - - ">="
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
111
173
  description: ''
112
174
  email:
113
175
  - dev@fetlife.com
@@ -143,7 +205,7 @@ homepage: https://github.com/fetlife/rollout-ui
143
205
  licenses:
144
206
  - MIT
145
207
  metadata: {}
146
- post_install_message:
208
+ post_install_message:
147
209
  rdoc_options: []
148
210
  require_paths:
149
211
  - lib
@@ -158,8 +220,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
158
220
  - !ruby/object:Gem::Version
159
221
  version: '0'
160
222
  requirements: []
161
- rubygems_version: 3.0.3
162
- signing_key:
223
+ rubygems_version: 3.3.3
224
+ signing_key:
163
225
  specification_version: 4
164
226
  summary: ''
165
227
  test_files: []