flipper-ui 0.16.2 → 0.20.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/docs/ui/README.md +34 -24
- data/docs/ui/images/banner.png +0 -0
- data/docs/ui/images/description.png +0 -0
- data/docs/ui/images/feature.png +0 -0
- data/docs/ui/images/features.png +0 -0
- data/examples/ui/basic.ru +20 -0
- data/flipper-ui.gemspec +2 -3
- data/lib/flipper/ui/action.rb +3 -6
- data/lib/flipper/ui/actions/feature.rb +5 -2
- data/lib/flipper/ui/actions/features.rb +14 -1
- data/lib/flipper/ui/actions/file.rb +1 -1
- data/lib/flipper/ui/assets/javascripts/application.coffee +5 -3
- data/lib/flipper/ui/configuration.rb +34 -10
- data/lib/flipper/ui/decorators/feature.rb +39 -13
- data/lib/flipper/ui/public/css/application.css +20 -6493
- data/lib/flipper/ui/public/js/application.js +5 -5
- data/lib/flipper/ui/util.rb +40 -0
- data/lib/flipper/ui/views/add_actor.erb +2 -2
- data/lib/flipper/ui/views/add_feature.erb +2 -2
- data/lib/flipper/ui/views/add_group.erb +1 -1
- data/lib/flipper/ui/views/feature.erb +199 -180
- data/lib/flipper/ui/views/features.erb +55 -36
- data/lib/flipper/ui/views/layout.erb +4 -14
- data/lib/flipper/ui.rb +4 -7
- data/lib/flipper/version.rb +1 -1
- data/spec/flipper/ui/actions/actors_gate_spec.rb +9 -13
- data/spec/flipper/ui/actions/feature_spec.rb +14 -16
- data/spec/flipper/ui/actions/features_spec.rb +49 -14
- data/spec/flipper/ui/actions/file_spec.rb +0 -10
- data/spec/flipper/ui/actions/groups_gate_spec.rb +0 -6
- data/spec/flipper/ui/actions/percentage_of_actors_gate_spec.rb +0 -2
- data/spec/flipper/ui/actions/percentage_of_time_gate_spec.rb +0 -2
- data/spec/flipper/ui/configuration_spec.rb +69 -34
- data/spec/flipper/ui/decorators/feature_spec.rb +2 -32
- data/spec/flipper/ui_spec.rb +1 -1
- metadata +21 -133
- data/docs/ui/images/configured-ui.png +0 -0
- data/docs/ui/images/environment-banner.png +0 -0
- data/lib/flipper/ui/assets/stylesheets/.DS_Store +0 -0
- data/lib/flipper/ui/assets/stylesheets/application.scss +0 -19
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_alert.scss +0 -51
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_badge.scss +0 -47
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_breadcrumb.scss +0 -38
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_button-group.scss +0 -166
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_buttons.scss +0 -143
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_card.scss +0 -270
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_carousel.scss +0 -191
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_close.scss +0 -34
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_code.scss +0 -56
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_custom-forms.scss +0 -297
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_dropdown.scss +0 -131
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_forms.scss +0 -333
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_functions.scss +0 -86
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_grid.scss +0 -52
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_images.scss +0 -42
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_input-group.scss +0 -159
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_jumbotron.scss +0 -16
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_list-group.scss +0 -115
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_media.scss +0 -8
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_mixins.scss +0 -42
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_modal.scss +0 -168
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_nav.scss +0 -118
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_navbar.scss +0 -311
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_pagination.scss +0 -77
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_popover.scss +0 -183
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_print.scss +0 -124
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_progress.scss +0 -33
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_reboot.scss +0 -482
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_root.scss +0 -19
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_tables.scss +0 -180
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_tooltip.scss +0 -115
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_transitions.scss +0 -36
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_type.scss +0 -125
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_utilities.scss +0 -14
- data/lib/flipper/ui/assets/stylesheets/bootstrap/_variables.scss +0 -894
- data/lib/flipper/ui/assets/stylesheets/bootstrap/bootstrap-grid.scss +0 -32
- data/lib/flipper/ui/assets/stylesheets/bootstrap/bootstrap-reboot.scss +0 -12
- data/lib/flipper/ui/assets/stylesheets/bootstrap/bootstrap.scss +0 -42
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_alert.scss +0 -13
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_background-variant.scss +0 -21
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_badge.scss +0 -12
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_border-radius.scss +0 -35
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_box-shadow.scss +0 -5
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_breakpoints.scss +0 -123
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_buttons.scss +0 -109
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_caret.scss +0 -65
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_clearfix.scss +0 -7
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_float.scss +0 -11
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_forms.scss +0 -137
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_gradients.scss +0 -45
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_grid-framework.scss +0 -67
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_grid.scss +0 -52
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_hover.scss +0 -39
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_image.scss +0 -36
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_list-group.scss +0 -21
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_lists.scss +0 -7
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_nav-divider.scss +0 -10
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_navbar-align.scss +0 -10
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_pagination.scss +0 -22
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_reset-text.scss +0 -17
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_resize.scss +0 -6
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_screen-reader.scss +0 -35
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_size.scss +0 -6
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_table-row.scss +0 -30
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_text-emphasis.scss +0 -14
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_text-hide.scss +0 -9
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_text-truncate.scss +0 -8
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_transition.scss +0 -9
- data/lib/flipper/ui/assets/stylesheets/bootstrap/mixins/_visibility.scss +0 -7
- data/lib/flipper/ui/assets/stylesheets/bootstrap/utilities/_align.scss +0 -8
- data/lib/flipper/ui/assets/stylesheets/bootstrap/utilities/_background.scss +0 -19
- data/lib/flipper/ui/assets/stylesheets/bootstrap/utilities/_borders.scss +0 -59
- data/lib/flipper/ui/assets/stylesheets/bootstrap/utilities/_clearfix.scss +0 -3
- data/lib/flipper/ui/assets/stylesheets/bootstrap/utilities/_display.scss +0 -38
- data/lib/flipper/ui/assets/stylesheets/bootstrap/utilities/_embed.scss +0 -52
- data/lib/flipper/ui/assets/stylesheets/bootstrap/utilities/_flex.scss +0 -46
- data/lib/flipper/ui/assets/stylesheets/bootstrap/utilities/_float.scss +0 -9
- data/lib/flipper/ui/assets/stylesheets/bootstrap/utilities/_position.scss +0 -36
- data/lib/flipper/ui/assets/stylesheets/bootstrap/utilities/_screenreaders.scss +0 -11
- data/lib/flipper/ui/assets/stylesheets/bootstrap/utilities/_sizing.scss +0 -12
- data/lib/flipper/ui/assets/stylesheets/bootstrap/utilities/_spacing.scss +0 -51
- data/lib/flipper/ui/assets/stylesheets/bootstrap/utilities/_text.scss +0 -52
- data/lib/flipper/ui/assets/stylesheets/bootstrap/utilities/_visibility.scss +0 -11
- data/lib/flipper/ui/assets/stylesheets/primer/.scss-lint.yml +0 -446
- data/lib/flipper/ui/assets/stylesheets/primer/_alerts.scss +0 -106
- data/lib/flipper/ui/assets/stylesheets/primer/_avatars.scss +0 -36
- data/lib/flipper/ui/assets/stylesheets/primer/_base.scss +0 -40
- data/lib/flipper/ui/assets/stylesheets/primer/_blankslate.scss +0 -96
- data/lib/flipper/ui/assets/stylesheets/primer/_buttons.scss +0 -404
- data/lib/flipper/ui/assets/stylesheets/primer/_counter.scss +0 -10
- data/lib/flipper/ui/assets/stylesheets/primer/_filter-list.scss +0 -68
- data/lib/flipper/ui/assets/stylesheets/primer/_flex-table.scss +0 -20
- data/lib/flipper/ui/assets/stylesheets/primer/_forms.scss +0 -756
- data/lib/flipper/ui/assets/stylesheets/primer/_layout.scss +0 -69
- data/lib/flipper/ui/assets/stylesheets/primer/_menu.scss +0 -113
- data/lib/flipper/ui/assets/stylesheets/primer/_mixins.scss +0 -53
- data/lib/flipper/ui/assets/stylesheets/primer/_normalize.scss +0 -425
- data/lib/flipper/ui/assets/stylesheets/primer/_states.scss +0 -32
- data/lib/flipper/ui/assets/stylesheets/primer/_tabnav.scss +0 -65
- data/lib/flipper/ui/assets/stylesheets/primer/_tooltips.scss +0 -255
- data/lib/flipper/ui/assets/stylesheets/primer/_truncate.scss +0 -27
- data/lib/flipper/ui/assets/stylesheets/primer/_type.scss +0 -92
- data/lib/flipper/ui/assets/stylesheets/primer/_utility.scss +0 -73
- data/lib/flipper/ui/assets/stylesheets/primer/_variables.scss +0 -34
- data/lib/flipper/ui/assets/stylesheets/primer/primer.scss +0 -39
- data/lib/flipper/ui/eruby.rb +0 -11
- data/lib/flipper/ui/public/fonts/bootstrap/glyphicons-halflings-regular.eot +0 -0
- data/lib/flipper/ui/public/fonts/bootstrap/glyphicons-halflings-regular.svg +0 -288
- data/lib/flipper/ui/public/fonts/bootstrap/glyphicons-halflings-regular.ttf +0 -0
- data/lib/flipper/ui/public/fonts/bootstrap/glyphicons-halflings-regular.woff +0 -0
- data/lib/flipper/ui/public/fonts/bootstrap/glyphicons-halflings-regular.woff2 +0 -0
- data/lib/flipper/ui/public/images/remove.png +0 -0
- data/lib/flipper/ui/public/octicons/octicons.less +0 -235
- data/lib/flipper/ui/public/octicons/sprockets-octicons.scss +0 -232
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: bfa566d9ce94dadf56643f0f8effcd75795dc478e8098a91374fa20b612d772c
|
4
|
+
data.tar.gz: 0423fa89225c97f21cfe5bc851b43c8d13dbe930764989a8255cd61ab23bdada
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b65bcd93a19db4a5807f6ef4900d99ec9e8bf3232e569d0e5c27d4ad54b294657055448d5b45ee68bc66b9bf03a5810c090b210adf1de7501ea3bd61cdbd4c39
|
7
|
+
data.tar.gz: 52c3fbade80bc667eed46f94059d65f84c1e46330a456dda768c6cbc5e807b0681bb5d8952e88fde8b4dae992009ac559c5073073987bfdc581b55ca75482790
|
data/docs/ui/README.md
CHANGED
@@ -5,9 +5,11 @@ UI for the [Flipper](https://github.com/jnunemaker/flipper) gem.
|
|
5
5
|
## Screenshots
|
6
6
|
|
7
7
|
Viewing list of features:
|
8
|
+
|
8
9
|
![features](images/features.png)
|
9
10
|
|
10
11
|
Viewing an individual feature:
|
12
|
+
|
11
13
|
![feature](images/feature.png)
|
12
14
|
|
13
15
|
## Installation
|
@@ -37,14 +39,15 @@ YourRailsApp::Application.routes.draw do
|
|
37
39
|
end
|
38
40
|
```
|
39
41
|
|
40
|
-
If you'd like to lazy load flipper, you can pass a block
|
42
|
+
If you'd like to lazy load flipper, you can instead pass a block to initialize it:
|
41
43
|
|
42
44
|
```ruby
|
43
45
|
# config/routes.rb
|
44
46
|
YourRailsApp::Application.routes.draw do
|
45
47
|
flipper_block = lambda {
|
46
48
|
# some flipper initialization here, for example:
|
47
|
-
|
49
|
+
adapter = Flipper::Adapters::Memory.new
|
50
|
+
Flipper.new(adapter)
|
48
51
|
}
|
49
52
|
mount Flipper::UI.app(flipper_block) => '/flipper'
|
50
53
|
end
|
@@ -95,7 +98,7 @@ end
|
|
95
98
|
# config/routes.rb
|
96
99
|
|
97
100
|
constraints CanAccessFlipperUI do
|
98
|
-
mount Flipper::UI.app(
|
101
|
+
mount Flipper::UI.app(Flipper) => '/flipper'
|
99
102
|
end
|
100
103
|
```
|
101
104
|
|
@@ -126,32 +129,30 @@ See [examples/ui/basic.ru](https://github.com/jnunemaker/flipper/blob/master/exa
|
|
126
129
|
|
127
130
|
### Configuration
|
128
131
|
|
129
|
-
Flipper UI can be customized via `configure`, which yields a configuration instance
|
132
|
+
Flipper UI can be customized via `configure`, which yields a configuration instance.
|
130
133
|
|
131
|
-
|
132
|
-
* `config.groups`
|
133
|
-
* `config.percentage_of_actors`
|
134
|
-
* `config.percentage_of_time`
|
135
|
-
* `config.delete`
|
134
|
+
#### Description
|
136
135
|
|
137
|
-
|
136
|
+
We can associate a `description` for each `feature` by providing a descriptions source:
|
138
137
|
|
139
|
-
*e.g. customzing the percentage_of_actors and delete sections' titles and descriptions*
|
140
138
|
```ruby
|
141
139
|
Flipper::UI.configure do |config|
|
142
|
-
config.
|
143
|
-
|
140
|
+
config.descriptions_source = ->(keys) do
|
141
|
+
# descriptions loaded from YAML file or database (postgres, mysql, etc)
|
142
|
+
# return has to be hash of {String key => String description}
|
143
|
+
end
|
144
144
|
|
145
|
-
|
146
|
-
|
145
|
+
# Defaults to false. Set to true to show feature descriptions on the list
|
146
|
+
# page as well as the view page.
|
147
|
+
# config.show_feature_description_in_list = true
|
147
148
|
end
|
148
149
|
```
|
149
150
|
|
150
|
-
|
151
|
+
Descriptions show up in the UI like so:
|
151
152
|
|
152
|
-
![
|
153
|
+
![description](images/description.png)
|
153
154
|
|
154
|
-
|
155
|
+
#### Banner
|
155
156
|
|
156
157
|
Flipper UI can display a banner across the top of the page. The `banner_text` and `banner_class` can be configured by using the `Flipper::UI.configure` block as seen below.
|
157
158
|
|
@@ -166,15 +167,24 @@ By default the `environment` is set to an empty string so no banner will show. I
|
|
166
167
|
|
167
168
|
The above configuration results in:
|
168
169
|
|
169
|
-
![
|
170
|
+
![banner](images/banner.png)
|
171
|
+
|
172
|
+
#### Fun mode
|
173
|
+
|
174
|
+
By default, Flipper UI displays a videoclip when there are no flags. The `fun` mode can be configured by using the `Flipper::UI.configure` block as seen below.
|
175
|
+
|
176
|
+
```ruby
|
177
|
+
Flipper::UI.configure do |config|
|
178
|
+
config.fun = false
|
179
|
+
end
|
180
|
+
```
|
170
181
|
|
171
182
|
## Contributing
|
172
183
|
|
173
184
|
1. Fork it
|
174
185
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
175
186
|
3. **Fire up the app** (`script/server`)
|
176
|
-
4.
|
177
|
-
5.
|
178
|
-
6.
|
179
|
-
7.
|
180
|
-
8. Create new Pull Request
|
187
|
+
4. Run the tests `bundle exec rake`
|
188
|
+
5. Commit your changes (`git commit -am 'Added some feature'`)
|
189
|
+
6. Push to the branch (`git push origin my-new-feature`)
|
190
|
+
7. Create new Pull Request
|
Binary file
|
Binary file
|
data/docs/ui/images/feature.png
CHANGED
Binary file
|
data/docs/ui/images/features.png
CHANGED
Binary file
|
data/examples/ui/basic.ru
CHANGED
@@ -34,6 +34,26 @@ end
|
|
34
34
|
adapter = Flipper::Adapters::PStore.new
|
35
35
|
flipper = Flipper.new(adapter, instrumenter: ActiveSupport::Notifications)
|
36
36
|
|
37
|
+
Flipper::UI.configure do |config|
|
38
|
+
# config.banner_text = 'Production Environment'
|
39
|
+
# config.banner_class = 'danger'
|
40
|
+
config.feature_creation_enabled = true
|
41
|
+
config.feature_removal_enabled = true
|
42
|
+
# config.show_feature_description_in_list = true
|
43
|
+
config.descriptions_source = lambda do |_keys|
|
44
|
+
{
|
45
|
+
"search_performance_another_long_thing" => "Just to test feature name length.",
|
46
|
+
"gauges_tracking" => "Should we track page views with gaug.es.",
|
47
|
+
"unused" => "Not used.",
|
48
|
+
"suits" => "Are suits necessary in business?",
|
49
|
+
"secrets" => "Secrets are lies.",
|
50
|
+
"logging" => "Log all the things.",
|
51
|
+
"new_cache" => "Like the old cache but newer.",
|
52
|
+
"a/b" => "Why would someone use a slash? I don't know but someone did. Let's make this really long so they regret using slashes. Please don't use slashes.",
|
53
|
+
}
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
37
57
|
# You can uncomment these to get some default data:
|
38
58
|
# flipper[:search_performance_another_long_thing].enable
|
39
59
|
# flipper[:gauges_tracking].enable
|
data/flipper-ui.gemspec
CHANGED
@@ -10,7 +10,6 @@ Gem::Specification.new do |gem|
|
|
10
10
|
gem.authors = ['John Nunemaker']
|
11
11
|
gem.email = ['nunemaker@gmail.com']
|
12
12
|
gem.summary = 'UI for the Flipper gem'
|
13
|
-
gem.description = 'Rack middleware that provides a fully featured web interface for the flipper gem.'
|
14
13
|
gem.license = 'MIT'
|
15
14
|
gem.homepage = 'https://github.com/jnunemaker/flipper'
|
16
15
|
|
@@ -22,7 +21,7 @@ Gem::Specification.new do |gem|
|
|
22
21
|
gem.metadata = Flipper::METADATA
|
23
22
|
|
24
23
|
gem.add_dependency 'rack', '>= 1.4', '< 3'
|
25
|
-
gem.add_dependency 'rack-protection', '>= 1.5.3', '< 2.
|
24
|
+
gem.add_dependency 'rack-protection', '>= 1.5.3', '< 2.2.0'
|
26
25
|
gem.add_dependency 'flipper', "~> #{Flipper::VERSION}"
|
27
|
-
gem.add_dependency '
|
26
|
+
gem.add_dependency 'erubi', '>= 1.0.0', '< 2.0.0'
|
28
27
|
end
|
data/lib/flipper/ui/action.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'forwardable'
|
2
|
+
require 'flipper/ui/configuration'
|
2
3
|
require 'flipper/ui/error'
|
3
|
-
require '
|
4
|
+
require 'erubi'
|
4
5
|
require 'json'
|
5
6
|
|
6
7
|
module Flipper
|
@@ -205,12 +206,8 @@ module Flipper
|
|
205
206
|
# Private
|
206
207
|
def view(name)
|
207
208
|
path = views_path.join("#{name}.erb")
|
208
|
-
|
209
209
|
raise "Template does not exist: #{path}" unless path.exist?
|
210
|
-
|
211
|
-
contents = path.read
|
212
|
-
compiled = Eruby.new(contents)
|
213
|
-
compiled.result proc {}.binding
|
210
|
+
eval(Erubi::Engine.new(path.read, escape: true).src)
|
214
211
|
end
|
215
212
|
|
216
213
|
# Internal: The path the app is mounted at.
|
@@ -10,9 +10,12 @@ module Flipper
|
|
10
10
|
route %r{\A/features/(?<feature_name>.*)\Z}
|
11
11
|
|
12
12
|
def get
|
13
|
-
|
13
|
+
flipper_feature = flipper[feature_name]
|
14
|
+
@feature = Decorators::Feature.new(flipper_feature)
|
15
|
+
descriptions = Flipper::UI.configuration.descriptions_source.call([flipper_feature.key])
|
16
|
+
@feature.description = descriptions[@feature.key]
|
14
17
|
@page_title = "#{@feature.key} // Features"
|
15
|
-
@percentages = [0, 1, 5, 10,
|
18
|
+
@percentages = [0, 1, 5, 10, 25, 50, 100]
|
16
19
|
|
17
20
|
breadcrumb 'Home', '/'
|
18
21
|
breadcrumb 'Features', '/features'
|
@@ -10,8 +10,21 @@ module Flipper
|
|
10
10
|
|
11
11
|
def get
|
12
12
|
@page_title = 'Features'
|
13
|
+
keys = flipper.features.map(&:key)
|
14
|
+
descriptions = if Flipper::UI.configuration.show_feature_description_in_list?
|
15
|
+
Flipper::UI.configuration.descriptions_source.call(keys)
|
16
|
+
else
|
17
|
+
{}
|
18
|
+
end
|
19
|
+
|
13
20
|
@features = flipper.features.map do |feature|
|
14
|
-
Decorators::Feature.new(feature)
|
21
|
+
decorated_feature = Decorators::Feature.new(feature)
|
22
|
+
|
23
|
+
if Flipper::UI.configuration.show_feature_description_in_list?
|
24
|
+
decorated_feature.description = descriptions[feature.key]
|
25
|
+
end
|
26
|
+
|
27
|
+
decorated_feature
|
15
28
|
end.sort
|
16
29
|
|
17
30
|
@show_blank_slate = @features.empty?
|
@@ -3,11 +3,7 @@ require 'flipper/ui/configuration/option'
|
|
3
3
|
module Flipper
|
4
4
|
module UI
|
5
5
|
class Configuration
|
6
|
-
attr_reader :
|
7
|
-
:delete,
|
8
|
-
:groups,
|
9
|
-
:percentage_of_actors,
|
10
|
-
:percentage_of_time
|
6
|
+
attr_reader :delete
|
11
7
|
|
12
8
|
attr_accessor :banner_text,
|
13
9
|
:banner_class
|
@@ -26,6 +22,24 @@ module Flipper
|
|
26
22
|
# set to false, users won't be able to delete features from the UI.
|
27
23
|
attr_accessor :feature_removal_enabled
|
28
24
|
|
25
|
+
# Public: Are you feeling lucky? Defaults to true. If set to false, users
|
26
|
+
# won't see a videoclip of Taylor Swift when there aren't any features
|
27
|
+
attr_accessor :fun
|
28
|
+
|
29
|
+
# Public: What should show up in the form to add actors. This can be
|
30
|
+
# different per application since flipper_id's can be whatever an
|
31
|
+
# application needs. Defaults to "a flipper id".
|
32
|
+
attr_accessor :add_actor_placeholder
|
33
|
+
|
34
|
+
# Public: If you set this, Flipper::UI will fetch descriptions
|
35
|
+
# from your external source. Descriptions for `features` will be shown on `feature`
|
36
|
+
# page, and optionally the `features` pages. Defaults to empty block.
|
37
|
+
attr_accessor :descriptions_source
|
38
|
+
|
39
|
+
# Public: Should feature descriptions be show on the `features` list page.
|
40
|
+
# Default false. Only works when using descriptions.
|
41
|
+
attr_accessor :show_feature_description_in_list
|
42
|
+
|
29
43
|
VALID_BANNER_CLASS_VALUES = %w(
|
30
44
|
danger
|
31
45
|
dark
|
@@ -37,16 +51,26 @@ module Flipper
|
|
37
51
|
warning
|
38
52
|
).freeze
|
39
53
|
|
54
|
+
DEFAULT_DESCRIPTIONS_SOURCE = ->(_keys) { {} }
|
55
|
+
|
40
56
|
def initialize
|
41
|
-
@
|
42
|
-
@groups = Option.new("Groups", "Enable groups using the form above.")
|
43
|
-
@percentage_of_actors = Option.new("Percentage of Actors", "Percentage of actors functions independently of percentage of time. If you enable 50% of Actors and 25% of Time then the feature will always be enabled for 50% of users and occasionally enabled 25% of the time for everyone.") # rubocop:disable Metrics/LineLength
|
44
|
-
@percentage_of_time = Option.new("Percentage of Time", "Percentage of actors functions independently of percentage of time. If you enable 50% of Actors and 25% of Time then the feature will always be enabled for 50% of users and occasionally enabled 25% of the time for everyone.") # rubocop:disable Metrics/LineLength
|
45
|
-
@delete = Option.new("Danger Zone", "Deleting a feature removes it from the list of features and disables it for everyone.") # rubocop:disable Metrics/LineLength
|
57
|
+
@delete = Option.new("Danger Zone", "Deleting a feature removes it from the list of features and disables it for everyone.")
|
46
58
|
@banner_text = nil
|
47
59
|
@banner_class = 'danger'
|
48
60
|
@feature_creation_enabled = true
|
49
61
|
@feature_removal_enabled = true
|
62
|
+
@fun = true
|
63
|
+
@add_actor_placeholder = "a flipper id"
|
64
|
+
@descriptions_source = DEFAULT_DESCRIPTIONS_SOURCE
|
65
|
+
@show_feature_description_in_list = false
|
66
|
+
end
|
67
|
+
|
68
|
+
def using_descriptions?
|
69
|
+
@descriptions_source != DEFAULT_DESCRIPTIONS_SOURCE
|
70
|
+
end
|
71
|
+
|
72
|
+
def show_feature_description_in_list?
|
73
|
+
using_descriptions? && @show_feature_description_in_list
|
50
74
|
end
|
51
75
|
|
52
76
|
def banner_class=(value)
|
@@ -11,24 +11,15 @@ module Flipper
|
|
11
11
|
# Public: The feature being decorated.
|
12
12
|
alias_method :feature, :__getobj__
|
13
13
|
|
14
|
+
# Internal: Used to preload description if descriptions_source is
|
15
|
+
# configured for Flipper::UI.
|
16
|
+
attr_accessor :description
|
17
|
+
|
14
18
|
# Public: Returns name titleized.
|
15
19
|
def pretty_name
|
16
20
|
@pretty_name ||= Util.titleize(name)
|
17
21
|
end
|
18
22
|
|
19
|
-
# Public: Returns instance as hash that is ready to be json dumped.
|
20
|
-
def as_json
|
21
|
-
gate_values = feature.gate_values
|
22
|
-
{
|
23
|
-
'id' => name.to_s,
|
24
|
-
'name' => pretty_name,
|
25
|
-
'state' => state.to_s,
|
26
|
-
'gates' => gates.map do |gate|
|
27
|
-
Decorators::Gate.new(gate, gate_values[gate.key]).as_json
|
28
|
-
end,
|
29
|
-
}
|
30
|
-
end
|
31
|
-
|
32
23
|
def color_class
|
33
24
|
case feature.state
|
34
25
|
when :on
|
@@ -40,6 +31,41 @@ module Flipper
|
|
40
31
|
end
|
41
32
|
end
|
42
33
|
|
34
|
+
def gates_in_words
|
35
|
+
return "Fully Enabled" if feature.boolean_value
|
36
|
+
|
37
|
+
statuses = []
|
38
|
+
|
39
|
+
if feature.actors_value.count > 0
|
40
|
+
statuses << %Q(<span data-toggle="tooltip" data-placement="bottom" title="#{Util.to_sentence(feature.actors_value.to_a)}">) + Util.pluralize(feature.actors_value.count, 'actor', 'actors') + "</span>"
|
41
|
+
end
|
42
|
+
|
43
|
+
if feature.groups_value.count > 0
|
44
|
+
statuses << %Q(<span data-toggle="tooltip" data-placement="bottom" title="#{Util.to_sentence(feature.groups_value.to_a)}">) + Util.pluralize(feature.groups_value.count, 'group', 'groups') + "</span>"
|
45
|
+
end
|
46
|
+
|
47
|
+
if feature.percentage_of_actors_value > 0
|
48
|
+
statuses << "#{feature.percentage_of_actors_value}% of actors"
|
49
|
+
end
|
50
|
+
|
51
|
+
if feature.percentage_of_time_value > 0
|
52
|
+
statuses << "#{feature.percentage_of_time_value}% of time"
|
53
|
+
end
|
54
|
+
|
55
|
+
Util.to_sentence(statuses)
|
56
|
+
end
|
57
|
+
|
58
|
+
def gate_state_title
|
59
|
+
case feature.state
|
60
|
+
when :on
|
61
|
+
"Fully enabled"
|
62
|
+
when :conditional
|
63
|
+
"Conditionally enabled"
|
64
|
+
else
|
65
|
+
"Disabled"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
43
69
|
def pretty_enabled_gate_names
|
44
70
|
enabled_gates.map { |gate| Util.titleize(gate.key) }.sort.join(', ')
|
45
71
|
end
|