sail 3.5.1 → 3.6.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e8099f602b777299cf808179f65707d3ca0775ab984a1d2951d46b31a832919b
4
- data.tar.gz: '059f2f1fa4c53ed9d51aa74f75043cb718f615b0c39a234cb01c8ae536c148db'
3
+ metadata.gz: 7ed99e4dc6a1bed5c7a9589ab92f2c6f949a3edd4736f51d8cc9a7d9db3371b5
4
+ data.tar.gz: f022be75af316c34c01921332e29ebdaf458e4d3bb479bc6d64e57922b26e0a1
5
5
  SHA512:
6
- metadata.gz: d0db559a3d7269c2da637cede11cabb6a1af367cc146efc81a7d7361b93c25792787444d7e756945cda043bd42327496ced9fac31490371509529cb4f04fa8d3
7
- data.tar.gz: 9cab8875585e0c1697cbbe4af5d6199767d820cab33dc1afedc678d6bd5efae820bcf6f6f12fc734cd6997d7de5670a33f5928d46de1262f420a4ed95cddc8f6
6
+ metadata.gz: 947727892ed9b5b32b627e9a09e6c4de4d0834e49cd6103eddafe562b4746dae304cdce768655bd20584238c8121e1f0f35f27a7539ee9ad7d9d6529e2ab28d5
7
+ data.tar.gz: 23f380a2e8a21b36b84f468e6828bd189a3d91f12cca6f1e43985e10573d24cd419d72ebb8545689f271953938c62167382723fa458486f3c51ef8f5bd006dc7
data/MIT-LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2017-2019 Vinicius Stock
1
+ Copyright (c) 2017-2021 Vinicius Stock
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -4,7 +4,9 @@
4
4
  Search related functions
5
5
  */
6
6
 
7
- let submitTimer, submitInterval, intervals = 1;
7
+ let submitTimer,
8
+ submitInterval,
9
+ intervals = 1;
8
10
  let queryElement = document.getElementById("query");
9
11
  let autoSearchEnabled = document.getElementById("auto_search_enabled").value;
10
12
  let progress = document.getElementById("search-submit-progress");
@@ -17,6 +19,8 @@ let guideButton = document.getElementById("btn-guide");
17
19
  let guide = document.getElementById("guide-modal");
18
20
  let guideSections = guide.getElementsByTagName("summary");
19
21
  let cardTitles = document.getElementsByClassName("card-title");
22
+ let inputs = document.getElementsByName("value");
23
+ const initialSettingValues = {};
20
24
  let i;
21
25
 
22
26
  function submitSearch() {
@@ -64,12 +68,23 @@ function toggleModal(modal) {
64
68
  function handleGenericClick(event) {
65
69
  let target = event.target;
66
70
 
67
- if (orderButton !== null && (target === sortMenu || sortMenu.contains(target) || target === orderButton || orderButton.contains(target))) {
71
+ if (
72
+ orderButton !== null &&
73
+ (target === sortMenu ||
74
+ sortMenu.contains(target) ||
75
+ target === orderButton ||
76
+ orderButton.contains(target))
77
+ ) {
68
78
  return;
69
79
  }
70
80
 
71
- if (profilesButton !== null && (target === profilesMenu || profilesMenu.contains(target) || target === profilesButton ||
72
- profilesButton.contains(target))) {
81
+ if (
82
+ profilesButton !== null &&
83
+ (target === profilesMenu ||
84
+ profilesMenu.contains(target) ||
85
+ target === profilesButton ||
86
+ profilesButton.contains(target))
87
+ ) {
73
88
  return;
74
89
  }
75
90
 
@@ -99,10 +114,14 @@ if (queryElement !== null) {
99
114
  }
100
115
 
101
116
  orderButton.addEventListener("click", toggleSortMenu);
102
- profilesButton.addEventListener("click", function () { toggleModal(profilesMenu) });
117
+ profilesButton.addEventListener("click", function () {
118
+ toggleModal(profilesMenu);
119
+ });
103
120
  }
104
121
 
105
- guideButton.addEventListener("click", function () { toggleModal(guide) });
122
+ guideButton.addEventListener("click", function () {
123
+ toggleModal(guide);
124
+ });
106
125
  document.body.addEventListener("click", handleGenericClick);
107
126
  document.addEventListener("keydown", closeAllModals);
108
127
 
@@ -117,18 +136,21 @@ function refreshClick() {
117
136
 
118
137
  if (!button.className.includes("active")) {
119
138
  button.classList.add("active");
120
- setTimeout(function() { button.classList.remove("active"); }, 500);
139
+ setTimeout(function () {
140
+ button.classList.remove("active");
141
+ }, 500);
121
142
  }
122
143
  }
123
144
 
124
- for(i = 0; i < refreshButtons.length; i++) refreshButtons[i].addEventListener("click", refreshClick);
145
+ for (i = 0; i < refreshButtons.length; i++)
146
+ refreshButtons[i].addEventListener("click", refreshClick);
125
147
 
126
148
  /*
127
149
  Guide related functions
128
150
  */
129
151
 
130
152
  function sectionClick() {
131
- for(i = 0; i < guideSections.length; i++) {
153
+ for (i = 0; i < guideSections.length; i++) {
132
154
  if (this.parentElement.open) {
133
155
  guideSections[i].parentElement.style.display = "block";
134
156
  } else if (this !== guideSections[i]) {
@@ -137,7 +159,8 @@ function sectionClick() {
137
159
  }
138
160
  }
139
161
 
140
- for(i = 0; i < guideSections.length; i++) guideSections[i].addEventListener("click", sectionClick);
162
+ for (i = 0; i < guideSections.length; i++)
163
+ guideSections[i].addEventListener("click", sectionClick);
141
164
 
142
165
  /*
143
166
  Cards related functions
@@ -147,4 +170,36 @@ function flipCard() {
147
170
  this.parentElement.parentElement.classList.toggle("flipped");
148
171
  }
149
172
 
150
- for(i = 0; i < cardTitles.length; i++) cardTitles[i].addEventListener("click", flipCard);
173
+ for (i = 0; i < cardTitles.length; i++)
174
+ cardTitles[i].addEventListener("click", flipCard);
175
+
176
+ function enableSubmitButton() {
177
+ const name = this.id.replace("input_for_", "");
178
+ const submitId = this.id.replace("input_for_", "btn-submit-");
179
+ const submit = document.getElementById(submitId);
180
+ const value = this.type === "checkbox" ? this.checked : this.value;
181
+
182
+ if (value === initialSettingValues[name]) {
183
+ submit.classList.remove("orange");
184
+ submit.disabled = true;
185
+ } else {
186
+ submit.classList.add("orange");
187
+ submit.disabled = false;
188
+ }
189
+ }
190
+
191
+ for (i = 0; i < inputs.length; i++) {
192
+ if (inputs[i].type === "text") {
193
+ inputs[i].addEventListener("input", enableSubmitButton);
194
+ } else {
195
+ inputs[i].addEventListener("change", enableSubmitButton);
196
+ }
197
+
198
+ if (inputs[i].type === "checkbox") {
199
+ initialSettingValues[inputs[i].id.replace("input_for_", "")] =
200
+ inputs[i].checked;
201
+ } else {
202
+ initialSettingValues[inputs[i].id.replace("input_for_", "")] =
203
+ inputs[i].value;
204
+ }
205
+ }
@@ -534,7 +534,7 @@
534
534
  -webkit-border-radius: 5px;
535
535
  -moz-border-radius: 5px;
536
536
  border-radius: 5px;
537
- background-color: var(--tangerine);
537
+ background-color: var(--aluminium);
538
538
  border: none;
539
539
  outline: none;
540
540
  -webkit-transition: background-color 0.5s;
@@ -545,11 +545,15 @@
545
545
  box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1), 0 1px 2px 0 rgba(0, 0, 0, 0.06);
546
546
  }
547
547
 
548
+ .btn-sail, #settings-dashboard .card .btn-value-submit.orange {
549
+ background-color: var(--tangerine);
550
+ }
551
+
548
552
  .btn-sail:active {
549
553
  color: var(--main-black);
550
554
  opacity: .8;
551
555
  }
552
556
 
553
- .btn-sail :hover {
557
+ .btn-sail:hover, #settings-dashboard .card .btn-value-submit.orange:hover {
554
558
  background-color: var(--dark-tangerine);
555
559
  }
@@ -34,7 +34,7 @@ module Sail
34
34
  private
35
35
 
36
36
  def s_params
37
- params.permit(:name)
37
+ params.permit(:name, :locale)
38
38
  end
39
39
  end
40
40
  end
@@ -20,7 +20,7 @@ module Sail
20
20
  def update
21
21
  respond_to do |format|
22
22
  @setting, @successful_update = Setting.set(s_params[:name], s_params[:value])
23
- format.js {}
23
+ format.js
24
24
  format.json { @successful_update ? head(:ok) : head(:conflict) }
25
25
  end
26
26
  end
@@ -65,7 +65,8 @@ module Sail
65
65
  def s_params
66
66
  params.permit(:page, :query, :name,
67
67
  :value, :positive, :negative,
68
- :throttled_by, :order_field)
68
+ :throttled_by, :order_field,
69
+ :_method, :locale, :authenticity_token)
69
70
  end
70
71
 
71
72
  def log_update
@@ -12,7 +12,7 @@ module Sail
12
12
  belongs_to :profile
13
13
  validates :value, :setting, :profile, presence: true
14
14
 
15
- scope :by_profile_name, ->(name) { joins(:profile).where("sail_profiles.name = ?", name) }
15
+ scope :by_profile_name, ->(name) { joins(:profile).where(sail_profiles: { name: name }) }
16
16
 
17
17
  delegate :name, to: :setting
18
18
 
@@ -151,7 +151,7 @@ module Sail
151
151
  end
152
152
 
153
153
  def relevancy
154
- (Sail.instrumenter.relative_usage_of(name) / Sail::Setting.count).round(1)
154
+ Sail.instrumenter.relevancy_of(name)
155
155
  end
156
156
 
157
157
  def should_not_cache?
@@ -62,7 +62,7 @@
62
62
  <% end %>
63
63
 
64
64
  <div class="submit-container">
65
- <button id="btn-submit-<%= setting.name %>" type="submit" class="btn-value-submit"><%= I18n.t("sail.save") %></button>
65
+ <button id="btn-submit-<%= setting.name %>" type="submit" class="btn-value-submit" disabled><%= I18n.t("sail.save") %></button>
66
66
 
67
67
  <span id="success-<%= setting.name %>" class="notice success">
68
68
  <%= image_tag("sail/checkmark.svg") %>
@@ -11,10 +11,16 @@ setTimeout(function () {
11
11
 
12
12
  if ("<%= @successful_update %>" === "true") {
13
13
  var input = document.getElementById("<%= "input_for_#{@setting.name}" %>");
14
+ var submitButton = document.getElementById("<%= "btn-submit-#{@setting.name}" %>");
14
15
 
15
16
  if ("<%= @setting.boolean? %>" === "true") {
16
17
  input.checked = "<%= @setting.value %>" === "true";
18
+ initialSettingValues["<%= @setting.name %>"] = "<%= @setting.value %>" === "true";
17
19
  } else {
18
20
  input.value = "<%= @setting.date? ? formatted_date(@setting) : @setting.value %>";
21
+ initialSettingValues["<%= @setting.name %>"] = "<%= @setting.date? ? formatted_date(@setting) : @setting.value %>";
19
22
  }
23
+
24
+ submitButton.classList.remove("orange");
25
+ submitButton.disabled = true;
20
26
  }
data/lib/sail/engine.rb CHANGED
@@ -14,7 +14,6 @@ module Sail
14
14
 
15
15
  config.middleware.use ActionDispatch::Flash
16
16
  config.middleware.use ActionDispatch::Cookies
17
- config.middleware.use ActionDispatch::Session::CookieStore
18
17
  config.middleware.use ActionDispatch::ContentSecurityPolicy::Middleware if defined?(ActionDispatch::ContentSecurityPolicy)
19
18
  config.middleware.use Rack::MethodOverride
20
19
  config.middleware.use Rails::Rack::Logger
@@ -40,6 +39,8 @@ module Sail
40
39
  errors = [ActiveRecord::NoDatabaseError]
41
40
  errors << PG::ConnectionBad if defined?(PG)
42
41
 
42
+ config.middleware.use Rails.application.config.session_store || ActionDispatch::Session::CookieStore
43
+
43
44
  begin
44
45
  Sail::Setting.load_defaults unless Rails.env.test?
45
46
  rescue *errors
@@ -49,9 +50,9 @@ module Sail
49
50
 
50
51
  private
51
52
 
52
- def to_prepare
53
+ def to_prepare(&block)
53
54
  klass = defined?(ActiveSupport::Reloader) ? ActiveSupport::Reloader : ActionDispatch::Reloader
54
- klass.to_prepare(&Proc.new)
55
+ klass.to_prepare(&block)
55
56
  end
56
57
  end
57
58
  end
@@ -15,6 +15,7 @@ module Sail
15
15
  # statistics
16
16
  def initialize
17
17
  @statistics = { settings: {}, profiles: {} }.with_indifferent_access
18
+ @number_of_settings = Setting.count
18
19
  end
19
20
 
20
21
  # []
@@ -59,7 +60,7 @@ module Sail
59
60
  def relative_usage_of(setting_name)
60
61
  return 0.0 if @statistics[:settings].empty?
61
62
 
62
- (100.0 * self[setting_name][:usages]) / @statistics[:settings].map { |_, entry| entry[:usages] }.sum
63
+ (100.0 * self[setting_name][:usages]) / @statistics[:settings].sum { |_, entry| entry[:usages] }
63
64
  end
64
65
 
65
66
  # increment_failure_of
@@ -76,6 +77,10 @@ module Sail
76
77
  Sail.reset(setting_name) if self[setting_name][:failures] > Sail.configuration.failures_until_reset
77
78
  end
78
79
 
80
+ def relevancy_of(setting_name)
81
+ (relative_usage_of(setting_name) / @number_of_settings).round(1)
82
+ end
83
+
79
84
  private
80
85
 
81
86
  def expire_cache_fragment(setting_name)
data/lib/sail/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sail
4
- VERSION = "3.5.1"
4
+ VERSION = "3.6.0"
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sail
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.5.1
4
+ version: 3.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Vinicius Stock
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-10-13 00:00:00.000000000 Z
11
+ date: 2021-02-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: fugit
@@ -212,14 +212,14 @@ dependencies:
212
212
  requirements:
213
213
  - - "~>"
214
214
  - !ruby/object:Gem::Version
215
- version: 0.19.0
215
+ version: 0.21.0
216
216
  type: :development
217
217
  prerelease: false
218
218
  version_requirements: !ruby/object:Gem::Requirement
219
219
  requirements:
220
220
  - - "~>"
221
221
  - !ruby/object:Gem::Version
222
- version: 0.19.0
222
+ version: 0.21.0
223
223
  - !ruby/object:Gem::Dependency
224
224
  name: sqlite3
225
225
  requirement: !ruby/object:Gem::Requirement
@@ -347,7 +347,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
347
347
  - !ruby/object:Gem::Version
348
348
  version: '0'
349
349
  requirements: []
350
- rubygems_version: 3.1.4
350
+ rubygems_version: 3.2.11
351
351
  signing_key:
352
352
  specification_version: 4
353
353
  summary: Sail is a lightweight Rails engine that brings an admin panel for managing