diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..dc8ff00 --- /dev/null +++ b/.babelrc @@ -0,0 +1,16 @@ +{ + "presets": [ + ["env", { + "modules": false, + "targets": { + "browsers": [ + "> .25%", + "Firefox >= 52", // last ESR + "IE >=10" + ], + "uglify": true + }, + "useBuiltIns": true + }] + ] +} diff --git a/.gitignore b/.gitignore index ebf0e92..c433235 100644 --- a/.gitignore +++ b/.gitignore @@ -91,7 +91,6 @@ yarn-error.log yarn-debug.log* -.yarn-integrity .env package-lock.json node_modules @@ -99,7 +98,6 @@ /public/packs-test spec/examples.txt -.babelrc .postcssrc.yml /public/packs /public/packs-test diff --git a/Gemfile b/Gemfile index 1a3b3fb..7963296 100644 --- a/Gemfile +++ b/Gemfile @@ -6,7 +6,7 @@ # RAILS # Full-stack web application framework. (http://www.rubyonrails.org) # Full-stack web application framework. (http://rubyonrails.org) -gem 'rails', '~> 4.2.10' +gem 'rails', '~> 4.2.11.1' # Rake is a Make-like program implemented in Ruby (https://github.com/ruby/rake) gem "rake" @@ -112,7 +112,7 @@ # bootstrap-sass is a Sass-powered version of Bootstrap 3, ready to drop right into your Sass powered applications. (https://github.com/twbs/bootstrap-sass) -gem 'bootstrap-sass', '~> 3.3.7' +gem 'bootstrap-sass', '~> 3.4.1' # This is required for Font-Awesome, but not used as the main sass compiler @@ -140,7 +140,7 @@ gem 'wkhtmltopdf-binary' # PDF generator (from HTML) gem for Ruby on Rails (https://github.com/mileszs/wicked_pdf) -gem 'wicked_pdf' +gem 'wicked_pdf', '~> 1.1.0' # This simple gem allows you to create MS Word docx documents from simple html documents. This makes it easy to create dynamic reports and forms that can be downloaded by your users as simple MS Word docx files. (http://github.com/karnov/htmltoword) gem 'htmltoword' diff --git a/Gemfile.lock b/Gemfile.lock index 09d17aa..87f3ab1 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,81 +1,81 @@ GEM remote: https://rubygems.org/ specs: - actionmailer (4.2.11) - actionpack (= 4.2.11) - actionview (= 4.2.11) - activejob (= 4.2.11) + actionmailer (4.2.11.1) + actionpack (= 4.2.11.1) + actionview (= 4.2.11.1) + activejob (= 4.2.11.1) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 1.0, >= 1.0.5) - actionpack (4.2.11) - actionview (= 4.2.11) - activesupport (= 4.2.11) + actionpack (4.2.11.1) + actionview (= 4.2.11.1) + activesupport (= 4.2.11.1) rack (~> 1.6) rack-test (~> 0.6.2) rails-dom-testing (~> 1.0, >= 1.0.5) rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (4.2.11) - activesupport (= 4.2.11) + actionview (4.2.11.1) + activesupport (= 4.2.11.1) builder (~> 3.1) erubis (~> 2.7.0) rails-dom-testing (~> 1.0, >= 1.0.5) rails-html-sanitizer (~> 1.0, >= 1.0.3) - activejob (4.2.11) - activesupport (= 4.2.11) + activejob (4.2.11.1) + activesupport (= 4.2.11.1) globalid (>= 0.3.0) - activemodel (4.2.11) - activesupport (= 4.2.11) + activemodel (4.2.11.1) + activesupport (= 4.2.11.1) builder (~> 3.1) - activerecord (4.2.11) - activemodel (= 4.2.11) - activesupport (= 4.2.11) + activerecord (4.2.11.1) + activemodel (= 4.2.11.1) + activesupport (= 4.2.11.1) arel (~> 6.0) - activerecord-session_store (1.1.1) + activerecord-session_store (1.1.3) actionpack (>= 4.0) activerecord (>= 4.0) multi_json (~> 1.11, >= 1.11.2) rack (>= 1.5.2, < 3) railties (>= 4.0) - activesupport (4.2.11) + activesupport (4.2.11.1) i18n (~> 0.7) minitest (~> 5.1) thread_safe (~> 0.3, >= 0.3.4) tzinfo (~> 1.1) - addressable (2.5.2) + addressable (2.6.0) public_suffix (>= 2.0.2, < 4.0) annotate (2.7.4) activerecord (>= 3.2, < 6.0) rake (>= 10.4, < 13.0) annotate_gem (0.0.13) bundler (~> 1.1) - archive-zip (0.11.0) + archive-zip (0.12.0) io-like (~> 0.3.0) arel (6.0.4) ast (2.4.0) - autoprefixer-rails (9.3.1) + autoprefixer-rails (9.5.1) execjs bcrypt (3.1.12) - better_errors (2.5.0) + better_errors (2.5.1) coderay (>= 1.0.0) erubi (>= 1.0.0) rack (>= 0.9.0) binding_of_caller (0.8.0) debug_inspector (>= 0.0.1) - bootstrap-sass (3.3.7) + bootstrap-sass (3.4.1) autoprefixer-rails (>= 5.2.1) - sass (>= 3.3.4) - brakeman (4.3.1) + sassc (>= 2.0.0) + brakeman (4.5.0) builder (3.2.3) bullet (5.9.0) activesupport (>= 3.0.0) uniform_notifier (~> 1.11) bundle-audit (0.1.0) bundler-audit - bundler-audit (0.6.0) - bundler (~> 1.2) + bundler-audit (0.6.1) + bundler (>= 1.2.0, < 3) thor (~> 0.18) - byebug (10.0.2) - capybara (3.12.0) + byebug (11.0.1) + capybara (3.18.0) addressable mini_mime (>= 0.1.3) nokogiri (~> 1.8) @@ -86,22 +86,22 @@ capybara-screenshot (1.0.22) capybara (>= 1.0, < 4) launchy - childprocess (0.9.0) - ffi (~> 1.0, >= 1.0.11) - chromedriver-helper (2.1.0) + childprocess (1.0.1) + rake (< 13.0) + chromedriver-helper (2.1.1) archive-zip (~> 0.10) nokogiri (~> 1.8) coderay (1.1.2) - concurrent-ruby (1.1.3) + concurrent-ruby (1.1.5) contact_us (1.2.0) rails (>= 4.2.0) crack (0.4.3) safe_yaml (~> 1.0.0) crass (1.0.4) - daemons (1.2.6) + daemons (1.3.1) database_cleaner (1.7.0) debug_inspector (0.0.3) - devise (4.5.0) + devise (4.6.2) bcrypt (~> 3.0) orm_adapter (~> 0.1) railties (>= 4.1.0, < 6.0) @@ -112,10 +112,10 @@ devise (>= 4.0.0) diff-lcs (1.3) docile (1.3.1) - dotenv (2.5.0) - dotenv-rails (2.5.0) - dotenv (= 2.5.0) - railties (>= 3.2, < 6.0) + dotenv (2.7.2) + dotenv-rails (2.7.2) + dotenv (= 2.7.2) + railties (>= 3.2, < 6.1) dragonfly (1.2.0) addressable (~> 2.3) multi_json (~> 1.0) @@ -123,31 +123,31 @@ dragonfly-s3_data_store (1.3.0) dragonfly (~> 1.0) fog-aws - erubi (1.7.1) + erubi (1.8.0) erubis (2.7.0) eventmachine (1.2.7) - excon (0.62.0) + excon (0.64.0) execjs (2.7.0) - factory_bot (4.11.1) - activesupport (>= 3.0.0) - factory_bot_rails (4.11.1) - factory_bot (~> 4.11.1) - railties (>= 3.0.0) - faker (1.9.1) + factory_bot (5.0.2) + activesupport (>= 4.2.0) + factory_bot_rails (5.0.2) + factory_bot (~> 5.0.2) + railties (>= 4.2.0) + faker (1.9.3) i18n (>= 0.7) faraday (0.15.4) multipart-post (>= 1.2, < 3) - faraday_middleware (0.12.2) + faraday_middleware (0.13.1) faraday (>= 0.7.4, < 1.0) - fast_gettext (1.7.0) + fast_gettext (2.0.1) feedjira (2.2.0) faraday (>= 0.9) faraday_middleware (>= 0.9) loofah (>= 2.0) sax-machine (>= 1.0) - ffi (1.9.25) + ffi (1.10.0) flag_shih_tzu (0.3.23) - fog-aws (3.3.0) + fog-aws (3.4.0) fog-core (~> 2.1) fog-json (~> 1.1) fog-xml (~> 0.1) @@ -179,7 +179,7 @@ gettext_i18n_rails (>= 0.7.1) po_to_json (>= 1.0.0) rails (>= 3.2.0) - globalid (0.4.1) + globalid (0.4.2) activesupport (>= 4.2.0) guard (2.15.0) formatador (>= 0.2.4) @@ -195,9 +195,9 @@ guard (~> 2.1) guard-compat (~> 1.1) rspec (>= 2.99.0, < 4.0) - hashdiff (0.3.7) - hashie (3.5.7) - highline (2.0.0) + hashdiff (0.3.9) + hashie (3.6.0) + highline (2.0.2) htmltoword (1.1.0) actionpack nokogiri @@ -206,11 +206,11 @@ concurrent-ruby (~> 1.0) io-like (0.3.0) ipaddress (0.8.3) - jaro_winkler (1.5.1) + jaro_winkler (1.5.2) jbuilder (2.6.4) activesupport (>= 3.0.0) multi_json (>= 1.2) - json (2.1.0) + json (2.2.0) jwt (2.1.0) kaminari (1.1.1) activesupport (>= 4.1.0) @@ -244,21 +244,21 @@ method_source (0.9.2) mime-types (3.2.2) mime-types-data (~> 3.2015) - mime-types-data (3.2018.0812) + mime-types-data (3.2019.0331) mini_mime (1.0.1) - mini_portile2 (2.3.0) + mini_portile2 (2.4.0) mini_racer (0.2.4) libv8 (>= 6.3) minitest (5.11.3) - mocha (1.7.0) + mocha (1.8.0) metaclass (~> 0.0.1) multi_json (1.13.1) multi_xml (0.6.0) multipart-post (2.0.0) mysql2 (0.4.10) nenv (0.3.0) - nokogiri (1.8.5) - mini_portile2 (~> 2.3.0) + nokogiri (1.10.3) + mini_portile2 (~> 2.4.0) notiffany (0.1.1) nenv (~> 0.1) shellany (~> 0.0) @@ -268,12 +268,12 @@ multi_json (~> 1.3) multi_xml (~> 0.5) rack (>= 1.2, < 3) - omniauth (1.8.1) - hashie (>= 3.4.6, < 3.6.0) + omniauth (1.9.0) + hashie (>= 3.4.6, < 3.7.0) rack (>= 1.6.2, < 3) - omniauth-oauth2 (1.5.0) + omniauth-oauth2 (1.6.0) oauth2 (~> 1.1) - omniauth (~> 1.2) + omniauth (~> 1.9) omniauth-orcid (2.1.1) omniauth-oauth2 (~> 1.3) ruby_dig (~> 0.0.2) @@ -281,40 +281,40 @@ omniauth (>= 1.0.0) options (2.3.2) orm_adapter (0.5.0) - parallel (1.12.1) - parser (2.5.3.0) + parallel (1.17.0) + parser (2.6.2.1) ast (~> 2.4.0) pg (0.19.0) po_to_json (1.0.1) json (>= 1.6.0) - powerpack (0.1.2) progress_bar (1.3.0) highline (>= 1.6, < 3) options (~> 2.3.0) pry (0.12.2) coderay (~> 1.1.0) method_source (~> 0.9.0) + psych (3.1.0) public_suffix (3.0.3) - puma (3.12.0) - pundit (2.0.0) + puma (3.12.1) + pundit (2.0.1) activesupport (>= 3.0.0) rack (1.6.11) - rack-mini-profiler (1.0.0) + rack-mini-profiler (1.0.2) rack (>= 1.2.0) rack-proxy (0.6.5) rack rack-test (0.6.3) rack (>= 1.0) - rails (4.2.11) - actionmailer (= 4.2.11) - actionpack (= 4.2.11) - actionview (= 4.2.11) - activejob (= 4.2.11) - activemodel (= 4.2.11) - activerecord (= 4.2.11) - activesupport (= 4.2.11) + rails (4.2.11.1) + actionmailer (= 4.2.11.1) + actionpack (= 4.2.11.1) + actionview (= 4.2.11.1) + activejob (= 4.2.11.1) + activemodel (= 4.2.11.1) + activerecord (= 4.2.11.1) + activesupport (= 4.2.11.1) bundler (>= 1.3.0, < 2.0) - railties (= 4.2.11) + railties (= 4.2.11.1) sprockets-rails rails-deprecated_sanitizer (1.0.3) activesupport (>= 4.2.0.alpha) @@ -329,23 +329,23 @@ rails_stdout_logging rails_serve_static_assets (0.0.5) rails_stdout_logging (0.0.5) - railties (4.2.11) - actionpack (= 4.2.11) - activesupport (= 4.2.11) + railties (4.2.11.1) + actionpack (= 4.2.11.1) + activesupport (= 4.2.11.1) rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) rainbow (3.0.0) - rake (12.3.1) + rake (12.3.2) rb-fsevent (0.10.3) - rb-inotify (0.9.10) - ffi (>= 0.5.0, < 2) - recaptcha (4.13.0) + rb-inotify (0.10.0) + ffi (~> 1.0) + recaptcha (4.14.0) json - regexp_parser (1.3.0) - responders (2.4.0) - actionpack (>= 4.2.0, < 5.3) - railties (>= 4.2.0, < 5.3) - rollbar (2.18.0) + regexp_parser (1.4.0) + responders (2.4.1) + actionpack (>= 4.2.0, < 6.0) + railties (>= 4.2.0, < 6.0) + rollbar (2.19.3) multi_json rspec (3.8.0) rspec-core (~> 3.8.0) @@ -355,13 +355,13 @@ rspec-expectations (>= 2.99.0.beta1) rspec-core (3.8.0) rspec-support (~> 3.8.0) - rspec-expectations (3.8.2) + rspec-expectations (3.8.3) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.8.0) rspec-mocks (3.8.0) diff-lcs (>= 1.2.0, < 2.0) rspec-support (~> 3.8.0) - rspec-rails (3.8.1) + rspec-rails (3.8.2) actionpack (>= 3.0) activesupport (>= 3.0) railties (>= 3.0) @@ -370,29 +370,29 @@ rspec-mocks (~> 3.8.0) rspec-support (~> 3.8.0) rspec-support (3.8.0) - rubocop (0.60.0) + rubocop (0.67.2) jaro_winkler (~> 1.5.1) parallel (~> 1.10) parser (>= 2.5, != 2.5.1.1) - powerpack (~> 0.1) + psych (>= 3.1.0) rainbow (>= 2.2.2, < 4.0) ruby-progressbar (~> 1.7) - unicode-display_width (~> 1.4.0) + unicode-display_width (>= 1.4.0, < 1.6) rubocop-dmp_roadmap (1.1.0) rubocop (>= 0.58.2) rubocop-rails_config (>= 0.2.2) rubocop-rspec (>= 1.27.0) - rubocop-rails_config (0.2.6) + rubocop-rails_config (0.5.1) railties (>= 3.0) - rubocop (~> 0.56) - rubocop-rspec (1.30.1) + rubocop (~> 0.60) + rubocop-rspec (1.32.0) rubocop (>= 0.60.0) ruby-progressbar (1.10.0) ruby_dep (1.5.0) ruby_dig (0.0.2) rubyzip (1.2.2) - safe_yaml (1.0.4) - sass (3.7.2) + safe_yaml (1.0.5) + sass (3.7.4) sass-listen (~> 4.0.0) sass-listen (4.0.0) rb-fsevent (~> 0.9, >= 0.9.4) @@ -403,25 +403,25 @@ sprockets (>= 2.8, < 4.0) sprockets-rails (>= 2.0, < 4.0) tilt (>= 1.1, < 3) - sassc (2.0.0) - ffi (~> 1.9.6) + sassc (2.0.1) + ffi (~> 1.9) rake - sassc-rails (2.0.0) + sassc-rails (2.1.1) railties (>= 4.0.0) sassc (>= 2.0) sprockets (> 3.0) sprockets-rails tilt sax-machine (1.3.2) - selenium-webdriver (3.141.0) - childprocess (~> 0.5) + selenium-webdriver (3.141.5926) + childprocess (>= 0.5, < 2.0) rubyzip (~> 1.2, >= 1.2.2) shellany (0.0.1) shoulda (3.6.0) shoulda-context (~> 1.0, >= 1.0.1) shoulda-matchers (~> 3.0) shoulda-context (1.2.2) - shoulda-matchers (3.1.2) + shoulda-matchers (3.1.3) activesupport (>= 4.0.0) simplecov (0.16.1) docile (~> 1.1) @@ -450,7 +450,7 @@ tomparse (0.4.2) tzinfo (1.2.5) thread_safe (~> 0.1) - unicode-display_width (1.4.0) + unicode-display_width (1.5.0) uniform_notifier (1.12.1) warden (1.2.7) rack (>= 1.0) @@ -458,11 +458,11 @@ activemodel (>= 4.2) debug_inspector railties (>= 4.2) - webmock (3.4.2) + webmock (3.5.1) addressable (>= 2.3.6) crack (>= 0.3.2) hashdiff - webpacker (3.5.5) + webpacker (3.6.0) activesupport (>= 4.2) rack-proxy (>= 0.6.1) railties (>= 4.2) @@ -470,7 +470,7 @@ wkhtmltopdf-binary (0.12.4) xpath (3.2.0) nokogiri (~> 1.8) - yard (0.9.16) + yard (0.9.19) yard-tomdoc (0.7.1) tomparse (>= 0.4.0) yard @@ -485,7 +485,7 @@ autoprefixer-rails better_errors binding_of_caller - bootstrap-sass (~> 3.3.7) + bootstrap-sass (~> 3.4.1) brakeman bullet bundle-audit @@ -526,7 +526,7 @@ puma pundit rack-mini-profiler - rails (~> 4.2.10) + rails (~> 4.2.11.1) rails_12factor railties rake @@ -549,7 +549,7 @@ web-console webmock webpacker (~> 3.5) - wicked_pdf + wicked_pdf (~> 1.1.0) wkhtmltopdf-binary yard yard-tomdoc diff --git a/app/assets/fonts/GillSans-Light.ttf b/app/assets/fonts/GillSans-Light.ttf new file mode 100644 index 0000000..5d5a135 --- /dev/null +++ b/app/assets/fonts/GillSans-Light.ttf Binary files differ diff --git a/app/assets/stylesheets/application.scss b/app/assets/stylesheets/application.scss index 94669db..64078d2 100644 --- a/app/assets/stylesheets/application.scss +++ b/app/assets/stylesheets/application.scss @@ -8,6 +8,11 @@ @debug "3 #{$navbar-branding-bg}"; @import "utils/*"; +// JQuery-UI CSS for Datepicker +@import "vendor/jquery-ui/datepicker/jquery-ui.min.css"; +@import "vendor/jquery-ui/datepicker/jquery-ui.structure.min.css"; +@import "vendor/jquery-ui/datepicker/jquery-ui.theme.min.css"; + @import "font-awesome-sprockets"; @import "font-awesome"; diff --git a/app/assets/stylesheets/blocks/_datepicker.scss b/app/assets/stylesheets/blocks/_datepicker.scss new file mode 100644 index 0000000..cc17f93 --- /dev/null +++ b/app/assets/stylesheets/blocks/_datepicker.scss @@ -0,0 +1,32 @@ +.ui-datepicker-header { + background: $color-seccondary-background; + color: $color-seccondary-text; + border: none; +} +.ui-datepicker-prev, +.ui-datepicker-next, +.ui-datepicker-prev:hover, .ui-datepicker-prev:focus, +.ui-datepicker-next:hover, .ui-datepicker-next:focus { + background: $color-primary-background; + color: $color-primary-text; + + .ui-icon { + background-attachment: none; + background-clip: none; + background-color: $color-primary-background; + background-image: none; + background-origin: none; + background-position: 1px 1px; + color: $color-primary-text; + } +} + +.ui-datepicker-next:before { + content: '\f0da'; + font-family: FontAwesome; + font-weight: normal; + font-style: normal; + margin: 0px 0px 0px 10px; + text-decoration: none; + width: 15px; +} diff --git a/app/assets/stylesheets/blocks/_question_container.scss b/app/assets/stylesheets/blocks/_question_container.scss new file mode 100644 index 0000000..d70077c --- /dev/null +++ b/app/assets/stylesheets/blocks/_question_container.scss @@ -0,0 +1,10 @@ +.question_container { + + dl.dl-horizontal { + padding-right: 10px; + border-right: 1px solid $color-black; + } + .fa-plus, .fa-minus { + font-size: 1.6rem; + } +} \ No newline at end of file diff --git a/app/assets/stylesheets/blocks/_readonly_textarea.scss b/app/assets/stylesheets/blocks/_readonly_textarea.scss new file mode 100644 index 0000000..ec288cf --- /dev/null +++ b/app/assets/stylesheets/blocks/_readonly_textarea.scss @@ -0,0 +1,19 @@ +/* For display of readonly textarea content without the TinyMCE editor */ +.display-readonly-textarea-content { + // Replicating some TinyMCE styling of textarea + overflow-y: hidden; + padding-left: 1px; + padding-right: 1px; + padding-bottom: 10px; + + // Ensure table borders are not lost + table { + td { + border: 1px solid black; + } + + td, tr { + padding: 10px; + } + } +} diff --git a/app/assets/stylesheets/utils/_break_words.scss b/app/assets/stylesheets/utils/_break_words.scss new file mode 100644 index 0000000..53a6c2d --- /dev/null +++ b/app/assets/stylesheets/utils/_break_words.scss @@ -0,0 +1,4 @@ +.allow-break-words { + overflow-wrap: break-word; + width: 100%; +} diff --git a/app/assets/stylesheets/variables/_bootstrap.scss b/app/assets/stylesheets/variables/_bootstrap.scss index fdfcc7c..edc5852 100644 --- a/app/assets/stylesheets/variables/_bootstrap.scss +++ b/app/assets/stylesheets/variables/_bootstrap.scss @@ -30,11 +30,11 @@ // from colors: -$dropdown-inverse-bg: $color-navbar-background; -$dropdown-inverse-border: $color-dropdown-inverse-border; -$dropdown-inverse-text: $color-dropdown-inverse-text; -$dropdown-inverse-text-hoover: $color-dropdown-inverse-text-hover; -$dropdown-inverse-bg-hoover: $color-navbar-background-active; +$dropdown-inverse-bg: $color-navbar-background !default; +$dropdown-inverse-border: $color-dropdown-inverse-border !default; +$dropdown-inverse-text: $color-dropdown-inverse-text !default; +$dropdown-inverse-text-hoover: $color-dropdown-inverse-text-hover !default; +$dropdown-inverse-bg-hoover: $color-navbar-background-active !default; // Navbar branding colours $navbar-branding-color: $color-navbar-text !default; @@ -55,5 +55,5 @@ $navbar-branding-toggle-border-color: $color-navbar-background-active !default; // org-navbar branding colors -$navbar-org-link-color: $color-org-navbar-links; -$navbar-org-link-hover-color: $color-org-navbar-links-hover; +$navbar-org-link-color: $color-org-navbar-links !default; +$navbar-org-link-hover-color: $color-org-navbar-links-hover !default; diff --git a/app/assets/stylesheets/vendor/jquery-ui/datepicker/jquery-ui.min.css b/app/assets/stylesheets/vendor/jquery-ui/datepicker/jquery-ui.min.css new file mode 100644 index 0000000..a686231 --- /dev/null +++ b/app/assets/stylesheets/vendor/jquery-ui/datepicker/jquery-ui.min.css @@ -0,0 +1,7 @@ +/*! jQuery UI - v1.12.1 - 2019-03-06 +* http://jqueryui.com +* Includes: core.css, datepicker.css, theme.css +* To view and modify this theme, visit http://jqueryui.com/themeroller/?scope=&folderName=custom-theme&bgImgOpacityError=&bgImgOpacityHighlight=&bgImgOpacityActive=&bgImgOpacityHover=&bgImgOpacityDefault=&bgImgOpacityContent=&bgImgOpacityHeader=&cornerRadiusShadow=8px&offsetLeftShadow=0px&offsetTopShadow=0px&thicknessShadow=5px&opacityShadow=30&bgImgOpacityShadow=0&bgTextureShadow=flat&bgColorShadow=%23666666&opacityOverlay=30&bgImgOpacityOverlay=0&bgTextureOverlay=flat&bgColorOverlay=%23aaaaaa&iconColorError=%23cc0000&fcError=%235f3f3f&borderColorError=%23f1a899&bgTextureError=flat&bgColorError=%23fddfdf&iconColorHighlight=%23fff&fcHighlight=%23fff&borderColorHighlight=%23337ab7&bgTextureHighlight=flat&bgColorHighlight=%23337ab7&iconColorActive=%23ffffff&fcActive=%23ffffff&borderColorActive=%23777&bgTextureActive=flat&bgColorActive=%234F5253&iconColorHover=%23555555&fcHover=%232b2b2b&borderColorHover=%23cccccc&bgTextureHover=flat&bgColorHover=%23ededed&iconColorDefault=%23777777&fcDefault=%23454545&borderColorDefault=%23c5c5c5&bgTextureDefault=flat&bgColorDefault=%23f6f6f6&iconColorContent=%234F5253&fcContent=%234F5253&borderColorContent=%23dddddd&bgTextureContent=flat&bgColorContent=%23ffffff&iconColorHeader=%23FFF&fcHeader=%23FFF&borderColorHeader=%234F5253&bgTextureHeader=flat&bgColorHeader=%234F5253&cornerRadius=3px&fwDefault=normal&fsDefault=1em&ffDefault=GillSansLight%2CArial%2Csans-serif +* Copyright jQuery Foundation and other contributors; Licensed MIT */ + +.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important;pointer-events:none}.ui-icon{display:inline-block;vertical-align:middle;margin-top:-.25em;position:relative;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-icon-block{left:50%;margin-left:-8px;display:block}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:45%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-datepicker .ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat;left:.5em;top:.3em}.ui-widget{font-family:GillSansLight,Arial,sans-serif;font-size:1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:GillSansLight,Arial,sans-serif;font-size:1em}.ui-widget.ui-widget-content{border:1px solid #c5c5c5}.ui-widget-content{border:1px solid #ddd;background:#fff;color:#4F5253}.ui-widget-content a{color:#4F5253}.ui-widget-header{border:1px solid #4F5253;background:#4F5253;color:#FFF;font-weight:bold}.ui-widget-header a{color:#FFF}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default,.ui-button,html .ui-button.ui-state-disabled:hover,html .ui-button.ui-state-disabled:active{border:1px solid #c5c5c5;background:#f6f6f6;font-weight:normal;color:#454545}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited,a.ui-button,a:link.ui-button,a:visited.ui-button,.ui-button{color:#454545;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus,.ui-button:hover,.ui-button:focus{border:1px solid #ccc;background:#ededed;font-weight:normal;color:#2b2b2b}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited,a.ui-button:hover,a.ui-button:focus{color:#2b2b2b;text-decoration:none}.ui-visual-focus{box-shadow:0 0 3px 1px rgb(94,158,214)}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active,a.ui-button:active,.ui-button:active,.ui-button.ui-state-active:hover{border:1px solid #777;background:#4F5253;font-weight:normal;color:#fff}.ui-icon-background,.ui-state-active .ui-icon-background{border:#777;background-color:#fff}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#fff;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #337ab7;background:#337ab7;color:#fff}.ui-state-checked{border:1px solid #337ab7;background:#337ab7}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#fff}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #f1a899;background:#fddfdf;color:#5f3f3f}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#5f3f3f}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#5f3f3f}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url("images/ui-icons_4F5253_256x240.png")}.ui-widget-header .ui-icon{background-image:url("images/ui-icons_FFF_256x240.png")}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon,.ui-button:hover .ui-icon,.ui-button:focus .ui-icon{background-image:url("images/ui-icons_555555_256x240.png")}.ui-state-active .ui-icon,.ui-button:active .ui-icon{background-image:url("images/ui-icons_ffffff_256x240.png")}.ui-state-highlight .ui-icon,.ui-button .ui-state-highlight.ui-icon{background-image:url("images/ui-icons_fff_256x240.png")}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url("images/ui-icons_cc0000_256x240.png")}.ui-button .ui-icon{background-image:url("images/ui-icons_777777_256x240.png")}.ui-icon-blank{background-position:16px 16px}.ui-icon-caret-1-n{background-position:0 0}.ui-icon-caret-1-ne{background-position:-16px 0}.ui-icon-caret-1-e{background-position:-32px 0}.ui-icon-caret-1-se{background-position:-48px 0}.ui-icon-caret-1-s{background-position:-65px 0}.ui-icon-caret-1-sw{background-position:-80px 0}.ui-icon-caret-1-w{background-position:-96px 0}.ui-icon-caret-1-nw{background-position:-112px 0}.ui-icon-caret-2-n-s{background-position:-128px 0}.ui-icon-caret-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-65px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-65px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:1px -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:3px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:3px}.ui-widget-overlay{background:#aaa;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{-webkit-box-shadow:0 0 5px #666;box-shadow:0 0 5px #666} \ No newline at end of file diff --git a/app/assets/stylesheets/vendor/jquery-ui/datepicker/jquery-ui.structure.min.css b/app/assets/stylesheets/vendor/jquery-ui/datepicker/jquery-ui.structure.min.css new file mode 100644 index 0000000..1390420 --- /dev/null +++ b/app/assets/stylesheets/vendor/jquery-ui/datepicker/jquery-ui.structure.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.12.1 - 2019-03-06 +* http://jqueryui.com +* Copyright jQuery Foundation and other contributors; Licensed MIT */ + +.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important;pointer-events:none}.ui-icon{display:inline-block;vertical-align:middle;margin-top:-.25em;position:relative;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-icon-block{left:50%;margin-left:-8px;display:block}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-datepicker{width:17em;padding:.2em .2em 0;display:none}.ui-datepicker .ui-datepicker-header{position:relative;padding:.2em 0}.ui-datepicker .ui-datepicker-prev,.ui-datepicker .ui-datepicker-next{position:absolute;top:2px;width:1.8em;height:1.8em}.ui-datepicker .ui-datepicker-prev-hover,.ui-datepicker .ui-datepicker-next-hover{top:1px}.ui-datepicker .ui-datepicker-prev{left:2px}.ui-datepicker .ui-datepicker-next{right:2px}.ui-datepicker .ui-datepicker-prev-hover{left:1px}.ui-datepicker .ui-datepicker-next-hover{right:1px}.ui-datepicker .ui-datepicker-prev span,.ui-datepicker .ui-datepicker-next span{display:block;position:absolute;left:50%;margin-left:-8px;top:50%;margin-top:-8px}.ui-datepicker .ui-datepicker-title{margin:0 2.3em;line-height:1.8em;text-align:center}.ui-datepicker .ui-datepicker-title select{font-size:1em;margin:1px 0}.ui-datepicker select.ui-datepicker-month,.ui-datepicker select.ui-datepicker-year{width:45%}.ui-datepicker table{width:100%;font-size:.9em;border-collapse:collapse;margin:0 0 .4em}.ui-datepicker th{padding:.7em .3em;text-align:center;font-weight:bold;border:0}.ui-datepicker td{border:0;padding:1px}.ui-datepicker td span,.ui-datepicker td a{display:block;padding:.2em;text-align:right;text-decoration:none}.ui-datepicker .ui-datepicker-buttonpane{background-image:none;margin:.7em 0 0 0;padding:0 .2em;border-left:0;border-right:0;border-bottom:0}.ui-datepicker .ui-datepicker-buttonpane button{float:right;margin:.5em .2em .4em;cursor:pointer;padding:.2em .6em .3em .6em;width:auto;overflow:visible}.ui-datepicker .ui-datepicker-buttonpane button.ui-datepicker-current{float:left}.ui-datepicker.ui-datepicker-multi{width:auto}.ui-datepicker-multi .ui-datepicker-group{float:left}.ui-datepicker-multi .ui-datepicker-group table{width:95%;margin:0 auto .4em}.ui-datepicker-multi-2 .ui-datepicker-group{width:50%}.ui-datepicker-multi-3 .ui-datepicker-group{width:33.3%}.ui-datepicker-multi-4 .ui-datepicker-group{width:25%}.ui-datepicker-multi .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-multi .ui-datepicker-group-middle .ui-datepicker-header{border-left-width:0}.ui-datepicker-multi .ui-datepicker-buttonpane{clear:left}.ui-datepicker-row-break{clear:both;width:100%;font-size:0}.ui-datepicker-rtl{direction:rtl}.ui-datepicker-rtl .ui-datepicker-prev{right:2px;left:auto}.ui-datepicker-rtl .ui-datepicker-next{left:2px;right:auto}.ui-datepicker-rtl .ui-datepicker-prev:hover{right:1px;left:auto}.ui-datepicker-rtl .ui-datepicker-next:hover{left:1px;right:auto}.ui-datepicker-rtl .ui-datepicker-buttonpane{clear:right}.ui-datepicker-rtl .ui-datepicker-buttonpane button{float:left}.ui-datepicker-rtl .ui-datepicker-buttonpane button.ui-datepicker-current,.ui-datepicker-rtl .ui-datepicker-group{float:right}.ui-datepicker-rtl .ui-datepicker-group-last .ui-datepicker-header,.ui-datepicker-rtl .ui-datepicker-group-middle .ui-datepicker-header{border-right-width:0;border-left-width:1px}.ui-datepicker .ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat;left:.5em;top:.3em} \ No newline at end of file diff --git a/app/assets/stylesheets/vendor/jquery-ui/datepicker/jquery-ui.theme.min.css b/app/assets/stylesheets/vendor/jquery-ui/datepicker/jquery-ui.theme.min.css new file mode 100644 index 0000000..ae47491 --- /dev/null +++ b/app/assets/stylesheets/vendor/jquery-ui/datepicker/jquery-ui.theme.min.css @@ -0,0 +1,5 @@ +/*! jQuery UI - v1.12.1 - 2019-03-06 +* http://jqueryui.com +* Copyright jQuery Foundation and other contributors; Licensed MIT */ + +.ui-widget{font-family:GillSansLight,Arial,sans-serif;font-size:1em}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:GillSansLight,Arial,sans-serif;font-size:1em}.ui-widget.ui-widget-content{border:1px solid #c5c5c5}.ui-widget-content{border:1px solid #ddd;background:#fff;color:#4F5253}.ui-widget-content a{color:#4F5253}.ui-widget-header{border:1px solid #4F5253;background:#4F5253;color:#FFF;font-weight:bold}.ui-widget-header a{color:#FFF}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default,.ui-button,html .ui-button.ui-state-disabled:hover,html .ui-button.ui-state-disabled:active{border:1px solid #c5c5c5;background:#f6f6f6;font-weight:normal;color:#454545}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited,a.ui-button,a:link.ui-button,a:visited.ui-button,.ui-button{color:#454545;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus,.ui-button:hover,.ui-button:focus{border:1px solid #ccc;background:#ededed;font-weight:normal;color:#2b2b2b}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited,.ui-state-focus a,.ui-state-focus a:hover,.ui-state-focus a:link,.ui-state-focus a:visited,a.ui-button:hover,a.ui-button:focus{color:#2b2b2b;text-decoration:none}.ui-visual-focus{box-shadow:0 0 3px 1px rgb(94,158,214)}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active,a.ui-button:active,.ui-button:active,.ui-button.ui-state-active:hover{border:1px solid #777;background:#4F5253;font-weight:normal;color:#fff}.ui-icon-background,.ui-state-active .ui-icon-background{border:#777;background-color:#fff}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#fff;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #337ab7;background:#337ab7;color:#fff}.ui-state-checked{border:1px solid #337ab7;background:#337ab7}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#fff}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #f1a899;background:#fddfdf;color:#5f3f3f}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#5f3f3f}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#5f3f3f}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url("images/ui-icons_4F5253_256x240.png")}.ui-widget-header .ui-icon{background-image:url("images/ui-icons_FFF_256x240.png")}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon,.ui-button:hover .ui-icon,.ui-button:focus .ui-icon{background-image:url("images/ui-icons_555555_256x240.png")}.ui-state-active .ui-icon,.ui-button:active .ui-icon{background-image:url("images/ui-icons_ffffff_256x240.png")}.ui-state-highlight .ui-icon,.ui-button .ui-state-highlight.ui-icon{background-image:url("images/ui-icons_fff_256x240.png")}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url("images/ui-icons_cc0000_256x240.png")}.ui-button .ui-icon{background-image:url("images/ui-icons_777777_256x240.png")}.ui-icon-blank{background-position:16px 16px}.ui-icon-caret-1-n{background-position:0 0}.ui-icon-caret-1-ne{background-position:-16px 0}.ui-icon-caret-1-e{background-position:-32px 0}.ui-icon-caret-1-se{background-position:-48px 0}.ui-icon-caret-1-s{background-position:-65px 0}.ui-icon-caret-1-sw{background-position:-80px 0}.ui-icon-caret-1-w{background-position:-96px 0}.ui-icon-caret-1-nw{background-position:-112px 0}.ui-icon-caret-2-n-s{background-position:-128px 0}.ui-icon-caret-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-65px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-65px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:1px -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:3px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:3px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:3px}.ui-widget-overlay{background:#aaa;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{-webkit-box-shadow:0 0 5px #666;box-shadow:0 0 5px #666} \ No newline at end of file diff --git a/app/assets/vendor/jquery-ui/datepicker/images/ui-bg_flat_0_aaaaaa_40x100.png b/app/assets/vendor/jquery-ui/datepicker/images/ui-bg_flat_0_aaaaaa_40x100.png new file mode 100644 index 0000000..88f194b --- /dev/null +++ b/app/assets/vendor/jquery-ui/datepicker/images/ui-bg_flat_0_aaaaaa_40x100.png @@ -0,0 +1,972 @@ + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + +Hello %{user_name}.
'\ - 'Your plan "%{plan_name}" has been submitted for feedback from an administrator at your organisation. '\ - 'If you have questions pertaining to this action, please contact us at %{organisation_email}.
') + _("Hello %{user_name}.
"\ + "Your plan \"%{plan_name}\" has been submitted for feedback from an + administrator at your organisation. "\ + "If you have questions pertaining to this action, please contact us + at %{organisation_email}.
") end def feedback_constant_to_text(text, user, plan, org) - _("#{text}") % {application_name: Rails.configuration.branding[:application][:name], - user_name: user.name, + _("#{text}") % { application_name: Rails.configuration.branding[:application][:name], + user_name: user.name(false), plan_name: plan.title, - organisation_email: org.contact_email} + organisation_email: org.contact_email } end + end diff --git a/app/helpers/orgs_helper.rb b/app/helpers/orgs_helper.rb index 91b503d..c90d10a 100644 --- a/app/helpers/orgs_helper.rb +++ b/app/helpers/orgs_helper.rb @@ -2,18 +2,18 @@ module OrgsHelper - DEFAULT_EMAIL = '%{organisation_email}' + EMAIL_PLACEHOLDER = "[Organisation Contact Email Placeholder]" - # Tooltip string for Org feedback form. + # Sample message for Org feedback form. # # org - The current Org we're updating feedback form for. # # Returns String - def tooltip_for_org_feedback_form(org) - email = org.contact_email.presence || DEFAULT_EMAIL - _("SAMPLE MESSAGE: A data librarian from %{org_name} will respond to your request within 48 + def sample_message_for_org_feedback_form(org) + email = org.contact_email || EMAIL_PLACEHOLDER + _("A data librarian from %{org_name} will respond to your request within 48 hours. If you have questions pertaining to this action please contact us - at %{organisation_email}.") % { + at %{organisation_email}.
") % { organisation_email: email, org_name: org.name } @@ -22,7 +22,7 @@ # The preferred logo url for the current configuration. If DRAGONFLY_AWS is true, return # the remote_url, otherwise return the url def logo_url_for_org(org) - if ENV['DRAGONFLY_AWS'] == "true" + if ENV["DRAGONFLY_AWS"] == "true" org.logo.remote_url else org.logo.url diff --git a/app/javascript/utils/datePicker.js b/app/javascript/utils/datePicker.js new file mode 100644 index 0000000..ba746bc --- /dev/null +++ b/app/javascript/utils/datePicker.js @@ -0,0 +1,16 @@ +import 'jquery-ui/ui/widgets/datepicker'; + +/* + * Date picker polyfill: + * Wire up the JQuery UI DatePicker if the browser does not support the HTML5 date + */ +export default () => { + if ($('[type="date"]').prop('type') !== 'date') { + $('[type="date"]').datepicker({ + dateFormat: 'yy-mm-dd', + constrainInput: true, + navigationAsDateFormat: true, + goToCurrent: true, + }); + } +}; diff --git a/app/javascript/utils/panelHeading.js b/app/javascript/utils/panelHeading.js index 670c048..534cad0 100644 --- a/app/javascript/utils/panelHeading.js +++ b/app/javascript/utils/panelHeading.js @@ -1,5 +1,5 @@ $(() => { - $('.heading-button').on('click', (e) => { + $('body').on('click', '.heading-button', (e) => { $(e.currentTarget) .find('i.fa-plus, i.fa-minus') .toggleClass('fa-plus') diff --git a/app/javascript/views/answers/edit.js b/app/javascript/views/answers/edit.js index 2ca15a1..a5fa338 100644 --- a/app/javascript/views/answers/edit.js +++ b/app/javascript/views/answers/edit.js @@ -5,6 +5,7 @@ } from '../../utils/isType'; import { Tinymce } from '../../utils/tinymce'; import debounce from '../../utils/debounce'; +import datePicker from '../../utils/datePicker'; import TimeagoFactory from '../../utils/timeagoFactory'; $(() => { @@ -184,6 +185,9 @@ editor.setMode('readonly'); }); } + + datePicker(); + // Example answer toggle const toggleIcon = (e) => { $(e.target) diff --git a/app/javascript/views/usage/index.js b/app/javascript/views/usage/index.js index edf7949..0873b2b 100644 --- a/app/javascript/views/usage/index.js +++ b/app/javascript/views/usage/index.js @@ -25,6 +25,27 @@ return rangeDates; }; + + // Register a plugin for displaying a message for no data + Chart.plugins.register({ + afterDraw: (chart) => { + if (chart.data.datasets.length === 0) { + const { ctx, width, height } = { + ctx: chart.chart.ctx, + width: chart.chart.width, + height: chart.chart.height, + }; + chart.clear(); + ctx.save(); + ctx.textAlign = 'center'; + ctx.textBaseline = 'middle'; + ctx.font = '25px bold'; + ctx.fillText('No data to display for selected time period', width / 2, height / 2); + ctx.restore(); + } + }, + }); + const createChart = ({ selector, data, appendTolabel = '' } = {}) => { new Chart($(selector), { // eslint-disable-line no-new type: 'bar', @@ -161,15 +182,21 @@ }; const yAxisLabel = date => moment(date).format('MMM-YY'); - const drawHorizontalBar = (canvasSelector, data) => { + const drawHorizontalBar = (canvasSelector, data, aspectRatio = 1) => { const chart = new Chart(canvasSelector, { // eslint-disable-line no-new type: 'horizontalBar', data, options: { + responsive: true, + maintainAspectRatio: true, + aspectRatio, scales: { xAxes: [{ - ticks: { beginAtZero: true }, - precision: 1, + ticks: { beginAtZero: true, stepSize: 10 }, + stacked: true, + }], + yAxes: [{ + stacked: true, }], }, }, @@ -179,7 +206,6 @@ const buildData = (data) => { const labels = data.map(current => yAxisLabel(current.date)); - const datasetsMap = data.reduce((acc, statCreatedPlan) => { statCreatedPlan.by_template.forEach((template) => { if (!acc[template.name]) { @@ -189,13 +215,32 @@ }); return acc; }, {}); - - const datasets = Object.keys(datasetsMap).map(key => datasetsMap[key]); - + // const datasets = Object.keys(datasetsMap).map(key => datasetsMap[key]); + const compare = (a, b) => { + const aIndex = labels.indexOf(a.y); + const bIndex = labels.indexOf(b.y); + if (aIndex > bIndex) return 1; + if (aIndex < bIndex) return -1; + return 0; + }; + const datasets = Object.keys(datasetsMap).map((key) => { + const datasetByKey = datasetsMap[key]; + const availableMonths = datasetByKey.data.reduce((acc, value) => { + // month has y as key + acc.push(value.y); + return acc; + }, []); + // Find missing months in data + const missingMonths = labels.filter(month => !availableMonths.includes(month)); + // Add data for missing months with x value set to 0 + missingMonths.forEach(month => datasetByKey.data.push({ x: 0, y: month })); + datasetByKey.data = datasetByKey.data.sort(compare); + return datasetByKey; + }); return { labels, datasets }; }; - const fetch = (lastDayOfMonth) => { + const fetch = (lastDayOfMonth, aspectRatio = 1) => { const baseUrl = $('select[name="monthly_plans_by_template"]').attr('data-url'); $.ajax({ url: `${baseUrl}?start_date=${lastDayOfMonth}`, @@ -205,14 +250,60 @@ if (drawnChart) { drawnChart.destroy(); } - drawnChart = drawHorizontalBar($(canvasSelector), chartData); + drawnChart = drawHorizontalBar($(canvasSelector), chartData, aspectRatio); }); }; + // Set Aspect Rate (width of X-axis/height of Y-axis) based on + // choice of selectedLastDayOfMonth in Time picker string value. Note aspect + const getAspectRatio = (selectedLastDayOfMonth) => { + let aspectRatio; + try { + const now = new Date(); + const dateOfSelectedMonth = new Date(selectedLastDayOfMonth); + const diff = new Date(now.getTime() - dateOfSelectedMonth.getTime()); + const diffInMonths = diff.getUTCMonth(); + + switch (diffInMonths) { + case 0: + case 1: + aspectRatio = 5; + break; + case 2: + case 3: + aspectRatio = 3.5; + break; + case 4: + case 5: + case 6: + aspectRatio = 2.5; + break; + case 7: + case 8: + case 9: + case 10: + aspectRatio = 2; + break; + case 11: + case 12: + aspectRatio = 1.5; + break; + default: + aspectRatio = 0.9; + } + } catch (e) { + aspectRatio = 0.9; + } + + return aspectRatio; + }; + const handler = () => { const selectedMonth = jQuerySelectorSelect.val(); + if (selectedMonth) { - fetch(selectedMonth); + const aspectRatio = getAspectRatio(selectedMonth); + fetch(selectedMonth, aspectRatio); } }; diff --git a/app/mailers/user_mailer.rb b/app/mailers/user_mailer.rb index d4a6dd5..1553635 100644 --- a/app/mailers/user_mailer.rb +++ b/app/mailers/user_mailer.rb @@ -73,6 +73,7 @@ if recipient.active? FastGettext.with_locale FastGettext.default_locale do mail(to: recipient.email, + from: requestor.org.contact_email, subject: _("%{application_name}: Expert feedback has been provided for %{plan_title}") % {application_name: Rails.configuration.branding[:application][:name], plan_title: @plan.title}) end end @@ -111,19 +112,21 @@ # commenter - User who wrote the comment # plan - Plan for which the comment is associated to - # def new_comment(commenter, plan) - # if commenter.is_a?(User) && plan.is_a?(Plan) - # owner = plan.owner - # if owner.present? && owner.active? - # @commenter = commenter - # @plan = plan - # FastGettext.with_locale FastGettext.default_locale do - # mail(to: plan.owner.email, subject: - # _('%{tool_name}: A new comment was added to %{plan_title}') %{ :tool_name => Rails.configuration.branding[:application][:name], :plan_title => plan.title }) - # end - # end - # end - # end + # answer - Answer commented on + def new_comment(commenter, plan, answer) + if commenter.is_a?(User) && plan.is_a?(Plan) + owner = plan.owner + if owner.present? && owner.active? + @commenter = commenter + @plan = plan + @answer = answer + FastGettext.with_locale FastGettext.default_locale do + mail(to: plan.owner.email, subject: + _('%{tool_name}: A new comment was added to %{plan_title}') %{ :tool_name => Rails.configuration.branding[:application][:name], :plan_title => plan.title }) + end + end + end + end def admin_privileges(user) @user = user diff --git a/app/models/concerns/exportable_plan.rb b/app/models/concerns/exportable_plan.rb index 8001a14..2c15056 100644 --- a/app/models/concerns/exportable_plan.rb +++ b/app/models/concerns/exportable_plan.rb @@ -151,10 +151,12 @@ if answer.present? || (answer.blank? && unanswered) answer_text = answer.present? ? answer.text : (unanswered ? _("Not Answered") : "") - if answer.present? && answer.question_options.any? - answer_text = answer.question_options.pluck(:text).join(", ") + if answer.present? && answer.is_valid? && answer.question_options.any? + answer_text = answer.question_options.pluck(:text).join(", ") + + " " + answer_text end end + single_line_answer_for_csv = sanitize_text(answer_text).gsub(/\r|\n/, " ") flds = (hash[:phases].many? ? [phase[:title]] : []) if headings if question[:text].is_a? String @@ -165,10 +167,9 @@ question[:text][0]) end flds << [ section[:title], sanitize_text(question_text), - sanitize_text(answer_text) - ] + single_line_answer_for_csv ] else - flds << [ sanitize_text(answer_text) ] + flds << [ single_line_answer_for_csv ] end csv << flds.flatten end diff --git a/app/models/guidance.rb b/app/models/guidance.rb index d3d7ab9..a0b9d19 100644 --- a/app/models/guidance.rb +++ b/app/models/guidance.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Guidance provides information from organisations to Users, helping them when # answering questions. (e.g. "Here's how to think about your data # protection responsibilities...") @@ -24,12 +26,15 @@ # [+Project:+] DMPRoadmap # [+Description:+] -# This class keeps the information organisations enter to support users when answering questions. -# It always belongs to a guidance group class and it can be linked directly to a question or through one or more themes +# This class keeps the information organisations enter to support users +# when answering questions. +# It always belongs to a guidance group class and it can be linked directly +# to a question or through one or more themes # [+Created:+] 07/07/2014 # [+Copyright:+] Digital Curation Centre and California Digital Library class Guidance < ActiveRecord::Base + include GlobalHelpers include ValidationMessages include ValidationValues @@ -52,7 +57,7 @@ validates :guidance_group, presence: { message: PRESENCE_MESSAGE } validates :published, inclusion: { message: INCLUSION_MESSAGE, - in: BOOLEAN_VALUES} + in: BOOLEAN_VALUES } validates :themes, presence: { message: PRESENCE_MESSAGE }, if: :published? @@ -64,7 +69,8 @@ scope :search, -> (term) { search_pattern = "%#{term}%" joins(:guidance_group) - .where("guidances.text LIKE ? OR guidance_groups.name LIKE ?", + .where("lower(guidances.text) LIKE lower(?) OR " + + "lower(guidance_groups.name) LIKE lower(?)", search_pattern, search_pattern) } @@ -120,10 +126,10 @@ # Returns Array def self.all_viewable(user) managing_groups = Org.includes(guidance_groups: :guidances) - .managing_orgs.collect{|o| o.guidance_groups} + .managing_orgs.collect { |o| o.guidance_groups } # find all groups owned by a Funder organisation funder_groups = Org.includes(guidance_groups: :guidances) - .funder.collect{|org| org.guidance_groups} + .funder.collect { |org| org.guidance_groups } # find all groups owned by any of the user's organisations organisation_groups = user.org.guidance_groups @@ -152,4 +158,5 @@ end return false end + end diff --git a/app/models/guidance_group.rb b/app/models/guidance_group.rb index ceba74f..45074d0 100644 --- a/app/models/guidance_group.rb +++ b/app/models/guidance_group.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # Set of Guidances that pertain to a certain category of Users (e.g. Maths # department, vs Biology department) # @@ -23,6 +25,7 @@ # class GuidanceGroup < ActiveRecord::Base + include GlobalHelpers include ValidationValues include ValidationMessages @@ -62,7 +65,7 @@ scope :search, lambda { |term| search_pattern = "%#{term}%" - where("name LIKE ?", search_pattern) + where("lower(name) LIKE lower(?)", search_pattern) } scope :published, -> { where(published: true) } @@ -125,4 +128,5 @@ all_viewable_groups = all_viewable_groups.flatten.uniq all_viewable_groups end + end diff --git a/app/models/org.rb b/app/models/org.rb index 209435d..bd8ee18 100644 --- a/app/models/org.rb +++ b/app/models/org.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # == Schema Information # # Table name: orgs @@ -35,6 +37,7 @@ # class Org < ActiveRecord::Base + include ValidationMessages include ValidationValues include FeedbacksHelper @@ -45,8 +48,10 @@ LOGO_FORMATS = %w[jpeg png gif jpg bmp].freeze - # Stores links as an JSON object: { org: [{"link":"www.example.com","text":"foo"}, ...] } - # The links are validated against custom validator allocated at validators/template_links_validator.rb + # Stores links as an JSON object: + # { org: [{"link":"www.example.com","text":"foo"}, ...] } + # The links are validated against custom validator allocated at + # validators/template_links_validator.rb serialize :links, JSON @@ -66,7 +71,9 @@ has_many :annotations - has_and_belongs_to_many :token_permission_types, join_table: "org_token_permissions", unique: true + has_and_belongs_to_many :token_permission_types, + join_table: "org_token_permissions", + unique: true has_many :org_identifiers @@ -87,10 +94,12 @@ validates :language, presence: { message: PRESENCE_MESSAGE } - validates :contact_name, presence: { message: PRESENCE_MESSAGE, if: :feedback_enabled } + validates :contact_name, presence: { message: PRESENCE_MESSAGE, + if: :feedback_enabled } validates :contact_email, email: { allow_nil: true }, - presence: { message: PRESENCE_MESSAGE, if: :feedback_enabled } + presence: { message: PRESENCE_MESSAGE, + if: :feedback_enabled } validates :org_type, presence: { message: PRESENCE_MESSAGE } @@ -104,9 +113,12 @@ if: :feedback_enabled } validates_property :format, of: :logo, in: LOGO_FORMATS, - message: _("must be one of the following formats: jpeg, jpg, png, gif, bmp") + message: _("must be one of the following formats: " + + "jpeg, jpg, png, gif, bmp") - validates_size_of :logo, maximum: 500.kilobytes, message: _("can't be larger than 500KB") + validates_size_of :logo, + maximum: 500.kilobytes, + message: _("can't be larger than 500KB") # allow validations for logo upload dragonfly_accessor :logo do @@ -122,7 +134,7 @@ 4 => :research_institute, 5 => :project, 6 => :school, - column: 'org_type' + column: "org_type" # Predefined queries for retrieving the managain organisation and funders scope :managing_orgs, -> do @@ -131,7 +143,19 @@ scope :search, -> (term) { search_pattern = "%#{term}%" - where("orgs.name LIKE ? OR orgs.contact_email LIKE ?", search_pattern, search_pattern) + where("lower(orgs.name) LIKE lower(?) OR " + + "lower(orgs.contact_email) LIKE lower(?)", + search_pattern, search_pattern) + } + + # Scope used in several controllers + scope :with_template_and_user_counts, -> { + joins("LEFT OUTER JOIN templates ON orgs.id = templates.org_id") + .joins("LEFT OUTER JOIN users ON orgs.id = users.org_id") + .group("orgs.id") + .select("orgs.*, + count(distinct templates.family_id) as template_count, + count(users.id) as user_count") } before_validation :set_default_feedback_email_subject @@ -170,7 +194,7 @@ ret << "Research Institute" if self.research_institute? ret << "Project" if self.project? ret << "School" if self.school? - return (ret.length > 0 ? ret.join(', ') : "None") + return (ret.length > 0 ? ret.join(", ") : "None") end def funder_only? @@ -207,7 +231,7 @@ def org_admins User.joins(:perms).where("users.org_id = ? AND perms.name IN (?)", self.id, - ['grant_permissions', 'modify_templates', 'modify_guidance', 'change_org_details']) + ["grant_permissions", "modify_templates", "modify_guidance", "change_org_details"]) end def plans @@ -219,7 +243,8 @@ end def grant_api!(token_permission_type) - self.token_permission_types << token_permission_type unless self.token_permission_types.include? token_permission_type + self.token_permission_types << token_permission_type unless + self.token_permission_types.include? token_permission_type end private @@ -230,7 +255,7 @@ def resize_image unless logo.nil? if logo.height != 100 - self.logo = logo.thumb('x100') # resize height and maintain aspect ratio + self.logo = logo.thumb("x100") # resize height and maintain aspect ratio end end end @@ -247,7 +272,7 @@ # Attempt to locate the file by name. If it exists update the uid logo = Dir.glob("#{data_store_path}/**/*#{self.logo_name}") if !logo.empty? - self.logo_uid = logo.first.gsub(data_store_path, '') + self.logo_uid = logo.first.gsub(data_store_path, "") else # Otherwise the logo is missing so clear it to prevent save failures self.logo = nil @@ -264,11 +289,12 @@ # creates a dfefault Guidance Group on create on the Org def create_guidance_group - GuidanceGroup.create!({ - name: abbreviation? ? self.abbreviation : self.name , + GuidanceGroup.create!( + name: abbreviation? ? self.abbreviation : self.name, org: self, optional_subset: false, published: false, - }) + ) end + end diff --git a/app/models/plan.rb b/app/models/plan.rb index d0f3ad7..daf3687 100644 --- a/app/models/plan.rb +++ b/app/models/plan.rb @@ -193,7 +193,7 @@ scope :search, lambda { |term| search_pattern = "%#{term}%" joins(:template) - .where("plans.title LIKE ? OR templates.title LIKE ?", + .where("lower(plans.title) LIKE lower(?) OR lower(templates.title) LIKE lower(?)", search_pattern, search_pattern) } @@ -353,9 +353,13 @@ if save! # Send an email confirmation to the owners and co-owners - deliver_if(recipients: owner_and_coowners, key: "users.feedback_provided") do |r| - UserMailer.feedback_complete(r, self, org_admin).deliver_now - end + deliver_if(recipients: owner_and_coowners, + key: "users.feedback_provided") do |r| + UserMailer.feedback_complete( + r, + self, + org_admin).deliver_now + end true else false @@ -541,7 +545,7 @@ # # Returns Boolean def visibility_allowed? - !is_test? && phases.select{ |phase| phase.visibility_allowed?(self) }.any? + !is_test? && phases.select { |phase| phase.visibility_allowed?(self) }.any? end # Determines whether or not a question (given its id) exists for the self plan diff --git a/app/models/stat_created_plan.rb b/app/models/stat_created_plan.rb index 0f0bd35..8decf3b 100644 --- a/app/models/stat_created_plan.rb +++ b/app/models/stat_created_plan.rb @@ -21,7 +21,9 @@ serialize :details, JSON def by_template - by_template = self.details["by_template"] + if self.details.present? + by_template = self.details["by_template"] + end return [] unless by_template.present? by_template end @@ -50,7 +52,7 @@ end.call(created_plans) data = created_plans.map do |created_plan| - tuple = { date: created_plan.date } + tuple = { Date: created_plan.date.strftime("%b %Y") } template_names.reduce(tuple) do |acc, name| acc[name] = 0 acc @@ -58,11 +60,10 @@ created_plan.details&.fetch("by_template", [])&.each do |name_count| tuple[name_count.fetch("name")] = name_count.fetch("count") end - tuple[:count] = created_plan.count + tuple[:Count] = created_plan.count tuple end - - Csvable.from_array_of_hashes(data) + Csvable.from_array_of_hashes(data, false) end end diff --git a/app/models/stat_created_plan/create_or_update.rb b/app/models/stat_created_plan/create_or_update.rb index cfc5d32..8802105 100644 --- a/app/models/stat_created_plan/create_or_update.rb +++ b/app/models/stat_created_plan/create_or_update.rb @@ -52,10 +52,16 @@ .administrator .merge(users(org)) .merge(plans(start_date: start_date, end_date: end_date)) - .select(:plan_id) - .distinct - template_counts = Plan.where(id: roleable_plan_ids).group(:template_id).count - template_names = Template.where(id: template_counts.keys).pluck(:id, :title) + .pluck(:plan_id) + .uniq + + template_counts = Plan.joins(:template).where(id: roleable_plan_ids) + .group("templates.family_id").count + most_recent_versions = Template.where(family_id: template_counts.keys) + .group(:family_id).maximum("version") + most_recent_versions = most_recent_versions.map { |k, v| "#{k}=#{v}" } + template_names = Template.where("CONCAT(family_id, '=', version) IN (?)", + most_recent_versions).pluck(:family_id, :title) template_names.map do |t| { name: t[1], count: template_counts[t[0]] } end diff --git a/app/models/template.rb b/app/models/template.rb index f19f526..31d4ef4 100644 --- a/app/models/template.rb +++ b/app/models/template.rb @@ -187,8 +187,10 @@ # Retrieves unarchived templates whose title or org.name includes the term # passed scope :search, lambda { |term| - unarchived.joins(:org).where("templates.title LIKE :term OR orgs.name LIKE :term", - term: "%#{term}%") + unarchived.joins(:org) + .where("lower(templates.title) LIKE lower(:term) OR " + + "lower(orgs.name) LIKE lower(:term)", + term: "%#{term}%") } diff --git a/app/models/theme.rb b/app/models/theme.rb index 640c5a0..49ed5eb 100644 --- a/app/models/theme.rb +++ b/app/models/theme.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # == Schema Information # # Table name: themes @@ -12,6 +14,7 @@ # class Theme < ActiveRecord::Base + include ValidationMessages include Dmpopidor::Models::Theme @@ -40,7 +43,8 @@ scope :search, -> (term) { search_pattern = "%#{term}%" - where("title LIKE ? OR description LIKE ?", search_pattern, search_pattern) + where("lower(title) LIKE lower(?) OR description LIKE lower(?)", + search_pattern, search_pattern) } # =========================== @@ -51,6 +55,7 @@ # # Returns String def to_s - title + title end + end diff --git a/app/models/user.rb b/app/models/user.rb index 56c0587..8ee3d1b 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + # == Schema Information # # Table name: users @@ -48,6 +50,7 @@ # class User < ActiveRecord::Base + include ConditionalUserMailer include ValidationMessages include ValidationValues @@ -59,7 +62,7 @@ # :lockable, :timeoutable and :omniauthable devise :invitable, :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, :omniauthable, - :omniauth_providers => [:shibboleth, :orcid] + omniauth_providers: [:shibboleth, :orcid] ## @@ -95,7 +98,7 @@ has_many :identifier_schemes, through: :user_identifiers has_and_belongs_to_many :notifications, dependent: :destroy, - join_table: 'notification_acknowledgements' + join_table: "notification_acknowledgements" # =============== @@ -118,8 +121,14 @@ # Retrieves all of the org_admins for the specified org scope :org_admins, -> (org_id) { - joins(:perms).where("users.org_id = ? AND perms.name IN (?) AND users.active = ?", org_id, - ['grant_permissions', 'modify_templates', 'modify_guidance', 'change_org_details'], true) + joins(:perms).where("users.org_id = ? AND perms.name IN (?) AND " + + "users.active = ?", + org_id, + ["grant_permissions", + "modify_templates", + "modify_guidance", + "change_org_details"], + true) } scope :search, -> (term) { @@ -128,9 +137,12 @@ # or concat functions do not exist for sqlite, we have to come up with this # conditional if ActiveRecord::Base.connection.adapter_name == "Mysql2" - where("concat_ws(' ', firstname, surname) LIKE ? OR email LIKE ?", search_pattern, search_pattern) + where("lower(concat_ws(' ', firstname, surname)) LIKE lower(?) OR " + + "lower(email) LIKE lower(?)", + search_pattern, search_pattern) else - where("firstname || ' ' || surname LIKE ? OR email LIKE ?", search_pattern, search_pattern) + where("lower(firstname || ' ' || surname) LIKE lower(?) OR " + + "email LIKE lower(?)", search_pattern, search_pattern) end } @@ -390,4 +402,5 @@ def clear_other_organisation self.other_organisation = nil end + end diff --git a/app/views/answers/_new_edit.html.erb b/app/views/answers/_new_edit.html.erb index ad6a1e4..67db511 100644 --- a/app/views/answers/_new_edit.html.erb +++ b/app/views/answers/_new_edit.html.erb @@ -6,7 +6,9 @@ <% q_format = question.question_format %> <% if q_format.rda_metadata? %>- <%= sanitize question.text %> +
- <%= sanitize question.text %> +