vario 0.4.12

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 (41) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +61 -0
  4. data/Rakefile +37 -0
  5. data/app/controllers/vario/application_controller.rb +15 -0
  6. data/app/controllers/vario/levels_controller.rb +63 -0
  7. data/app/controllers/vario/settings_controller.rb +35 -0
  8. data/app/helpers/vario/application_helper.rb +13 -0
  9. data/app/jobs/vario/application_job.rb +4 -0
  10. data/app/mailers/vario/application_mailer.rb +6 -0
  11. data/app/models/vario/application_record.rb +5 -0
  12. data/app/models/vario/condition.rb +39 -0
  13. data/app/models/vario/level.rb +94 -0
  14. data/app/models/vario/setting.rb +188 -0
  15. data/app/views/vario/levels/_form.html.slim +53 -0
  16. data/app/views/vario/levels/create.js.erb +4 -0
  17. data/app/views/vario/levels/destroy.js.erb +4 -0
  18. data/app/views/vario/levels/update.js.erb +4 -0
  19. data/app/views/vario/settings/_levels.html.slim +22 -0
  20. data/app/views/vario/settings/_new_level.html.slim +7 -0
  21. data/app/views/vario/settings/_settings.html.slim +30 -0
  22. data/app/views/vario/settings/index.html.slim +28 -0
  23. data/app/views/vario/settings/levels.html.slim +1 -0
  24. data/app/views/vario/settings/show.html.slim +13 -0
  25. data/config/locales/en.yml +6 -0
  26. data/config/locales/nl.yml +6 -0
  27. data/config/routes.rb +10 -0
  28. data/db/migrate/20180628103728_create_vario_settings.rb +20 -0
  29. data/db/migrate/20180706130136_remove_fields_from_settings.rb +7 -0
  30. data/db/migrate/20180706155055_add_keys_to_setting.rb +5 -0
  31. data/db/migrate/20211027040546_unique_levels.rb +8 -0
  32. data/lib/vario/action_view_helpers.rb +31 -0
  33. data/lib/vario/active_record_helpers.rb +23 -0
  34. data/lib/vario/api.rb +148 -0
  35. data/lib/vario/config.rb +112 -0
  36. data/lib/vario/engine.rb +15 -0
  37. data/lib/vario/settable.rb +44 -0
  38. data/lib/vario/settings_reader.rb +35 -0
  39. data/lib/vario/version.rb +5 -0
  40. data/lib/vario.rb +30 -0
  41. metadata +194 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 5e58ac2e2f8d599f2c079997d4a1aff97eab6f942d3defabf2be5e761fbd153c
4
+ data.tar.gz: 38b17c68f3d33f8c6244761249831457cb7c2e1d0659128b54bb65140ca82947
5
+ SHA512:
6
+ metadata.gz: 18dac0cfad4d0e2d4dce4dc8cde21163fa068bb4f2f6c26db0eb87d040477f12eb8eb9a02716bab740a729ba0e300634994aef06512cf36a644b05f520059cf9
7
+ data.tar.gz: 4fbdb499f8cb06c0ccc1e419efe323e7ee1b538495822762aff7c10d1c94ca9bc3fe046676d3b9927c44e04b0363b3e48757b244226e59a8cf03a342195fd908
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2018 Andre Meij
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,61 @@
1
+ # Vario
2
+
3
+ Vario allows configuration over multiple levels and tied to different objects. It is a simple and flexible way to configure your project.
4
+
5
+ ## Usage
6
+
7
+ Add the vario.rb initializer to your project and configure it.
8
+ Say your way to separate tenants is using an Account model, you would make 'Account' the settable and you can configure settings on it:
9
+
10
+ ```ruby
11
+ Vario.setup do |config|
12
+ config.key :environment, name: 'Environment', type: :select, collection_proc: -> { [%w[Production production], %w[Test test], %w[Development development]] }, value_proc: -> { Rails.env }
13
+
14
+ config.for_settable_type 'Account' do |settable|
15
+ settable.raise_on_undefined true
16
+
17
+ settable.setting 'internationalization.default_currency', type: :string, default: 'USD', description: 'Default currency for new products.', collection_proc: -> { Money::Currency.map { |currency| ["#{currency.iso_code} - #{currency.name}", currency.iso_code] }.sort }
18
+ settable.setting 'internationalization.week_start', type: :symbol, default: :monday, description: 'First day of the week', collection: [['Monday', :monday], ['Tuesday', :tuesday], ['Wednesday', :wednesday], ['Thursday', :thursday], ['Friday', :friday], ['Saturday', :saturday], ['Sunday', :sunday]]
19
+ end
20
+ end
21
+ ```
22
+
23
+ Next add vario to your routes.rb:
24
+
25
+ ```ruby
26
+ mount Vario::Engine, at: "/settings", as: "vario"
27
+ ```
28
+
29
+ Then add a menu entry, or link to the settings page:
30
+
31
+ ```ruby
32
+ link_to("Settings", vario.settings_path(settable: Current&.account&.to_sgid(for: "Vario").to_s))
33
+ ```
34
+
35
+ ## Installation
36
+
37
+ Add this line to your application's Gemfile:
38
+
39
+ ```ruby
40
+ gem 'vario'
41
+ ```
42
+
43
+ And then execute:
44
+
45
+ ```bash
46
+ $ bundle
47
+ ```
48
+
49
+ Or install it yourself as:
50
+
51
+ ```bash
52
+ $ gem install vario
53
+ ```
54
+
55
+ ## Contributing
56
+
57
+ Contribution directions go here.
58
+
59
+ ## License
60
+
61
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,37 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Vario'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.md')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
18
+ load 'rails/tasks/engine.rake'
19
+
20
+ load 'rails/tasks/statistics.rake'
21
+
22
+ require 'bundler/gem_tasks'
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'test'
28
+ t.pattern = 'test/**/*_test.rb'
29
+ t.verbose = false
30
+ t.warning = false
31
+ end
32
+
33
+ task default: :test
34
+
35
+ # Adds the Auxilium semver task
36
+ spec = Gem::Specification.find_by_name 'auxilium'
37
+ load "#{spec.gem_dir}/lib/tasks/semver.rake"
@@ -0,0 +1,15 @@
1
+ module Vario
2
+ class ApplicationController < Vario.config.base_controller.constantize
3
+ protect_from_forgery with: :exception
4
+
5
+ layout Vario.config.admin_layout
6
+
7
+ def add_breadcrumbs(*args)
8
+ method(:add_breadcrumbs).super_method&.call(*args)
9
+ end
10
+
11
+ def breadcrumb_settings_path(setting, options = {})
12
+ settings_path(options.merge(settable: setting.settable.to_sgid(for: 'Vario').to_s))
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,63 @@
1
+ require_dependency 'vario/application_controller'
2
+
3
+ module Vario
4
+ class LevelsController < ApplicationController
5
+ self.responder = Auxilium::Responder
6
+ respond_to :html, :js
7
+
8
+ before_action :set_objects
9
+
10
+ def create
11
+ @level = Level.new(@setting, level_params)
12
+ @setting.levels.unshift @level
13
+ @setting.save
14
+
15
+ respond_with @setting, collection_location: setting_path(@setting)
16
+ end
17
+
18
+ def update
19
+ if params[:commit] == 'delete'
20
+ self.action_name = 'destroy'
21
+ return destroy
22
+ end
23
+
24
+ @level = @setting.levels.find { |level| level.id == params[:id] }
25
+ @level.value = level_params[:value]
26
+ @level.conditions = level_params[:conditions].to_h
27
+ @setting.save
28
+
29
+ respond_with @setting, collection_location: setting_path(@setting)
30
+ end
31
+
32
+ def destroy
33
+ @setting.levels.reject! { |level| level.id == params[:id] }
34
+ @setting.save
35
+
36
+ respond_with @setting, collection_location: setting_path(@setting)
37
+ end
38
+
39
+ def move
40
+ oldIndex = @setting.levels.find_index { |level| level.id == params[:id] }
41
+ newIndex = params[:index]
42
+ @level = @setting.levels[oldIndex]
43
+ @level.move(oldIndex - newIndex)
44
+
45
+ render json: { old: oldIndex, new: newIndex }
46
+ end
47
+
48
+ private
49
+
50
+ def set_objects
51
+ @context = params.dig(:level, :context) || {}
52
+ @setting = Setting.find(params[:setting_id])
53
+ if respond_to? :add_breadcrumb
54
+ add_breadcrumb I18n.t('breadcrumbs.vario.settings.index'), breadcrumb_settings_path(@setting)
55
+ add_breadcrumb @setting.name, setting_path(@setting)
56
+ end
57
+ end
58
+
59
+ def level_params
60
+ params.require(:level).permit(:value, value: [], conditions: {}, context: {})
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,35 @@
1
+ require_dependency 'vario/application_controller'
2
+
3
+ module Vario
4
+ class SettingsController < ApplicationController
5
+ def index
6
+ if respond_to?(:add_breadcrumb)
7
+ add_breadcrumb I18n.t('breadcrumbs.vario.settings.index'), settings_path(settable: params[:settable])
8
+ end
9
+
10
+ @settable = GlobalID::Locator.locate_signed(params[:settable], for: 'Vario')
11
+ @title = 'Settings'
12
+ @title = "#{@title} for #{@settable.class.name} #{@settable.name}" if @settable.respond_to?(:name)
13
+ Vario.config.pre_create_settings(@settable)
14
+
15
+ @settings = Setting.where(settable: @settable).order(:name).includes(:settable)
16
+ @groups = @settings.map(&:name).select { |setting| setting =~ /\./ }.map { |setting| setting.split('.').first }
17
+ @groups = @groups.find_all { |g| Vario.config.show_group?(g) }
18
+ @groups = @groups.each_with_object(Hash.new(0)) { |v, h| h[v] += 1; }.map { |k, v| { name: k, settings: v } }
19
+ end
20
+
21
+ def show
22
+ @setting = Setting.find(params[:id])
23
+
24
+ if respond_to?(:add_breadcrumb)
25
+ add_breadcrumb I18n.t('breadcrumbs.vario.settings.index'), breadcrumb_settings_path(@setting)
26
+ add_breadcrumb @setting.name, setting_path(@setting)
27
+ end
28
+ end
29
+
30
+ def levels
31
+ @setting = Setting.find(params[:id])
32
+ render :levels, layout: false
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Vario
4
+ module ApplicationHelper
5
+ def method_missing(method, *args, &block)
6
+ if main_app.respond_to?(method)
7
+ main_app.send(method, *args)
8
+ else
9
+ super
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,4 @@
1
+ module Vario
2
+ class ApplicationJob < ActiveJob::Base
3
+ end
4
+ end
@@ -0,0 +1,6 @@
1
+ module Vario
2
+ class ApplicationMailer < ActionMailer::Base
3
+ default from: 'from@example.com'
4
+ layout 'mailer'
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module Vario
2
+ class ApplicationRecord < ActiveRecord::Base
3
+ self.abstract_class = true
4
+ end
5
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Vario
4
+ class Condition
5
+ include ActiveModel::Model
6
+ attr_accessor :key, :value
7
+
8
+ def initialize(setting, key, value)
9
+ @setting = setting
10
+ @key = key
11
+ @value = value
12
+ end
13
+
14
+ def human_value
15
+ if key_data[:type] == :select
16
+ collection.find { |entry| entry.last == value }.first
17
+ else
18
+ value
19
+ end
20
+ end
21
+
22
+ def key_data
23
+ Vario.config.key_data_for(key)
24
+ end
25
+
26
+ def collection
27
+ return @collection if @collection
28
+
29
+ @collection = key_data[:collection]
30
+ @collection ||= instance_exec(&key_data[:collection_proc]) if key_data[:collection_proc]
31
+ @collection ||= []
32
+ if value.present?
33
+ current_value = @collection.find { |entry| entry.last == value }
34
+ @collection << ["<#{value}>", value] unless current_value
35
+ end
36
+ @collection
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,94 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Vario
4
+ class Level
5
+ include ActiveModel::Model
6
+ attr_reader :conditions
7
+ attr_accessor :id, :setting, :value
8
+
9
+ def initialize(setting, level, new_record = false)
10
+ level = level.to_h.with_indifferent_access
11
+ @setting = setting
12
+ @id = level[:id] || SecureRandom.hex
13
+ @value = level[:value]
14
+ @new_record = new_record
15
+ self.conditions = level[:conditions]
16
+ end
17
+
18
+ def conditions=(new_conditions)
19
+ new_conditions = (new_conditions || {}).with_indifferent_access
20
+ @conditions = setting.keys.map do |key|
21
+ Condition.new(setting, key, new_conditions[key])
22
+ end
23
+ end
24
+
25
+ def conditions_for(context)
26
+ conditions.select { |condition| context.key?(condition.key.to_sym) }
27
+ end
28
+
29
+ def conditions_not_for(context)
30
+ conditions.reject { |condition| context.key?(condition.key.to_sym) }
31
+ end
32
+
33
+ def set_conditions
34
+ conditions.reject { |condition| condition.value.blank? }
35
+ end
36
+
37
+ def conditions_hash
38
+ set_conditions.map { |c| [c.key.to_sym, c.value] }.to_h
39
+ end
40
+
41
+ def with_context_values?(context)
42
+ context.each do |key, value|
43
+ condition = conditions.find { |condition| condition.key == key.to_s }
44
+ return false if condition.value != value
45
+ end
46
+
47
+ true
48
+ end
49
+
50
+ def move(positions)
51
+ if positions.positive?
52
+ move_up(positions)
53
+ else
54
+ move_down(positions.abs)
55
+ end
56
+ end
57
+
58
+ def move_up(positions = 1)
59
+ positions.times { |time| setting.move_level_up(self) }
60
+ setting.save!
61
+ end
62
+
63
+ def move_down(positions = 1)
64
+ positions.times { |time| setting.move_level_down(self) }
65
+ setting.save!
66
+ end
67
+
68
+ def human_value
69
+ hv = setting.human_value(value)
70
+ return unless hv
71
+ setting.type == :array ? hv.join(', ') : hv.to_s
72
+ end
73
+
74
+ def to_h
75
+ {
76
+ id: id,
77
+ conditions: conditions_hash,
78
+ value: value
79
+ }
80
+ end
81
+
82
+ def value_present?
83
+ value === false || value.present?
84
+ end
85
+
86
+ def default?
87
+ set_conditions.size.zero?
88
+ end
89
+
90
+ def persisted?
91
+ !@new_record
92
+ end
93
+ end
94
+ end
@@ -0,0 +1,188 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Vario
4
+ class Setting < ApplicationRecord
5
+ attr_reader :settable_setting, :type, :default, :description
6
+
7
+ has_paper_trail if respond_to?(:has_paper_trail)
8
+
9
+ belongs_to :settable, polymorphic: true, optional: true
10
+ validates :name, uniqueness: { scope: %i[settable_type settable_id] }
11
+ validate :validate_levels
12
+
13
+ after_initialize :configure, :levels # pre-init the levels
14
+ before_save :update_level_data
15
+
16
+ scope :for_group, ->(group_name) { where('name ilike ?', "#{group_name}.%") }
17
+ scope :without_group, -> { where.not('name ilike ?', "%.%") }
18
+
19
+ def group_name
20
+ return nil if name.blank?
21
+
22
+ parts = name.split('.', 2)
23
+
24
+ return nil if parts.size == 1
25
+
26
+ parts.first
27
+ end
28
+
29
+ def setting_name
30
+ return name if name.blank?
31
+
32
+ name.split('.', 2).last || name
33
+ end
34
+
35
+ def title
36
+ return "#{group_name.humanize}: #{setting_name.humanize}" if group_name.present?
37
+
38
+ setting_name.humanize if setting_name.present?
39
+ end
40
+
41
+ def value_for(context)
42
+ current_default = context.delete(:default)
43
+
44
+ unless initialized?
45
+ raise UnknownSetting, "Configuration key '#{name}' not initialized for #{settable_type}" if Vario.config.raise_on_undefined?(settable_type)
46
+ return current_default unless Vario.config.create_on_request?(settable_type)
47
+
48
+ # This is a new record, save it to the table since create_on_request? is true
49
+ self.keys = Vario.config.default_keys?(settable_type)
50
+ self.levels << Vario::Level.new(self, conditions: {}, value: current_default)
51
+ end
52
+
53
+ context = context.symbolize_keys
54
+ update_context(context)
55
+ validate_context(context)
56
+
57
+ result = levels.find do |level|
58
+ context >= level.conditions_hash
59
+ end
60
+
61
+ return parse_value(result.value) if result.present? && result.value_present?
62
+
63
+ parse_value(current_default || default)
64
+ end
65
+
66
+ def configure
67
+ self.keys ||= []
68
+
69
+ @settable_setting = Vario.config.settable_setting(settable_type, name)
70
+ return unless settable_setting
71
+
72
+ @type = settable_setting[:type]
73
+ self.keys = settable_setting[:keys]
74
+ @default = settable_setting[:default]
75
+ @description = settable_setting[:description]
76
+ end
77
+
78
+ def levels
79
+ @levels ||= (attributes['levels'] || []).map { |level| Level.new(self, level) }
80
+ end
81
+
82
+ def uniq_levels
83
+ selected = []
84
+
85
+ levels.each do |level|
86
+ next if selected.select { |uniq_level| uniq_level.conditions_hash == level.conditions_hash}.present?
87
+
88
+ selected << level
89
+ end
90
+
91
+ selected
92
+ end
93
+
94
+ def uniq_levels!
95
+ self.levels = uniq_levels.select { |l| l.value_present? }.map(&:to_h)
96
+ @levels = nil
97
+ save!
98
+ end
99
+
100
+ def update_level_data
101
+ self.levels = levels.select { |l| l.value_present? }.map(&:to_h)
102
+ end
103
+
104
+ def move_level_up(level)
105
+ index = levels.index(level)
106
+ level = levels.delete(level)
107
+ levels.insert(index - 1, level)
108
+ end
109
+
110
+ def move_level_down(level)
111
+ index = levels.index(level)
112
+ level = levels.delete(level)
113
+ levels.insert(index + 1, level)
114
+ end
115
+
116
+ def initialized?
117
+ return false if Vario.config.raise_on_undefined?(settable) && !persisted?
118
+ settable_setting.present? || persisted?
119
+ end
120
+
121
+ def parse_value(value)
122
+ return false if [0, '0', 'false', '', false].include?(value) && type == :boolean
123
+ return true if [1, '1', 'true', true].include?(value) && type == :boolean
124
+ return unless value.present?
125
+ return parse_value_array(value) if type == :array
126
+ return value unless value.is_a?(String)
127
+ return YAML.load(value) if type == :hash
128
+ return value.to_i if type == :integer
129
+
130
+ value
131
+ end
132
+
133
+ def human_value(value)
134
+ parsed_value = parse_value(value)
135
+ return parsed_value if collection.blank?
136
+ return parsed_value.map { |pv| collection.find { |i| i.last == pv }.first } if type == :array
137
+
138
+ collection.find { |i| i.last == parsed_value }.first
139
+ end
140
+
141
+ def parse_value_array(value)
142
+ values = value
143
+ values = values.split(/,|\n/).map(&:strip) if values.is_a?(String)
144
+ values = values.reject(&:blank?)
145
+
146
+ # If a collection has been defined, and 'all' is in the selected values, return all id's from the colletion
147
+ return collection.map(&:last) if (values.include?('all') || values.include?(:all)) && collection
148
+
149
+ values
150
+ end
151
+
152
+ def collection
153
+ return @collection if @collection
154
+ return unless settable_setting
155
+
156
+ @collection = settable_setting[:collection]
157
+ @collection ||= instance_exec(&settable_setting[:collection_proc]) if settable_setting[:collection_proc]
158
+ @collection ||= []
159
+ @collection
160
+ end
161
+
162
+ def new_level
163
+ Level.new(self, {}, true)
164
+ end
165
+
166
+ private
167
+
168
+ ###
169
+ # Fill blank values for which we've got a value_proc
170
+ #
171
+ def update_context(context)
172
+ keys.each do |key|
173
+ key = key.to_sym
174
+ key_data = Vario.config.key_data_for(key)
175
+ context[key] ||= instance_exec(&key_data[:value_proc]) if key_data.key?(:value_proc)
176
+ end
177
+ end
178
+
179
+ def validate_context(context)
180
+ missing = keys.map(&:to_sym) - context.keys
181
+ raise ArgumentError, "missing context '#{missing.join(', ')}''" if missing.present?
182
+ end
183
+
184
+ def validate_levels
185
+ errors.add(:levels, I18n.t('errors.messages.taken')) if levels.map(&:conditions_hash).uniq.size != levels.size
186
+ end
187
+ end
188
+ end
@@ -0,0 +1,53 @@
1
+ - label = nil if label.blank?
2
+ - context = {} if context.blank?
3
+ - draggable = true if draggable.nil?
4
+
5
+ = sts.form_for([setting, level], id: level.id, url: polymorphic_path([vario, setting, level]), remote: true, title: label, footer: false, header: label.present?, padding: label.present?) do |f|
6
+ - context.each do |key, value|
7
+ = f.fields_for :context do |ff|
8
+ = ff.input key, as: :hidden, input_html: { value: value }
9
+ - level.conditions_for(context).each do |condition|
10
+ = f.fields_for :conditions do |ff|
11
+ = ff.input condition.key, as: :hidden, input_html: { value: context[condition.key.to_sym] }
12
+ .grid.grid-cols-12.gap-4
13
+ .col-span-1
14
+ - if draggable
15
+ button.draggable
16
+ i class="fal fa-grip-lines" style="margin-top: 8px; margin-left: 16px;"
17
+ .col-span-7
18
+ .grid.grid-cols-12.gap-4
19
+ - level.conditions_not_for(context).each do |condition|
20
+ div class="col-span-#{[12 / level.conditions_not_for(context).size, 3].max}"
21
+ = f.fields_for :conditions do |ff|
22
+ - case condition.key_data[:type]
23
+ - when :select
24
+ = ff.input condition.key, as: :dropdown, label: condition.key, collection: condition.collection, include_blank: true, required: false, input_html: { id: "#{condition.key}_#{level.id}", value: condition.value }
25
+ - when :boolean
26
+ = ff.input condition.key, as: :switch, label: condition.key, value: condition.value, required: false
27
+ - else
28
+ = ff.input condition.key, label: condition.key, required: false, input_html: { value: context[condition.key.to_sym] }
29
+
30
+ .col-span-2
31
+ - case setting.type
32
+ - when :array
33
+ - if setting.collection.present?
34
+ = f.input :value, as: :select, input_html: { multiple: true, id: "value_#{level.id}" }, collection: [["All", 'all']] + setting.collection, required: false
35
+ - else
36
+ = f.input :value, as: :text, input_html: { rows: 10, style: 'height: auto' }, hint: 'Multiple values possible, separate with "," or new lines.'
37
+ - when :integer
38
+ = f.input :value, as: :number
39
+ - when :boolean
40
+ = f.input :value, as: :switch
41
+ - when :text
42
+ = f.input :value, as: :editor, mode: 'text/plain'
43
+ - when :hash
44
+ = f.input :value, as: :editor, mode: 'application/yaml'
45
+ - else
46
+ - if setting.collection.present?
47
+ = f.input :value, as: :dropdown, collection: setting.collection, required: false
48
+ - else
49
+ = f.input :value
50
+ .col-span-1.p-3
51
+ = f.button t('.save'), value: 'save'
52
+ .col-span-1.p-3
53
+ = f.button t('.delete'), value: 'delete' unless label.present?
@@ -0,0 +1,4 @@
1
+ <% if @setting.saved_changes? %>
2
+ document.querySelector("[data-id='<%= @setting.id %>_levels']").innerHTML = "<%= escape_javascript(render(partial: 'vario/settings/levels', locals: { setting: @setting, context: @context })) %>"
3
+ document.querySelector("[data-id='<%= @setting.id %>_new_level']").innerHTML = "<%= escape_javascript(render(partial: 'vario/settings/new_level', locals: { setting: @setting, context: @context })) %>"
4
+ <% end %>
@@ -0,0 +1,4 @@
1
+ <% if @setting.saved_changes? %>
2
+ document.querySelector("[data-id='<%= @setting.id %>_levels']").innerHTML = "<%= escape_javascript(render(partial: 'vario/settings/levels', locals: { setting: @setting, context: @context })) %>"
3
+ document.querySelector("[data-id='<%= @setting.id %>_new_level']").innerHTML = "<%= escape_javascript(render(partial: 'vario/settings/new_level', locals: { setting: @setting, context: @context })) %>"
4
+ <% end %>
@@ -0,0 +1,4 @@
1
+ <% if @setting.saved_changes? %>
2
+ document.querySelector("[data-id='<%= @setting.id %>_levels']").innerHTML = "<%= escape_javascript(render(partial: 'vario/settings/levels', locals: { setting: @setting, context: @context })) %>"
3
+ document.querySelector("[data-id='<%= @setting.id %>_new_level']").innerHTML = "<%= escape_javascript(render(partial: 'vario/settings/new_level', locals: { setting: @setting, context: @context })) %>"
4
+ <% end %>