super_settings 0.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +9 -0
  3. data/MIT-LICENSE +20 -0
  4. data/README.md +313 -0
  5. data/VERSION +1 -0
  6. data/app/helpers/super_settings/settings_helper.rb +32 -0
  7. data/app/views/layouts/super_settings/settings.html.erb +20 -0
  8. data/config/routes.rb +13 -0
  9. data/db/migrate/20210414004553_create_super_settings.rb +34 -0
  10. data/lib/super_settings/application/api.js +88 -0
  11. data/lib/super_settings/application/helper.rb +119 -0
  12. data/lib/super_settings/application/images/edit.svg +1 -0
  13. data/lib/super_settings/application/images/info.svg +1 -0
  14. data/lib/super_settings/application/images/plus.svg +1 -0
  15. data/lib/super_settings/application/images/slash.svg +1 -0
  16. data/lib/super_settings/application/images/trash.svg +1 -0
  17. data/lib/super_settings/application/index.html.erb +169 -0
  18. data/lib/super_settings/application/layout.html.erb +22 -0
  19. data/lib/super_settings/application/layout_styles.css +193 -0
  20. data/lib/super_settings/application/scripts.js +718 -0
  21. data/lib/super_settings/application/styles.css +122 -0
  22. data/lib/super_settings/application.rb +38 -0
  23. data/lib/super_settings/attributes.rb +24 -0
  24. data/lib/super_settings/coerce.rb +66 -0
  25. data/lib/super_settings/configuration.rb +144 -0
  26. data/lib/super_settings/controller_actions.rb +81 -0
  27. data/lib/super_settings/encryption.rb +76 -0
  28. data/lib/super_settings/engine.rb +70 -0
  29. data/lib/super_settings/history_item.rb +26 -0
  30. data/lib/super_settings/local_cache.rb +306 -0
  31. data/lib/super_settings/rack_middleware.rb +210 -0
  32. data/lib/super_settings/rest_api.rb +195 -0
  33. data/lib/super_settings/setting.rb +599 -0
  34. data/lib/super_settings/storage/active_record_storage.rb +123 -0
  35. data/lib/super_settings/storage/http_storage.rb +279 -0
  36. data/lib/super_settings/storage/redis_storage.rb +293 -0
  37. data/lib/super_settings/storage/test_storage.rb +158 -0
  38. data/lib/super_settings/storage.rb +254 -0
  39. data/lib/super_settings/version.rb +5 -0
  40. data/lib/super_settings.rb +213 -0
  41. data/lib/tasks/super_settings.rake +9 -0
  42. data/super_settings.gemspec +35 -0
  43. metadata +113 -0
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-plus"><line x1="12" y1="5" x2="12" y2="19"></line><line x1="5" y1="12" x2="19" y2="12"></line></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-slash"><circle cx="12" cy="12" r="10"></circle><line x1="4.93" y1="4.93" x2="19.07" y2="19.07"></line></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-trash-2"><polyline points="3 6 5 6 21 6"></polyline><path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"></path><line x1="10" y1="11" x2="10" y2="17"></line><line x1="14" y1="11" x2="14" y2="17"></line></svg>
@@ -0,0 +1,169 @@
1
+ <%= style_tag %>
2
+
3
+ <main>
4
+ <form class="form-inline" style="display:block;" onsubmit="return false">
5
+ <div class="super-settings-sticky-top">
6
+ <span class="js-settings-count" style="display:inline-block; margin-right:1rem;"></span>
7
+
8
+ <label for="filter" class="super-settings-sr-only">Filter</label>
9
+ <input type="text" name="filter" value="" placeholder="Filter Keys" size="20" class="form-control" title="Filter Keys" id="filter" style="margin-right:1rem;">
10
+
11
+ <button type="button" class="btn btn-default" id="add-setting"><%= icon_image(:plus) %> Add Setting</button>
12
+
13
+ <button type="button" class="btn btn-default" id="discard-changes" disabled>
14
+ Discard Changes
15
+ </button>
16
+
17
+ <button type="button" class="btn btn-primary" id="save-settings" disabled>
18
+ Save <span class="count"></span> Changes
19
+ </button>
20
+
21
+ <strong class="js-flash" style="display:none; margin-left:3rem;"></strong>
22
+ </div>
23
+
24
+ <table class="table table-striped" id="settings-table">
25
+ <thead>
26
+ <tr>
27
+ <th scope="col" class="super-settings-key">Key</th>
28
+ <th scope="col" class="super-settings-value">Value</th>
29
+ <th scope="col" class="super-settings-value-type">Type</th>
30
+ <th scope="col" class="super-settings-description">Description</th>
31
+ <th scope="col" class="super-settings-controls"><span class="super-settings-sr-only">Controls</span></th>
32
+ </tr>
33
+ </thead>
34
+ <tbody translate="no">
35
+ </tbody>
36
+ </table>
37
+ </form>
38
+ </main>
39
+
40
+ <div id="modal" class="super-settings-modal js-close-modal" aria-hidden="true" aria-role="dialog">
41
+ <div class="super-settings-modal-dialog">
42
+ <button type="button" title="Close Dialog" class="super-settings-modal-close js-close-modal">&times;</button>
43
+ <div class="super-settings-modal-content">
44
+ </div>
45
+ </div>
46
+ </div>
47
+
48
+ <template id="setting-row-template" style="display:none;">
49
+ <tr>
50
+ <td class="super-settings-key">
51
+ <div class="js-value-placeholder"></div>
52
+ <input type="hidden" value="" name="settings[{{id}}][key]" class="js-setting-key">
53
+ <input type="hidden" value="" name="settings[{{id}}][delete]" class="js-setting-deleted">
54
+ </td>
55
+
56
+ <td class="super-settings-value">
57
+ <div class="js-value-placeholder"></div>
58
+ </td>
59
+
60
+ <td class="super-settings-value-type">
61
+ <div class="js-value-placeholder"></div>
62
+ </td>
63
+
64
+ <td class="super-settings-description">
65
+ <div class="js-value-placeholder"></div>
66
+ </td>
67
+
68
+ <td class="super-settings-controls">
69
+ <%= icon_button(:info, title: "Setting Info", color: "royalblue", js_class: "js-show-history") %>
70
+ <%= icon_button(:edit, title: "Edit Setting", color: "green", js_class: "js-edit-setting") %>
71
+ <%= icon_button(:trash, title: "Remove Setting", color: "firebrick", js_class: "js-remove-setting") %>
72
+ <%= icon_button(:slash, title: "Cancel Changes", color: "firebrick", js_class: "js-restore-setting", link_style: "display:none;") %>
73
+ </td>
74
+ </tr>
75
+ </template>
76
+
77
+ <template id="setting-row-edit-template" style="display:none;">
78
+ <tr data-edited="true" class="super-settings-edit-row">
79
+ <td class="super-settings-key">
80
+ <div>
81
+ <label for="settings_{{id}}_key" class="super-settings-sr-only">Key</label>
82
+ <input type="text" id="settings_{{id}}_key" name="settings[{{id}}][key]" value="" maxlength="190" class="form-control js-setting-key" required>
83
+ </div>
84
+ </td>
85
+
86
+ <td class="super-settings-value">
87
+ <div>
88
+ <label for="settings_{{id}}_value" class="super-settings-sr-only">Value</label>
89
+ <span class="js-value-placeholder"></span>
90
+ </div>
91
+ <div class="container text-danger js-setting-errors" style="display:none;">
92
+ </div>
93
+ </td>
94
+
95
+ <td class="super-settings-value-type">
96
+ <div>
97
+ <label for="settings_{{id}}_value_type" class="super-settings-sr-only">Value Type</label>
98
+ <select name="settings[{{id}}][value_type]" class="form-control js-setting-value-type" id="settings_{{id}}_value_type">
99
+ <% SuperSettings::Setting::VALUE_TYPES.each do |value_type| %>
100
+ <option value="<%= ERB::Util.html_escape(value_type) %>"><%= ERB::Util.html_escape(value_type) %></option>
101
+ <% end %>
102
+ </select>
103
+ </div>
104
+ </td>
105
+
106
+ <td class="super-settings-description">
107
+ <div>
108
+ <label for="settings_{{id}}_description" class="super-settings-sr-only">Description</label>
109
+ <textarea id="settings_{{id}}_description" name="settings[{{id}}][description]" value="" class="form-control" rows="4"></textarea>
110
+ </div>
111
+ </td>
112
+
113
+ <td class="super-settings-controls">
114
+ <%= icon_button(:info, title: "Setting Info", color: "royalblue", js_class: "js-show-history") %>
115
+ <%= icon_button(:edit, title: "Edit Setting", color: "gray", js_class: "js-no-op", disabled: true) %>
116
+ <%= icon_button(:slash, title: "Cancel Changes", color: "firebrick", js_class: "js-restore-setting") %>
117
+ </td>
118
+ </tr>
119
+ </template>
120
+
121
+ <template id="setting-value-field-template" style="display:none;">
122
+ <textarea id="settings_{{id}}_value" name="settings[{{id}}][value]" class="form-control js-setting-value" rows="4"></textarea>
123
+ </template>
124
+
125
+ <template id="setting-value-field-integer-template" style="display:none;">
126
+ <input type="number" step="1" id="settings_{{id}}_value" name="settings[{{id}}][value]" value="" class="form-control js-setting-value">
127
+ </template>
128
+
129
+ <template id="setting-value-field-float-template" style="display:none;">
130
+ <input type="number" step="any" id="settings_{{id}}_value" name="settings[{{id}}][value]" value="" class="form-control js-setting-value">
131
+ </template>
132
+
133
+ <template id="setting-value-field-datetime-template" style="display:none;">
134
+ <span>
135
+ <input type="date" id="settings_{{id}}_value" name="_settings[{{id}}][date]" value="" class="form-control js-date-input">
136
+ <label for="settings_{{id}}_value_time" class="super-settings-sr-only">Time</label>
137
+ <input type="time" id="settings_{{id}}_value_time" name="_settings[{{id}}][time]" value="" class="form-control js-time-input" aria-label="Time">
138
+ <input type="hidden" name="settings[{{id}}][value]" value="" class="js-setting-value">
139
+ <small class="text-muted">Time in UTC</small>
140
+ </span>
141
+ </template>
142
+
143
+ <template id="setting-value-field-boolean-template" style="display:none;">
144
+ <span class="form-check">
145
+ <input type="checkbox" id="settings_{{id}}_value" name="settings[{{id}}][value]" value="true" class="js-setting-value">
146
+ <label for="settings_{{id}}_value">Enabled</label>
147
+ </span>
148
+ </template>
149
+
150
+ <template id="setting-value-field-array-template" style="display:none;">
151
+ <textarea id="settings_{{id}}_value" name="settings[{{id}}][value]" value="" class="form-control js-setting-value" rows="8" placeholder="one entry per line"></textarea>
152
+ </template>
153
+
154
+ <template id="setting-history-table" style="display:none">
155
+ <h3>Setting History: <span class="super-settings-history-key"></span></h3>
156
+ <table class="table table-striped" id="super-settings-history">
157
+ <thead>
158
+ <tr>
159
+ <th scope="col" class="super-settings-text-nowrap">Time</th>
160
+ <th scope="col">Changed By</th>
161
+ <th scope="col">Value</th>
162
+ </tr>
163
+ </thead>
164
+ <tbody>
165
+ </tbody>
166
+ </table>
167
+ </template>
168
+
169
+ <%= javascript_tag %>
@@ -0,0 +1,22 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <title><%= application_name %> Settings</title>
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <meta name="pinterest" content="nopin" />
7
+ <meta name="format-detection" content="telephone=no">
8
+ <%= layout_style_tag %>
9
+ <%= add_to_head %>
10
+ </head>
11
+
12
+ <body class="super_settings">
13
+ <header>
14
+ <h1 class="logo">
15
+ <%= application_header %>
16
+ </h1>
17
+ </header>
18
+ <div class="container">
19
+ <%= yield %>
20
+ </div>
21
+ </body>
22
+ </html>
@@ -0,0 +1,193 @@
1
+ * {box-sizing:border-box;}
2
+
3
+ body {
4
+ font-family: sans-serif;
5
+ font-size: 1rem;
6
+ line-height: 1.5;
7
+ text-align: left;
8
+ color: #212529;
9
+ background-color: #ffffff;
10
+ margin: 0;
11
+ padding: 0;
12
+ }
13
+
14
+ header {
15
+ background-color: #666;
16
+ color: white;
17
+ padding: 1rem;
18
+ }
19
+
20
+ header h1.logo {
21
+ font-size: 20px;
22
+ margin: 0;
23
+ }
24
+
25
+ header h1.logo a {
26
+ color: #ffffff;
27
+ text-decoration: none;
28
+ }
29
+ header h1.logo a:visited {
30
+ color: #ffffff;
31
+ }
32
+
33
+ header h1.logo img {
34
+ max-height: 3rem;
35
+ vertical-align: middle;
36
+ display: inline-block;
37
+ margin-right: 1rem;
38
+ }
39
+
40
+ .align-center {
41
+ text-align: center;
42
+ }
43
+
44
+ .container {
45
+ padding-left: 15px;
46
+ padding-right: 15px;
47
+ margin-left: auto;
48
+ margin-right: auto;
49
+ }
50
+
51
+ a {
52
+ text-decoration: none;
53
+ color: #369;
54
+ }
55
+
56
+ a:visited {
57
+ color: #369;n
58
+ }
59
+
60
+ .btn {
61
+ box-shadow:inset 0px 1px 0px 0px #ffffff;
62
+ background:linear-gradient(to bottom, #f9f9f9 5%, #e9e9e9 100%);
63
+ background-color:#f9f9f9;
64
+ border-radius:6px;
65
+ border:1px solid #dcdcdc;
66
+ display:inline-block;
67
+ color:#666666;
68
+ font-family:Arial;
69
+ font-size:15px;
70
+ font-weight:bold;
71
+ padding:9px 16px;
72
+ text-decoration:none;
73
+ text-shadow:0px 1px 0px #ffffff;
74
+ vertical-align: middle;
75
+ }
76
+ .btn:hover {
77
+ background:linear-gradient(to bottom, #e9e9e9 5%, #f9f9f9 100%);
78
+ background-color:#e9e9e9;
79
+ }
80
+ .btn:active {
81
+ position:relative;
82
+ top:1px;
83
+ }
84
+ .btn:disabled {
85
+ background:linear-gradient(to bottom, #f9f9f9 5%, #e9e9e9 100%);
86
+ background-color:#f9f9f9;
87
+ opacity: 0.65;
88
+ box-shadow: none;
89
+ }
90
+
91
+ .btn-primary {
92
+ box-shadow:inset 0px 1px 0px 0px #9fb4f2;
93
+ background:linear-gradient(to bottom, #7892c2 5%, #476e9e 100%);
94
+ background-color:#7892c2;
95
+ color:#ffffff;
96
+ text-shadow:0px 1px 0px #283966;
97
+ }
98
+ .btn-primary:hover {
99
+ background:linear-gradient(to bottom, #476e9e 5%, #7892c2 100%);
100
+ background-color:#476e9e;
101
+ }
102
+ .btn-primary:disabled {
103
+ background:linear-gradient(to bottom, #7892c2 5%, #476e9e 100%);
104
+ background-color:#7892c2;
105
+ }
106
+
107
+ .btn:not(:disabled) {
108
+ cursor: pointer;
109
+ }
110
+ .btn:disabled {
111
+ opacity: .65;
112
+ }
113
+
114
+ .table {
115
+ width: 100%;
116
+ max-width: 100%;
117
+ margin-bottom: 1rem;
118
+ border-collapse: collapse;
119
+ }
120
+
121
+ .table thead th {
122
+ vertical-align: bottom;
123
+ border-bottom: 2px solid #dee2e6;
124
+ }
125
+
126
+ .table td, .table th {
127
+ padding: 0.75rem;
128
+ vertical-align: top;
129
+ border-top: 1px solid #dee2e6;
130
+ }
131
+
132
+ .table-striped tbody tr:nth-of-type(odd) {
133
+ background-color: rgba(0, 0, 0, .05);
134
+ }
135
+
136
+ textarea {
137
+ font-family: inherit;
138
+ margin: 0;
139
+ overflow: auto;
140
+ resize: vertical;
141
+ }
142
+
143
+ .form-control {
144
+ font-family: inherit;
145
+ margin: 0;
146
+ overflow: visible;
147
+ display: block;
148
+ width: 100%;
149
+ padding: .375rem .75rem;
150
+ font-size: 1rem;
151
+ line-height: 1.5;
152
+ color: #495057;
153
+ background-color: #fff;
154
+ background-clip: padding-box;
155
+ border: 1px solid #ced4da;
156
+ border-radius: .25rem;
157
+ transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out;
158
+ }
159
+
160
+ select.form-control:not([size]):not([multiple]) {
161
+ height: calc(2.25rem + 2px);
162
+ }
163
+
164
+ .form-check {
165
+ margin-top: .5rem;
166
+ display: inline-block;
167
+ }
168
+
169
+ .form-check input[type=checkbox] {
170
+ vertical-align: middle;
171
+ }
172
+
173
+ .form-inline {
174
+ display: inline-block;
175
+ }
176
+
177
+ .form-inline .form-control {
178
+ display: inline-block;
179
+ width: auto;
180
+ vertical-align: middle;
181
+ }
182
+
183
+ .text-success {
184
+ color: green !important;
185
+ }
186
+
187
+ .text-danger {
188
+ color: firebrick !important;
189
+ }
190
+
191
+ .text-muted {
192
+ color: #666 !important;
193
+ }