From 966a956f36cd0ef6a838b9ae6b20818c5509766c Mon Sep 17 00:00:00 2001 From: Brandon Keepers Date: Fri, 1 Mar 2024 08:37:34 -0500 Subject: [PATCH 1/2] Replace breadcrumbs with nav --- examples/ui/basic.ru | 3 ++ lib/flipper/ui/action.rb | 25 +++----------- lib/flipper/ui/actions/actors_gate.rb | 6 ---- lib/flipper/ui/actions/add_feature.rb | 9 ----- lib/flipper/ui/actions/feature.rb | 7 ---- lib/flipper/ui/actions/features.rb | 7 ---- lib/flipper/ui/actions/groups_gate.rb | 5 --- lib/flipper/ui/actions/settings.rb | 3 -- lib/flipper/ui/configuration.rb | 18 ++++++++-- lib/flipper/ui/views/add_actor.erb | 6 +++- lib/flipper/ui/views/add_group.erb | 5 ++- lib/flipper/ui/views/feature.erb | 9 +++-- lib/flipper/ui/views/features.erb | 2 +- lib/flipper/ui/views/layout.erb | 35 ++++++++++++------- spec/flipper/ui/configuration_spec.rb | 13 ++++--- spec/flipper/ui_spec.rb | 50 ++++++++++----------------- 16 files changed, 90 insertions(+), 113 deletions(-) diff --git a/examples/ui/basic.ru b/examples/ui/basic.ru index 83f21ad1a..518d469ad 100644 --- a/examples/ui/basic.ru +++ b/examples/ui/basic.ru @@ -46,6 +46,8 @@ Flipper::UI.configure do |config| '6' => 'Brandon', } end + + config.application_href = "https://example.com" end # You can uncomment these to get some default data: @@ -63,5 +65,6 @@ end use Rack::Reloader run Flipper::UI.app { |builder| + builder.use Rack::Reloader, 1 builder.use Rack::Session::Cookie, secret: "_super_secret" } diff --git a/lib/flipper/ui/action.rb b/lib/flipper/ui/action.rb index 56eb99741..61557d8b8 100644 --- a/lib/flipper/ui/action.rb +++ b/lib/flipper/ui/action.rb @@ -93,12 +93,6 @@ def initialize(flipper, request) @request = request @code = 200 @headers = {Rack::CONTENT_TYPE => 'text/plain'} - @breadcrumbs = - if Flipper::UI.configuration.application_breadcrumb_href - [Breadcrumb.new('App', Flipper::UI.configuration.application_breadcrumb_href)] - else - [] - end end # Public: Runs the request method for the provided request. @@ -202,16 +196,6 @@ def active? end end - # Public: Add a breadcrumb to the trail. - # - # text - The String text for the breadcrumb. - # href - The String href for the anchor tag (optional). If nil, breadcrumb - # is assumed to be the end of the trail. - def breadcrumb(text, href = nil) - breadcrumb_href = href.nil? ? href : "#{script_name}#{href}" - @breadcrumbs << Breadcrumb.new(text, breadcrumb_href) - end - # Private def view_with_layout(&block) view :layout, &block @@ -235,6 +219,10 @@ def script_name request.env['SCRIPT_NAME'] end + def url_for(*parts) + URI.join(request.base_url, script_name, *parts).to_s + end + # Private def views_path self.class.views_path @@ -262,11 +250,6 @@ def valid_request_method? # to inform people of that fact. def render_read_only status 403 - - breadcrumb 'Home', '/' - breadcrumb 'Features', '/features' - breadcrumb 'Noooooope' - halt view_response(:read_only) end diff --git a/lib/flipper/ui/actions/actors_gate.rb b/lib/flipper/ui/actions/actors_gate.rb index 31dd92487..e76a39f87 100644 --- a/lib/flipper/ui/actions/actors_gate.rb +++ b/lib/flipper/ui/actions/actors_gate.rb @@ -13,12 +13,6 @@ class ActorsGate < UI::Action def get feature = flipper[feature_name] @feature = Decorators::Feature.new(feature) - - breadcrumb 'Home', '/' - breadcrumb 'Features', '/features' - breadcrumb @feature.key, "/features/#{@feature.key}" - breadcrumb 'Add Actor' - view_response :add_actor end diff --git a/lib/flipper/ui/actions/add_feature.rb b/lib/flipper/ui/actions/add_feature.rb index 8d3a3febc..d672e81cb 100644 --- a/lib/flipper/ui/actions/add_feature.rb +++ b/lib/flipper/ui/actions/add_feature.rb @@ -12,18 +12,9 @@ def get unless Flipper::UI.configuration.feature_creation_enabled status 403 - - breadcrumb 'Home', '/' - breadcrumb 'Features', '/features' - breadcrumb 'Noooooope' - halt view_response(:feature_creation_disabled) end - breadcrumb 'Home', '/' - breadcrumb 'Features', '/features' - breadcrumb 'Add' - view_response :add_feature end end diff --git a/lib/flipper/ui/actions/feature.rb b/lib/flipper/ui/actions/feature.rb index 8830bde8f..19ee1fb6a 100644 --- a/lib/flipper/ui/actions/feature.rb +++ b/lib/flipper/ui/actions/feature.rb @@ -18,10 +18,6 @@ def get @page_title = "#{@feature.key} // Features" @percentages = [0, 1, 5, 10, 25, 50, 100] - breadcrumb 'Home', '/' - breadcrumb 'Features', '/features' - breadcrumb @feature.key - view_response :feature end @@ -31,9 +27,6 @@ def delete unless Flipper::UI.configuration.feature_removal_enabled status 403 - breadcrumb 'Home', '/' - breadcrumb 'Features', '/features' - halt view_response(:feature_removal_disabled) end diff --git a/lib/flipper/ui/actions/features.rb b/lib/flipper/ui/actions/features.rb index 552cfaac6..96a4b9c6c 100644 --- a/lib/flipper/ui/actions/features.rb +++ b/lib/flipper/ui/actions/features.rb @@ -29,9 +29,6 @@ def get @show_blank_slate = @features.empty? - breadcrumb 'Home', '/' - breadcrumb 'Features' - view_response :features end @@ -41,10 +38,6 @@ def post unless Flipper::UI.configuration.feature_creation_enabled status 403 - breadcrumb 'Home', '/' - breadcrumb 'Features', '/features' - breadcrumb 'Noooooope' - halt view_response(:feature_creation_disabled) end diff --git a/lib/flipper/ui/actions/groups_gate.rb b/lib/flipper/ui/actions/groups_gate.rb index 7fa73f744..173ccc245 100644 --- a/lib/flipper/ui/actions/groups_gate.rb +++ b/lib/flipper/ui/actions/groups_gate.rb @@ -13,11 +13,6 @@ def get feature = flipper[feature_name] @feature = Decorators::Feature.new(feature) - breadcrumb 'Home', '/' - breadcrumb 'Features', '/features' - breadcrumb @feature.key, "/features/#{@feature.key}" - breadcrumb 'Add Group' - view_response :add_group end diff --git a/lib/flipper/ui/actions/settings.rb b/lib/flipper/ui/actions/settings.rb index 8a5f654c4..24e4c9394 100644 --- a/lib/flipper/ui/actions/settings.rb +++ b/lib/flipper/ui/actions/settings.rb @@ -10,9 +10,6 @@ class Settings < UI::Action def get @page_title = 'Settings' - breadcrumb 'Home', '/' - breadcrumb 'Settings' - view_response :settings end end diff --git a/lib/flipper/ui/configuration.rb b/lib/flipper/ui/configuration.rb index c6b1bd242..4582ea595 100644 --- a/lib/flipper/ui/configuration.rb +++ b/lib/flipper/ui/configuration.rb @@ -13,10 +13,20 @@ class Configuration # (feature_creation_enabled and feature_removal_enabled). attr_accessor :read_only - # Public: If you set this, the UI will always have a first breadcrumb that + # Public: If you set this, the UI will always have a first nav item that # says "App" which points to this href. The href can be a path (ie: "/") # or full url ("https://app.example.com/"). - attr_accessor :application_breadcrumb_href + attr_accessor :application_href + alias_method :application_breadcrumb_href, :application_href + alias_method :application_breadcrumb_href=, :application_href= + + # Public: An array of nav items to show. By default "Features" and + # "Settings" are shown, but you can add your own. Each item must have + # a `:title` and `:href` key: + # + # config.nav_items << { title: "Custom", href: "/custom/page" } + # + attr_accessor :nav_items # Public: Is feature creation allowed from the UI? Defaults to true. If # set to false, users of the UI cannot create features. All feature @@ -97,6 +107,10 @@ def initialize @confirm_fully_enable = false @confirm_disable = true @read_only = false + @nav_items = [ + { title: "Features", href: "features" }, + { title: "Settings", href: "settings" }, + ] end def using_descriptions? diff --git a/lib/flipper/ui/views/add_actor.erb b/lib/flipper/ui/views/add_actor.erb index c54de54d2..e401d0b7e 100644 --- a/lib/flipper/ui/views/add_actor.erb +++ b/lib/flipper/ui/views/add_actor.erb @@ -5,7 +5,11 @@ <% end %>
-

Enable Actor for <%= @feature.key %>

+

+ <%= @feature.key %> + / + Enable Actor +

Turn on this feature for actors. diff --git a/lib/flipper/ui/views/add_group.erb b/lib/flipper/ui/views/add_group.erb index cd9b79572..feb93bf88 100644 --- a/lib/flipper/ui/views/add_group.erb +++ b/lib/flipper/ui/views/add_group.erb @@ -5,7 +5,10 @@ <% end %>

-

Enable Group for <%= @feature.key %>

+

+ <%= @feature.key %> + / + Enable Group

<% if @feature.disabled_groups.empty? %>

All groups are enabled for this feature which means there is nothing to add.

diff --git a/lib/flipper/ui/views/feature.erb b/lib/flipper/ui/views/feature.erb index 0efc69bd3..6a144c3d8 100644 --- a/lib/flipper/ui/views/feature.erb +++ b/lib/flipper/ui/views/feature.erb @@ -21,8 +21,13 @@
<%# Gate State Header %>
- - <%= @feature.gate_state_title %> +
+

<%= feature_name %>

+
+ + <%= @feature.gate_state_title %> +
+
<% unless @feature.boolean_value %> diff --git a/lib/flipper/ui/views/features.erb b/lib/flipper/ui/views/features.erb index 3d2156528..2dc8bba7d 100644 --- a/lib/flipper/ui/views/features.erb +++ b/lib/flipper/ui/views/features.erb @@ -30,7 +30,7 @@

Features

<%- if write_allowed? && Flipper::UI.configuration.feature_creation_enabled -%> <%- end -%>
diff --git a/lib/flipper/ui/views/layout.erb b/lib/flipper/ui/views/layout.erb index d54e7d547..e2bf588ee 100644 --- a/lib/flipper/ui/views/layout.erb +++ b/lib/flipper/ui/views/layout.erb @@ -18,9 +18,6 @@ <%- end -%>
- Docs • - Settings • - Version: <%= Flipper::VERSION %> @@ -36,19 +33,31 @@ <% end %>
+
diff --git a/spec/flipper/ui/configuration_spec.rb b/spec/flipper/ui/configuration_spec.rb index b5423e101..b41567011 100644 --- a/spec/flipper/ui/configuration_spec.rb +++ b/spec/flipper/ui/configuration_spec.rb @@ -35,14 +35,19 @@ end end - describe "#application_breadcrumb_href" do + describe "#application_href" do it "has default value" do - expect(configuration.application_breadcrumb_href).to eq(nil) + expect(configuration.application_href).to eq(nil) end it "can be updated" do - configuration.application_breadcrumb_href = 'http://www.myapp.com' - expect(configuration.application_breadcrumb_href).to eq('http://www.myapp.com') + configuration.application_href = 'http://www.myapp.com' + expect(configuration.application_href).to eq('http://www.myapp.com') + end + + it 'aliases application_breadcrumb_href to application_href' do + configuration.application_breadcrumb_href = "/myapp" + expect(configuration.application_href).to eq("/myapp") end end diff --git a/spec/flipper/ui_spec.rb b/spec/flipper/ui_spec.rb index 5ed579264..63600e143 100644 --- a/spec/flipper/ui_spec.rb +++ b/spec/flipper/ui_spec.rb @@ -76,56 +76,44 @@ end end - describe "application_breadcrumb_href" do - it 'does not have an application_breadcrumb_href by default' do - expect(configuration.application_breadcrumb_href).to be(nil) + describe "application_href" do + around do |example| + original_href = configuration.application_href + example.run + ensure + configuration.application_href = original_href end - context 'with application_breadcrumb_href not set' do - before do - @original_application_breadcrumb_href = configuration.application_breadcrumb_href - configuration.application_breadcrumb_href = nil - end - - after do - configuration.application_breadcrumb_href = @original_application_breadcrumb_href - end + it 'does not have an application_href by default' do + expect(configuration.application_href).to be(nil) + end - it 'does not add App breadcrumb' do + context 'with application_href not set' do + it 'does not add App link' do get '/features' expect(last_response.body).not_to include('App') end end - context 'with application_breadcrumb_href set' do + context 'with application_href set' do before do - @original_application_breadcrumb_href = configuration.application_breadcrumb_href - configuration.application_breadcrumb_href = '/myapp' + configuration.application_href = '/myapp' end - after do - configuration.application_breadcrumb_href = @original_application_breadcrumb_href - end - - it 'does add App breadcrumb' do + it 'does add App link' do get '/features' - expect(last_response.body).to include('App') + expect(last_response.body).to match('App') + expect(last_response.body).to match(' Date: Fri, 1 Mar 2024 09:00:21 -0500 Subject: [PATCH 2/2] Fix url_for when app is mapped to namespace --- lib/flipper/ui/action.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/flipper/ui/action.rb b/lib/flipper/ui/action.rb index 61557d8b8..0ff4053e3 100644 --- a/lib/flipper/ui/action.rb +++ b/lib/flipper/ui/action.rb @@ -219,8 +219,14 @@ def script_name request.env['SCRIPT_NAME'] end + # Internal: Generate urls relative to the app's script name. + # + # url_for("feature") # => "http://localhost:9292/flipper/feature" + # url_for("/thing") # => "http://localhost:9292/thing" + # url_for("https://example.com") # => "https://example.com" + # def url_for(*parts) - URI.join(request.base_url, script_name, *parts).to_s + URI.join(request.base_url, script_name + '/', *parts).to_s end # Private