system_settings 0.6.1 → 0.9.0
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 +4 -4
- data/README.md +11 -13
- data/app/assets/config/manifest.js +1 -0
- data/app/assets/stylesheets/system_settings/application.css +227 -0
- data/app/controllers/system_settings/application_controller.rb +2 -6
- data/app/controllers/system_settings/settings_controller.rb +21 -16
- data/app/helpers/system_settings/application_helper.rb +34 -0
- data/app/models/system_settings/application_record.rb +2 -0
- data/app/models/system_settings/boolean_setting.rb +2 -0
- data/app/models/system_settings/configurator.rb +38 -10
- data/app/models/system_settings/decimal_list_setting.rb +8 -0
- data/app/models/system_settings/decimal_setting.rb +8 -0
- data/app/models/system_settings/errors/error.rb +2 -0
- data/app/models/system_settings/errors/not_found_error.rb +3 -1
- data/app/models/system_settings/errors/not_loaded_error.rb +8 -0
- data/app/models/system_settings/errors/settings_read_error.rb +2 -0
- data/app/models/system_settings/integer_list_setting.rb +3 -1
- data/app/models/system_settings/integer_setting.rb +3 -1
- data/app/models/system_settings/list_of_decimals_validator.rb +37 -0
- data/app/models/system_settings/list_of_integers_validator.rb +2 -0
- data/app/models/system_settings/list_of_strings_validator.rb +2 -0
- data/app/models/system_settings/setting.rb +2 -0
- data/app/models/system_settings/string_list_setting.rb +2 -0
- data/app/models/system_settings/string_setting.rb +7 -0
- data/app/models/system_settings/type/decimal_list.rb +42 -0
- data/app/models/system_settings/type/integer_list.rb +10 -15
- data/app/models/system_settings/type/string_list.rb +2 -0
- data/app/views/layouts/system_settings/application.html.erb +21 -0
- data/app/views/system_settings/settings/_common_attributes.html.erb +14 -0
- data/app/views/system_settings/settings/_form.html.erb +18 -0
- data/app/views/system_settings/settings/edit.html.erb +2 -0
- data/app/views/system_settings/settings/index.html.erb +29 -0
- data/app/views/system_settings/settings/show.html.erb +9 -0
- data/config/locales/system_settings.en.yml +27 -1
- data/config/routes.rb +7 -4
- data/lib/system_settings.rb +13 -7
- data/lib/system_settings/engine.rb +6 -13
- data/lib/system_settings/version.rb +3 -1
- metadata +17 -14
- data/app/controllers/system_settings/root_controller.rb +0 -11
- data/app/models/system_settings/pagination.rb +0 -18
- data/frontend/build/asset-manifest.json +0 -11
- data/frontend/build/favicon.ico +0 -0
- data/frontend/build/index.html +0 -1
- data/frontend/build/precache-manifest.cace9a6c696c96461d63a2e3a1cca55e.js +0 -22
- data/frontend/build/service-worker.js +0 -39
- data/frontend/build/static/css/main.003e6dc8.chunk.css +0 -1
- data/frontend/build/static/js/2.42b63415.chunk.js +0 -1
- data/frontend/build/static/js/main.9315e265.chunk.js +0 -1
- data/frontend/build/static/js/runtime~main.a09e9b82.js +0 -1
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SystemSettings
|
2
4
|
class IntegerListSetting < SystemSettings::Setting
|
3
|
-
attribute :value, SystemSettings::Type::IntegerList.new
|
5
|
+
attribute :value, SystemSettings::Type::IntegerList.new(limit: 8)
|
4
6
|
validates :value, "system_settings/list_of_integers": true
|
5
7
|
end
|
6
8
|
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SystemSettings
|
4
|
+
class ListOfDecimalsValidator < ActiveModel::EachValidator
|
5
|
+
LIST_REGEXP = /\A[+-]?\d+(?:\.\d+){0,1}(?:; *[+-]?\d+(?:\.\d+){0,1})*\z/.freeze
|
6
|
+
SINGLE_REGEXP = /\A[+-]?\d+(?:\.\d+){0,1}\z/.freeze
|
7
|
+
|
8
|
+
def validate_each(record, attr_name, value)
|
9
|
+
came_from_user = :"#{attr_name}_came_from_user?"
|
10
|
+
|
11
|
+
raw_value = record.read_attribute_before_type_cast(attr_name) if record.respond_to?(came_from_user) && record.public_send(came_from_user)
|
12
|
+
raw_value ||= value
|
13
|
+
|
14
|
+
raw_value = value if record_attribute_changed_in_place?(record, attr_name)
|
15
|
+
|
16
|
+
record.errors.add(attr_name, :not_a_list_of_decimals) unless matches_list_of_decimals_regexp?(raw_value)
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def record_attribute_changed_in_place?(record, attr_name)
|
22
|
+
record.respond_to?(:attribute_changed_in_place?) &&
|
23
|
+
record.attribute_changed_in_place?(attr_name.to_s)
|
24
|
+
end
|
25
|
+
|
26
|
+
def matches_list_of_decimals_regexp?(raw_value)
|
27
|
+
case raw_value
|
28
|
+
when String
|
29
|
+
LIST_REGEXP.match?(raw_value)
|
30
|
+
when Array
|
31
|
+
raw_value.all? { |v| SINGLE_REGEXP.match?(v.to_s) }
|
32
|
+
else
|
33
|
+
false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -1,6 +1,13 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SystemSettings
|
2
4
|
class StringSetting < SystemSettings::Setting
|
3
5
|
attribute :value, :string
|
4
6
|
validates :value, presence: true
|
7
|
+
|
8
|
+
def value=(original_value)
|
9
|
+
next_value = original_value.to_s.blank? ? nil : original_value.to_s.strip
|
10
|
+
super(next_value)
|
11
|
+
end
|
5
12
|
end
|
6
13
|
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module SystemSettings
|
4
|
+
module Type
|
5
|
+
class DecimalList < ActiveModel::Type::Value
|
6
|
+
SEPARATOR = ";"
|
7
|
+
|
8
|
+
def initialize(precision: nil, limit: nil, scale: nil)
|
9
|
+
super
|
10
|
+
@single_type = ActiveModel::Type::Decimal.new(precision: precision, limit: limit, scale: scale)
|
11
|
+
end
|
12
|
+
|
13
|
+
def type
|
14
|
+
:decimal_list
|
15
|
+
end
|
16
|
+
|
17
|
+
def deserialize(value)
|
18
|
+
result = value.presence && JSON.parse(value)
|
19
|
+
if result.is_a?(Array)
|
20
|
+
result.map { |v| @single_type.cast(v) }
|
21
|
+
else
|
22
|
+
result
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def serialize(value)
|
27
|
+
JSON.dump(value) unless value.nil?
|
28
|
+
end
|
29
|
+
|
30
|
+
private
|
31
|
+
|
32
|
+
def cast_value(value)
|
33
|
+
case value
|
34
|
+
when Array
|
35
|
+
value.map { |v| @single_type.cast(v) }
|
36
|
+
when String
|
37
|
+
value.split(SEPARATOR).map { |v| @single_type.cast(v) }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -1,7 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module SystemSettings
|
2
4
|
module Type
|
3
5
|
class IntegerList < ActiveModel::Type::Value
|
4
|
-
SEPARATOR = ";"
|
6
|
+
SEPARATOR = ";"
|
7
|
+
|
8
|
+
def initialize(precision: nil, limit: nil, scale: nil)
|
9
|
+
super
|
10
|
+
@single_type = ActiveModel::Type::Integer.new(precision: precision, limit: limit, scale: scale)
|
11
|
+
end
|
5
12
|
|
6
13
|
def type
|
7
14
|
:integer_list
|
@@ -20,21 +27,9 @@ module SystemSettings
|
|
20
27
|
def cast_value(value)
|
21
28
|
case value
|
22
29
|
when Array
|
23
|
-
value.map
|
24
|
-
begin
|
25
|
-
v.to_i
|
26
|
-
rescue StandardError
|
27
|
-
nil
|
28
|
-
end
|
29
|
-
end
|
30
|
+
value.map { |v| @single_type.cast(v) }
|
30
31
|
when String
|
31
|
-
value.split(SEPARATOR).map
|
32
|
-
begin
|
33
|
-
v.to_i
|
34
|
-
rescue StandardError
|
35
|
-
nil
|
36
|
-
end
|
37
|
-
end
|
32
|
+
value.split(SEPARATOR).map { |v| @single_type.cast(v) }
|
38
33
|
end
|
39
34
|
end
|
40
35
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<meta charset="utf-8" />
|
5
|
+
<title>System Settings - <%= SystemSettings::VERSION %></title>
|
6
|
+
<%= csrf_meta_tags %>
|
7
|
+
<%= stylesheet_link_tag 'system_settings/application', media: 'all' %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
<header>
|
11
|
+
<div class="container">
|
12
|
+
<%= link_to "System Settings", root_path, class: "app-name" %>
|
13
|
+
</div>
|
14
|
+
</header>
|
15
|
+
<main>
|
16
|
+
<div class="container">
|
17
|
+
<%= yield %>
|
18
|
+
</div>
|
19
|
+
</main>
|
20
|
+
</body>
|
21
|
+
</html>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<div class="attribute">
|
2
|
+
<div class="name"><%= setting.class.human_attribute_name(:name) %></div>
|
3
|
+
<div class="value">
|
4
|
+
<span class="sys-name"><%= setting.name %></span>
|
5
|
+
</div>
|
6
|
+
</div>
|
7
|
+
<div class="attribute">
|
8
|
+
<div class="name"><%= setting.class.human_attribute_name(:type) %></div>
|
9
|
+
<div class="value"><%= setting.model_name.human %></div>
|
10
|
+
</div>
|
11
|
+
<div class="attribute">
|
12
|
+
<div class="name"><%= setting.class.human_attribute_name(:description) %></div>
|
13
|
+
<div class="value"><%= setting.description %></div>
|
14
|
+
</div>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<%= form_for setting, as: :setting, url: setting_path(setting), method: "post" do |f| %>
|
2
|
+
<div class="attribute">
|
3
|
+
<%= f.label :value, class: "name" %>
|
4
|
+
<% if f.object.is_a?(SystemSettings::BooleanSetting) %>
|
5
|
+
<%= f.check_box :value, value: f.object.value %>
|
6
|
+
<% else %>
|
7
|
+
<%= f.text_field :value, value: format_value_for_form(f.object), class: "value" %>
|
8
|
+
<% end %>
|
9
|
+
<% if f.object.errors.messages[:value].any? %>
|
10
|
+
<div class="errors"><%= f.object.errors.messages[:value].join("; ") %></div>
|
11
|
+
<% end %>
|
12
|
+
<div class="hint"><%= t(f.object.type, scope: "system_settings.settings.form.hints_by_type", default: "").html_safe %></div>
|
13
|
+
</div>
|
14
|
+
<div class="buttons">
|
15
|
+
<%= f.submit t(".save"), class: "primary" %>
|
16
|
+
<%= link_to t(".back"), setting_path(setting), class: "button" %>
|
17
|
+
</div>
|
18
|
+
<% end %>
|
@@ -0,0 +1,29 @@
|
|
1
|
+
<table class="settings-table">
|
2
|
+
<thead>
|
3
|
+
<tr>
|
4
|
+
<th class="name"><%= SystemSettings::Setting.human_attribute_name(:name) %></th>
|
5
|
+
<th class="description"><%= SystemSettings::Setting.human_attribute_name(:description) %></th>
|
6
|
+
<th class="value"><%= SystemSettings::Setting.human_attribute_name(:value) %></th>
|
7
|
+
</tr>
|
8
|
+
</thead>
|
9
|
+
<tbody>
|
10
|
+
<% if @settings.any? %>
|
11
|
+
<% @settings.each do |setting| %>
|
12
|
+
<tr>
|
13
|
+
<td class="name"><%= link_to setting.name, setting_path(setting), class: "sys-name" %></td>
|
14
|
+
<td class="description"><%= setting.description %></td>
|
15
|
+
<td class="value"><%= format_value setting.value %></td>
|
16
|
+
</tr>
|
17
|
+
<% end %>
|
18
|
+
<% else %>
|
19
|
+
<tr>
|
20
|
+
<td colspan="3" class="no-entries"><%= t(".no_settings").html_safe %></td>
|
21
|
+
</tr>
|
22
|
+
<% end %>
|
23
|
+
</tbody>
|
24
|
+
<tfoot>
|
25
|
+
<tr>
|
26
|
+
<td colspan="3"><%= t(".add_new", path: display_settings_file_path).html_safe %></td>
|
27
|
+
</tr>
|
28
|
+
</tfoot>
|
29
|
+
</table>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<%= render "common_attributes", setting: @setting %>
|
2
|
+
<div class="attribute">
|
3
|
+
<div class="name"><%= @setting.class.human_attribute_name(:value) %></div>
|
4
|
+
<div class="value"><%= format_value @setting.value %></div>
|
5
|
+
</div>
|
6
|
+
<div class="buttons">
|
7
|
+
<%= link_to t(".edit"), edit_setting_path(@setting), class: "button primary" %>
|
8
|
+
<%= link_to t(".back"), root_path, class: "button" %>
|
9
|
+
</div>
|
@@ -16,11 +16,21 @@ en:
|
|
16
16
|
system_settings/string_setting:
|
17
17
|
one: "System Setting (String)"
|
18
18
|
other: "System Settings (String)"
|
19
|
+
system_settings/decimal_setting:
|
20
|
+
one: "System Setting (Decimal)"
|
21
|
+
other: "System Settings (Decimal)"
|
22
|
+
system_settings/decimal_list_setting:
|
23
|
+
one: "System Setting (Decimal list)"
|
24
|
+
other: "System Settings (Decimal list)"
|
25
|
+
system_settings/boolean_setting:
|
26
|
+
one: "System Setting (Boolean)"
|
27
|
+
other: "System Settings (Boolean)"
|
19
28
|
attributes:
|
20
29
|
system_settings/setting:
|
21
30
|
id: "ID"
|
22
31
|
name: "Name"
|
23
32
|
type: "Type"
|
33
|
+
value: "Value"
|
24
34
|
description: "Description"
|
25
35
|
created_at: "Created at"
|
26
36
|
uploaded_at: "Updated at"
|
@@ -31,7 +41,23 @@ en:
|
|
31
41
|
value:
|
32
42
|
not_a_list_of_integers: "not a list of integers"
|
33
43
|
not_a_list_of_strings: "not a list of strings"
|
44
|
+
not_a_list_of_decimals: "not a list of decimals"
|
34
45
|
system_settings/boolean_setting:
|
35
46
|
attributes:
|
36
47
|
value:
|
37
|
-
inclusion: "must be set to true or false"
|
48
|
+
inclusion: "must be set to true or false"
|
49
|
+
system_settings:
|
50
|
+
settings:
|
51
|
+
index:
|
52
|
+
no_settings: "No settings"
|
53
|
+
add_new: "Add new entries in <code>%{path}</code>"
|
54
|
+
show:
|
55
|
+
edit: Edit
|
56
|
+
back: Back
|
57
|
+
form:
|
58
|
+
save: Save
|
59
|
+
back: Back
|
60
|
+
hints_by_type:
|
61
|
+
"SystemSettings::StringListSetting": "Separate values by <code>;</code> character."
|
62
|
+
"SystemSettings::IntegerListSetting": "Separate values by <code>;</code> character."
|
63
|
+
"SystemSettings::DecimalListSetting": "Decimal separator is the <code>.</code> character. Separate multiple values by <code>;</code> character."
|
data/config/routes.rb
CHANGED
@@ -1,7 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
SystemSettings::Engine.routes.draw do
|
2
|
-
|
3
|
-
|
4
|
+
resources :settings, only: [:show, :edit] do
|
5
|
+
member do
|
6
|
+
post "/", to: "settings#update"
|
7
|
+
end
|
4
8
|
end
|
5
|
-
root to: "
|
6
|
-
get "*rest", to: "root#index", as: :catch_all
|
9
|
+
root to: "settings#index"
|
7
10
|
end
|
data/lib/system_settings.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "system_settings/version"
|
1
4
|
require "system_settings/engine"
|
2
5
|
|
3
6
|
module SystemSettings
|
@@ -9,21 +12,24 @@ module SystemSettings
|
|
9
12
|
instrument("system_settings.find", name: name) do |payload|
|
10
13
|
record = Setting.find_by(name: name)
|
11
14
|
unless record
|
12
|
-
message =
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
15
|
+
message = <<~MESSAGE.strip
|
16
|
+
Couldn't find system setting #{name}
|
17
|
+
|
18
|
+
It might not be loaded from settings file(#{settings_file_path}).
|
19
|
+
To load missing settings with their initial values you can call SystemSettings.load from your Rails environment or run Rails task:
|
20
|
+
|
21
|
+
bin/rails system_settings:load RAILS_ENV=#{::Rails.env}
|
22
|
+
MESSAGE
|
17
23
|
raise(Errors::NotFoundError, message)
|
18
24
|
end
|
19
25
|
payload[:value] = record.value
|
20
26
|
end
|
21
27
|
end
|
22
28
|
|
23
|
-
def self.load
|
29
|
+
def self.load(*names)
|
24
30
|
instrument("system_settings.load", path: settings_file_path) do |payload|
|
25
31
|
configurator = Configurator.from_file(settings_file_path)
|
26
|
-
payload[:success] = configurator.persist
|
32
|
+
payload[:success] = configurator.persist(only: names)
|
27
33
|
end
|
28
34
|
end
|
29
35
|
|