super_settings 2.3.1 → 2.4.1
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/ARCHITECTURE.md +0 -0
- data/CHANGELOG.md +16 -0
- data/README.md +6 -2
- data/VERSION +1 -1
- data/lib/super_settings/application/helper.rb +14 -0
- data/lib/super_settings/application/index.html.erb +95 -98
- data/lib/super_settings/application/layout.html.erb +1 -1
- data/lib/super_settings/application/scripts.js +177 -139
- data/lib/super_settings/application/style_vars.css.erb +22 -4
- data/lib/super_settings/application/styles.css +294 -75
- data/lib/super_settings/application.rb +1 -1
- data/lib/super_settings/coerce.rb +1 -0
- data/lib/super_settings/context/current.rb +23 -0
- data/lib/super_settings/context.rb +3 -0
- data/lib/super_settings/local_cache.rb +14 -0
- data/lib/super_settings/rack_application.rb +3 -1
- data/lib/super_settings/rest_api.rb +22 -3
- data/lib/super_settings/setting.rb +4 -0
- data/lib/super_settings/storage/http_storage.rb +2 -4
- data/lib/super_settings/storage/redis_storage.rb +3 -0
- data/lib/super_settings/storage/test_storage.rb +1 -0
- data/lib/super_settings/time_precision.rb +18 -0
- data/lib/super_settings.rb +3 -1
- metadata +3 -2
@@ -5,29 +5,209 @@
|
|
5
5
|
margin-right: auto;
|
6
6
|
}
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
/* Card Layout Styles */
|
9
|
+
.super-settings-cards-container {
|
10
|
+
display: flex;
|
11
|
+
flex-direction: column;
|
12
|
+
gap: 0.75rem;
|
13
|
+
padding: 1rem 0;
|
14
|
+
}
|
15
|
+
|
16
|
+
.super-settings-card {
|
17
|
+
border: 2px solid var(--table-border-color);
|
18
|
+
border-radius: 0.5rem;
|
19
|
+
background-color: var(--card-bg-color);
|
20
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
|
21
|
+
transition: box-shadow 0.2s ease-in-out;
|
22
|
+
width: 100%;
|
11
23
|
}
|
12
24
|
|
13
|
-
|
14
|
-
|
25
|
+
.super-settings-card:hover {
|
26
|
+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
15
27
|
}
|
16
28
|
|
17
|
-
|
18
|
-
|
29
|
+
.super-settings-cards-container .super-settings-card:nth-child(even) {
|
30
|
+
background-color: var(--alt-row-color);
|
31
|
+
}
|
32
|
+
|
33
|
+
.super-settings-card-edit {
|
34
|
+
background-color: var(--edit-bg-color) !important;
|
35
|
+
border-color: var(--primary-border-color);
|
19
36
|
}
|
20
37
|
|
21
|
-
|
38
|
+
.super-settings-card[data-deleted] {
|
22
39
|
background-color: var(--deleted-row-bg-color) !important;
|
23
40
|
color: var(--deleted-row-color);
|
41
|
+
}
|
42
|
+
|
43
|
+
.super-settings-card[data-deleted] .js-value-placeholder,
|
44
|
+
.super-settings-card[data-deleted] strong,
|
45
|
+
.super-settings-card[data-deleted] .super-settings-form-control {
|
24
46
|
text-decoration: line-through;
|
25
47
|
}
|
26
48
|
|
27
|
-
|
28
|
-
|
49
|
+
.super-settings-card[data-deleted] .super-settings-card-label {
|
50
|
+
text-decoration: none;
|
51
|
+
}
|
52
|
+
|
53
|
+
/* Card content layout for desktop - column alignment */
|
54
|
+
@media (min-width: 768px) {
|
55
|
+
.super-settings-card-content {
|
56
|
+
display: grid;
|
57
|
+
grid-template-columns: 2fr 2fr 1fr 3fr 1fr 1fr;
|
58
|
+
gap: 1rem;
|
59
|
+
align-items: start;
|
60
|
+
padding: 1rem;
|
61
|
+
}
|
62
|
+
|
63
|
+
.super-settings-card-key {
|
64
|
+
grid-column: 1;
|
65
|
+
}
|
66
|
+
|
67
|
+
.super-settings-card-value {
|
68
|
+
grid-column: 2;
|
69
|
+
margin-bottom: 0;
|
70
|
+
}
|
71
|
+
|
72
|
+
.super-settings-card-type {
|
73
|
+
grid-column: 3;
|
74
|
+
}
|
75
|
+
|
76
|
+
.super-settings-card-description {
|
77
|
+
grid-column: 4;
|
78
|
+
margin-bottom: 0;
|
79
|
+
}
|
80
|
+
|
81
|
+
.super-settings-card-modified {
|
82
|
+
grid-column: 5;
|
83
|
+
}
|
84
|
+
|
85
|
+
.super-settings-card-controls {
|
86
|
+
grid-column: 6;
|
87
|
+
margin-left: 0;
|
88
|
+
}
|
89
|
+
}
|
90
|
+
|
91
|
+
/* Mobile layout - stacked */
|
92
|
+
@media (max-width: 767px) {
|
93
|
+
.super-settings-card-content {
|
94
|
+
padding: 1rem;
|
95
|
+
}
|
96
|
+
|
97
|
+
.super-settings-card-key {
|
98
|
+
margin-bottom: 1rem;
|
99
|
+
}
|
100
|
+
|
101
|
+
.super-settings-card-value {
|
102
|
+
margin-bottom: 1rem;
|
103
|
+
}
|
104
|
+
|
105
|
+
.super-settings-card-meta {
|
106
|
+
display: grid;
|
107
|
+
grid-template-columns: 1fr 1fr;
|
108
|
+
gap: 1rem;
|
109
|
+
margin-bottom: 1rem;
|
110
|
+
}
|
111
|
+
|
112
|
+
.super-settings-card-description {
|
113
|
+
margin-bottom: 1rem;
|
114
|
+
}
|
115
|
+
|
116
|
+
.super-settings-card-controls {
|
117
|
+
display: flex;
|
118
|
+
gap: 0.25rem;
|
119
|
+
justify-content: flex-end;
|
120
|
+
}
|
29
121
|
}
|
30
122
|
|
123
|
+
.super-settings-card-key input[type="text"] {
|
124
|
+
margin: 0;
|
125
|
+
width: 100%;
|
126
|
+
}
|
127
|
+
|
128
|
+
.super-settings-card-controls {
|
129
|
+
display: flex;
|
130
|
+
gap: 0.25rem;
|
131
|
+
flex-shrink: 0;
|
132
|
+
}
|
133
|
+
|
134
|
+
.super-settings-card-label {
|
135
|
+
display: block;
|
136
|
+
font-size: 0.75rem;
|
137
|
+
font-weight: 600;
|
138
|
+
color: var(--muted-color);
|
139
|
+
margin-bottom: 0.25rem;
|
140
|
+
text-transform: uppercase;
|
141
|
+
letter-spacing: 0.025em;
|
142
|
+
}
|
143
|
+
|
144
|
+
/* Sort Controls */
|
145
|
+
@media (min-width: 768px) {
|
146
|
+
.super-settings-sort-controls {
|
147
|
+
display: grid;
|
148
|
+
grid-template-columns: 2fr 2fr 1fr 3fr 1fr 1fr;
|
149
|
+
gap: 1rem;
|
150
|
+
align-items: center;
|
151
|
+
padding: 0.125rem 1rem 0.125rem 1rem;
|
152
|
+
background-color: transparent;
|
153
|
+
border: none;
|
154
|
+
margin-bottom: 0.25rem;
|
155
|
+
}
|
156
|
+
|
157
|
+
.super-settings-sort-label {
|
158
|
+
display: none;
|
159
|
+
}
|
160
|
+
|
161
|
+
.super-settings-sort-controls .super-settings-sort-control {
|
162
|
+
padding: 0.125rem 0;
|
163
|
+
margin: 0;
|
164
|
+
margin-top: 1rem; /* Align with card content that has labels */
|
165
|
+
text-align: left;
|
166
|
+
font-weight: 600;
|
167
|
+
color: var(--form-control-color);
|
168
|
+
}
|
169
|
+
|
170
|
+
.super-settings-sort-controls > span {
|
171
|
+
font-weight: 600;
|
172
|
+
color: var(--form-control-color);
|
173
|
+
}
|
174
|
+
}
|
175
|
+
|
176
|
+
/* Mobile sort controls */
|
177
|
+
@media (max-width: 767px) {
|
178
|
+
.super-settings-sort-controls {
|
179
|
+
display: flex;
|
180
|
+
align-items: center;
|
181
|
+
gap: 1rem;
|
182
|
+
margin-bottom: 0.5rem;
|
183
|
+
padding: 0.25rem 1rem;
|
184
|
+
background-color: transparent;
|
185
|
+
border: none;
|
186
|
+
}
|
187
|
+
|
188
|
+
.super-settings-sort-label {
|
189
|
+
font-weight: 600;
|
190
|
+
color: var(--form-control-color);
|
191
|
+
}
|
192
|
+
|
193
|
+
.super-settings-sort-control {
|
194
|
+
display: flex;
|
195
|
+
align-items: center;
|
196
|
+
gap: 0.25rem;
|
197
|
+
padding: 0.25rem 0.5rem;
|
198
|
+
border: 1px solid transparent;
|
199
|
+
border-radius: 0.25rem;
|
200
|
+
transition: all 0.2s ease-in-out;
|
201
|
+
}
|
202
|
+
|
203
|
+
.super-settings-sort-control[data-selected="true"] {
|
204
|
+
background-color: var(--primary-color);
|
205
|
+
color: var(--primary-contrast-color);
|
206
|
+
border-color: var(--primary-border-color);
|
207
|
+
}
|
208
|
+
}
|
209
|
+
|
210
|
+
/* Icons and Button Controls */
|
31
211
|
.super-settings-icon {
|
32
212
|
display: inline-block;
|
33
213
|
}
|
@@ -47,8 +227,6 @@
|
|
47
227
|
cursor: pointer;
|
48
228
|
}
|
49
229
|
|
50
|
-
|
51
|
-
|
52
230
|
.super-settings-sort-control {
|
53
231
|
color: var(--unselected-color);
|
54
232
|
}
|
@@ -57,74 +235,94 @@
|
|
57
235
|
vertical-align: middle;
|
58
236
|
}
|
59
237
|
|
60
|
-
|
61
|
-
background-color: var(--edit-bg-color) !important;
|
62
|
-
}
|
63
|
-
|
64
|
-
.super-settings-key {
|
65
|
-
overflow-wrap: break-word;
|
66
|
-
max-width: 30rem;
|
67
|
-
min-width: 8rem;
|
68
|
-
}
|
69
|
-
|
70
|
-
.super-settings-value {
|
71
|
-
overflow-wrap: break-word;
|
72
|
-
max-width: 30rem;
|
73
|
-
min-width: 8rem;
|
74
|
-
}
|
75
|
-
|
76
|
-
.super-settings-value-type {
|
77
|
-
width: 7rem;
|
78
|
-
}
|
79
|
-
|
80
|
-
.super-settings-description {
|
81
|
-
min-width: 20rem;
|
82
|
-
}
|
83
|
-
|
238
|
+
/* Utility Classes */
|
84
239
|
.super-settings-max-height-text {
|
85
240
|
max-height: 15rem;
|
86
241
|
overflow-y: scroll;
|
87
242
|
}
|
88
243
|
|
89
|
-
.super-settings-controls {
|
90
|
-
width: 6rem;
|
91
|
-
white-space: nowrap;
|
92
|
-
text-align: right;
|
93
|
-
text-decoration: none !important;
|
94
|
-
}
|
95
|
-
|
96
244
|
.super-settings-history-key {
|
97
245
|
font-weight: normal;
|
98
246
|
color: var(--history-key-color);
|
99
247
|
}
|
100
248
|
|
101
|
-
|
249
|
+
/* History Display Layout */
|
250
|
+
.super-settings-history-container {
|
102
251
|
width: 100%;
|
103
|
-
max-width: 100%;
|
104
252
|
margin-bottom: 1rem;
|
105
|
-
border-collapse: collapse;
|
106
253
|
}
|
107
254
|
|
108
|
-
.super-settings-
|
109
|
-
|
255
|
+
.super-settings-history-header {
|
256
|
+
display: grid;
|
257
|
+
grid-template-columns: 2fr 2fr 3fr;
|
258
|
+
gap: 1rem;
|
259
|
+
padding: 0.75rem;
|
260
|
+
font-weight: 600;
|
110
261
|
border-bottom: 2px solid var(--table-border-color);
|
111
|
-
|
262
|
+
background-color: var(--table-header-bg-color);
|
263
|
+
}
|
264
|
+
|
265
|
+
.super-settings-history-items {
|
266
|
+
display: flex;
|
267
|
+
flex-direction: column;
|
112
268
|
}
|
113
269
|
|
114
|
-
.super-settings-
|
270
|
+
.super-settings-history-item {
|
271
|
+
display: grid;
|
272
|
+
grid-template-columns: 2fr 2fr 3fr;
|
273
|
+
gap: 1rem;
|
115
274
|
padding: 0.75rem;
|
116
|
-
|
117
|
-
|
275
|
+
border-bottom: 1px solid var(--table-border-color);
|
276
|
+
align-items: start;
|
118
277
|
}
|
119
278
|
|
120
|
-
.super-settings-
|
279
|
+
.super-settings-history-item:nth-of-type(even) {
|
121
280
|
background-color: var(--alt-row-color);
|
122
281
|
}
|
123
282
|
|
283
|
+
.super-settings-history-time {
|
284
|
+
white-space: nowrap;
|
285
|
+
}
|
286
|
+
|
287
|
+
.super-settings-history-user {
|
288
|
+
word-break: break-word;
|
289
|
+
}
|
290
|
+
|
291
|
+
.super-settings-history-value {
|
292
|
+
word-break: break-word;
|
293
|
+
}
|
294
|
+
|
295
|
+
/* Mobile responsive layout for history */
|
296
|
+
@media (max-width: 767px) {
|
297
|
+
.super-settings-history-header {
|
298
|
+
display: none;
|
299
|
+
}
|
300
|
+
|
301
|
+
.super-settings-history-item {
|
302
|
+
display: block;
|
303
|
+
padding: 1rem;
|
304
|
+
margin-bottom: 0.5rem;
|
305
|
+
border: 1px solid var(--table-border-color);
|
306
|
+
border-radius: 0.5rem;
|
307
|
+
background-color: var(--form-control-bg-color);
|
308
|
+
}
|
309
|
+
|
310
|
+
.super-settings-history-item:nth-of-type(odd) {
|
311
|
+
background-color: var(--form-control-bg-color);
|
312
|
+
}
|
313
|
+
|
314
|
+
.super-settings-history-time,
|
315
|
+
.super-settings-history-user,
|
316
|
+
.super-settings-history-value {
|
317
|
+
margin-bottom: 0.5rem;
|
318
|
+
}
|
319
|
+
}
|
320
|
+
|
124
321
|
.super-settings-align-center {
|
125
322
|
text-align: center;
|
126
323
|
}
|
127
324
|
|
325
|
+
/* Modal Dialog */
|
128
326
|
.super-settings-modal {
|
129
327
|
z-index: 1000000000000;
|
130
328
|
display: none;
|
@@ -167,6 +365,7 @@
|
|
167
365
|
font-weight: 500;
|
168
366
|
}
|
169
367
|
|
368
|
+
/* Screen Reader and Accessibility */
|
170
369
|
.super-settings-sr-only {
|
171
370
|
position: absolute;
|
172
371
|
width: 1px;
|
@@ -178,6 +377,7 @@
|
|
178
377
|
border: 0;
|
179
378
|
}
|
180
379
|
|
380
|
+
/* Utility Classes */
|
181
381
|
.super-settings-text-nowrap {
|
182
382
|
white-space: nowrap !important;
|
183
383
|
}
|
@@ -189,6 +389,24 @@
|
|
189
389
|
background-color: var(--table-header-bg-color);
|
190
390
|
}
|
191
391
|
|
392
|
+
.super-settings-align-center {
|
393
|
+
text-align: center;
|
394
|
+
}
|
395
|
+
|
396
|
+
.super-settings-text-success {
|
397
|
+
color: var(--success-color) !important;
|
398
|
+
}
|
399
|
+
|
400
|
+
.super-settings-text-danger {
|
401
|
+
color: var(--danger-color) !important;
|
402
|
+
}
|
403
|
+
|
404
|
+
.super-settings-text-muted {
|
405
|
+
color: var(--muted-color) !important;
|
406
|
+
}
|
407
|
+
|
408
|
+
/* Form Controls */
|
409
|
+
|
192
410
|
.super-settings-form-control {
|
193
411
|
font-family: inherit;
|
194
412
|
margin: 0;
|
@@ -240,43 +458,43 @@ select.super-settings-form-control:not([size]):not([multiple]) {
|
|
240
458
|
resize: vertical;
|
241
459
|
}
|
242
460
|
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
color: var(--danger-color) !important;
|
461
|
+
/* Ensure textareas use full width in edit mode */
|
462
|
+
.super-settings-card-edit .super-settings-card-description textarea {
|
463
|
+
width: 100%;
|
464
|
+
box-sizing: border-box;
|
465
|
+
min-width: 0; /* Allow shrinking in grid */
|
249
466
|
}
|
250
467
|
|
251
|
-
|
252
|
-
color: var(--muted-color) !important;
|
253
|
-
}
|
468
|
+
/* Buttons */
|
254
469
|
|
255
470
|
.super-settings-btn {
|
256
|
-
|
471
|
+
display: inline-block;
|
257
472
|
vertical-align: middle;
|
258
473
|
padding: 0.375rem 0.75rem;
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
474
|
+
border-radius: 0.375rem;
|
475
|
+
color: var(--form-control-color);
|
476
|
+
border: 1px solid var(--form-control-border-color);
|
477
|
+
background-color: var(--form-control-bg-color);
|
478
|
+
text-decoration: none;
|
263
479
|
text-align: center;
|
264
|
-
|
480
|
+
font-family: Arial, sans-serif;
|
265
481
|
font-size: 1rem;
|
266
|
-
|
482
|
+
font-weight: 400;
|
267
483
|
line-height: 1.5;
|
268
484
|
user-select: none;
|
269
485
|
cursor: pointer;
|
270
|
-
transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out, box-shadow .15s ease-in-out;
|
486
|
+
transition: color .15s ease-in-out, background-color .15s ease-in-out, border-color .15s ease-in-out, box-shadow .15s ease-in-out;
|
271
487
|
}
|
272
488
|
|
273
489
|
.super-settings-btn:hover:not(:disabled) {
|
274
|
-
|
490
|
+
background-color: var(--btn-hover-color);
|
275
491
|
}
|
492
|
+
|
276
493
|
.super-settings-btn:active {
|
277
|
-
|
278
|
-
|
494
|
+
position: relative;
|
495
|
+
top: 1px;
|
279
496
|
}
|
497
|
+
|
280
498
|
.super-settings-btn:disabled {
|
281
499
|
opacity: 0.8;
|
282
500
|
cursor: not-allowed;
|
@@ -285,10 +503,11 @@ select.super-settings-form-control:not([size]):not([multiple]) {
|
|
285
503
|
.super-settings-btn-primary {
|
286
504
|
background-color: var(--primary-color);
|
287
505
|
border-color: var(--primary-border-color);
|
288
|
-
|
506
|
+
color: var(--primary-contrast-color);
|
289
507
|
}
|
508
|
+
|
290
509
|
.super-settings-btn-primary:hover:not(:disabled) {
|
291
|
-
|
510
|
+
background-color: var(--primary-hover-color);
|
292
511
|
}
|
293
512
|
|
294
513
|
.super-settings-btn-primary:disabled {
|
@@ -29,7 +29,7 @@ module SuperSettings
|
|
29
29
|
|
30
30
|
# Render the web UI application HTML.
|
31
31
|
#
|
32
|
-
# @return [
|
32
|
+
# @return [String] the rendered HTML
|
33
33
|
def render
|
34
34
|
template = ERB.new(File.read(File.expand_path(File.join("application", "index.html.erb"), __dir__)))
|
35
35
|
html = template.result(binding)
|
@@ -5,6 +5,7 @@ require "set"
|
|
5
5
|
module SuperSettings
|
6
6
|
# Utility functions for coercing values to other data types.
|
7
7
|
class Coerce
|
8
|
+
# Set of values that should be considered false when converting to boolean.
|
8
9
|
# rubocop:disable Lint/BooleanSymbol
|
9
10
|
FALSE_VALUES = Set.new([
|
10
11
|
"0", :"0",
|
@@ -2,28 +2,51 @@
|
|
2
2
|
|
3
3
|
module SuperSettings
|
4
4
|
module Context
|
5
|
+
# Current context for maintaining consistent setting values and random numbers
|
6
|
+
# within a specific execution context.
|
5
7
|
class Current
|
6
8
|
def initialize
|
7
9
|
@context = {}
|
8
10
|
@seed = nil
|
9
11
|
end
|
10
12
|
|
13
|
+
# Check if the context includes a specific key.
|
14
|
+
#
|
15
|
+
# @param key [String] the key to check
|
16
|
+
# @return [Boolean] true if the key exists in the context
|
11
17
|
def include?(key)
|
12
18
|
@context.include?(key)
|
13
19
|
end
|
14
20
|
|
21
|
+
# Get a value from the context.
|
22
|
+
#
|
23
|
+
# @param key [String] the key to retrieve
|
24
|
+
# @return [Object] the value associated with the key
|
15
25
|
def [](key)
|
16
26
|
@context[key]
|
17
27
|
end
|
18
28
|
|
29
|
+
# Set a value in the context.
|
30
|
+
#
|
31
|
+
# @param key [String] the key to set
|
32
|
+
# @param value [Object] the value to store
|
33
|
+
# @return [Object] the stored value
|
19
34
|
def []=(key, value)
|
20
35
|
@context[key] = value
|
21
36
|
end
|
22
37
|
|
38
|
+
# Delete a value from the context.
|
39
|
+
#
|
40
|
+
# @param key [String] the key to delete
|
41
|
+
# @return [Object] the deleted value
|
23
42
|
def delete(key)
|
24
43
|
@context.delete(key)
|
25
44
|
end
|
26
45
|
|
46
|
+
# Generate a consistent random number for this context.
|
47
|
+
#
|
48
|
+
# @param max [Integer, Float, Range] the maximum value or range
|
49
|
+
# @return [Integer, Float] the random number
|
27
50
|
def rand(max = nil)
|
28
51
|
@seed ||= Random.new_seed
|
29
52
|
Random.new(@seed).rand(max || 1.0)
|
@@ -1,6 +1,9 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module SuperSettings
|
4
|
+
# Context classes for maintaining consistent state during execution blocks.
|
5
|
+
# These contexts ensure that settings and random values remain constant
|
6
|
+
# within a specific execution scope.
|
4
7
|
module Context
|
5
8
|
autoload :Current, File.join(__dir__, "context/current")
|
6
9
|
autoload :RackMiddleware, File.join(__dir__, "context/rack_middleware")
|
@@ -60,6 +60,7 @@ module SuperSettings
|
|
60
60
|
end
|
61
61
|
|
62
62
|
return nil if value == NOT_DEFINED
|
63
|
+
|
63
64
|
value
|
64
65
|
end
|
65
66
|
|
@@ -105,11 +106,15 @@ module SuperSettings
|
|
105
106
|
end
|
106
107
|
|
107
108
|
# Load all the settings from the database into the cache.
|
109
|
+
#
|
110
|
+
# @param asynchronous [Boolean] whether to load settings in a background thread
|
111
|
+
# @return [void]
|
108
112
|
def load_settings(asynchronous = false)
|
109
113
|
return if @refreshing
|
110
114
|
|
111
115
|
@lock.synchronize do
|
112
116
|
return if @refreshing
|
117
|
+
|
113
118
|
@refreshing = true
|
114
119
|
@next_check_at = Time.now + @refresh_interval
|
115
120
|
end
|
@@ -135,6 +140,9 @@ module SuperSettings
|
|
135
140
|
end
|
136
141
|
|
137
142
|
# Load only settings that have changed since the last load.
|
143
|
+
#
|
144
|
+
# @param asynchronous [Boolean] whether to refresh settings in a background thread
|
145
|
+
# @return [void]
|
138
146
|
def refresh(asynchronous = false)
|
139
147
|
last_refresh_time = @last_refreshed
|
140
148
|
return if last_refresh_time.nil?
|
@@ -142,8 +150,10 @@ module SuperSettings
|
|
142
150
|
|
143
151
|
@lock.synchronize do
|
144
152
|
return if @refreshing
|
153
|
+
|
145
154
|
@next_check_at = Time.now + @refresh_interval
|
146
155
|
return if @cache.empty?
|
156
|
+
|
147
157
|
@refreshing = true
|
148
158
|
end
|
149
159
|
|
@@ -166,6 +176,8 @@ module SuperSettings
|
|
166
176
|
end
|
167
177
|
|
168
178
|
# Reset the cache to an unloaded state.
|
179
|
+
#
|
180
|
+
# @return [void]
|
169
181
|
def reset
|
170
182
|
@lock.synchronize do
|
171
183
|
@cache = {}.freeze
|
@@ -189,6 +201,7 @@ module SuperSettings
|
|
189
201
|
# @api private
|
190
202
|
def update_setting(setting)
|
191
203
|
return if Coerce.blank?(setting.key)
|
204
|
+
|
192
205
|
@lock.synchronize do
|
193
206
|
@cache = @cache.merge(setting.key => setting.value)
|
194
207
|
end
|
@@ -199,6 +212,7 @@ module SuperSettings
|
|
199
212
|
def wait_for_load
|
200
213
|
loop do
|
201
214
|
return unless @refreshing
|
215
|
+
|
202
216
|
sleep(0.001)
|
203
217
|
end
|
204
218
|
end
|
@@ -11,7 +11,7 @@ module SuperSettings
|
|
11
11
|
#
|
12
12
|
# You are also responsible for implementing any CSRF protection if your authentication method
|
13
13
|
# uses stateful requests (i.e. cookies or Basic auth where browser automatically include the
|
14
|
-
# credentials on every
|
14
|
+
# credentials on every request). There are other gems available that can be integrated into
|
15
15
|
# your middleware stack to provide this feature. If you need to inject meta elements into
|
16
16
|
# the page, you can do so with the +add_to_head+ method.
|
17
17
|
class RackApplication
|
@@ -225,8 +225,10 @@ module SuperSettings
|
|
225
225
|
def check_authorization(request, write_required: false)
|
226
226
|
user = current_user(request)
|
227
227
|
return json_response(401, error: "Authentiation required") unless authenticated?(user)
|
228
|
+
|
228
229
|
allowed = (write_required ? allow_write?(user) : allow_read?(user))
|
229
230
|
return json_response(403, error: "Access denied") unless allowed
|
231
|
+
|
230
232
|
yield(user)
|
231
233
|
end
|
232
234
|
|