system_settings 0.8.0 → 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 +3 -11
- 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 +0 -6
- data/app/controllers/system_settings/settings_controller.rb +19 -13
- data/app/helpers/system_settings/application_helper.rb +34 -0
- data/app/models/system_settings/list_of_decimals_validator.rb +1 -1
- data/app/models/system_settings/string_setting.rb +5 -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 +20 -1
- data/config/routes.rb +5 -4
- data/lib/system_settings.rb +1 -0
- data/lib/system_settings/engine.rb +3 -12
- data/lib/system_settings/version.rb +1 -1
- metadata +12 -18
- data/app/controllers/system_settings/root_controller.rb +0 -13
- data/app/models/system_settings/pagination.rb +0 -20
- data/frontend/build/asset-manifest.json +0 -21
- data/frontend/build/favicon.ico +0 -0
- data/frontend/build/index.html +0 -1
- data/frontend/build/precache-manifest.2a3085e0df9528a5989319fa25e318b5.js +0 -22
- data/frontend/build/service-worker.js +0 -39
- data/frontend/build/static/css/main.04fc5f62.chunk.css +0 -2
- data/frontend/build/static/css/main.04fc5f62.chunk.css.map +0 -1
- data/frontend/build/static/js/2.bb361686.chunk.js +0 -2
- data/frontend/build/static/js/2.bb361686.chunk.js.map +0 -1
- data/frontend/build/static/js/main.7e8676c5.chunk.js +0 -2
- data/frontend/build/static/js/main.7e8676c5.chunk.js.map +0 -1
- data/frontend/build/static/js/runtime-main.ffc5e8a3.js +0 -2
- data/frontend/build/static/js/runtime-main.ffc5e8a3.js.map +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 321c73f1b71d88e67c98191025ac69b6fa58ea6dbbaa838cb5a6eaea6622337a
|
4
|
+
data.tar.gz: 17bd42a54230f37063f618fe2cfebc3875410d3879757e9ed38138990c6a952d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4231c986165f29d944aec79b4cc5239ccc9f7d614ef710ec77e452a238f8579ec3afcf20c09c0701ec49b3a89547ebbfcc3e4f395a71d024b1349fadb8df1cfc
|
7
|
+
data.tar.gz: bab2dd0fbf7b7f5f38ea38e4ebdcb1d732eb0254a2e3278925ac16408cca8d3c05c898137c92e7916c2b4f85c6105a9ad1e1ec5be0e51eb9d8a0fa617ff3fd47
|
data/README.md
CHANGED
@@ -105,13 +105,8 @@ And if you modify settings values in test example you can reset to defaults with
|
|
105
105
|
|
106
106
|
## Development
|
107
107
|
|
108
|
-
Required development dependencies:
|
109
|
-
* [Node.js](https://nodejs.org/) - JavaScript runtime
|
110
|
-
* [Yarn](https://yarnpkg.com/) - package manager
|
111
|
-
|
112
108
|
Optional development tools:
|
113
|
-
* [
|
114
|
-
* [direnv](https://direnv.net/) - Unclutter your .profile
|
109
|
+
* [direnv](https://direnv.net/) - Unclutter your .profile
|
115
110
|
|
116
111
|
Required environment variables:
|
117
112
|
* `RAILS_VERSION`
|
@@ -126,16 +121,13 @@ Getting started with development:
|
|
126
121
|
1) `RAILS_VERSION=5.2.3 SQLITE3_VERSION=1.4.1 bundle`
|
127
122
|
2) `RAILS_VERSION=5.2.3 SQLITE3_VERSION=1.4.1 ./bin/rails db:create db:migrate`
|
128
123
|
3) `RAILS_VERSION=5.2.3 SQLITE3_VERSION=1.4.1 ./bin/rails test`
|
129
|
-
4) `RAILS_VERSION=5.2.3 SQLITE3_VERSION=1.4.1 ./bin/rails frontend:install`
|
130
|
-
4) `RAILS_VERSION=5.2.3 SQLITE3_VERSION=1.4.1 ./bin/rails app:system_settings:load`
|
131
|
-
4) `RAILS_VERSION=5.2.3 SQLITE3_VERSION=1.4.1 overmind start`
|
132
|
-
|
133
124
|
|
134
125
|
## Build status
|
135
126
|
System Settings is being tested with Rails versions - `5.0`, `5.1`, `5.2`, `6.0`, `rails repo master branch`
|
136
127
|
|
137
128
|
[](https://dev.azure.com/kristsozols/System%20Settings/_build/latest?definitionId=1&branchName=master)
|
138
|
-
|
129
|
+
[](https://codeclimate.com/github/krists/system_settings/maintainability)
|
130
|
+
[](https://codeclimate.com/github/krists/system_settings/test_coverage)
|
139
131
|
|
140
132
|
## License
|
141
133
|
The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
|
@@ -0,0 +1 @@
|
|
1
|
+
//= link_directory ../stylesheets .css
|
@@ -0,0 +1,227 @@
|
|
1
|
+
html {
|
2
|
+
box-sizing: border-box;
|
3
|
+
font-size: 14px;
|
4
|
+
font-family: Arial, Helvetica, sans-serif;
|
5
|
+
overflow-y: scroll;
|
6
|
+
}
|
7
|
+
|
8
|
+
*, *:before, *:after {box-sizing: inherit;}
|
9
|
+
|
10
|
+
body {
|
11
|
+
margin: 0;
|
12
|
+
padding: 0;
|
13
|
+
font-weight: normal;
|
14
|
+
min-height: 100vh;
|
15
|
+
position: relative;
|
16
|
+
display: flex;
|
17
|
+
flex-direction: column;
|
18
|
+
color: #233656;
|
19
|
+
background: white;
|
20
|
+
font-size: 1rem;
|
21
|
+
line-height: 1.5rem;
|
22
|
+
}
|
23
|
+
|
24
|
+
header {
|
25
|
+
border-bottom: 1px solid #e1e1e1;
|
26
|
+
height: 2rem;
|
27
|
+
padding: 0.5rem 0;
|
28
|
+
box-sizing: content-box;
|
29
|
+
background: white;
|
30
|
+
position: sticky;
|
31
|
+
top: 0;
|
32
|
+
width: 100%;
|
33
|
+
}
|
34
|
+
|
35
|
+
main {
|
36
|
+
padding: 3rem 0;
|
37
|
+
}
|
38
|
+
|
39
|
+
header .container,
|
40
|
+
main .container {
|
41
|
+
max-width: 1020px;
|
42
|
+
margin: 0 auto;
|
43
|
+
}
|
44
|
+
|
45
|
+
a { color: #233656; text-decoration: none; }
|
46
|
+
a:hover { text-decoration: underline; }
|
47
|
+
|
48
|
+
.app-name, .app-name:hover, .app-name:active {
|
49
|
+
font-size: 1.5rem;
|
50
|
+
line-height: 2rem;
|
51
|
+
font-weight: bold;
|
52
|
+
user-select: none;
|
53
|
+
text-decoration: none;
|
54
|
+
}
|
55
|
+
|
56
|
+
.sys-name {
|
57
|
+
display: inline-block;
|
58
|
+
background: #f2f2f2;
|
59
|
+
border-radius: 3px;
|
60
|
+
padding: 0 0.5em;
|
61
|
+
font-family: "Courier New", Courier, monospace;
|
62
|
+
font-size: 0.75em;
|
63
|
+
max-width: 100%;
|
64
|
+
}
|
65
|
+
|
66
|
+
table th {
|
67
|
+
text-align: left;
|
68
|
+
}
|
69
|
+
|
70
|
+
.settings-table {
|
71
|
+
width: 100%;
|
72
|
+
table-layout: fixed;
|
73
|
+
white-space: nowrap;
|
74
|
+
user-select: none;
|
75
|
+
}
|
76
|
+
|
77
|
+
.settings-table td:empty:after {
|
78
|
+
content: "-";
|
79
|
+
}
|
80
|
+
|
81
|
+
.settings-table td {
|
82
|
+
overflow: hidden;
|
83
|
+
text-overflow: ellipsis;
|
84
|
+
}
|
85
|
+
|
86
|
+
.settings-table .description { width: 35% }
|
87
|
+
.settings-table .value { width: 25% }
|
88
|
+
|
89
|
+
.settings-table tbody td.no-entries {
|
90
|
+
color: #737373;
|
91
|
+
padding-top: 1rem;
|
92
|
+
margin-bottom: 1rem;
|
93
|
+
}
|
94
|
+
|
95
|
+
.settings-table tfoot td {
|
96
|
+
font-size: 0.8em;
|
97
|
+
padding-top: 1rem;
|
98
|
+
margin-bottom: 1rem;
|
99
|
+
}
|
100
|
+
|
101
|
+
.settings-table .value .value-part, .attribute .value .value-part {
|
102
|
+
max-width: 100%;
|
103
|
+
margin-right: 0.25em;
|
104
|
+
}
|
105
|
+
|
106
|
+
.settings-table .value .value-part:last-child, .attribute .value .value-part:last-child {
|
107
|
+
margin-right: 0;
|
108
|
+
}
|
109
|
+
|
110
|
+
.attribute {
|
111
|
+
display: flex;
|
112
|
+
flex-direction: column;
|
113
|
+
margin-bottom: 1rem;
|
114
|
+
}
|
115
|
+
|
116
|
+
.attribute .name {
|
117
|
+
font-size: 0.8em;
|
118
|
+
color: #737373;
|
119
|
+
user-select: none;
|
120
|
+
}
|
121
|
+
|
122
|
+
.attribute .value {
|
123
|
+
align-self: flex-start;
|
124
|
+
}
|
125
|
+
.attribute .value:empty:after {
|
126
|
+
content: "-";
|
127
|
+
}
|
128
|
+
|
129
|
+
.attribute .field_with_errors .name, .attribute .errors {
|
130
|
+
color: #d01d1d;
|
131
|
+
}
|
132
|
+
.attribute .hint {
|
133
|
+
font-size: 0.8em;
|
134
|
+
display: block;
|
135
|
+
}
|
136
|
+
|
137
|
+
.buttons {
|
138
|
+
border-top: 1px dotted #f2f2f2;
|
139
|
+
padding-top: 1rem;
|
140
|
+
margin-bottom: 1rem;
|
141
|
+
}
|
142
|
+
.buttons > * {
|
143
|
+
margin-right: 0.5rem;
|
144
|
+
}
|
145
|
+
|
146
|
+
button, input[type=submit], input[type=button], a.button {
|
147
|
+
display: inline-block;
|
148
|
+
cursor: pointer;
|
149
|
+
border: none;
|
150
|
+
border-radius: 3px;
|
151
|
+
padding: 0.375rem 0.75rem;
|
152
|
+
font-size: 1rem;
|
153
|
+
line-height: 1.5;
|
154
|
+
user-select: none;
|
155
|
+
white-space: nowrap;
|
156
|
+
}
|
157
|
+
|
158
|
+
button, input[type=submit], input[type=button] {
|
159
|
+
color: #4d4d4d;
|
160
|
+
background-color: #d9d9d9;
|
161
|
+
transition: background-color 0.1s ease-in-out;
|
162
|
+
outline: none;
|
163
|
+
}
|
164
|
+
|
165
|
+
button:focus, button:hover, input[type=submit]:focus, input[type=submit]:hover, input[type=button]:focus, input[type=button]:hover {
|
166
|
+
background-color: #b8b8b8;
|
167
|
+
}
|
168
|
+
|
169
|
+
button:active, input[type=submit]:active, input[type=button]:active {
|
170
|
+
background-color: #828282;
|
171
|
+
}
|
172
|
+
|
173
|
+
a.button {
|
174
|
+
color: #4d4d4d;
|
175
|
+
background-color: transparent;
|
176
|
+
transition: background-color 0.1s ease-in-out;
|
177
|
+
outline: none;
|
178
|
+
text-decoration: none;
|
179
|
+
}
|
180
|
+
|
181
|
+
a.button:focus, a.button:hover {
|
182
|
+
background-color: rgba(0, 0, 0, 0.15);
|
183
|
+
}
|
184
|
+
|
185
|
+
a.button:active {
|
186
|
+
background-color: rgba(0, 0, 0, 0.4);
|
187
|
+
}
|
188
|
+
|
189
|
+
button.primary, input[type=submit].primary, input[type=button].primary, a.button.primary {
|
190
|
+
color: #4d4d4d;
|
191
|
+
background-color: #a6a6a6;
|
192
|
+
transition: background-color 0.1s ease-in-out;
|
193
|
+
outline: none;
|
194
|
+
}
|
195
|
+
|
196
|
+
button.primary:focus, button.primary:hover, input[type=submit].primary:focus, input[type=submit].primary:hover, input[type=button].primary:focus, input[type=button].primary:hover, a.button.primary:focus, a.button.primary:hover {
|
197
|
+
background-color: #8d8d8d;
|
198
|
+
}
|
199
|
+
|
200
|
+
button.primary:active, input[type=submit].primary:active, input[type=button].primary:active, a.button.primary:active {
|
201
|
+
background-color: #646464;
|
202
|
+
}
|
203
|
+
|
204
|
+
input[type=text] {
|
205
|
+
border: none;
|
206
|
+
border-radius: 3px;
|
207
|
+
padding: 0.5em;
|
208
|
+
font-size: 1rem;
|
209
|
+
line-height: normal;
|
210
|
+
color: #4d4d4d;
|
211
|
+
background-color: #e6e6e6;
|
212
|
+
transition: background-color 0.1s ease-in-out;
|
213
|
+
outline: none;
|
214
|
+
box-sizing: content-box;
|
215
|
+
width: auto;
|
216
|
+
min-width: 12ch;
|
217
|
+
max-width: calc(100% - 2em);
|
218
|
+
will-change: width;
|
219
|
+
}
|
220
|
+
|
221
|
+
input[type=text]:focus {
|
222
|
+
background-color: #c4c4c4;
|
223
|
+
}
|
224
|
+
|
225
|
+
input[type=text]:active {
|
226
|
+
background-color: #bfbfbf;
|
227
|
+
}
|
@@ -3,11 +3,5 @@
|
|
3
3
|
module SystemSettings
|
4
4
|
class ApplicationController < ActionController::Base
|
5
5
|
protect_from_forgery with: :exception
|
6
|
-
|
7
|
-
private
|
8
|
-
|
9
|
-
def add_authenticity_token
|
10
|
-
response.headers["Authenticity-Token"] = form_authenticity_token if protect_against_forgery?
|
11
|
-
end
|
12
6
|
end
|
13
7
|
end
|
@@ -2,27 +2,33 @@
|
|
2
2
|
|
3
3
|
module SystemSettings
|
4
4
|
class SettingsController < SystemSettings::ApplicationController
|
5
|
-
RETURN_ATTRIBUTES = [
|
5
|
+
RETURN_ATTRIBUTES = %w[id name type value description].freeze
|
6
|
+
before_action :set_setting, only: [:edit, :show, :update]
|
6
7
|
|
7
8
|
def index
|
8
|
-
@
|
9
|
-
@settings = SystemSettings::Setting.order(:name).extending(SystemSettings::Pagination).page(params[:page], per_page: params[:per])
|
10
|
-
render json: {items: @settings.map { |s| s.as_json(only: RETURN_ATTRIBUTES) }, total_count: @total_count}
|
9
|
+
@settings = SystemSettings::Setting.order(:name)
|
11
10
|
end
|
12
11
|
|
13
|
-
def
|
14
|
-
|
15
|
-
|
16
|
-
render json: @setting.as_json(only: RETURN_ATTRIBUTES)
|
17
|
-
end
|
12
|
+
def edit; end
|
13
|
+
|
14
|
+
def show; end
|
18
15
|
|
19
16
|
def update
|
20
|
-
@setting
|
21
|
-
|
22
|
-
render json: @setting.as_json(only: RETURN_ATTRIBUTES)
|
17
|
+
if @setting.update(setting_params)
|
18
|
+
redirect_to setting_path(@setting)
|
23
19
|
else
|
24
|
-
render
|
20
|
+
render :edit
|
25
21
|
end
|
26
22
|
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def set_setting
|
27
|
+
@setting = SystemSettings::Setting.find(params[:id])
|
28
|
+
end
|
29
|
+
|
30
|
+
def setting_params
|
31
|
+
params.require(:setting).permit(:value)
|
32
|
+
end
|
27
33
|
end
|
28
34
|
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module SystemSettings::ApplicationHelper
|
2
|
+
SEPARATOR = ";".freeze
|
3
|
+
|
4
|
+
def format_value(value)
|
5
|
+
if value.respond_to?(:each)
|
6
|
+
capture do
|
7
|
+
value.each do |v|
|
8
|
+
concat content_tag(:span, v, class: "value-part")
|
9
|
+
end
|
10
|
+
end
|
11
|
+
else
|
12
|
+
value
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def format_value_for_form(record)
|
17
|
+
case record
|
18
|
+
when SystemSettings::StringListSetting
|
19
|
+
record.value.map { |v| v.gsub(SEPARATOR, "\\#{SEPARATOR}") }.join(SEPARATOR)
|
20
|
+
when SystemSettings::IntegerListSetting, SystemSettings::DecimalListSetting
|
21
|
+
record.value.join(SEPARATOR)
|
22
|
+
else
|
23
|
+
record.value
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def display_settings_file_path
|
28
|
+
if SystemSettings.settings_file_path.to_s.include?(Rails.root.to_s)
|
29
|
+
Pathname.new(SystemSettings.settings_file_path).relative_path_from(Rails.root)
|
30
|
+
else
|
31
|
+
SystemSettings.settings_file_path
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
@@ -20,7 +20,7 @@ module SystemSettings
|
|
20
20
|
|
21
21
|
def record_attribute_changed_in_place?(record, attr_name)
|
22
22
|
record.respond_to?(:attribute_changed_in_place?) &&
|
23
|
-
|
23
|
+
record.attribute_changed_in_place?(attr_name.to_s)
|
24
24
|
end
|
25
25
|
|
26
26
|
def matches_list_of_decimals_regexp?(raw_value)
|
@@ -4,5 +4,10 @@ module SystemSettings
|
|
4
4
|
class StringSetting < SystemSettings::Setting
|
5
5
|
attribute :value, :string
|
6
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
|
7
12
|
end
|
8
13
|
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 %>
|