flipflop 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- Mjk5MWNkOGUyOGViMGIxOTJmZmY0NTc5NjU3Yjk3NjM0NWIyNDE1ZA==
4
+ YWY3YjRjMGU0YmZlNDljMWM5YTNjYTllZmQ3MDljZTU2NDE0NTVkZA==
5
5
  data.tar.gz: !binary |-
6
- NjRiOGU3YTg3ZDAyYmMxM2RmZmEzZDcyOTBlZTNjZmRlMWI4YTdiNA==
6
+ MjUzZTE3MjY4MDFmY2MxZjE0YWIwZmViYTk4NjNkZjUwMTlkYTE3NA==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- YTRkOTdlMjAyMzVjYjdjOWJlMDkxOWYxZmYwMmUzMDMxYmE3YjcyNmI5ZWZk
10
- MWMxYjY1ZTU2MTBiOWYxMDNlOGI0MDE2Y2RmYWQ3ZTZiMTUzNjE5ZDA2NmEw
11
- YTViYjdmNzNkNTljZWFiMTUwOWZmNDhhMDgzYThiNGJmMTdlM2I=
9
+ ZTE1ZWM5ODgzZDM5NTA1MTllZGEyYTg3OWViYzAzOGE4YmZhMjFmYzg1NTZh
10
+ ZTkwOWQ0ODhhMzE3ZTI0YzIxMWQyYjI1MmFhN2ZjZWZmYjZhYmVhZGE5N2Mx
11
+ YWQzYWVkMzRkMTkxNTg1ODVhZDJmZGIzMWI3ODc0YmFjNjU2NTE=
12
12
  data.tar.gz: !binary |-
13
- MTllZjMwYjA5YWZmMzVjNGM3YjRmMGE0Mjk0NTg3MGY4NmY2MTgwNjcxOWVk
14
- NzE3NzllOWQwZDgzN2FkYjg2YThiMThlMDI4ZGMzODk5ZjFiYTIzYzQ3MGU5
15
- NDU0OTcxYjdjYzJkZWIwNTI5OTdkOWIxMGRjYmJkZDVmYmM4OTI=
13
+ ZWI4YTJhZTg5ZWQ4NWI0ZDRmNWU4MDVmYTc2MzYyN2NmZjA3Mjg5YjVmNGE0
14
+ Nzg3YWJiMDY0MjBmMjljNjIyZDAzYzhlZmQwY2E2NTAxZDVlODJmNTMwZTY1
15
+ MGJlNzVlYTE3ZmE1ZDc3MjhkY2E0ZGQ1YjgyNWRjY2MzMjgzOWI=
data/.gitignore CHANGED
@@ -1,4 +1,5 @@
1
1
  *.gem
2
+ *.css
2
3
  .bundle
3
4
  Gemfile.lock
4
5
  pkg/*
data/.travis.yml CHANGED
@@ -40,6 +40,7 @@ notifications:
40
40
  email: false
41
41
  slack:
42
42
  secure: crOO1QGnFn9T1DpVgxkukTSiN8lQq09X8WF8oi1Eoa7Liex4gzWq7f8wlIXPrRFAsNjU47fSrz+L1C6Eg068Vd2df9pkqjW0pLNeqUViJ35TzpYISTtzJrX+x3nvCQLlvS4leP6lkijlsvlu1IN0xnXadW5cmcMoEcPo4Yma1RUklwlreSRIEmJiutYKVFRw3gIZA9vsnXNEcD408mvSY/8Kuw+hmRQupODUalXDpZo1q3HH+ZPQq+/rGuJ7XRf9sBtxjpUF0G4FJZQhVP4CrLNYVBE/83rHJ6HSf6u3SlYVIMiautq0nWpVLPHUrkOPJVeVh6EPtoFeI/cehH1NyoAVvL5a39wFRBlJ4jVPWUrrnihJT/6+P6GM9PSnYogxtIoTsdrYES2FgtWGgwG5uLyw8U6bW7G7rCzQwBP7enVHWVCbDgdSSjE1Mg1I9qhRuL6pHs5des4VKk6pfD3p+BRqLmOZR2jx4v8MFwakSFqQWOMxaD0U1lfxecqSx9OkwWEhCFSnHeXeHInEhY6qKCdZZzT+beYn0xppUMPJGMTqe5+po8gL+5MxQwI8Xs/5hSve5frfmuS7UQf5BnFMOzwoThQrXCFRz58wXvcZTD9eTdVBV44Hsi5OLdYn9K58sNUhgcxGfRgdE7Gy9P7DD4fHPGakD/Tz++HuCmCUXNs=
43
+ before_deploy: rake assets:compile
43
44
  deploy:
44
45
  provider: rubygems
45
46
  api_key:
data/Gemfile CHANGED
@@ -1,6 +1,10 @@
1
1
  source "https://rubygems.org"
2
2
  gemspec
3
3
 
4
+ if ENV["CONTINUOUS_INTEGRATION"]
5
+ gem "bootstrap", "= 4.0.0.alpha3"
6
+ end
7
+
4
8
  group :test do
5
9
  version = ENV["RAILS_VERSION"] || "master"
6
10
  if version == "master"
data/README.md CHANGED
@@ -75,12 +75,15 @@ The following strategies are provided:
75
75
  * `:active_record` – Save feature settings in the database.
76
76
  * `:class` – Provide the feature model. `Flipflop::Feature` by default (which uses the table `features`). Honors `default_scope` when features are resolved or switched on/off.
77
77
  * `:cookie` – Save feature settings in browser cookies for the current user.
78
+ * `:prefix` – String prefix for all cookie names. Defaults to no prefix.
78
79
  * `:path` – The path for which the cookies apply. Defaults to the root of the application.
79
80
  * `:domain` – Cookie domain. Is `nil` by default (no specific domain). Can be `:all` to use the topmost domain. Can be an array of domains.
80
81
  * `:secure` – Only set cookies if the connection is secured with TLS. Default is `false`.
81
82
  * `:httponly` – Whether the cookies are accessible via scripting or only HTTP. Default is `false`.
82
83
  * `:query_string` – Interpret query string parameters as features. This strategy is only used for resolving. It does not allow switching features on/off.
84
+ * `:prefix` – String prefix for all query string parameters. Defaults to no prefix.
83
85
  * `:session` – Save feature settings in the current user's application session.
86
+ * `:prefix` – String prefix for all session variables. Defaults to no prefix.
84
87
  * `:default` – Not strictly needed, all feature defaults will be applied if no strategies match a feature. Include this strategy to determine the order of using the default value, and to make it appear in the dashboard.
85
88
 
86
89
  All strategies support these options, to change the appearance of the dashboard:
data/Rakefile CHANGED
@@ -1,16 +1,39 @@
1
1
  require "bundler/gem_tasks"
2
2
  require "rake/testtask"
3
3
 
4
- Rake::TestTask.new("test") do |test|
4
+ Rake::TestTask.new("test" => "assets:compile") do |test|
5
5
  test.pattern = "test/**/*_test.rb"
6
6
  end
7
7
 
8
- Rake::TestTask.new("test:unit") do |test|
8
+ Rake::TestTask.new("test:unit" => "assets:compile") do |test|
9
9
  test.pattern = "test/unit/**/*_test.rb"
10
10
  end
11
11
 
12
- Rake::TestTask.new("test:integration") do |test|
12
+ Rake::TestTask.new("test:integration" => "assets:compile") do |test|
13
13
  test.pattern = "test/integration/**/*_test.rb"
14
14
  end
15
15
 
16
16
  task default: :test
17
+
18
+ namespace :assets do
19
+ stylesheets_path = "app/assets/stylesheets"
20
+ stylesheet_file = "flipflop.css"
21
+ stylesheet_path = stylesheets_path + "/" + stylesheet_file
22
+
23
+ task :compile do
24
+ require "bundler/setup"
25
+ require "flipflop"
26
+ require "sprockets"
27
+ require "bootstrap"
28
+
29
+ environment = Sprockets::Environment.new
30
+ environment.append_path stylesheets_path
31
+ environment.append_path Bootstrap.stylesheets_path
32
+ environment.css_compressor = :scss
33
+ File.write(stylesheet_path, environment[stylesheet_file])
34
+ end
35
+
36
+ task :clean do
37
+ FileUtils.rm(stylesheet_path)
38
+ end
39
+ end
@@ -1,5 +1,3 @@
1
- require "bootstrap"
2
-
3
1
  module Flipflop
4
2
  class FeaturesController < ApplicationController
5
3
  include EnvironmentFilters
@@ -1,3 +1,2 @@
1
1
  class Flipflop::Feature < ActiveRecord::Base
2
- self.table_name = "features"
3
2
  end
@@ -30,13 +30,13 @@
30
30
  <%= submit_tag "on",
31
31
  type: "submit",
32
32
  class: @feature_set.strategy_status(strategy, feature) == "on" ? "active" : nil,
33
- disabled: strategy.switchable? ? false : true
33
+ disabled: !strategy.switchable?
34
34
  -%>
35
35
 
36
36
  <%= submit_tag "off",
37
37
  type: "submit",
38
38
  class: @feature_set.strategy_status(strategy, feature) == "off" ? "active" : nil,
39
- disabled: strategy.switchable? ? false : true
39
+ disabled: !strategy.switchable?
40
40
  -%>
41
41
  </div>
42
42
  <% end -%>
data/flipflop.gemspec CHANGED
@@ -13,11 +13,14 @@ Gem::Specification.new do |s|
13
13
  s.description = %q{Declarative API for specifying features, switchable in declaration, database and cookies.}
14
14
  s.license = "MIT"
15
15
 
16
+ s.add_dependency("activesupport", ">= 4.0")
17
+ if ENV["CONTINUOUS_INTEGRATION"]
18
+ s.files = `git ls-files`.split("\n").map { |f| f.sub(".scss", ".css") }
19
+ else
20
+ s.add_dependency("bootstrap", "= 4.0.0.alpha3")
16
21
  s.files = `git ls-files`.split("\n")
22
+ end
17
23
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
24
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
25
  s.require_paths = ["lib"]
20
-
21
- s.add_dependency("activesupport", ">= 4.0")
22
- s.add_dependency("bootstrap", "~> 4.0.0.alpha3")
23
26
  end
@@ -1,5 +1,7 @@
1
1
  module Flipflop
2
2
  class Engine < ::Rails::Engine
3
+ attr_accessor :rake_task_executing
4
+
3
5
  isolate_namespace Flipflop
4
6
 
5
7
  config.app_middleware.insert_after ActionDispatch::Callbacks,
@@ -23,16 +25,12 @@ module Flipflop
23
25
  end
24
26
 
25
27
  initializer "flipflop.dashboard", after: "flipflop.features_reloader" do |app|
28
+ next if rake_task_executing
26
29
  if actions = config.flipflop.dashboard_access_filter
27
30
  to_prepare do
28
31
  Flipflop::FeaturesController.before_action(*actions)
29
32
  Flipflop::StrategiesController.before_action(*actions)
30
33
  end
31
- else
32
- unless defined?(Rails::Generators) or defined?(Rake)
33
- warn("WARNING: You have not set `config.flipflop.dashboard_access_filter`; " +
34
- "the Flipflop dashboard is now always public!")
35
- end
36
34
  end
37
35
  end
38
36
 
@@ -41,6 +39,12 @@ module Flipflop
41
39
  ActionController::Base.send(:include, interceptor)
42
40
  end
43
41
 
42
+ def run_tasks_blocks(app)
43
+ # Skip initialization if we're in a rake task.
44
+ self.rake_task_executing = true
45
+ super
46
+ end
47
+
44
48
  private
45
49
 
46
50
  def feature_reloader(app)
@@ -10,6 +10,7 @@ module Flipflop
10
10
  def initialize(**options)
11
11
  # TODO: Support :expires as a runtime-evaluated option?
12
12
  @options = options.extract!(:path, :domain, :secure, :httponly).freeze
13
+ @prefix = options.delete(:prefix).to_s.freeze
13
14
  super(**options)
14
15
  end
15
16
 
@@ -19,25 +20,25 @@ module Flipflop
19
20
 
20
21
  def enabled?(feature)
21
22
  return unless request?
22
- return unless request.cookie_jar.has_key?(cookie_name(feature))
23
- cookie = request.cookie_jar[cookie_name(feature)]
23
+ return unless request.cookie_jar.has_key?(cookie_key(feature))
24
+ cookie = request.cookie_jar[cookie_key(feature)]
24
25
  cookie_value = cookie.is_a?(Hash) ? cookie["value"] : cookie
25
26
  cookie_value === "1"
26
27
  end
27
28
 
28
29
  def switch!(feature, enabled)
29
30
  value = @options.merge(value: enabled ? "1" : "0")
30
- request.cookie_jar[cookie_name(feature)] = value
31
+ request.cookie_jar[cookie_key(feature)] = value
31
32
  end
32
33
 
33
34
  def clear!(feature)
34
- request.cookie_jar.delete(cookie_name(feature), **@options)
35
+ request.cookie_jar.delete(cookie_key(feature), **@options)
35
36
  end
36
37
 
37
38
  protected
38
39
 
39
- def cookie_name(feature)
40
- :"flipflop_#{feature}"
40
+ def cookie_key(feature)
41
+ @prefix + feature.to_s
41
42
  end
42
43
  end
43
44
  end
@@ -7,10 +7,21 @@ module Flipflop
7
7
  end
8
8
  end
9
9
 
10
+ def initialize(**options)
11
+ @prefix = options.delete(:prefix).to_s.freeze
12
+ super(**options)
13
+ end
14
+
10
15
  def enabled?(feature)
11
16
  return unless request?
12
- return unless request.params.has_key?(feature)
13
- request.params[feature].to_s != "0"
17
+ return unless request.params.has_key?(param_key(feature))
18
+ request.params[param_key(feature)].to_s != "0"
19
+ end
20
+
21
+ protected
22
+
23
+ def param_key(feature)
24
+ @prefix + feature.to_s
14
25
  end
15
26
  end
16
27
  end
@@ -7,22 +7,33 @@ module Flipflop
7
7
  end
8
8
  end
9
9
 
10
+ def initialize(**options)
11
+ @prefix = options.delete(:prefix).to_s.freeze
12
+ super(**options)
13
+ end
14
+
10
15
  def switchable?
11
16
  request?
12
17
  end
13
18
 
14
19
  def enabled?(feature)
15
20
  return unless request?
16
- return unless request.session.has_key?(feature)
17
- request.session[feature]
21
+ return unless request.session.has_key?(variable_key(feature))
22
+ request.session[variable_key(feature)] == true
18
23
  end
19
24
 
20
25
  def switch!(feature, enabled)
21
- request.session[feature] = enabled
26
+ request.session[variable_key(feature)] = enabled
22
27
  end
23
28
 
24
29
  def clear!(feature)
25
- request.session.delete(feature)
30
+ request.session.delete(variable_key(feature))
31
+ end
32
+
33
+ protected
34
+
35
+ def variable_key(feature)
36
+ @prefix + feature.to_s
26
37
  end
27
38
  end
28
39
  end
@@ -1,3 +1,3 @@
1
1
  module Flipflop
2
- VERSION = "2.0.0"
2
+ VERSION = "2.1.0"
3
3
  end
@@ -1,6 +1,6 @@
1
1
  class CreateFeatures < ActiveRecord::Migration<%= Rails.version >= "5" ? "[#{ActiveRecord::Migration.current_version}]" : "" %>
2
2
  def change
3
- create_table :features do |t|
3
+ create_table :flipflop_features do |t|
4
4
  t.string :key, null: false
5
5
  t.boolean :enabled, null: false, default: false
6
6
 
@@ -9,6 +9,10 @@ describe Flipflop do
9
9
  @app
10
10
  end
11
11
 
12
+ after do
13
+ Flipflop::Strategies::AbstractStrategy::RequestInterceptor.request = nil
14
+ end
15
+
12
16
  describe "middleware" do
13
17
  it "should include cache middleware" do
14
18
  middlewares = Rails.application.middleware.map(&:klass)
@@ -13,6 +13,10 @@ describe Flipflop do
13
13
  @app
14
14
  end
15
15
 
16
+ after do
17
+ Flipflop::Strategies::AbstractStrategy::RequestInterceptor.request = nil
18
+ end
19
+
16
20
  describe "outside development and test" do
17
21
  before do
18
22
  Rails.env.stub(:test?, false) do
@@ -33,7 +33,7 @@ describe Flipflop::Strategies::CookieStrategy do
33
33
 
34
34
  describe "with enabled feature" do
35
35
  before do
36
- subject.send(:request).cookie_jar[subject.send(:cookie_name, :one)] = "1"
36
+ subject.send(:request).cookie_jar["one"] = "1"
37
37
  end
38
38
 
39
39
  it "should have feature enabled" do
@@ -53,7 +53,7 @@ describe Flipflop::Strategies::CookieStrategy do
53
53
 
54
54
  describe "with disabled feature" do
55
55
  before do
56
- subject.send(:request).cookie_jar[subject.send(:cookie_name, :two)] = "0"
56
+ subject.send(:request).cookie_jar["two"] = "0"
57
57
  end
58
58
 
59
59
  it "should not have feature enabled" do
@@ -88,13 +88,19 @@ describe Flipflop::Strategies::CookieStrategy do
88
88
  domain: :all,
89
89
  path: "/foo",
90
90
  httponly: true,
91
+ prefix: :my_cookie_,
91
92
  ).freeze
92
93
  end
93
94
 
95
+ it "should use prefix to resolve parameters" do
96
+ subject.send(:request).cookie_jar["my_cookie_one"] = "1"
97
+ assert_equal true, subject.enabled?(:one)
98
+ end
99
+
94
100
  it "should pass options when setting value" do
95
101
  subject.switch!(:one, true)
96
102
  subject.send(:request).cookie_jar.write(headers = {})
97
- assert_equal "flipflop_one=1; domain=.example.com; path=/foo; HttpOnly",
103
+ assert_equal "my_cookie_one=1; domain=.example.com; path=/foo; HttpOnly",
98
104
  headers["Set-Cookie"]
99
105
  end
100
106
 
@@ -102,7 +108,7 @@ describe Flipflop::Strategies::CookieStrategy do
102
108
  subject.switch!(:one, true)
103
109
  subject.clear!(:one)
104
110
  subject.send(:request).cookie_jar.write(headers = {})
105
- assert_equal "flipflop_one=; domain=.example.com; path=/foo; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000; HttpOnly",
111
+ assert_equal "my_cookie_one=; domain=.example.com; path=/foo; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000; HttpOnly",
106
112
  headers["Set-Cookie"]
107
113
  end
108
114
  end
@@ -56,6 +56,22 @@ describe Flipflop::Strategies::QueryStringStrategy do
56
56
  assert_nil subject.enabled?(:three)
57
57
  end
58
58
  end
59
+
60
+ describe "with options" do
61
+ subject do
62
+ Flipflop::Strategies::QueryStringStrategy.new(
63
+ prefix: :my_feature_,
64
+ ).freeze
65
+ end
66
+
67
+ before do
68
+ subject.send(:request).params[:my_feature_one] = "1"
69
+ end
70
+
71
+ it "should use prefix to resolve parameters" do
72
+ assert_equal true, subject.enabled?(:one)
73
+ end
74
+ end
59
75
  end
60
76
 
61
77
  describe "outside request context" do
@@ -33,7 +33,7 @@ describe Flipflop::Strategies::SessionStrategy do
33
33
 
34
34
  describe "with enabled feature" do
35
35
  before do
36
- subject.send(:request).session[:one] = true
36
+ subject.send(:request).session["one"] = true
37
37
  end
38
38
 
39
39
  it "should have feature enabled" do
@@ -53,7 +53,7 @@ describe Flipflop::Strategies::SessionStrategy do
53
53
 
54
54
  describe "with disabled feature" do
55
55
  before do
56
- subject.send(:request).session[:two] = false
56
+ subject.send(:request).session["two"] = false
57
57
  end
58
58
 
59
59
  it "should not have feature enabled" do
@@ -81,6 +81,22 @@ describe Flipflop::Strategies::SessionStrategy do
81
81
  assert_equal true, subject.enabled?(:three)
82
82
  end
83
83
  end
84
+
85
+ describe "with options" do
86
+ subject do
87
+ Flipflop::Strategies::SessionStrategy.new(
88
+ prefix: :my_feature_,
89
+ ).freeze
90
+ end
91
+
92
+ before do
93
+ subject.send(:request).session["my_feature_one"] = true
94
+ end
95
+
96
+ it "should use prefix to resolve parameters" do
97
+ assert_equal true, subject.enabled?(:one)
98
+ end
99
+ end
84
100
  end
85
101
 
86
102
  describe "outside request context" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flipflop
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Annesley
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2016-03-17 00:00:00.000000000 Z
13
+ date: 2016-03-18 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: activesupport
@@ -26,20 +26,6 @@ dependencies:
26
26
  - - ! '>='
27
27
  - !ruby/object:Gem::Version
28
28
  version: '4.0'
29
- - !ruby/object:Gem::Dependency
30
- name: bootstrap
31
- requirement: !ruby/object:Gem::Requirement
32
- requirements:
33
- - - ~>
34
- - !ruby/object:Gem::Version
35
- version: 4.0.0.alpha3
36
- type: :runtime
37
- prerelease: false
38
- version_requirements: !ruby/object:Gem::Requirement
39
- requirements:
40
- - - ~>
41
- - !ruby/object:Gem::Version
42
- version: 4.0.0.alpha3
43
29
  description: Declarative API for specifying features, switchable in declaration, database
44
30
  and cookies.
45
31
  email:
@@ -56,7 +42,7 @@ files:
56
42
  - LICENSE
57
43
  - README.md
58
44
  - Rakefile
59
- - app/assets/stylesheets/flipflop.scss
45
+ - app/assets/stylesheets/flipflop.css
60
46
  - app/controllers/concerns/flipflop/environment_filters.rb
61
47
  - app/controllers/flipflop/features_controller.rb
62
48
  - app/controllers/flipflop/strategies_controller.rb
@@ -1,109 +0,0 @@
1
- $enable-transitions: true;
2
- @import "bootstrap";
3
-
4
- section.flipflop {
5
- @extend .container-fluid;
6
- margin: 5rem 0 0;
7
-
8
- table {
9
- @extend .table;
10
- @extend .table-striped;
11
-
12
- thead {
13
- @extend .thead-inverse;
14
-
15
- th {
16
- position: relative;
17
- cursor: default;
18
-
19
- &[data-tooltip]:before, &[data-tooltip]:after {
20
- @include transition(all 0.2s ease-out);
21
- transform: translateY(0.2rem) translateZ(0);
22
- opacity: 0;
23
-
24
- display: block;
25
- position: absolute;
26
- }
27
-
28
- &[data-tooltip]:before {
29
- content: attr(data-tooltip);
30
- width: 98%;
31
- left: 0;
32
- bottom: 3.75rem;
33
- margin: 0;
34
- padding: 0.5rem 0.75rem;
35
- background: $gray;
36
- border-radius: 0.2rem;
37
- font-size: 0.875rem;
38
- font-weight: normal;
39
- pointer-events: none;
40
- }
41
-
42
- &[data-tooltip]:after {
43
- content: " ";
44
- width: 0;
45
- height: 0;
46
- left: 1rem;
47
- bottom: 3.25rem;
48
- border-left: solid transparent 0.5rem;
49
- border-right: solid transparent 0.5rem;
50
- border-top: solid $gray 0.5rem;
51
- }
52
-
53
- &:hover {
54
- &[data-tooltip]:before, &[data-tooltip]:after {
55
- transform: translateY(0) translateZ(0);
56
- opacity: 1;
57
- }
58
- }
59
- }
60
- }
61
-
62
- tbody {
63
- td.status {
64
- width: 2rem;
65
- font-size: 1.1rem;
66
-
67
- span {
68
- width: 2rem;
69
- @extend .label;
70
- @extend .label-pill;
71
- &.on { @extend .label-success; }
72
- &.off { @extend .label-default; }
73
- }
74
- }
75
-
76
- td.name {
77
- min-width: 11rem;
78
- padding-top: 0.9rem;
79
- font-weight: bold;
80
- }
81
-
82
- td.description {
83
- min-width: 11rem;
84
- padding-top: 0.9rem;
85
- }
86
-
87
- td.toggle {
88
- min-width: 11rem;
89
-
90
- div.toolbar {
91
- @extend .btn-toolbar;
92
- margin-left: 0;
93
-
94
- div.group {
95
- @extend .btn-group;
96
- @extend .btn-group-sm;
97
-
98
- input[type=submit] {
99
- @extend .btn;
100
- @extend .btn-sm;
101
- &.active { @extend .btn-primary; }
102
- &:not(.active) { @extend .btn-secondary; }
103
- }
104
- }
105
- }
106
- }
107
- }
108
- }
109
- }