flipper-ui 0.26.2 → 0.27.1

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: 26fdd20163d7685661dc097fa0c26fd3f5f4d79656cef5a16e9ae23f14e2f007
4
- data.tar.gz: adb26eb7bbc5920c1acd667293a9aaf636341718ddfd9ab579e1851ab582a023
3
+ metadata.gz: 65f98a2ad17e351b3e366d5fcc570e7783e6e2d757bcb585d49b4b32251c8d8b
4
+ data.tar.gz: 3a267dc1a8c6cd8d69a2774772c2b5de03e39c3ba2170f707f0c86feb246a57f
5
5
  SHA512:
6
- metadata.gz: 436b20f854c2506009b730a385eef183c3eabb173f6440581b82cd86f76c5054a0cde665db2d3451a840eab8ae3a8070cb4c02f8937d40a724e5afb3a7913cb8
7
- data.tar.gz: 04301543cbcb8aa32053ba1c5bdd581d44b3881b3ee93660d0ab519fc1936422fc6c860de04f2cd4c2774cfebf8097a787a72176c38a68625af05f24bcf3fd3f
6
+ metadata.gz: 6100a0f6f8a04877b106afe6a686a730f451ae285b31705297dd8db1b2596a061c0da758a5639e4ac55cbe46e7b59e0c1aa507b8734cfc7e69edebae08fd2f95
7
+ data.tar.gz: c7d0e4d58c421381c766421046ed013e1218fde1518567bec0429af960d3e4ed531881e7afd39d06ce826d0dd987cb8cb4439bbc347e4f5760cce3e350ed7972
@@ -5,6 +5,7 @@
5
5
  # http://localhost:9999/
6
6
  #
7
7
  require 'bundler/setup'
8
+ require 'rack/reloader'
8
9
  require "flipper/ui"
9
10
  require "flipper/adapters/pstore"
10
11
 
@@ -40,6 +41,8 @@ end
40
41
  # Flipper.enable_percentage_of_actors(:new_cache, 15)
41
42
  # Flipper.add("a/b")
42
43
 
44
+ use Rack::Reloader
45
+
43
46
  run Flipper::UI.app { |builder|
44
47
  builder.use Rack::Session::Cookie, secret: "_super_secret"
45
48
  builder.use FlipperReadOnlyMiddleware
data/examples/ui/basic.ru CHANGED
@@ -9,6 +9,7 @@
9
9
  # http://localhost:9999/
10
10
  #
11
11
  require 'bundler/setup'
12
+ require 'rack/reloader'
12
13
  require "flipper/ui"
13
14
  require "flipper/adapters/pstore"
14
15
 
@@ -26,7 +27,7 @@ Flipper::UI.configure do |config|
26
27
  config.feature_creation_enabled = true
27
28
  config.feature_removal_enabled = true
28
29
  config.cloud_recommendation = true
29
- config.confirm_fully_enable = true
30
+ config.confirm_fully_enable = false
30
31
  # config.show_feature_description_in_list = true
31
32
  config.descriptions_source = lambda do |_keys|
32
33
  {
@@ -54,6 +55,8 @@ end
54
55
  # Flipper.enable_percentage_of_actors(:new_cache, 15)
55
56
  # Flipper.add("a/b")
56
57
 
58
+ use Rack::Reloader
59
+
57
60
  run Flipper::UI.app { |builder|
58
61
  builder.use Rack::Session::Cookie, secret: "_super_secret"
59
62
  }
@@ -9,6 +9,7 @@
9
9
  # http://localhost:9999/
10
10
  #
11
11
  require 'bundler/setup'
12
+ require 'rack/reloader'
12
13
  require "flipper/ui"
13
14
  require "flipper/adapters/pstore"
14
15
 
@@ -38,6 +39,8 @@ end
38
39
  # Flipper.enable_percentage_of_actors(:new_cache, 15)
39
40
  # Flipper.add("a/b")
40
41
 
42
+ use Rack::Reloader
43
+
41
44
  run Flipper::UI.app { |builder|
42
45
  builder.use Rack::Session::Cookie, secret: "_super_secret"
43
46
  }
@@ -174,7 +174,12 @@ module Flipper
174
174
  # Returns a response.
175
175
  def json_response(object)
176
176
  header 'Content-Type', 'application/json'
177
- body = JSON.dump(object)
177
+ body = case object
178
+ when String
179
+ object
180
+ else
181
+ JSON.dump(object)
182
+ end
178
183
  halt [@code, @headers, [body]]
179
184
  end
180
185
 
@@ -0,0 +1,19 @@
1
+ require 'flipper/ui/action'
2
+ require 'flipper/ui/util'
3
+
4
+ module Flipper
5
+ module UI
6
+ module Actions
7
+ class Export < UI::Action
8
+ route %r{\A/settings\/export/?\Z}
9
+
10
+ def post
11
+ header 'Content-Disposition', "Attachment;filename=flipper_#{flipper.adapter.adapter.name}_#{Time.now.to_i}.json"
12
+
13
+ export = flipper.export(format: :json, version: 1)
14
+ json_response export.contents
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,19 @@
1
+ require 'flipper/ui/action'
2
+ require 'flipper/ui/util'
3
+
4
+ module Flipper
5
+ module UI
6
+ module Actions
7
+ class Import < UI::Action
8
+ route %r{\A/settings\/import/?\Z}
9
+
10
+ def post
11
+ contents = params['file'][:tempfile].read
12
+ export = Flipper::Exporters::Json::Export.new(contents: contents)
13
+ flipper.import(export)
14
+ redirect_to "/features"
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,21 @@
1
+ require 'flipper/ui/action'
2
+ require 'flipper/ui/util'
3
+
4
+ module Flipper
5
+ module UI
6
+ module Actions
7
+ class Settings < UI::Action
8
+ route %r{\A/settings/?\Z}
9
+
10
+ def get
11
+ @page_title = 'Settings'
12
+
13
+ breadcrumb 'Home', '/'
14
+ breadcrumb 'Settings'
15
+
16
+ view_response :settings
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -25,6 +25,9 @@ module Flipper
25
25
  @action_collection.add UI::Actions::PercentageOfActorsGate
26
26
  @action_collection.add UI::Actions::Feature
27
27
  @action_collection.add UI::Actions::Features
28
+ @action_collection.add UI::Actions::Export
29
+ @action_collection.add UI::Actions::Import
30
+ @action_collection.add UI::Actions::Settings
28
31
 
29
32
  # Static Assets/Files
30
33
  @action_collection.add UI::Actions::File
@@ -17,6 +17,12 @@
17
17
  </div>
18
18
  <%- end -%>
19
19
 
20
+ <div class="container text-muted small mb-3">
21
+ <a href="https://www.flippercloud.io/docs/ui?utm_source=oss&utm_medium=ui&utm_campaign=docs">Docs</a> &bull;
22
+ <a href="<%= script_name %>/settings">Settings</a> &bull;
23
+ Version: <%= Flipper::VERSION %>
24
+ </div>
25
+
20
26
  <nav aria-label="breadcrumb">
21
27
  <ol class="breadcrumb bg-white border align-items-center mb-4">
22
28
  <% @breadcrumbs.each do |breadcrumb| %>
@@ -0,0 +1,26 @@
1
+ <div class="card mb-4 ">
2
+ <div class="card-header">
3
+ <h4 class="m-0">Export</h4>
4
+ </div>
5
+ <div class="card-body">
6
+ <form action="<%= script_name %>/settings/export" method="post">
7
+ <%== csrf_input_tag %>
8
+ <p>Download all your feature data in a single file.</p>
9
+ <input type="submit" value="Download" class="btn btn-sm btn-light">
10
+ </form>
11
+ </div>
12
+ </div>
13
+
14
+ <div class="card">
15
+ <div class="card-header">
16
+ <h4 class="m-0">Import</h4>
17
+ </div>
18
+ <div class="card-body">
19
+ <p>Import a backup file to restore your feature data. This will overwrite any of your existing feature data so be sure you are uploading the correct export.</p>
20
+ <form action="<%= script_name %>/settings/import" method="post" class="form-inline" enctype="multipart/form-data">
21
+ <%== csrf_input_tag %>
22
+ <input type="file" name="file" class="form-control form-control-sm mr-sm-2 mb-2 mb-sm-0">
23
+ <input type="submit" value="Import" class="btn btn-sm btn-light">
24
+ </form>
25
+ </div>
26
+ </div>
@@ -1,3 +1,3 @@
1
1
  module Flipper
2
- VERSION = '0.26.2'.freeze
2
+ VERSION = '0.27.1'.freeze
3
3
  end
@@ -0,0 +1,49 @@
1
+ RSpec.describe Flipper::UI::Actions::Features do
2
+ let(:token) do
3
+ if Rack::Protection::AuthenticityToken.respond_to?(:random_token)
4
+ Rack::Protection::AuthenticityToken.random_token
5
+ else
6
+ 'a'
7
+ end
8
+ end
9
+
10
+ let(:session) do
11
+ { :csrf => token, 'csrf' => token, '_csrf_token' => token }
12
+ end
13
+
14
+ describe "POST /settings/export" do
15
+ before do
16
+ flipper.enable_percentage_of_actors :search, 10
17
+ flipper.enable_percentage_of_time :search, 15
18
+ flipper.enable_actor :search, Flipper::Actor.new('User;1')
19
+ flipper.enable_actor :search, Flipper::Actor.new('User;100')
20
+ flipper.enable_group :search, :admins
21
+ flipper.enable_group :search, :employees
22
+ flipper.enable :plausible
23
+ flipper.disable :google_analytics
24
+
25
+ post '/settings/export',
26
+ {'authenticity_token' => token},
27
+ 'rack.session' => session
28
+ end
29
+
30
+ it 'responds with success' do
31
+ expect(last_response.status).to be(200)
32
+ end
33
+
34
+ it 'sets content disposition' do
35
+ expect(last_response.headers['Content-Disposition']).to match(/Attachment;filename=flipper_memory_[0-9]*\.json/)
36
+ end
37
+
38
+ it 'renders json' do
39
+ data = JSON.parse(last_response.body)
40
+ expect(last_response.headers['Content-Type']).to eq('application/json')
41
+ expect(data['version']).to eq(1)
42
+ expect(data['features']).to eq({
43
+ "search"=> {"boolean"=>nil, "groups"=>["admins", "employees"], "actors"=>["User;1", "User;100"], "percentage_of_actors"=>"10", "percentage_of_time"=>"15"},
44
+ "plausible"=> {"boolean"=>"true", "groups"=>[], "actors"=>[], "percentage_of_actors"=>nil, "percentage_of_time"=>nil},
45
+ "google_analytics"=> {"boolean"=>nil, "groups"=>[], "actors"=>[], "percentage_of_actors"=>nil, "percentage_of_time"=>nil},
46
+ })
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,41 @@
1
+ RSpec.describe Flipper::UI::Actions::Import do
2
+ let(:token) do
3
+ if Rack::Protection::AuthenticityToken.respond_to?(:random_token)
4
+ Rack::Protection::AuthenticityToken.random_token
5
+ else
6
+ 'a'
7
+ end
8
+ end
9
+
10
+ let(:session) do
11
+ { :csrf => token, 'csrf' => token, '_csrf_token' => token }
12
+ end
13
+
14
+ describe "POST /settings/import" do
15
+ before do
16
+ flipper.enable :plausible
17
+ flipper.disable :google_analytics
18
+ path = FlipperRoot.join("spec", "fixtures", "flipper_pstore_1679087600.json")
19
+
20
+ post '/settings/import',
21
+ {
22
+ 'authenticity_token' => token,
23
+ 'file' => Rack::Test::UploadedFile.new(path, "application/json"),
24
+ },
25
+ 'rack.session' => session
26
+ end
27
+
28
+ it 'imports the file export' do
29
+ expect(flipper[:search].actors_value).to eq(Set.new(['john', 'another', 'testing']))
30
+ expect(flipper[:search].groups_value).to eq(Set.new(['admins']))
31
+ expect(flipper[:google_analytics_tag].percentage_of_actors_value).to eq(100)
32
+ expect(flipper[:new_pricing].boolean_value).to eq(true)
33
+ expect(flipper[:nope].boolean_value).to eq(false)
34
+ end
35
+
36
+ it 'responds with redirect to settings' do
37
+ expect(last_response.status).to be(302)
38
+ expect(last_response.headers['Location']).to eq('/features')
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,27 @@
1
+ RSpec.describe Flipper::UI::Actions::Settings do
2
+ let(:token) do
3
+ if Rack::Protection::AuthenticityToken.respond_to?(:random_token)
4
+ Rack::Protection::AuthenticityToken.random_token
5
+ else
6
+ 'a'
7
+ end
8
+ end
9
+
10
+ let(:session) do
11
+ { :csrf => token, 'csrf' => token, '_csrf_token' => token }
12
+ end
13
+
14
+ describe 'GET /settings' do
15
+ before do
16
+ get '/settings'
17
+ end
18
+
19
+ it 'responds with success' do
20
+ expect(last_response.status).to be(200)
21
+ end
22
+
23
+ it 'renders template' do
24
+ expect(last_response.body).to include('Download')
25
+ end
26
+ end
27
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flipper-ui
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.26.2
4
+ version: 0.27.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Nunemaker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-03-15 00:00:00.000000000 Z
11
+ date: 2023-03-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rack
@@ -56,14 +56,14 @@ dependencies:
56
56
  requirements:
57
57
  - - "~>"
58
58
  - !ruby/object:Gem::Version
59
- version: 0.26.2
59
+ version: 0.27.1
60
60
  type: :runtime
61
61
  prerelease: false
62
62
  version_requirements: !ruby/object:Gem::Requirement
63
63
  requirements:
64
64
  - - "~>"
65
65
  - !ruby/object:Gem::Version
66
- version: 0.26.2
66
+ version: 0.27.1
67
67
  - !ruby/object:Gem::Dependency
68
68
  name: erubi
69
69
  requirement: !ruby/object:Gem::Requirement
@@ -116,13 +116,16 @@ files:
116
116
  - lib/flipper/ui/actions/actors_gate.rb
117
117
  - lib/flipper/ui/actions/add_feature.rb
118
118
  - lib/flipper/ui/actions/boolean_gate.rb
119
+ - lib/flipper/ui/actions/export.rb
119
120
  - lib/flipper/ui/actions/feature.rb
120
121
  - lib/flipper/ui/actions/features.rb
121
122
  - lib/flipper/ui/actions/file.rb
122
123
  - lib/flipper/ui/actions/groups_gate.rb
123
124
  - lib/flipper/ui/actions/home.rb
125
+ - lib/flipper/ui/actions/import.rb
124
126
  - lib/flipper/ui/actions/percentage_of_actors_gate.rb
125
127
  - lib/flipper/ui/actions/percentage_of_time_gate.rb
128
+ - lib/flipper/ui/actions/settings.rb
126
129
  - lib/flipper/ui/configuration.rb
127
130
  - lib/flipper/ui/configuration/option.rb
128
131
  - lib/flipper/ui/decorators/feature.rb
@@ -142,18 +145,22 @@ files:
142
145
  - lib/flipper/ui/views/features.erb
143
146
  - lib/flipper/ui/views/layout.erb
144
147
  - lib/flipper/ui/views/read_only.erb
148
+ - lib/flipper/ui/views/settings.erb
145
149
  - lib/flipper/version.rb
146
150
  - spec/flipper/ui/action_spec.rb
147
151
  - spec/flipper/ui/actions/actors_gate_spec.rb
148
152
  - spec/flipper/ui/actions/add_feature_spec.rb
149
153
  - spec/flipper/ui/actions/boolean_gate_spec.rb
154
+ - spec/flipper/ui/actions/export_spec.rb
150
155
  - spec/flipper/ui/actions/feature_spec.rb
151
156
  - spec/flipper/ui/actions/features_spec.rb
152
157
  - spec/flipper/ui/actions/file_spec.rb
153
158
  - spec/flipper/ui/actions/groups_gate_spec.rb
154
159
  - spec/flipper/ui/actions/home_spec.rb
160
+ - spec/flipper/ui/actions/import_spec.rb
155
161
  - spec/flipper/ui/actions/percentage_of_actors_gate_spec.rb
156
162
  - spec/flipper/ui/actions/percentage_of_time_gate_spec.rb
163
+ - spec/flipper/ui/actions/settings_spec.rb
157
164
  - spec/flipper/ui/configuration_spec.rb
158
165
  - spec/flipper/ui/decorators/feature_spec.rb
159
166
  - spec/flipper/ui/decorators/gate_spec.rb
@@ -188,13 +195,16 @@ test_files:
188
195
  - spec/flipper/ui/actions/actors_gate_spec.rb
189
196
  - spec/flipper/ui/actions/add_feature_spec.rb
190
197
  - spec/flipper/ui/actions/boolean_gate_spec.rb
198
+ - spec/flipper/ui/actions/export_spec.rb
191
199
  - spec/flipper/ui/actions/feature_spec.rb
192
200
  - spec/flipper/ui/actions/features_spec.rb
193
201
  - spec/flipper/ui/actions/file_spec.rb
194
202
  - spec/flipper/ui/actions/groups_gate_spec.rb
195
203
  - spec/flipper/ui/actions/home_spec.rb
204
+ - spec/flipper/ui/actions/import_spec.rb
196
205
  - spec/flipper/ui/actions/percentage_of_actors_gate_spec.rb
197
206
  - spec/flipper/ui/actions/percentage_of_time_gate_spec.rb
207
+ - spec/flipper/ui/actions/settings_spec.rb
198
208
  - spec/flipper/ui/configuration_spec.rb
199
209
  - spec/flipper/ui/decorators/feature_spec.rb
200
210
  - spec/flipper/ui/decorators/gate_spec.rb