flipper-ui 1.2.2 → 1.3.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.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/examples/ui/basic.ru +3 -0
  3. data/flipper-ui.gemspec +2 -1
  4. data/lib/flipper/ui/action.rb +20 -44
  5. data/lib/flipper/ui/actions/actors_gate.rb +0 -6
  6. data/lib/flipper/ui/actions/add_feature.rb +0 -9
  7. data/lib/flipper/ui/actions/feature.rb +0 -7
  8. data/lib/flipper/ui/actions/features.rb +0 -7
  9. data/lib/flipper/ui/actions/groups_gate.rb +0 -5
  10. data/lib/flipper/ui/actions/settings.rb +0 -3
  11. data/lib/flipper/ui/configuration.rb +16 -2
  12. data/lib/flipper/ui/public/css/bootstrap.min.css +6 -0
  13. data/lib/flipper/ui/public/js/application.js +17 -33
  14. data/lib/flipper/ui/public/js/bootstrap.min.js +7 -0
  15. data/lib/flipper/ui/public/js/popper.min.js +6 -0
  16. data/lib/flipper/ui/sources.json +5 -0
  17. data/lib/flipper/ui/views/add_actor.erb +8 -4
  18. data/lib/flipper/ui/views/add_feature.erb +3 -3
  19. data/lib/flipper/ui/views/add_group.erb +14 -9
  20. data/lib/flipper/ui/views/feature.erb +81 -66
  21. data/lib/flipper/ui/views/features.erb +29 -29
  22. data/lib/flipper/ui/views/layout.erb +27 -19
  23. data/lib/flipper/ui/views/settings.erb +4 -4
  24. data/lib/flipper/version.rb +1 -1
  25. data/spec/flipper/ui/actions/actors_gate_spec.rb +2 -2
  26. data/spec/flipper/ui/actions/add_feature_spec.rb +1 -1
  27. data/spec/flipper/ui/actions/groups_gate_spec.rb +1 -1
  28. data/spec/flipper/ui/configuration_spec.rb +9 -4
  29. data/spec/flipper/ui_spec.rb +19 -31
  30. metadata +33 -12
  31. data/lib/flipper/ui/public/css/bootstrap-4.6.0.min.css +0 -7
  32. data/lib/flipper/ui/public/js/bootstrap-4.6.0.min.js +0 -7
  33. data/lib/flipper/ui/public/js/popper-1.12.9.min.js +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c01a5710e8e8c432d0fa8bfd515b75ff75303fdfae89a03a17fd2d0d93506497
4
- data.tar.gz: 36727960c77afaaf1232575824d1c24cf06e1e56bbd59b302e1c0c0f0b9a0031
3
+ metadata.gz: a12462296a49980315b89c5292f35db1ee3725103f9f5d74bfad27b46566847d
4
+ data.tar.gz: c18ce3fbdda93706f31a9216133e3f7db0b8fdc653734e9f5c53e58b737535c6
5
5
  SHA512:
6
- metadata.gz: 163424980f5684d3ba00682fef0b3b50a2bd565f45751bf3f7daa06af8cfd5b1246ea4a76d509edd8a0bdf9d136a7ab583369db8e7578bc07eb903fa5d3949bb
7
- data.tar.gz: c54c31ebe8cceb4859abfa9feaefb38eed81f6d1396fda01baccc561bbf4cc3f20fd6c9807ae27d3888ef7343cf3ce95e693ffbaffd3ec267b69271c4c877e34
6
+ metadata.gz: 3abfd1c41c26090ab35f4d140eb016b2a3537563f6e5bf31b230dc8187d22f7ae8c2955a255d08c33a6f5f06c38a17b917db022997f3a4f1b9f48a7e27b060db
7
+ data.tar.gz: a24a6e6e614e42f36fcbba8d072cab5cc0dab7cef19dac2199925566e79b76ba091bc043741dcf13fd8a2e0dbc683540e1160853c2c4193e7ef825c60a645ae1
data/examples/ui/basic.ru CHANGED
@@ -46,6 +46,8 @@ Flipper::UI.configure do |config|
46
46
  '6' => '<a href="https://opensoul.org">Brandon</a>',
47
47
  }
48
48
  end
49
+
50
+ config.application_href = "https://example.com"
49
51
  end
50
52
 
51
53
  # You can uncomment these to get some default data:
@@ -63,5 +65,6 @@ end
63
65
  use Rack::Reloader
64
66
 
65
67
  run Flipper::UI.app { |builder|
68
+ builder.use Rack::Reloader, 1
66
69
  builder.use Rack::Session::Cookie, secret: "_super_secret"
67
70
  }
data/flipper-ui.gemspec CHANGED
@@ -21,7 +21,8 @@ Gem::Specification.new do |gem|
21
21
  gem.metadata = Flipper::METADATA
22
22
 
23
23
  gem.add_dependency 'rack', '>= 1.4', '< 4'
24
- gem.add_dependency 'rack-protection', '>= 1.5.3', '<= 4.0.0'
24
+ gem.add_dependency 'rack-protection', '>= 1.5.3', '<5.0.0'
25
+ gem.add_dependency 'rack-session', '>= 1.0.2', '< 3.0.0'
25
26
  gem.add_dependency 'flipper', "~> #{Flipper::VERSION}"
26
27
  gem.add_dependency 'erubi', '>= 1.0.0', '< 2.0.0'
27
28
  gem.add_dependency 'sanitize', '< 7'
@@ -27,24 +27,7 @@ module Flipper
27
27
  'delete'.freeze,
28
28
  ]).freeze
29
29
 
30
- SOURCES = {
31
- bootstrap_css: {
32
- src: '/css/bootstrap-4.6.0.min.css'.freeze,
33
- hash: 'sha384-B0vP5xmATw1+K9KRQjQERJvTumQW0nPEzvF6L/Z6nronJ3oUOFUFpCjEUQouq2+l'.freeze
34
- }.freeze,
35
- jquery_js: {
36
- src: '/js/jquery-3.6.0.slim.js'.freeze,
37
- hash: 'sha256-HwWONEZrpuoh951cQD1ov2HUK5zA5DwJ1DNUXaM6FsY='.freeze
38
- }.freeze,
39
- popper_js: {
40
- src: '/js/popper-1.12.9.min.js'.freeze,
41
- hash: 'sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q'.freeze
42
- }.freeze,
43
- bootstrap_js: {
44
- src: '/js/bootstrap-4.6.0.min.js'.freeze,
45
- hash: 'sha384-+YQ4JLhjyBLPDQt//I+STsc9iw4uQqACwlvpslubQzn4u2UU2UFM80nGisd026JF'.freeze
46
- }.freeze
47
- }.freeze
30
+ SOURCES = JSON.parse(File.read(File.expand_path('sources.json', __dir__))).freeze
48
31
  CONTENT_SECURITY_POLICY = <<-CSP.delete("\n")
49
32
  default-src 'none';
50
33
  img-src 'self';
@@ -110,12 +93,6 @@ module Flipper
110
93
  @request = request
111
94
  @code = 200
112
95
  @headers = {Rack::CONTENT_TYPE => 'text/plain'}
113
- @breadcrumbs =
114
- if Flipper::UI.configuration.application_breadcrumb_href
115
- [Breadcrumb.new('App', Flipper::UI.configuration.application_breadcrumb_href)]
116
- else
117
- []
118
- end
119
96
  end
120
97
 
121
98
  # Public: Runs the request method for the provided request.
@@ -219,16 +196,6 @@ module Flipper
219
196
  end
220
197
  end
221
198
 
222
- # Public: Add a breadcrumb to the trail.
223
- #
224
- # text - The String text for the breadcrumb.
225
- # href - The String href for the anchor tag (optional). If nil, breadcrumb
226
- # is assumed to be the end of the trail.
227
- def breadcrumb(text, href = nil)
228
- breadcrumb_href = href.nil? ? href : "#{script_name}#{href}"
229
- @breadcrumbs << Breadcrumb.new(text, breadcrumb_href)
230
- end
231
-
232
199
  # Private
233
200
  def view_with_layout(&block)
234
201
  view :layout, &block
@@ -252,6 +219,16 @@ module Flipper
252
219
  request.env['SCRIPT_NAME']
253
220
  end
254
221
 
222
+ # Internal: Generate urls relative to the app's script name.
223
+ #
224
+ # url_for("feature") # => "http://localhost:9292/flipper/feature"
225
+ # url_for("/thing") # => "http://localhost:9292/thing"
226
+ # url_for("https://example.com") # => "https://example.com"
227
+ #
228
+ def url_for(*parts)
229
+ URI.join(request.base_url, script_name + '/', *parts).to_s
230
+ end
231
+
255
232
  # Private
256
233
  def views_path
257
234
  self.class.views_path
@@ -279,11 +256,6 @@ module Flipper
279
256
  # to inform people of that fact.
280
257
  def render_read_only
281
258
  status 403
282
-
283
- breadcrumb 'Home', '/'
284
- breadcrumb 'Features', '/features'
285
- breadcrumb 'Noooooope'
286
-
287
259
  halt view_response(:read_only)
288
260
  end
289
261
 
@@ -296,19 +268,23 @@ module Flipper
296
268
  end
297
269
 
298
270
  def bootstrap_css
299
- SOURCES[:bootstrap_css]
271
+ asset_hash "/css/bootstrap.min.css"
300
272
  end
301
273
 
302
274
  def bootstrap_js
303
- SOURCES[:bootstrap_js]
275
+ asset_hash "/js/bootstrap.min.js"
304
276
  end
305
277
 
306
278
  def popper_js
307
- SOURCES[:popper_js]
279
+ asset_hash "/js/popper.min.js"
308
280
  end
309
281
 
310
- def jquery_js
311
- SOURCES[:jquery_js]
282
+ def asset_hash(src)
283
+ v = ENV["RACK_ENV"] == "development" ? Time.now.to_i : Flipper::VERSION
284
+ {
285
+ src: "#{src}?v=#{v}",
286
+ hash: SOURCES[src]
287
+ }
312
288
  end
313
289
  end
314
290
  end
@@ -13,12 +13,6 @@ module Flipper
13
13
  def get
14
14
  feature = flipper[feature_name]
15
15
  @feature = Decorators::Feature.new(feature)
16
-
17
- breadcrumb 'Home', '/'
18
- breadcrumb 'Features', '/features'
19
- breadcrumb @feature.key, "/features/#{@feature.key}"
20
- breadcrumb 'Add Actor'
21
-
22
16
  view_response :add_actor
23
17
  end
24
18
 
@@ -12,18 +12,9 @@ module Flipper
12
12
 
13
13
  unless Flipper::UI.configuration.feature_creation_enabled
14
14
  status 403
15
-
16
- breadcrumb 'Home', '/'
17
- breadcrumb 'Features', '/features'
18
- breadcrumb 'Noooooope'
19
-
20
15
  halt view_response(:feature_creation_disabled)
21
16
  end
22
17
 
23
- breadcrumb 'Home', '/'
24
- breadcrumb 'Features', '/features'
25
- breadcrumb 'Add'
26
-
27
18
  view_response :add_feature
28
19
  end
29
20
  end
@@ -18,10 +18,6 @@ module Flipper
18
18
  @page_title = "#{@feature.key} // Features"
19
19
  @percentages = [0, 1, 5, 10, 25, 50, 100]
20
20
 
21
- breadcrumb 'Home', '/'
22
- breadcrumb 'Features', '/features'
23
- breadcrumb @feature.key
24
-
25
21
  view_response :feature
26
22
  end
27
23
 
@@ -31,9 +27,6 @@ module Flipper
31
27
  unless Flipper::UI.configuration.feature_removal_enabled
32
28
  status 403
33
29
 
34
- breadcrumb 'Home', '/'
35
- breadcrumb 'Features', '/features'
36
-
37
30
  halt view_response(:feature_removal_disabled)
38
31
  end
39
32
 
@@ -29,9 +29,6 @@ module Flipper
29
29
 
30
30
  @show_blank_slate = @features.empty?
31
31
 
32
- breadcrumb 'Home', '/'
33
- breadcrumb 'Features'
34
-
35
32
  view_response :features
36
33
  end
37
34
 
@@ -41,10 +38,6 @@ module Flipper
41
38
  unless Flipper::UI.configuration.feature_creation_enabled
42
39
  status 403
43
40
 
44
- breadcrumb 'Home', '/'
45
- breadcrumb 'Features', '/features'
46
- breadcrumb 'Noooooope'
47
-
48
41
  halt view_response(:feature_creation_disabled)
49
42
  end
50
43
 
@@ -13,11 +13,6 @@ module Flipper
13
13
  feature = flipper[feature_name]
14
14
  @feature = Decorators::Feature.new(feature)
15
15
 
16
- breadcrumb 'Home', '/'
17
- breadcrumb 'Features', '/features'
18
- breadcrumb @feature.key, "/features/#{@feature.key}"
19
- breadcrumb 'Add Group'
20
-
21
16
  view_response :add_group
22
17
  end
23
18
 
@@ -10,9 +10,6 @@ module Flipper
10
10
  def get
11
11
  @page_title = 'Settings'
12
12
 
13
- breadcrumb 'Home', '/'
14
- breadcrumb 'Settings'
15
-
16
13
  view_response :settings
17
14
  end
18
15
  end
@@ -13,10 +13,20 @@ module Flipper
13
13
  # (feature_creation_enabled and feature_removal_enabled).
14
14
  attr_accessor :read_only
15
15
 
16
- # Public: If you set this, the UI will always have a first breadcrumb that
16
+ # Public: If you set this, the UI will always have a first nav item that
17
17
  # says "App" which points to this href. The href can be a path (ie: "/")
18
18
  # or full url ("https://app.example.com/").
19
- attr_accessor :application_breadcrumb_href
19
+ attr_accessor :application_href
20
+ alias_method :application_breadcrumb_href, :application_href
21
+ alias_method :application_breadcrumb_href=, :application_href=
22
+
23
+ # Public: An array of nav items to show. By default "Features" and
24
+ # "Settings" are shown, but you can add your own. Each item must have
25
+ # a `:title` and `:href` key:
26
+ #
27
+ # config.nav_items << { title: "Custom", href: "/custom/page" }
28
+ #
29
+ attr_accessor :nav_items
20
30
 
21
31
  # Public: Is feature creation allowed from the UI? Defaults to true. If
22
32
  # set to false, users of the UI cannot create features. All feature
@@ -97,6 +107,10 @@ module Flipper
97
107
  @confirm_fully_enable = false
98
108
  @confirm_disable = true
99
109
  @read_only = false
110
+ @nav_items = [
111
+ { title: "Features", href: "features" },
112
+ { title: "Settings", href: "settings" },
113
+ ]
100
114
  end
101
115
 
102
116
  def using_descriptions?