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.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -11
  3. data/app/assets/config/manifest.js +1 -0
  4. data/app/assets/stylesheets/system_settings/application.css +227 -0
  5. data/app/controllers/system_settings/application_controller.rb +0 -6
  6. data/app/controllers/system_settings/settings_controller.rb +19 -13
  7. data/app/helpers/system_settings/application_helper.rb +34 -0
  8. data/app/models/system_settings/list_of_decimals_validator.rb +1 -1
  9. data/app/models/system_settings/string_setting.rb +5 -0
  10. data/app/views/layouts/system_settings/application.html.erb +21 -0
  11. data/app/views/system_settings/settings/_common_attributes.html.erb +14 -0
  12. data/app/views/system_settings/settings/_form.html.erb +18 -0
  13. data/app/views/system_settings/settings/edit.html.erb +2 -0
  14. data/app/views/system_settings/settings/index.html.erb +29 -0
  15. data/app/views/system_settings/settings/show.html.erb +9 -0
  16. data/config/locales/system_settings.en.yml +20 -1
  17. data/config/routes.rb +5 -4
  18. data/lib/system_settings.rb +1 -0
  19. data/lib/system_settings/engine.rb +3 -12
  20. data/lib/system_settings/version.rb +1 -1
  21. metadata +12 -18
  22. data/app/controllers/system_settings/root_controller.rb +0 -13
  23. data/app/models/system_settings/pagination.rb +0 -20
  24. data/frontend/build/asset-manifest.json +0 -21
  25. data/frontend/build/favicon.ico +0 -0
  26. data/frontend/build/index.html +0 -1
  27. data/frontend/build/precache-manifest.2a3085e0df9528a5989319fa25e318b5.js +0 -22
  28. data/frontend/build/service-worker.js +0 -39
  29. data/frontend/build/static/css/main.04fc5f62.chunk.css +0 -2
  30. data/frontend/build/static/css/main.04fc5f62.chunk.css.map +0 -1
  31. data/frontend/build/static/js/2.bb361686.chunk.js +0 -2
  32. data/frontend/build/static/js/2.bb361686.chunk.js.map +0 -1
  33. data/frontend/build/static/js/main.7e8676c5.chunk.js +0 -2
  34. data/frontend/build/static/js/main.7e8676c5.chunk.js.map +0 -1
  35. data/frontend/build/static/js/runtime-main.ffc5e8a3.js +0 -2
  36. 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: '0342639e1515fcf5d530d0561009f375199df5b86d00ee80cd1517bd9522fbf9'
4
- data.tar.gz: ce20dab7409179611cdf5c223df76d5b9627cdb17ee10e90e0bff6dfbdb794c5
3
+ metadata.gz: 321c73f1b71d88e67c98191025ac69b6fa58ea6dbbaa838cb5a6eaea6622337a
4
+ data.tar.gz: 17bd42a54230f37063f618fe2cfebc3875410d3879757e9ed38138990c6a952d
5
5
  SHA512:
6
- metadata.gz: 49e264aa4aee4f8451362b1687fbd3ac8a73b3584fc012b3d2f20c2bc5da931f780dace23589bcbc587d1ddef7f42fe5f2a4d92b33a96d66e8c8c9ff55cfa636
7
- data.tar.gz: a2a95984c03860e6249007cc17739a445f5208c7ef985c49f0151565c682bd3510fedf3338fcc56985b2c582ff8508a5c1d840c5739811303a3a6dfaca8aaeda
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
- * [overmind](https://github.com/DarthSim/overmind) - Process manager for Procfile-based applications and tmux
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
  [![Build Status](https://dev.azure.com/kristsozols/System%20Settings/_apis/build/status/krists.system_settings?branchName=master)](https://dev.azure.com/kristsozols/System%20Settings/_build/latest?definitionId=1&branchName=master)
138
-
129
+ [![Maintainability](https://api.codeclimate.com/v1/badges/3ad889ca36f62bad04dc/maintainability)](https://codeclimate.com/github/krists/system_settings/maintainability)
130
+ [![Test Coverage](https://api.codeclimate.com/v1/badges/3ad889ca36f62bad04dc/test_coverage)](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 = ["id", "name", "type", "value", "description"].freeze
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
- @total_count = SystemSettings::Setting.count
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 show
14
- @setting = SystemSettings::Setting.find(params[:id])
15
- add_authenticity_token
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 = SystemSettings::Setting.find(params[:id])
21
- if @setting.update(value: params[:value])
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 json: {errors: @setting.errors.as_json}, status: :unprocessable_entity
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
- record.attribute_changed_in_place?(attr_name.to_s)
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 %>