sail 3.2.4 → 3.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/MIT-LICENSE +1 -1
  3. data/README.md +48 -7
  4. data/Rakefile +3 -3
  5. data/app/assets/images/sail/angle-left.svg +1 -1
  6. data/app/assets/images/sail/angle-right.svg +1 -1
  7. data/app/assets/images/sail/checkmark.svg +1 -0
  8. data/app/assets/images/sail/cog.svg +1 -1
  9. data/app/assets/images/sail/error.svg +1 -0
  10. data/app/assets/images/sail/reset.svg +1 -0
  11. data/app/assets/images/sail/sort.svg +1 -1
  12. data/app/assets/javascripts/sail/{application.js.erb → application.js} +1 -10
  13. data/app/assets/javascripts/{settings.js.erb → sail/settings.js} +81 -13
  14. data/app/assets/stylesheets/sail/application.css.erb +419 -0
  15. data/app/assets/stylesheets/sail/settings.css +559 -0
  16. data/app/controllers/sail/profiles_controller.rb +1 -1
  17. data/app/controllers/sail/settings_controller.rb +5 -15
  18. data/app/helpers/sail/application_helper.rb +4 -0
  19. data/app/models/sail/entry.rb +1 -1
  20. data/app/models/sail/setting.rb +4 -8
  21. data/app/views/layouts/sail/application.html.erb +2 -6
  22. data/app/views/sail/profiles/_profile.html.erb +29 -17
  23. data/app/views/sail/settings/_guide_modal.html.erb +2 -2
  24. data/app/views/sail/settings/_setting.html.erb +74 -52
  25. data/app/views/sail/settings/index.html.erb +21 -14
  26. data/app/views/sail/settings/update.js.erb +10 -4
  27. data/config/locales/en.yml +1 -4
  28. data/lib/generators/sail/install/install_generator.rb +5 -1
  29. data/lib/generators/sail/install/templates/sail.yml.tt +5 -0
  30. data/lib/generators/sail/update/update_generator.rb +1 -1
  31. data/lib/sail.rb +1 -0
  32. data/lib/sail/constant_collection.rb +2 -2
  33. data/lib/sail/engine.rb +7 -6
  34. data/lib/sail/graphql.rb +43 -0
  35. data/lib/sail/instrumenter.rb +6 -1
  36. data/lib/sail/mutations.rb +49 -0
  37. data/lib/sail/version.rb +1 -1
  38. metadata +25 -102
  39. data/app/assets/images/sail/refresh.svg +0 -1
  40. data/app/assets/stylesheets/sail/_colors.scss +0 -9
  41. data/app/assets/stylesheets/sail/_shared.scss +0 -52
  42. data/app/assets/stylesheets/sail/application.scss +0 -353
  43. data/app/assets/stylesheets/sail/settings.scss +0 -422
  44. data/app/views/sail/settings/_setting_minimal.html.erb +0 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 40fb8e4bc4918c09d226baa2e97666dc61cf6734967538bb62f61d12391c5024
4
- data.tar.gz: 53903455199dbf9fd1d310c50dd538856880cb2a740e11576c929609312099ae
3
+ metadata.gz: 7ed99e4dc6a1bed5c7a9589ab92f2c6f949a3edd4736f51d8cc9a7d9db3371b5
4
+ data.tar.gz: f022be75af316c34c01921332e29ebdaf458e4d3bb479bc6d64e57922b26e0a1
5
5
  SHA512:
6
- metadata.gz: bb1365f1162a6b41ef8a57cc54b15f25e37dfa4dde08eb1a556dde193f0bf33600740c72f4e69e652ca4a2c6666bedc564d15af320f010cde018a73cf0d530c4
7
- data.tar.gz: 6002b3b8f33133fd9b0181b9cc52b174e3533f9e28aa493a70ab52194415e44877f017a003a3488641cd673b20d06fce4ca7c8bb04db2be9288a4c5f7ececa39
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
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
- ![dashboard](https://raw.githubusercontent.com/vinistock/sail/master/app/assets/images/sail/sail.png)
1
+ ![dashboard](https://raw.githubusercontent.com/vinistock/sail/master/app/assets/images/sail/sail.gif)
2
2
 
3
- [![Maintainability](https://api.codeclimate.com/v1/badges/00ed468acd8b93f66478/maintainability)](https://codeclimate.com/github/vinistock/sail/maintainability) [![Build Status](https://travis-ci.org/vinistock/sail.svg?branch=master)](https://travis-ci.org/vinistock/sail) [![Test Coverage](https://codeclimate.com/github/vinistock/sail/badges/coverage.svg)](https://codeclimate.com/github/vinistock/sail/coverage) [![Gem Version](https://badge.fury.io/rb/sail.svg)](https://badge.fury.io/rb/sail) ![](http://ruby-gem-downloads-badge.herokuapp.com/sail?color=brightgreen&type=total) [![Mentioned in Awesome Ruby](https://awesome.re/mentioned-badge.svg)](https://github.com/markets/awesome-ruby)
3
+ [![Build Status](https://github.com/vinistock/sail/workflows/Ruby%20on%20Rails/badge.svg?branch=master)](https://github.com/vinistock/sail/actions) [![codecov](https://codecov.io/gh/vinistock/sail/branch/master/graph/badge.svg)](https://codecov.io/gh/vinistock/sail) [![Gem Version](https://badge.fury.io/rb/sail.svg)](https://badge.fury.io/rb/sail) ![](http://ruby-gem-downloads-badge.herokuapp.com/sail?color=brightgreen&type=total) [![Mentioned in Awesome Ruby](https://awesome.re/mentioned-badge.svg)](https://github.com/markets/awesome-ruby)
4
4
 
5
5
  # Sail
6
6
 
@@ -139,10 +139,10 @@ All possible cast types as well as detailed examples of usage can be found in th
139
139
  # Get setting value with appropriate cast type
140
140
  #
141
141
  # Returns setting value with cast or yields it if passed a block
142
- Sail.get("name")
142
+ Sail.get(:name)
143
143
 
144
144
  # This usage will return the result of the block
145
- Sail.get("name") do |setting_value|
145
+ Sail.get(:name) do |setting_value|
146
146
  my_code(setting_value)
147
147
  end
148
148
 
@@ -153,15 +153,15 @@ end
153
153
 
154
154
  # For example, this will ignore ExampleError, but any other error raised will increase
155
155
  # the count until the setting "name" is reset.
156
- Sail.get("name", expected_errors: [ExampleError]) do |value|
156
+ Sail.get(:name, expected_errors: [ExampleError]) do |value|
157
157
  code_that_can_raise_example_error(value)
158
158
  end
159
159
 
160
160
  # Set setting value
161
- Sail.set("name", "value")
161
+ Sail.set(:name, "value")
162
162
 
163
163
  # Reset setting value (requires the sail.yml file!)
164
- Sail.reset("name")
164
+ Sail.reset(:name)
165
165
 
166
166
  # Switcher
167
167
  # This method will take three setting names as parameters
@@ -209,6 +209,47 @@ Response
209
209
  200 OK
210
210
  ```
211
211
 
212
+ ### GraphQL
213
+
214
+ For GraphQL APIs, types and mutations are defined for convenience. Include Sail's Graphql modules to get the appropriate fields.
215
+
216
+ ```ruby
217
+ # app/graphql/types/query_type.rb
218
+
219
+ module Types
220
+ class QueryType < Types::BaseObject
221
+ include Sail::Graphql::Types
222
+ end
223
+ end
224
+
225
+ # app/graphql/types/mutation_type.rb
226
+
227
+ module Types
228
+ class MutationType < Types::BaseObject
229
+ include Sail::Graphql::Mutations
230
+ end
231
+ end
232
+ ```
233
+
234
+ To query settings via GraphQL, use the following pattern.
235
+
236
+ ```graphql
237
+ query {
238
+ sailGet(name: "my_setting")
239
+ sailSwitcher(positive: "positive_case_setting", negative: "negative_case_setting", throttledBy: "throttle_setting")
240
+ }
241
+
242
+ mutation {
243
+ sailSet(name: "my_setting", value: "value") {
244
+ success
245
+ }
246
+
247
+ sailProfileSwitch(name: "my_profile") {
248
+ success
249
+ }
250
+ }
251
+ ```
252
+
212
253
  ## Localization
213
254
 
214
255
  Sail's few strings are all localized for English in [en.yml], making it easy to create translations for the desired languages.
data/Rakefile CHANGED
@@ -20,8 +20,8 @@ require "rspec/core/rake_task"
20
20
  RSpec::Core::RakeTask.new(spec: "app:db:test:prepare")
21
21
  task default: :spec
22
22
 
23
- task :all do
24
- system("brakeman --no-pager && rake && rubocop --auto-correct && rails_best_practices")
23
+ task all: :environment do
24
+ system("brakeman --no-pager && rake && rubocop -A")
25
25
  end
26
26
 
27
- system("cd ./spec/dummy; RAILS_ENV=test rails db:environment:set; cd ../..") if Rails::VERSION::MAJOR >= 5
27
+ system("cd ./spec/dummy; RAILS_ENV=test rails db:environment:set; cd ../..")
@@ -1 +1 @@
1
- <svg aria-hidden="true" data-prefix="fas" data-icon="angle-left" class="svg-inline--fa fa-angle-left fa-w-8" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 512"><path fill="currentColor" d="M31.7 239l136-136c9.4-9.4 24.6-9.4 33.9 0l22.6 22.6c9.4 9.4 9.4 24.6 0 33.9L127.9 256l96.4 96.4c9.4 9.4 9.4 24.6 0 33.9L201.7 409c-9.4 9.4-24.6 9.4-33.9 0l-136-136c-9.5-9.4-9.5-24.6-.1-34z"></path></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M7.05 9.293L6.343 10 12 15.657l1.414-1.414L9.172 10l4.242-4.243L12 4.343z"/></svg>
@@ -1 +1 @@
1
- <svg aria-hidden="true" data-prefix="fas" data-icon="angle-right" class="svg-inline--fa fa-angle-right fa-w-8" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 512"><path fill="currentColor" d="M224.3 273l-136 136c-9.4 9.4-24.6 9.4-33.9 0l-22.6-22.6c-9.4-9.4-9.4-24.6 0-33.9l96.4-96.4-96.4-96.4c-9.4-9.4-9.4-24.6 0-33.9L54.3 103c9.4-9.4 24.6-9.4 33.9 0l136 136c9.5 9.4 9.5 24.6.1 34z"></path></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M12.95 10.707l.707-.707L8 4.343 6.586 5.757 10.828 10l-4.242 4.243L8 15.657l4.95-4.95z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M0 11l2-2 5 5L18 3l2 2L7 18z"/></svg>
@@ -1 +1 @@
1
- <svg aria-hidden="true" data-prefix="fas" data-icon="cog" class="svg-inline--fa fa-cog fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M444.788 291.1l42.616 24.599c4.867 2.809 7.126 8.618 5.459 13.985-11.07 35.642-29.97 67.842-54.689 94.586a12.016 12.016 0 0 1-14.832 2.254l-42.584-24.595a191.577 191.577 0 0 1-60.759 35.13v49.182a12.01 12.01 0 0 1-9.377 11.718c-34.956 7.85-72.499 8.256-109.219.007-5.49-1.233-9.403-6.096-9.403-11.723v-49.184a191.555 191.555 0 0 1-60.759-35.13l-42.584 24.595a12.016 12.016 0 0 1-14.832-2.254c-24.718-26.744-43.619-58.944-54.689-94.586-1.667-5.366.592-11.175 5.459-13.985L67.212 291.1a193.48 193.48 0 0 1 0-70.199l-42.616-24.599c-4.867-2.809-7.126-8.618-5.459-13.985 11.07-35.642 29.97-67.842 54.689-94.586a12.016 12.016 0 0 1 14.832-2.254l42.584 24.595a191.577 191.577 0 0 1 60.759-35.13V25.759a12.01 12.01 0 0 1 9.377-11.718c34.956-7.85 72.499-8.256 109.219-.007 5.49 1.233 9.403 6.096 9.403 11.723v49.184a191.555 191.555 0 0 1 60.759 35.13l42.584-24.595a12.016 12.016 0 0 1 14.832 2.254c24.718 26.744 43.619 58.944 54.689 94.586 1.667 5.366-.592 11.175-5.459 13.985L444.788 220.9a193.485 193.485 0 0 1 0 70.2zM336 256c0-44.112-35.888-80-80-80s-80 35.888-80 80 35.888 80 80 80 80-35.888 80-80z"></path></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M3.94 6.5L2.22 3.64l1.42-1.42L6.5 3.94c.52-.3 1.1-.54 1.7-.7L9 0h2l.8 3.24c.6.16 1.18.4 1.7.7l2.86-1.72 1.42 1.42-1.72 2.86c.3.52.54 1.1.7 1.7L20 9v2l-3.24.8c-.16.6-.4 1.18-.7 1.7l1.72 2.86-1.42 1.42-2.86-1.72c-.52.3-1.1.54-1.7.7L11 20H9l-.8-3.24c-.6-.16-1.18-.4-1.7-.7l-2.86 1.72-1.42-1.42 1.72-2.86c-.3-.52-.54-1.1-.7-1.7L0 11V9l3.24-.8c.16-.6.4-1.18.7-1.7zM10 13a3 3 0 1 0 0-6 3 3 0 0 0 0 6z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M10 8.586L2.929 1.515 1.515 2.929 8.586 10l-7.071 7.071 1.414 1.414L10 11.414l7.071 7.071 1.414-1.414L11.414 10l7.071-7.071-1.414-1.414L10 8.586z"/></svg>
@@ -0,0 +1 @@
1
+ <svg aria-hidden="true" focusable="false" data-prefix="fas" data-icon="undo" class="svg-inline--fa fa-undo fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M212.333 224.333H12c-6.627 0-12-5.373-12-12V12C0 5.373 5.373 0 12 0h48c6.627 0 12 5.373 12 12v78.112C117.773 39.279 184.26 7.47 258.175 8.007c136.906.994 246.448 111.623 246.157 248.532C504.041 393.258 393.12 504 256.333 504c-64.089 0-122.496-24.313-166.51-64.215-5.099-4.622-5.334-12.554-.467-17.42l33.967-33.967c4.474-4.474 11.662-4.717 16.401-.525C170.76 415.336 211.58 432 256.333 432c97.268 0 176-78.716 176-176 0-97.267-78.716-176-176-176-58.496 0-110.28 28.476-142.274 72.333h98.274c6.627 0 12 5.373 12 12v48c0 6.627-5.373 12-12 12z"></path></svg>
@@ -1 +1 @@
1
- <svg aria-hidden="true" data-prefix="fas" data-icon="sort-amount-down" class="svg-inline--fa fa-sort-amount-down fa-w-16" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="currentColor" d="M187.298 395.314l-79.984 80.002c-6.248 6.247-16.383 6.245-22.627 0L4.705 395.314C-5.365 385.244 1.807 368 16.019 368H64V48c0-8.837 7.163-16 16-16h32c8.837 0 16 7.163 16 16v320h47.984c14.241 0 21.363 17.264 11.314 27.314zM240 96h256c8.837 0 16-7.163 16-16V48c0-8.837-7.163-16-16-16H240c-8.837 0-16 7.163-16 16v32c0 8.837 7.163 16 16 16zm-16 112v-32c0-8.837 7.163-16 16-16h192c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H240c-8.837 0-16-7.163-16-16zm0 256v-32c0-8.837 7.163-16 16-16h64c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16h-64c-8.837 0-16-7.163-16-16zm0-128v-32c0-8.837 7.163-16 16-16h128c8.837 0 16 7.163 16 16v32c0 8.837-7.163 16-16 16H240c-8.837 0-16-7.163-16-16z"></path></svg>
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M17 16v4h-2v-4h-2v-3h6v3h-2zM1 9h6v3H1V9zm6-4h6v3H7V5zM3 0h2v8H3V0zm12 0h2v12h-2V0zM9 0h2v4H9V0zM3 12h2v8H3v-8zm6-4h2v12H9V8z"/></svg>
@@ -10,14 +10,5 @@
10
10
  // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
11
11
  // about supported directives.
12
12
  //
13
- <%
14
- if Rails::VERSION::MAJOR >= 5
15
- require_asset("rails-ujs")
16
- else
17
- require_asset("jquery")
18
- require_asset("jquery_ujs")
19
- end
20
-
21
- require_asset("settings")
22
- %>
13
+ //= require rails-ujs
23
14
  //= require_tree .
@@ -4,9 +4,11 @@
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
- let autoSearchEnabled = "<%= Sail.configuration.enable_search_auto_submit %>";
11
+ let autoSearchEnabled = document.getElementById("auto_search_enabled").value;
10
12
  let progress = document.getElementById("search-submit-progress");
11
13
  let sortMenu = document.getElementById("sort-menu");
12
14
  let orderButton = document.getElementById("btn-order");
@@ -16,7 +18,10 @@ let dashboardBody = document.getElementById("settings-dashboard");
16
18
  let guideButton = document.getElementById("btn-guide");
17
19
  let guide = document.getElementById("guide-modal");
18
20
  let guideSections = guide.getElementsByTagName("summary");
19
- var i;
21
+ let cardTitles = document.getElementsByClassName("card-title");
22
+ let inputs = document.getElementsByName("value");
23
+ const initialSettingValues = {};
24
+ let i;
20
25
 
21
26
  function submitSearch() {
22
27
  document.getElementById("search-form").submit();
@@ -63,12 +68,23 @@ function toggleModal(modal) {
63
68
  function handleGenericClick(event) {
64
69
  let target = event.target;
65
70
 
66
- 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
+ ) {
67
78
  return;
68
79
  }
69
80
 
70
- if (profilesButton !== null && (target === profilesMenu || profilesMenu.contains(target) || target === profilesButton ||
71
- profilesButton.contains(target))) {
81
+ if (
82
+ profilesButton !== null &&
83
+ (target === profilesMenu ||
84
+ profilesMenu.contains(target) ||
85
+ target === profilesButton ||
86
+ profilesButton.contains(target))
87
+ ) {
72
88
  return;
73
89
  }
74
90
 
@@ -98,10 +114,14 @@ if (queryElement !== null) {
98
114
  }
99
115
 
100
116
  orderButton.addEventListener("click", toggleSortMenu);
101
- profilesButton.addEventListener("click", function () { toggleModal(profilesMenu) });
117
+ profilesButton.addEventListener("click", function () {
118
+ toggleModal(profilesMenu);
119
+ });
102
120
  }
103
121
 
104
- guideButton.addEventListener("click", function () { toggleModal(guide) });
122
+ guideButton.addEventListener("click", function () {
123
+ toggleModal(guide);
124
+ });
105
125
  document.body.addEventListener("click", handleGenericClick);
106
126
  document.addEventListener("keydown", closeAllModals);
107
127
 
@@ -116,16 +136,21 @@ function refreshClick() {
116
136
 
117
137
  if (!button.className.includes("active")) {
118
138
  button.classList.add("active");
119
- setTimeout(function() { button.classList.remove("active"); }, 500);
139
+ setTimeout(function () {
140
+ button.classList.remove("active");
141
+ }, 500);
120
142
  }
121
143
  }
122
144
 
123
- 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);
124
147
 
125
- // Guide related functions
148
+ /*
149
+ Guide related functions
150
+ */
126
151
 
127
152
  function sectionClick() {
128
- for(i = 0; i < guideSections.length; i++) {
153
+ for (i = 0; i < guideSections.length; i++) {
129
154
  if (this.parentElement.open) {
130
155
  guideSections[i].parentElement.style.display = "block";
131
156
  } else if (this !== guideSections[i]) {
@@ -134,4 +159,47 @@ function sectionClick() {
134
159
  }
135
160
  }
136
161
 
137
- 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);
164
+
165
+ /*
166
+ Cards related functions
167
+ */
168
+
169
+ function flipCard() {
170
+ this.parentElement.parentElement.classList.toggle("flipped");
171
+ }
172
+
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
+ }
@@ -0,0 +1,419 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
10
+ * files in this directory. Styles in this file should be added after the last require_* statement.
11
+ * It is generally better to create a new file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
16
+
17
+ :root {
18
+ --main-black: #0B0C10;
19
+ --dark-green: #306B34;
20
+ --light-green: #44AF69;
21
+ --cerulean: #4484CE;
22
+ --aluminium: #D9D9D9;
23
+ --dark-aluminium: #8D8D8D;
24
+ --darker-aluminium: #666666;
25
+ --light-yellow: #F9CF00;
26
+ --tangerine: #F19F4D;
27
+ --dark-tangerine: #C86C10;
28
+ --lead: #003049;
29
+ --bright-red: #E63946;
30
+ }
31
+
32
+ @-webkit-keyframes fadeIn {
33
+ from { opacity: 0; }
34
+ to { opacity: 1; }
35
+ }
36
+
37
+ @keyframes fadeIn {
38
+ from { opacity: 0; }
39
+ to { opacity: 1; }
40
+ }
41
+
42
+ * {
43
+ font-family: 'Open Sans', sans-serif;
44
+ -webkit-font-smoothing: antialiased;
45
+ -moz-osx-font-smoothing: grayscale;
46
+ }
47
+
48
+ .title {
49
+ font-family: 'Montserrat', sans-serif;
50
+ }
51
+
52
+ html, body {
53
+ height: 100vh;
54
+ margin: 0;
55
+ padding: 0;
56
+ background-color: var(--cerulean);
57
+ }
58
+
59
+ .clearfix {
60
+ clear: both;
61
+ }
62
+
63
+ #nav-bar {
64
+ background-color: var(--lead);
65
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.15), 0 5px 12px rgba(0, 0, 0, 0.1);
66
+ }
67
+
68
+ #nav-bar .home-link {
69
+ -webkit-transition : color .25s ease-in;
70
+ -moz-transition : color .25s ease-in;
71
+ -o-transition : color .25s ease-in;
72
+ transition : color .25s ease-in;
73
+ color: white;
74
+ text-decoration: none;
75
+ }
76
+
77
+ #nav-bar .home-link:visited {
78
+ color: white;
79
+ }
80
+
81
+ #nav-bar .home-link:hover {
82
+ color: var(--tangerine);
83
+ }
84
+
85
+ #nav-bar .home-link .title {
86
+ margin: 0;
87
+ text-align: center;
88
+ font-size: 3rem;
89
+ padding: .75rem 0;
90
+ }
91
+
92
+ #nav-bar .nav-button {
93
+ float: right;
94
+ position: relative;
95
+ bottom: 50px;
96
+ font-size: 20px;
97
+ outline: none;
98
+ background: transparent;
99
+ border: none;
100
+ -webkit-transition : color .25s ease-in;
101
+ -moz-transition : color .25s ease-in;
102
+ -o-transition : color .25s ease-in;
103
+ transition : color .25s ease-in;
104
+ color: white;
105
+ text-decoration: none;
106
+ }
107
+
108
+ #nav-bar .nav-button:visited {
109
+ color: white;
110
+ }
111
+
112
+ #nav-bar .nav-button:hover {
113
+ color: var(--tangerine);
114
+ }
115
+
116
+ #nav-bar .nav-button:hover {
117
+ cursor: pointer;
118
+ }
119
+
120
+ #nav-bar #btn-guide {
121
+ right: 70px;
122
+ padding: 0;
123
+ margin: 0;
124
+ }
125
+
126
+ @media (min-width: 1200px) {
127
+ #nav-bar #btn-guide {
128
+ right: 110px;
129
+ }
130
+ }
131
+
132
+ @media (max-width: 991px) {
133
+ #nav-bar .nav-button {
134
+ display: none;
135
+ }
136
+ }
137
+
138
+ #pagination {
139
+ text-align: center;
140
+ margin-top: 2rem;
141
+ }
142
+
143
+ #pagination a {
144
+ color: var(--main-black);
145
+ text-decoration: none;
146
+ background-color: white;
147
+ padding: 20px;
148
+ -webkit-border-radius: 5px;
149
+ -moz-border-radius: 5px;
150
+ border-radius: 5px;
151
+ box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
152
+ font-weight: bold;
153
+ }
154
+
155
+ #pagination a.active {
156
+ background-color: var(--tangerine);
157
+ color: white;
158
+ }
159
+
160
+ #pagination .page-links a {
161
+ font-size: 1.2rem;
162
+ margin: 0 2px 0 2px;
163
+ }
164
+
165
+ #pagination .page-links #angle-left-link {
166
+ background: white url(<%= asset_url("sail/angle-left.svg") %>) center no-repeat;
167
+ margin-right: 6px;
168
+ padding: 20px 24px 20px 24px;
169
+ }
170
+
171
+ #pagination .page-links #angle-right-link {
172
+ background: white url(<%= asset_url("sail/angle-right.svg") %>) center no-repeat;
173
+ margin-left: 6px;
174
+ padding: 20px 24px 20px 24px;
175
+ }
176
+
177
+ #profiles-modal, #guide-modal {
178
+ position: fixed;
179
+ height: 70%;
180
+ width: 70%;
181
+ top: 15%;
182
+ left: 15%;
183
+ background-color: white;
184
+ z-index: 1;
185
+ box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);
186
+ -webkit-border-radius: 5px;
187
+ -moz-border-radius: 5px;
188
+ border-radius: 5px;
189
+ -webkit-animation: fadeIn 0.5s;
190
+ animation: fadeIn 0.5s;
191
+ padding: 15px;
192
+ overflow: scroll;
193
+ }
194
+
195
+ @media (max-width: 1200px) {
196
+ #profiles-modal, #guide-modal {
197
+ width: 90%;
198
+ left: 3%;
199
+ }
200
+ }
201
+
202
+ @media (max-width: 767px) {
203
+ #profiles-modal, #guide-modal {
204
+ width: 90%;
205
+ left: 1%;
206
+ }
207
+ }
208
+
209
+ #profiles-modal {
210
+ text-align: center;
211
+ }
212
+
213
+ #profiles-modal h1 {
214
+ margin-left: 35px;
215
+ }
216
+
217
+ #profiles-modal h1 #response-message {
218
+ float: right;
219
+ font-size: 18px;
220
+ margin-right: 3px;
221
+ position: relative;
222
+ top: 5px;
223
+ min-width: 50px;
224
+ min-height: 20px;
225
+ color: var(--dark-green);
226
+ }
227
+
228
+ #profiles-modal .profile-entry {
229
+ padding: 10px;
230
+ font-size: 20px;
231
+ border-bottom: 2px solid transparent;
232
+ margin-bottom: 15px;
233
+ -webkit-transition : border .25s ease-in;
234
+ -moz-transition : border .25s ease-in;
235
+ -o-transition : border .25s ease-in;
236
+ transition : border .25s ease-in;
237
+ outline: none;
238
+ }
239
+
240
+ #profiles-modal .profile-entry:focus,
241
+ #profiles-modal .profile-entry:hover {
242
+ border-color: var(--tangerine);
243
+ outline: none;
244
+ }
245
+
246
+ #profiles-modal .profile-entry button {
247
+ padding: 10px;
248
+ }
249
+
250
+ #profiles-modal .profile-entry .entry-name {
251
+ position: relative;
252
+ top: 10px;
253
+ }
254
+
255
+ #profiles-modal .buttons button {
256
+ margin: 0 5px 0 5px;
257
+ }
258
+
259
+ @media (max-width: 767px) {
260
+ #profiles-modal .profile-entry .entry-name {
261
+ width: 90%;
262
+ margin-bottom: 15px;
263
+ }
264
+
265
+ #profiles-modal #new-profile-input {
266
+ width: 70%;
267
+ }
268
+ }
269
+
270
+ #profiles-modal .profile-entry .active-indicator {
271
+ position: relative;
272
+ top: 7px;
273
+ }
274
+
275
+ #profiles-modal .profile-entry .active-indicator.yellow {
276
+ color: var(--light-yellow);
277
+ }
278
+
279
+ #profiles-modal .profile-entry .active-indicator.green {
280
+ color: var(--light-green);
281
+ }
282
+
283
+ #profiles-modal .profile-entry .errors-indicator {
284
+ position: relative;
285
+ top: 9px;
286
+ left: 15px;
287
+ font-style: italic;
288
+ color: var(--dark-aluminium);
289
+ }
290
+
291
+ #profiles-modal #new-profile-input {
292
+ height: 100%;
293
+ border: none;
294
+ font-size: 20px;
295
+ width: 90%;
296
+ position: relative;
297
+ top: 10px;
298
+ text-overflow: ellipsis;
299
+ }
300
+
301
+ #profiles-modal #new-profile-input:focus {
302
+ outline: none;
303
+ }
304
+
305
+ @media (max-width: 1200px) {
306
+ #profiles-modal #new-profile-input {
307
+ width: 88%;
308
+ }
309
+ }
310
+
311
+ #guide-modal h1 {
312
+ text-align: center;
313
+ }
314
+
315
+ #guide-modal details {
316
+ padding: 15px;
317
+ }
318
+
319
+ #guide-modal details summary {
320
+ font-size: 20px;
321
+ outline: none;
322
+ border-bottom: 1px solid transparent;
323
+ -webkit-transition : border .25s ease-in;
324
+ -moz-transition : border .25s ease-in;
325
+ -o-transition : border .25s ease-in;
326
+ transition : border .25s ease-in;
327
+ outline: none;
328
+ }
329
+
330
+ #guide-modal details > summary {
331
+ list-style: none;
332
+ }
333
+
334
+ #guide-modal details > summary::-webkit-details-marker {
335
+ display: none;
336
+ }
337
+
338
+ #guide-modal details summary:focus,
339
+ #guide-modal details summary:hover {
340
+ border-color: var(--tangerine);
341
+ outline: none;
342
+ }
343
+
344
+ #guide-modal details summary div {
345
+ padding-bottom: 10px;
346
+ }
347
+
348
+ #guide-modal details summary label {
349
+ color: var(--dark-aluminium);
350
+ font-size: 18px;
351
+ float: right;
352
+ }
353
+
354
+ #guide-modal details summary img {
355
+ display: none;
356
+ }
357
+
358
+ #guide-modal details summary::-webkit-details-marker,
359
+ #guide-modal details summary::marker {
360
+ display: none;
361
+ font-size: 0;
362
+ }
363
+
364
+ #guide-modal details summary:hover {
365
+ cursor: pointer;
366
+ }
367
+
368
+ #guide-modal details summary:focus {
369
+ border-color: transparent;
370
+ }
371
+
372
+ #guide-modal details[open] p p ~ * {
373
+ -webkit-animation: fadeIn 0.5s;
374
+ animation: fadeIn 0.5s;
375
+ }
376
+
377
+ #guide-modal details[open] summary {
378
+ border-bottom: 1px solid var(--tangerine);
379
+ }
380
+
381
+ #guide-modal details[open] summary div {
382
+ font-size: 28px;
383
+ text-align: center;
384
+ }
385
+
386
+ #guide-modal details[open] summary label {
387
+ display: none;
388
+ }
389
+
390
+ #guide-modal details[open] summary img {
391
+ display: block;
392
+ height: 20px;
393
+ width: 20px;
394
+ float: left;
395
+ position: relative;
396
+ top: 10px;
397
+ }
398
+
399
+ #guide-modal details p, .items-container {
400
+ text-align: center;
401
+ font-size: 20px;
402
+ }
403
+
404
+ #guide-modal details p ul,
405
+ .items-container ul {
406
+ list-style-type: none;
407
+ }
408
+
409
+ #guide-modal details p ul li,
410
+ .items-container ul li {
411
+ padding: 10px;
412
+ }
413
+
414
+ hr {
415
+ border: 0;
416
+ height: 1px;
417
+ border-top: 1px solid rgba(0, 0, 0, 0.1);
418
+ border-bottom: 1px solid rgba(255, 255, 255, 0.3);
419
+ }