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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jquery-ui/ui-bg_flat_0_aaaaaa_40x100.png at master ยท jquery/jquery-ui + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Skip to content +
+ + + + + + + + + + + +
+ +
+ +
+ +
+ + + +
+
+
+ + + + + + + + + + + +
+
+ +
    + + + +
  • +
    + +
    + + + Watch + + +
    + Notifications +
    +
    + + + + + + + +
    +
    +
    + +
    +
  • + +
  • +
    +
    + + +
    +
    + + +
    + +
  • + +
  • +
    + + Fork + +
    + +

    Fork jquery-ui

    +
    +
    + +
    +

    If this dialog fails to load, you can visit the fork page directly.

    +
    +
    +
    +
    + + +
  • +
+ +

+ + /jquery-ui + +

+ +
+ + + + +
+
+
+ + + + + + + + Permalink + + + + + +
+ +
+ + Branch: + master + + + + + + + +
+ +
+ + Find file + + + Copy path + +
+ +
+ + + +
+ + +
+ +
+ + + 2 contributors + + +
+ +

Users who have contributed to this file

+
+ + + +
+
+ + @TravisCarden + + @PeterDaveHello + + +
+
+ + + + + +
+ +
+ +
+ 86 Bytes +
+ +
+ + + + +
+ +
+ +
+
+
+ + + +
+
+ ui-bg_flat_0_aaaaaa_40x100.png +
+
+ +
+ + + +
+ + +
+ + +
+
+ + + +
+ +
+ +
+
+ + +
+ + + + + + +
+ + + You canโ€™t perform that action at this time. +
+ + + + + + + + + +
+ + You signed in with another tab or window. Reload to refresh your session. + You signed out in another tab or window. Reload to refresh your session. +
+ + + + +
+ + + + diff --git a/app/assets/vendor/jquery-ui/datepicker/images/ui-icons_444444_256x240.png b/app/assets/vendor/jquery-ui/datepicker/images/ui-icons_444444_256x240.png new file mode 100644 index 0000000..9221438 --- /dev/null +++ b/app/assets/vendor/jquery-ui/datepicker/images/ui-icons_444444_256x240.png Binary files differ diff --git a/app/assets/vendor/jquery-ui/datepicker/images/ui-icons_555555_256x240.png b/app/assets/vendor/jquery-ui/datepicker/images/ui-icons_555555_256x240.png new file mode 100644 index 0000000..c974ed9 --- /dev/null +++ b/app/assets/vendor/jquery-ui/datepicker/images/ui-icons_555555_256x240.png @@ -0,0 +1,993 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jquery-ui/ui-icons_555555_256x240.png at master ยท jquery/jquery-ui + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Skip to content +
+ + + + + + + + + + + +
+ +
+ +
+ +
+ + + +
+
+
+ + + + + + + + + + + +
+
+ +
    + + + +
  • +
    + +
    + + + Watch + + +
    + Notifications +
    +
    + + + + + + + +
    +
    +
    + +
    +
  • + +
  • +
    +
    + + +
    +
    + + +
    + +
  • + +
  • +
    + + Fork + +
    + +

    Fork jquery-ui

    +
    +
    + +
    +

    If this dialog fails to load, you can visit the fork page directly.

    +
    +
    +
    +
    + + +
  • +
+ +

+ + /jquery-ui + +

+ +
+ + + + +
+
+
+ + + + + + + + Permalink + + + + + +
+ +
+ + Branch: + master + + + + + + + +
+ +
+ + Find file + + + Copy path + +
+ +
+ + + +
+ + +
+ +
+ + + 5 contributors + + +
+ +

Users who have contributed to this file

+
+ + + +
+
+ + @scottgonzalez + + @peritpatrio + + @jaspermdegroot + + @joliss + + @PeterDaveHello + + +
+
+ + + + + +
+ +
+ +
+ 3.2 KB +
+ +
+ + + + +
+ +
+ +
+
+
+ + + +
+
+ ui-icons_555555_256x240.png +
+
+ +
+ + + +
+ + +
+ + +
+
+ + + +
+ +
+ +
+
+ + +
+ + + + + + +
+ + + You canโ€™t perform that action at this time. +
+ + + + + + + + + +
+ + You signed in with another tab or window. Reload to refresh your session. + You signed out in another tab or window. Reload to refresh your session. +
+ + + + +
+ + + + diff --git a/app/assets/vendor/jquery-ui/datepicker/images/ui-icons_777620_256x240.png b/app/assets/vendor/jquery-ui/datepicker/images/ui-icons_777620_256x240.png new file mode 100644 index 0000000..1ba9301 --- /dev/null +++ b/app/assets/vendor/jquery-ui/datepicker/images/ui-icons_777620_256x240.png @@ -0,0 +1,993 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jquery-ui/ui-icons_777620_256x240.png at master ยท jquery/jquery-ui + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Skip to content +
+ + + + + + + + + + + +
+ +
+ +
+ +
+ + + +
+
+
+ + + + + + + + + + + +
+
+ +
    + + + +
  • +
    + +
    + + + Watch + + +
    + Notifications +
    +
    + + + + + + + +
    +
    +
    + +
    +
  • + +
  • +
    +
    + + +
    +
    + + +
    + +
  • + +
  • +
    + + Fork + +
    + +

    Fork jquery-ui

    +
    +
    + +
    +

    If this dialog fails to load, you can visit the fork page directly.

    +
    +
    +
    +
    + + +
  • +
+ +

+ + /jquery-ui + +

+ +
+ + + + +
+
+
+ + + + + + + + Permalink + + + + + +
+ +
+ + Branch: + master + + + + + + + +
+ +
+ + Find file + + + Copy path + +
+ +
+ + + +
+ + +
+ +
+ + + 5 contributors + + +
+ +

Users who have contributed to this file

+
+ + + +
+
+ + @scottgonzalez + + @peritpatrio + + @jaspermdegroot + + @joliss + + @PeterDaveHello + + +
+
+ + + + + +
+ +
+ +
+ 3.19 KB +
+ +
+ + + + +
+ +
+ +
+
+
+ + + +
+
+ ui-icons_777620_256x240.png +
+
+ +
+ + + +
+ + +
+ + +
+
+ + + +
+ +
+ +
+
+ + +
+ + + + + + +
+ + + You canโ€™t perform that action at this time. +
+ + + + + + + + + +
+ + You signed in with another tab or window. Reload to refresh your session. + You signed out in another tab or window. Reload to refresh your session. +
+ + + + +
+ + + + diff --git a/app/assets/vendor/jquery-ui/datepicker/images/ui-icons_777777_256x240.png b/app/assets/vendor/jquery-ui/datepicker/images/ui-icons_777777_256x240.png new file mode 100644 index 0000000..8d34c9a --- /dev/null +++ b/app/assets/vendor/jquery-ui/datepicker/images/ui-icons_777777_256x240.png @@ -0,0 +1,993 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jquery-ui/ui-icons_777777_256x240.png at master ยท jquery/jquery-ui + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Skip to content +
+ + + + + + + + + + + +
+ +
+ +
+ +
+ + + +
+
+
+ + + + + + + + + + + +
+
+ +
    + + + +
  • +
    + +
    + + + Watch + + +
    + Notifications +
    +
    + + + + + + + +
    +
    +
    + +
    +
  • + +
  • +
    +
    + + +
    +
    + + +
    + +
  • + +
  • +
    + + Fork + +
    + +

    Fork jquery-ui

    +
    +
    + +
    +

    If this dialog fails to load, you can visit the fork page directly.

    +
    +
    +
    +
    + + +
  • +
+ +

+ + /jquery-ui + +

+ +
+ + + + +
+
+
+ + + + + + + + Permalink + + + + + +
+ +
+ + Branch: + master + + + + + + + +
+ +
+ + Find file + + + Copy path + +
+ +
+ + + +
+ + +
+ +
+ + + 5 contributors + + +
+ +

Users who have contributed to this file

+
+ + + +
+
+ + @scottgonzalez + + @peritpatrio + + @jaspermdegroot + + @joliss + + @PeterDaveHello + + +
+
+ + + + + +
+ +
+ +
+ 3.19 KB +
+ +
+ + + + +
+ +
+ +
+
+
+ + + +
+
+ ui-icons_777777_256x240.png +
+
+ +
+ + + +
+ + +
+ + +
+
+ + + +
+ +
+ +
+
+ + +
+ + + + + + +
+ + + You canโ€™t perform that action at this time. +
+ + + + + + + + + +
+ + You signed in with another tab or window. Reload to refresh your session. + You signed out in another tab or window. Reload to refresh your session. +
+ + + + +
+ + + + diff --git a/app/assets/vendor/jquery-ui/datepicker/images/ui-icons_FFF_256x240.png b/app/assets/vendor/jquery-ui/datepicker/images/ui-icons_FFF_256x240.png new file mode 100644 index 0000000..60f8fb2 --- /dev/null +++ b/app/assets/vendor/jquery-ui/datepicker/images/ui-icons_FFF_256x240.png @@ -0,0 +1,993 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jquery-ui/ui-icons_ffffff_256x240.png at master ยท jquery/jquery-ui + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Skip to content +
+ + + + + + + + + + + +
+ +
+ +
+ +
+ + + +
+
+
+ + + + + + + + + + + +
+
+ +
    + + + +
  • +
    + +
    + + + Watch + + +
    + Notifications +
    +
    + + + + + + + +
    +
    +
    + +
    +
  • + +
  • +
    +
    + + +
    +
    + + +
    + +
  • + +
  • +
    + + Fork + +
    + +

    Fork jquery-ui

    +
    +
    + +
    +

    If this dialog fails to load, you can visit the fork page directly.

    +
    +
    +
    +
    + + +
  • +
+ +

+ + /jquery-ui + +

+ +
+ + + + +
+
+
+ + + + + + + + Permalink + + + + + +
+ +
+ + Branch: + master + + + + + + + +
+ +
+ + Find file + + + Copy path + +
+ +
+ + + +
+ + +
+ +
+ + + 5 contributors + + +
+ +

Users who have contributed to this file

+
+ + + +
+
+ + @scottgonzalez + + @peritpatrio + + @jaspermdegroot + + @joliss + + @PeterDaveHello + + +
+
+ + + + + +
+ +
+ +
+ 3.19 KB +
+ +
+ + + + +
+ +
+ +
+
+
+ + + +
+
+ ui-icons_ffffff_256x240.png +
+
+ +
+ + + +
+ + +
+ + +
+
+ + + +
+ +
+ +
+
+ + +
+ + + + + + +
+ + + You canโ€™t perform that action at this time. +
+ + + + + + + + + +
+ + You signed in with another tab or window. Reload to refresh your session. + You signed out in another tab or window. Reload to refresh your session. +
+ + + + +
+ + + + diff --git a/app/assets/vendor/jquery-ui/datepicker/images/ui-icons_cc0000_256x240.png b/app/assets/vendor/jquery-ui/datepicker/images/ui-icons_cc0000_256x240.png new file mode 100644 index 0000000..4afd18e --- /dev/null +++ b/app/assets/vendor/jquery-ui/datepicker/images/ui-icons_cc0000_256x240.png @@ -0,0 +1,993 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + jquery-ui/ui-icons_cc0000_256x240.png at master ยท jquery/jquery-ui + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Skip to content +
+ + + + + + + + + + + +
+ +
+ +
+ +
+ + + +
+
+
+ + + + + + + + + + + +
+
+ +
    + + + +
  • +
    + +
    + + + Watch + + +
    + Notifications +
    +
    + + + + + + + +
    +
    +
    + +
    +
  • + +
  • +
    +
    + + +
    +
    + + +
    + +
  • + +
  • +
    + + Fork + +
    + +

    Fork jquery-ui

    +
    +
    + +
    +

    If this dialog fails to load, you can visit the fork page directly.

    +
    +
    +
    +
    + + +
  • +
+ +

+ + /jquery-ui + +

+ +
+ + + + +
+
+
+ + + + + + + + Permalink + + + + + +
+ +
+ + Branch: + master + + + + + + + +
+ +
+ + Find file + + + Copy path + +
+ +
+ + + +
+ + +
+ +
+ + + 5 contributors + + +
+ +

Users who have contributed to this file

+
+ + + +
+
+ + @scottgonzalez + + @peritpatrio + + @jaspermdegroot + + @joliss + + @PeterDaveHello + + +
+
+ + + + + +
+ +
+ +
+ 3.19 KB +
+ +
+ + + + +
+ +
+ +
+
+
+ + + +
+
+ ui-icons_cc0000_256x240.png +
+
+ +
+ + + +
+ + +
+ + +
+
+ + + +
+ +
+ +
+
+ + +
+ + + + + + +
+ + + You canโ€™t perform that action at this time. +
+ + + + + + + + + +
+ + You signed in with another tab or window. Reload to refresh your session. + You signed out in another tab or window. Reload to refresh your session. +
+ + + + +
+ + + + diff --git a/app/controllers/answers_controller.rb b/app/controllers/answers_controller.rb index a2c5f4a..5b232d4 100644 --- a/app/controllers/answers_controller.rb +++ b/app/controllers/answers_controller.rb @@ -146,6 +146,10 @@ if !permitted[:id].present? permitted.delete(:id) end + # If no question options has been chosen. + if params[:answer][:question_option_ids].nil? + permitted[:question_option_ids] = [] + end permitted end diff --git a/app/controllers/api/v0/statistics_controller.rb b/app/controllers/api/v0/statistics_controller.rb index 6b3a121..c06ef51 100644 --- a/app/controllers/api/v0/statistics_controller.rb +++ b/app/controllers/api/v0/statistics_controller.rb @@ -28,6 +28,9 @@ r[k] = scoped.where(created_at: dates_to_range(v)).count end + # Reverse hash r, so dates in ascending order + r = Hash[r.to_a.reverse] + respond_to do |format| format.json { render(json: r.to_json) } format.csv { @@ -66,6 +69,9 @@ r[k] = scoped.where(created_at: dates_to_range(v)).count end + # Reverse hash r, so dates in ascending order + r = Hash[r.to_a.reverse] + respond_to do |format| format.json { render(json: r.to_json) } format.csv { @@ -104,6 +110,9 @@ r[k] = scoped.where(created_at: dates_to_range(v)).count end + # Reverse hash r, so dates in ascending order + r = Hash[r.to_a.reverse] + respond_to do |format| format.json { render(json: r.to_json) } format.csv { @@ -126,19 +135,23 @@ # Displays the number of DMPs using templates owned/create by the caller's Org # between the optional specified dates def using_template + org_templates = @user.org.templates.where(customization_of: nil) unless Api::V0::StatisticsPolicy.new(@user, org_templates.first).using_template? raise Pundit::NotAuthorizedError end - org_templates = @user.org.templates.where(customization_of: nil) @templates = {} org_templates.each do |template| if @templates[template.title].blank? - @templates[template.title] = {} + @templates[template.title] = {} @templates[template.title][:title] = template.title @templates[template.title][:id] = template.family_id + @templates[template.title][:uses] = 0 end - scoped = template.plans.where(plans: { created_at: dates_to_range(params) }) - @templates[template.title][:uses] = scoped.length + scoped = template.plans + if params["start_date"].present? || params["end_date"].present? + scoped = scoped.where(created_at: dates_to_range(params)) + end + @templates[template.title][:uses] += scoped.length end respond_with @templates end @@ -153,7 +166,11 @@ raise Pundit::NotAuthorizedError end @templates = {} - @user.org.plans.each do |plan| + scoped = @user.org.plans + if params["start_date"].present? || params["end_date"].present? + scoped = scoped.where(created_at: dates_to_range(params)) + end + scoped.each do |plan| # if hash exists if @templates[plan.template.title].blank? @templates[plan.template.title] = {} @@ -176,7 +193,11 @@ unless Api::V0::StatisticsPolicy.new(@user, :statistics).plans? raise Pundit::NotAuthorizedError end - respond_with @user.org.plans + @org_plans = @user.org.plans + if params["start_date"].present? || params["end_date"].present? + @org_plans = @org_plans.where(created_at: dates_to_range(params)) + end + respond_with @org_plans end diff --git a/app/controllers/notes_controller.rb b/app/controllers/notes_controller.rb index 287a1a0..09e7048 100644 --- a/app/controllers/notes_controller.rb +++ b/app/controllers/notes_controller.rb @@ -44,7 +44,7 @@ # plan = answer.plan # owner = plan.owner # deliver_if(recipients: owner, key: "users.new_comment") do |r| - # UserMailer.new_comment(current_user, plan).deliver_now() + # UserMailer.new_comment(current_user, plan, answer).deliver_now() # end # @notice = success_message(@note, _("created")) # render(json: { diff --git a/app/controllers/org_admin/plans_controller.rb b/app/controllers/org_admin/plans_controller.rb index 6265013..f2d8674 100644 --- a/app/controllers/org_admin/plans_controller.rb +++ b/app/controllers/org_admin/plans_controller.rb @@ -14,7 +14,7 @@ # feedback_ids = Role.where(user_id: current_user.id).reviewer.pluck(:plan_id).uniq # @feedback_plans = Plan.where(id: feedback_ids) - # @plans = current_user.org.plans + # @plans = current_user.org.plans.page(1) # end # GET org_admin/plans/:id/feedback_complete diff --git a/app/controllers/org_admin/templates_controller.rb b/app/controllers/org_admin/templates_controller.rb index ea57ead..cee3329 100644 --- a/app/controllers/org_admin/templates_controller.rb +++ b/app/controllers/org_admin/templates_controller.rb @@ -20,7 +20,7 @@ @orgs = Org.all @title = _("All Templates") - @templates = templates.includes(:org) + @templates = templates.includes(:org).page(1) @query_params = { sort_field: "templates.title", sort_direction: "asc" } @all_count = templates.length @published_count = published.present? ? published : 0 @@ -47,7 +47,7 @@ else _("Own Templates") end - @templates = templates + @templates = templates.page(1) @query_params = { sort_field: "templates.title", sort_direction: "asc" } @all_count = templates.length @published_count = published.present? ? published : 0 diff --git a/app/controllers/paginable/guidance_groups_controller.rb b/app/controllers/paginable/guidance_groups_controller.rb index 4605ffe..4cd3893 100644 --- a/app/controllers/paginable/guidance_groups_controller.rb +++ b/app/controllers/paginable/guidance_groups_controller.rb @@ -7,8 +7,11 @@ # /paginable/guidance_groups/index/:page def index authorize(Guidance) - paginable_renderise(partial: "index", - scope: GuidanceGroup.by_org(current_user.org)) + paginable_renderise( + partial: "index", + scope: GuidanceGroup.by_org(current_user.org), + query_params: { sort_field: "guidance_groups.name", sort_direction: :asc } + ) end end diff --git a/app/controllers/paginable/guidances_controller.rb b/app/controllers/paginable/guidances_controller.rb index 4ad8492..efec2eb 100644 --- a/app/controllers/paginable/guidances_controller.rb +++ b/app/controllers/paginable/guidances_controller.rb @@ -7,9 +7,12 @@ # /paginable/guidances/index/:page def index authorize(Guidance) - paginable_renderise(partial: "index", + paginable_renderise( + partial: "index", scope: Guidance.by_org(current_user.org) - .includes(:guidance_group, :themes)) + .includes(:guidance_group, :themes), + query_params: { sort_field: "guidances.text", sort_direction: :asc } + ) end end diff --git a/app/controllers/paginable/orgs_controller.rb b/app/controllers/paginable/orgs_controller.rb index 17c8e26..b561930 100644 --- a/app/controllers/paginable/orgs_controller.rb +++ b/app/controllers/paginable/orgs_controller.rb @@ -9,7 +9,7 @@ authorize(Org) paginable_renderise( partial: "index", - scope: Org.includes(:templates, :users), + scope: Org.with_template_and_user_counts, query_params: { sort_field: "orgs.name", sort_direction: :asc }) end diff --git a/app/controllers/paginable/plans_controller.rb b/app/controllers/paginable/plans_controller.rb index 6f15447..0ca5e69 100644 --- a/app/controllers/paginable/plans_controller.rb +++ b/app/controllers/paginable/plans_controller.rb @@ -12,7 +12,8 @@ end paginable_renderise( partial: "privately_visible", - scope: Plan.active(current_user) + scope: Plan.active(current_user), + query_params: { sort_field: 'plans.updated_at', sort_direction: :desc } ) end # GET /paginable/plans/organisationally_or_publicly_visible/:page @@ -22,7 +23,8 @@ end paginable_renderise( partial: "organisationally_or_publicly_visible", - scope: Plan.organisationally_or_publicly_visible(current_user) + scope: Plan.organisationally_or_publicly_visible(current_user), + query_params: { sort_field: 'plans.updated_at', sort_direction: :desc } ) end @@ -30,10 +32,23 @@ def publicly_visible paginable_renderise( partial: "publicly_visible", - scope: Plan.publicly_visible + scope: Plan.publicly_visible.includes(:template), + query_params: { sort_field: 'plans.updated_at', sort_direction: :desc } ) end + # GET /paginable/plans/org_admin/:page + # def org_admin + # unless current_user.present? && current_user.can_org_admin? + # raise Pundit::NotAuthorizedError + # end + # paginable_renderise( + # partial: "org_admin", + # scope: current_user.org.plans, + # query_params: { sort_field: 'plans.updated_at', sort_direction: :desc } + # ) + # end + # CHANGES: New Visibility # /paginable/plans/privately_private_visible/:page # Paginable for Privately Private Visibility @@ -44,19 +59,9 @@ end paginable_renderise( partial: "privately_private_visible", - scope: Plan.active(current_user) + scope: Plan.active(current_user), + query_params: { sort_field: 'plans.updated_at', sort_direction: :desc } ) end - # GET /paginable/plans/org_admin/:page - # def org_admin - # unless current_user.present? && current_user.can_org_admin? - # raise Pundit::NotAuthorizedError - # end - # paginable_renderise( - # partial: "org_admin", - # scope: current_user.org.plans - # ) - # end - end diff --git a/app/controllers/paginable/templates_controller.rb b/app/controllers/paginable/templates_controller.rb index 0fefd51..8f730f9 100644 --- a/app/controllers/paginable/templates_controller.rb +++ b/app/controllers/paginable/templates_controller.rb @@ -3,6 +3,7 @@ class Paginable::TemplatesController < ApplicationController include Dmpopidor::Controllers::Paginable::Templates + include CustomizableTemplateLinkHelper include Paginable # TODO: Clean up this code for Rubocop @@ -24,6 +25,7 @@ paginable_renderise( partial: "index", scope: templates.includes(:org), + query_params: { sort_field: 'templates.title', sort_direction: :asc }, locals: { action: "index" } ) end @@ -45,6 +47,7 @@ paginable_renderise( partial: "organisational", scope: templates, + query_params: { sort_field: 'templates.title', sort_direction: :asc }, locals: { action: "organisational" } ) end @@ -68,6 +71,7 @@ paginable_renderise( partial: "customisable", scope: templates.joins(:org).includes(:org), + query_params: { sort_field: 'templates.title', sort_direction: :asc }, locals: { action: "customisable", customizations: customizations } ) end @@ -86,6 +90,7 @@ # .includes(:org) # .where(id: templates.uniq.flatten) # .published + # query_params: { sort_field: 'templates.title', sort_direction: :asc } # ) # end @@ -99,6 +104,7 @@ paginable_renderise( partial: "history", scope: @templates, + query_params: { sort_field: 'templates.title', sort_direction: :asc }, locals: { current: @templates.maximum(:version) } ) end diff --git a/app/controllers/paginable/users_controller.rb b/app/controllers/paginable/users_controller.rb index c429e15..82eb578 100644 --- a/app/controllers/paginable/users_controller.rb +++ b/app/controllers/paginable/users_controller.rb @@ -16,6 +16,7 @@ # paginable_renderise( # partial: "index", # scope: scope, + # query_params: { sort_field: 'users.surname', sort_direction: :asc }, # view_all: !current_user.can_super_admin? # ) # end diff --git a/app/controllers/plan_exports_controller.rb b/app/controllers/plan_exports_controller.rb index 0e54236..5417fa0 100644 --- a/app/controllers/plan_exports_controller.rb +++ b/app/controllers/plan_exports_controller.rb @@ -67,8 +67,10 @@ end def show_docx + # Using and optional locals_assign export_format render docx: "#{file_name}.docx", - content: render_to_string(partial: "shared/export/plan") + content: render_to_string(partial: "shared/export/plan", + locals: { export_format: "docx" }) end def show_pdf @@ -81,7 +83,8 @@ }, font_size: 8, spacing: (Integer(@formatting[:margin][:bottom]) / 2) - 4, - right: "[page] of [topage]" + right: "[page] of [topage]", + encoding: "utf8" } end diff --git a/app/controllers/public_pages_controller.rb b/app/controllers/public_pages_controller.rb index 223ec42..6089d29 100644 --- a/app/controllers/public_pages_controller.rb +++ b/app/controllers/public_pages_controller.rb @@ -62,7 +62,7 @@ font_size: 8, spacing: (@formatting[:margin][:bottom] / 2) - 4, right: "[page] of [topage]", - encoding: 'utf8' + encoding: "utf8" } # rubocop:enable LineLength end @@ -77,7 +77,7 @@ # GET /plans_index # ------------------------------------------------------------------------------------ def plan_index - @plans = Plan.publicly_visible.page(1) + @plans = Plan.publicly_visible.includes(:template).page(1) render "plan_index", locals: { query_params: { sort_field: "plans.updated_at", diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index 8cd7c92..e2e25c0 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -191,6 +191,9 @@ successfully_updated = false else successfully_updated = current_user.update_with_password(password_update) + if !successfully_updated + message = _("Save unsuccessful. That email address is already registered. You must enter a unique email address.") + end end else # This case is never reached since this method when called with diff --git a/app/controllers/super_admin/orgs_controller.rb b/app/controllers/super_admin/orgs_controller.rb index c6fcd5b..5bff645 100644 --- a/app/controllers/super_admin/orgs_controller.rb +++ b/app/controllers/super_admin/orgs_controller.rb @@ -8,7 +8,9 @@ def index authorize Org - render "index", locals: { orgs: Org.includes(:templates, :users) } + render "index", locals: { + orgs: Org.with_template_and_user_counts.page(1) + } end def new diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index c41ec17..03558aa 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -19,9 +19,9 @@ # respond_to do |format| # format.html do # if current_user.can_super_admin? - # @users = User.page(1) + # @users = User.includes(:roles).page(1) # else - # @users = current_user.org.users.page(1) + # @users = current_user.org.users.includes(:roles).page(1) # end # end diff --git a/app/helpers/customizable_template_link_helper.rb b/app/helpers/customizable_template_link_helper.rb new file mode 100644 index 0000000..aad7542 --- /dev/null +++ b/app/helpers/customizable_template_link_helper.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +module CustomizableTemplateLinkHelper + + # Link to the appropriate customizable template. + # Default link name set if name not set which can be overwritten. + def link_to_customizable_template(name = nil, customization, template) + if customization.present? + if customization.created_at < template.created_at + name = name.blank? ? _("Transfer customisation") : name + link_to name, + org_admin_template_customization_transfers_path(customization.id), + data: { method: "post" } + else + name = name.blank? ? _("Edit customisation") : name + link_to name, org_admin_template_path(id: customization.id) + end + else + name = name.blank? ? _("Customise") : name + link_to name, + org_admin_template_customizations_path(template.id), + "data-method": "post" + end + end + +end diff --git a/app/helpers/exports_helper.rb b/app/helpers/exports_helper.rb index d60364b..5b9c416 100644 --- a/app/helpers/exports_helper.rb +++ b/app/helpers/exports_helper.rb @@ -3,18 +3,18 @@ module ExportsHelper PAGE_MARGINS = { - top: '5', + top: "5", bottom: "10", left: "12", right: "12", } def font_face - @formatting[:font_face].presence || 'Arial, Helvetica, Sans-Serif' + @formatting[:font_face].presence || "Arial, Helvetica, Sans-Serif" end def font_size - @formatting[:font_size].presence || '12' + @formatting[:font_size].presence || "12" end def margin_top @@ -36,7 +36,7 @@ def plan_attribution(attribution) attribution = Array(attribution) prefix = attribution.many? ? _("Creators:") : _("Creator:") - "#{prefix} #{attribution.join(', ')}" + "#{prefix} #{attribution.join(', ')}" end private @@ -49,4 +49,5 @@ @formatting.dig(:margin, side).presence || PAGE_MARGINS[side] end end -end \ No newline at end of file + +end diff --git a/app/helpers/feedbacks_helper.rb b/app/helpers/feedbacks_helper.rb index 15fca1b..713b192 100644 --- a/app/helpers/feedbacks_helper.rb +++ b/app/helpers/feedbacks_helper.rb @@ -1,18 +1,24 @@ +# frozen_string_literal: true + module FeedbacksHelper + def feedback_confirmation_default_subject - _('%{application_name}: Your plan has been submitted for feedback') + _("%{application_name}: Your plan has been submitted for feedback") end def feedback_confirmation_default_message - _('

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 %> +

<% answer_hash = answer.answer_hash %>
@@ -55,11 +57,13 @@ <% end %>
> <% if question.option_based? || question.question_format.rda_metadata? %> - <%= render(partial: 'questions/new_edit_question_option_based', locals: { f: f, question: question, answer: answer }) %> + <%= render(partial: 'questions/new_edit_question_option_based', locals: { f: f, question: question, answer: answer, readonly: readonly }) %> <% elsif question.question_format.textfield?%> <%= render(partial: 'questions/new_edit_question_textfield', locals: { f: f, question: question, answer: answer }) %> <% elsif question.question_format.textarea? %> - <%= render(partial: 'questions/new_edit_question_textarea', locals: { f: f, question: question, answer: answer, locking: locking, readonly: readonly}) %> + <%= render(partial: 'questions/new_edit_question_textarea', locals: { f: f, question: question, answer: answer, locking: locking, readonly: readonly }) %> + <% elsif question.question_format.date? %> + <%= render(partial: 'questions/new_edit_question_datefield', locals: { f: f, question: question, answer: answer, locking: locking, readonly: readonly }) %> <% end %> <%= f.button(_('Save'), class: "btn btn-default", type: "submit") %>
@@ -72,7 +76,7 @@ <%="#{annotation.org.abbreviation} "%> <%=_('example answer')%>
- <%= sanitize annotation.text %> +
<%= sanitize annotation.text %>
<% end %> diff --git a/app/views/branded/answers/_new_edit.html.erb b/app/views/branded/answers/_new_edit.html.erb index eec3f8d..b5f6180 100644 --- a/app/views/branded/answers/_new_edit.html.erb +++ b/app/views/branded/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 %> +

<% answer_hash = answer.answer_hash %>
@@ -58,15 +60,15 @@ <% end %>
> <% if question.option_based? || question.question_format.rda_metadata? %> - <%= render(partial: 'questions/new_edit_question_option_based', locals: { f: f, question: question, answer: answer, research_output: research_output }) %> + <%= render(partial: 'questions/new_edit_question_option_based', locals: { f: f, question: question, answer: answer, research_output: research_output, readonly: readonly }) %> <% elsif question.question_format.textfield?%> <%= render(partial: 'questions/new_edit_question_textfield', locals: { f: f, question: question, answer: answer, research_output: research_output }) %> - <% elsif question.question_format.date? %> - <%= render(partial: 'questions/new_edit_question_datefield', locals: { f: f, question: question, answer: answer, research_output: research_output }) %> - <% elsif question.question_format.number? %> - <%= render(partial: 'questions/new_edit_question_numberfield', locals: { f: f, question: question, answer: answer, research_output: research_output }) %> <% elsif question.question_format.textarea? %> <%= render(partial: 'questions/new_edit_question_textarea', locals: { f: f, question: question, answer: answer, research_output: research_output, locking: locking, readonly: readonly}) %> + <% elsif question.question_format.date? %> + <%= render(partial: 'questions/new_edit_question_datefield', locals: { f: f, question: question, answer: answer, research_output: research_output, readonly: readonly }) %> + <% elsif question.question_format.number? %> + <%= render(partial: 'questions/new_edit_question_numberfield', locals: { f: f, question: question, answer: answer, research_output: research_output, readonly: readonly }) %> <% end %> <%= f.button(_('Save'), class: "btn btn-default", type: "submit") %>
diff --git a/app/views/branded/guidance_groups/_index_by_theme.html.erb b/app/views/branded/guidance_groups/_index_by_theme.html.erb index 85ca9a9..8d8af27 100644 --- a/app/views/branded/guidance_groups/_index_by_theme.html.erb +++ b/app/views/branded/guidance_groups/_index_by_theme.html.erb @@ -1,15 +1,18 @@ <%# locals{ question, research_output, guidance_groups_by_theme } %> <% parent_id = guidance_groups_by_theme.object_id %>
- <% guidance_groups_by_theme.each_pair do |guidance_group, theme_hash| %> <% guidances_output = [] %> + <%# Do not show expand/collapse all links if there is only one item in theme_hash %> + <% if theme_hash.length > 1 %> + + <% end %> <% theme_hash.each_pair do |theme, guidances| %> <% question_guidance_id = "#{question.object_id}-#{guidances.object_id}-research-output-#{research_output.id}" %> <%# if guidances with this theme have not been output %> @@ -42,7 +45,9 @@ <% end %>

<% unless guidances_output.include?(guidance.id) %> - <%= sanitize(guidance.text) %> +

+ <%= sanitize(guidance.text) %> +
<% guidances_output << guidance.id %> <% multiple = true %> <% end %> diff --git a/app/views/branded/paginable/orgs/_index.html.erb b/app/views/branded/paginable/orgs/_index.html.erb new file mode 100644 index 0000000..caf5932 --- /dev/null +++ b/app/views/branded/paginable/orgs/_index.html.erb @@ -0,0 +1,44 @@ +
+ + + + + + + + + + + + + <% scope.each do |org| %> + + + + + + + + + <% end %> + +
<%= _('Organisation') %> <%= paginable_sort_link('orgs.name') %><%= _('Administrator Email') %> <%= paginable_sort_link('orgs.contact_email') %><%= _('Organisation Type(s)') %> <%= paginable_sort_link('orgs.org_type') %><%= _('Templates') %><%= _('Users') %><%= _('Actions') %>
<%= org.name %><%= org.contact_email %><%= org.org_type_to_s %><%= org.template_count %><%= org.users.uniq.length %> + +
+
diff --git a/app/views/branded/phases/_edit_plan_answers_research_outputs.html.erb b/app/views/branded/phases/_edit_plan_answers_research_outputs.html.erb index a1eb3e1..0761ce0 100644 --- a/app/views/branded/phases/_edit_plan_answers_research_outputs.html.erb +++ b/app/views/branded/phases/_edit_plan_answers_research_outputs.html.erb @@ -61,7 +61,11 @@ ><%= _('This section\'s answers are common to all research outputs') %>

<% end %> -
<%= sanitize section.description %>
+
+
+ <%= sanitize section.description %> +
+
<% section.questions.each_with_index do |question, i| %> <% # Load the answer or create a new one diff --git a/app/views/branded/questions/_new_edit_question_datefield.html.erb b/app/views/branded/questions/_new_edit_question_datefield.html.erb deleted file mode 100644 index fea2b98..0000000 --- a/app/views/branded/questions/_new_edit_question_datefield.html.erb +++ /dev/null @@ -1,5 +0,0 @@ -<%# locals: { f, question, answer, research_output } %> -
- <%= f.label(:text, raw(question.text), class: 'control-label') %> - <%= date_field_tag('answer[text]', strip_tags(answer.text || question.default_value), class: 'form-control') %> -
\ No newline at end of file diff --git a/app/views/branded/questions/_new_edit_question_option_based.html.erb b/app/views/branded/questions/_new_edit_question_option_based.html.erb index 6fc0b2b..8da3df7 100644 --- a/app/views/branded/questions/_new_edit_question_option_based.html.erb +++ b/app/views/branded/questions/_new_edit_question_option_based.html.erb @@ -41,6 +41,12 @@ <% if question.option_comment_display %> <% text = question.question_format.rda_metadata? ? answer.answer_hash['text'] : answer.text %> <%= label_tag('answer[text]', _('Additional Information'), class: 'control-label') %> - <%= text_area_tag('answer[text]', text, id: "answer-text-#{question.id}-research-output-#{research_output.id}", class: "form-control tinymce_answer") %> + <% if readonly %> +
+ <%= sanitize("

#{text}

") %> +
+ <% else %> + <%= text_area_tag('answer[text]', text, id: "answer-text-#{question.id}-research-output-#{research_output.id}", class: "form-control tinymce_answer") %> + <% end %> <% end %>
diff --git a/app/views/branded/questions/_new_edit_question_textarea.html.erb b/app/views/branded/questions/_new_edit_question_textarea.html.erb index e1bfc1f..c4d0315 100644 --- a/app/views/branded/questions/_new_edit_question_textarea.html.erb +++ b/app/views/branded/questions/_new_edit_question_textarea.html.erb @@ -7,10 +7,14 @@ rather cumbersome. As such, this workaround, simplifies the logic when a stale answer is found by rendering the html of the answer directly within a paragraph. %> -
- <%= f.label(:text, sanitize(question.text), class: 'control-label') %> +
+
+ <%= f.label(:text, sanitize(question.text), class: 'control-label') %> +
<% if locking || readonly %> - <%= sanitize("

#{answer.text || question.default_value}

") %> +
+ <%= sanitize("

#{answer.text || question.default_value}

") %> +
<% else %> <%= text_area_tag('answer[text]', answer.text || question.default_value, id: "answer-text-#{question.id}-research-output-#{research_output.id}", class: "form-control tinymce_answer") %> <% end %> diff --git a/app/views/branded/shared/export/_export_by_question.erb b/app/views/branded/shared/export/_export_by_question.erb index 8fb2e7f..1ae2bbc 100644 --- a/app/views/branded/shared/export/_export_by_question.erb +++ b/app/views/branded/shared/export/_export_by_question.erb @@ -14,7 +14,13 @@ <% if !@public_plan && @show_sections_questions && idx == 0 %>

-

<%= sanitize question[:text].to_s, scrubber: TableFreeScrubber.new %>

+ <%# Hack: for DOCX export - otherwise, bold highlighting of question inconsistent. %> + <% if local_assigns[:export_format] && export_format == 'docx' %> +

<%= sanitize question[:text].to_s, scrubber: TableFreeScrubber.new %>

+ <% else %> +

<%= sanitize question[:text].to_s, scrubber: TableFreeScrubber.new %>

+ <% end %> +


<% end %> @@ -25,7 +31,9 @@ <% if !section_has_common_answers %> <%= research_output.fullname %> : <% end %> +
<%= _('Question not answered.') -%> +


<% else %> @@ -55,6 +63,7 @@ <% end %>

<%= sanitize ah['text'] %>

+
<%# case for displaying comments OR text %> <% elsif !blank %>

@@ -62,6 +71,7 @@ <%= research_output.fullname %> : <% end %> <%= sanitize answer.text %> +

<% end %>
diff --git a/app/views/branded/shared/export/_export_by_research_output.erb b/app/views/branded/shared/export/_export_by_research_output.erb index 3e5070d..44bf0cc 100644 --- a/app/views/branded/shared/export/_export_by_research_output.erb +++ b/app/views/branded/shared/export/_export_by_research_output.erb @@ -16,13 +16,21 @@
<% if !@public_plan && @show_sections_questions%>

-

<%= sanitize question[:text].to_s, scrubber: TableFreeScrubber.new %>

+ <%# Hack: for DOCX export - otherwise, bold highlighting of question inconsistent. %> + <% if local_assigns[:export_format] && export_format == 'docx' %> +

<%= sanitize question[:text].to_s, scrubber: TableFreeScrubber.new %>

+ <% else %> +

<%= sanitize question[:text].to_s, scrubber: TableFreeScrubber.new %>

+ <% end %> +


<% end %> <%# case where question has not been answered sufficiently to display%> <% if @show_unanswered && (answer.blank? || (options.blank? && blank))%> +

<%= _('Question not answered.') -%>

+


<% else %> @@ -45,9 +53,11 @@ <% end %>

<%= sanitize ah['text'] %>

+
<%# case for displaying comments OR text %> <% elsif !blank %> -

<%= sanitize answer.text %>

+ <%= sanitize answer.text %> +
<% end %>
<% end %> diff --git a/app/views/branded/shared/export/_plan.erb b/app/views/branded/shared/export/_plan.erb index b5afd31..503c04a 100644 --- a/app/views/branded/shared/export/_plan.erb +++ b/app/views/branded/shared/export/_plan.erb @@ -17,14 +17,16 @@ <% end %> <% @hash[:phases].each do |phase| %> - + <%# Page break before each phase %>

<%= download_plan_page_title(@plan, phase, @hash) %>


<% phase[:sections].each do |section| %> <% if display_section?(@hash[:customization], section, @show_custom_sections) %> <% if @show_sections_questions %> +

<%= section[:title] %>

+
<% end %> <% if @research_output_export_mode == "by_section" %> <%= render partial: 'shared/export/export_by_research_output', diff --git a/app/views/branded/shared/export/_plan_coversheet.erb b/app/views/branded/shared/export/_plan_coversheet.erb index 10b575c..f468423 100644 --- a/app/views/branded/shared/export/_plan_coversheet.erb +++ b/app/views/branded/shared/export/_plan_coversheet.erb @@ -1,15 +1,13 @@

<%= @plan.title %>

-

- <%= _("A Data Management Plan created using ") + Rails.configuration.branding[:application][:name] %> -

+

<%= _("A Data Management Plan created using ") + Rails.configuration.branding[:application][:name] %>


-

- <%= plan_attribution(@hash[:attribution]) %> -


+ <%# Using tags as the htmltoword gem does not recognise css styles defined %> + <%# Allow raw html (==) for plan_attribution as it has tags %> +

<%== plan_attribution(@hash[:attribution]) %>


-

<%= _("Affiliation: ") + @hash[:affiliation] %>


+

<%= _("Affiliation: ") %><%= @hash[:affiliation] %>


<% if @hash[:funder].present? %>

<%= _("Template: ") + @hash[:funder] %>


@@ -18,20 +16,20 @@ <% end %> <% if @plan.principal_investigator_identifier.present? %> -

<%= _("ORCID iD: ") + @plan.principal_investigator_identifier %>


+

<%= _("ORCID iD: ") %><%= @plan.principal_investigator_identifier %>


<% end %> <% if @plan.grant_number.present? %> -

<%= _("Grant number: ") + @plan.grant_number %>


+

<%= _("Grant number: ") %><%= @plan.grant_number %>


<% end %> <% if @plan.description.present? %> -

<%= _("Project abstract: ") %>

+

<%= _("Project abstract: ") %>

<%= sanitize(@plan.description) %>

<% end %> <% if @hash[:research_outputs].length > 1 || !@hash[:research_outputs][0].main?%> -

<%= _("Research outputs: ") %>

+

<%= _("Research outputs: ") %>

    <% @hash[:research_outputs].each do |research_output| %>
  • @@ -47,7 +45,7 @@
    <% end %> -

    <%= _("Last modified: ") + l(@plan.updated_at.to_date, formats: :short) %>


    +

    <%= _("Last modified: ") %><%= l(@plan.updated_at.to_date, formats: :short) %>


    <% if @public_plan %>

    <%= _("Copyright information:") %>

    diff --git a/app/views/branded/shared/export/_plan_styling.erb b/app/views/branded/shared/export/_plan_styling.erb index fa0d3e1..9e5ef0f 100644 --- a/app/views/branded/shared/export/_plan_styling.erb +++ b/app/views/branded/shared/export/_plan_styling.erb @@ -11,18 +11,18 @@ h1 { font-size: 1.5rem; - font-face: bold; + font-weight: bold; padding: 0; } h2 { font-size: 1.3rem; - font-face: bold; + font-weight: bold; padding: 0; margin: 1em 0 0 0; } h3 { font-size: 1.1rem; - font-face: bold; + font-weight: bold; padding: 0; margin: 1em 0 0 0; } @@ -60,6 +60,9 @@ position: absolute; bottom: 0; } + .bold { + font-weight: bold; + } .research-output { border: 1px solid black; diff --git a/app/views/branded/usage/index.html.erb b/app/views/branded/usage/index.html.erb index 9af02b0..1a45729 100644 --- a/app/views/branded/usage/index.html.erb +++ b/app/views/branded/usage/index.html.erb @@ -6,7 +6,7 @@

    <%= _('Usage statistics') %>

- <%= link_to(_('Download global usage'), usage_downloads_path(format: :csv), class: 'btn btn-default mt-25') if current_user.can_super_admin? %> + <%= link_to(_('Download global usage'), usage_downloads_path(format: :csv), class: 'btn btn-default mt-25') if current_user.can_super_admin? %>
@@ -29,7 +29,7 @@
-

<%= _('Run your own filter') %>

+

<%= _('Run your own filter') %>

<% if current_user.api_token.present? %>
<%= hidden_field_tag('api_token', current_user.api_token) %> @@ -105,10 +105,17 @@
-
+ +
+
+

* <%= _('Move the mouse pointer over the bars of a chart to see numbers.') %>

+
+
+ +
-

<%= _('No. users joined during last year') %>

+

<%= _('No. users joined during last year') %>

-

<%= _('No. plans during last year') %>

+

<%= _('No. plans during last year') %>

-
-
-

<%= _('No. plans by template') %>

-
-
-
-
+
+
+
+
+
+
+
+
+
+
+

<%= _('No. plans by template') %>

+
+
+
+
  • - <%= label_tag('monthly_plans_by_template', _('Time picker')) %> + <%= label_tag('monthly_plans_by_template', _('Time period')) %>
  • @@ -161,9 +176,11 @@
-
-
-
+
+
+ +
+
diff --git a/app/views/guidance_groups/_index_by_theme.html.erb b/app/views/guidance_groups/_index_by_theme.html.erb index 707dc11..db1da61 100644 --- a/app/views/guidance_groups/_index_by_theme.html.erb +++ b/app/views/guidance_groups/_index_by_theme.html.erb @@ -1,15 +1,18 @@ <%# locals{ guidance_groups_by_theme } %> <% parent_id = guidance_groups_by_theme.object_id %>
- <% guidance_groups_by_theme.each_pair do |guidance_group, theme_hash| %> <% guidances_output = [] %> + <%# Do not show expand/collapse all links if there is only one item in theme_hash %> + <% if theme_hash.length > 1 %> + + <% end %> <% theme_hash.each_pair do |theme, guidances| %> <% question_guidance_id = "#{question.object_id}-#{guidances.object_id}" %> <%# if guidances with this theme have not been output %> @@ -42,7 +45,9 @@ <% end %>

<% unless guidances_output.include?(guidance.id) %> - <%= sanitize(guidance.text) %> +

+ <%= sanitize(guidance.text) %> +
<% guidances_output << guidance.id %> <% multiple = true %> <% end %> diff --git a/app/views/guidances/_guidance_display.html.erb b/app/views/guidances/_guidance_display.html.erb index 3454f45..6208b8a 100644 --- a/app/views/guidances/_guidance_display.html.erb +++ b/app/views/guidances/_guidance_display.html.erb @@ -13,7 +13,9 @@
- <%= sanitize question.guidance_annotation(current_user.org).text %> +
+ <%= sanitize question.guidance_annotation(current_user.org).text %> +
@@ -29,7 +31,11 @@
-
<%= sanitize guidance.text %>
+
+
+ <%= sanitize guidance.text %> +
+
<% end %> diff --git a/app/views/notes/_list.html.erb b/app/views/notes/_list.html.erb index 2c55831..dd43a76 100644 --- a/app/views/notes/_list.html.erb +++ b/app/views/notes/_list.html.erb @@ -5,7 +5,7 @@
  • -
    +
    <%= render partial: "notes/show", locals: {note: note }, formats: [:html] %>
    <% if plan.commentable_by?(current_user) %> diff --git a/app/views/notes/_show.html.erb b/app/views/notes/_show.html.erb index e3d78c6..988b8cf 100644 --- a/app/views/notes/_show.html.erb +++ b/app/views/notes/_show.html.erb @@ -2,7 +2,11 @@ <% if !note.nil? %> <% user = User.find(note.user_id) %>
      -
    • <%= sanitize note.text %>
    • +
    • +
      + <%= sanitize note.text %> +
      +
    • <%= "#{user.name} at #{l(note.updated_at, format: :short)}" %> diff --git a/app/views/org_admin/annotations/_show.html.erb b/app/views/org_admin/annotations/_show.html.erb index 584b1b3..34e97b2 100644 --- a/app/views/org_admin/annotations/_show.html.erb +++ b/app/views/org_admin/annotations/_show.html.erb @@ -2,10 +2,18 @@ > <% if example_answer.present? %>
      <%= _('%{org} Example Answer') % { org: example_answer.org.short_name } %>
      -
      <%= sanitize example_answer.text %>
      +
      +
      + <%= sanitize example_answer.text %> +
      +
      <% end %> <% if guidance.present? %> -
      <%= sanitize guidance.text %>
      +
      +
      + <%= sanitize guidance.text %> +
      +
      <% end %> <% end %> diff --git a/app/views/org_admin/phases/_index.html.erb b/app/views/org_admin/phases/_index.html.erb index 35570da..71d668b 100644 --- a/app/views/org_admin/phases/_index.html.erb +++ b/app/views/org_admin/phases/_index.html.erb @@ -21,9 +21,9 @@ <% phase = phase_hash[:data] %>

      - <%= sanitize phase.description %> +

      + <%= sanitize phase.description %> +

      @@ -38,7 +40,13 @@ <% phase.sections.each do |section| %> -

      <%= section.title %>

      + +

      +

      + <%= section.title %> +
      +

      + <% if section.questions.present? %>
        diff --git a/app/views/org_admin/phases/_show.html.erb b/app/views/org_admin/phases/_show.html.erb index a9f7982..9179112 100644 --- a/app/views/org_admin/phases/_show.html.erb +++ b/app/views/org_admin/phases/_show.html.erb @@ -4,5 +4,9 @@
        <%= _('Order of display') %>
        <%= phase.number %>
        <%= _('Description') %>
        -
        <%= sanitize phase.description %>
        +
        +
        + <%= sanitize phase.description %> +
        +
        diff --git a/app/views/org_admin/questions/_show.html.erb b/app/views/org_admin/questions/_show.html.erb index 2df3df2..d582f2d 100644 --- a/app/views/org_admin/questions/_show.html.erb +++ b/app/views/org_admin/questions/_show.html.erb @@ -5,15 +5,19 @@ **Copyright: Digital Curation Centre and California Digital Library -->
        -
        +
        -
        +
        <% q_format = question.question_format %>
        <%= _('Question number')%>
        <%= question.number %>
        <%= _('Question text')%>
        -
        <%= sanitize question.text %>
        +
        +
        + <%= sanitize question.text %> +
        +
        <% if question.option_based? %>
        <%= _('Question options') %>
        @@ -23,13 +27,21 @@ <% if q_format.textfield? || q_format.textarea? %> <% if !question.default_value.nil? %>
        <%= _('Default value')%>
        -
        <%= sanitize question.default_value %>
        +
        + <% if q_format.textarea? %> +
        + <%= sanitize question.default_value %> +
        + <% else %> + <%= sanitize question.default_value %> + <% end %> +
        <% end %> <% end %>
        <%= _('Answer format')%>
        - <%= q_format.title %> + <%= q_format.title + "."%> <% if q_format.option_based? %> <%= _('Additional comment area will be displayed.')%> <% else %> @@ -38,17 +50,30 @@
        <% if !question.section.phase.template.org.funder? %> - <% example_answer = question.example_answers(template.base_org.id).first %> + <% example_answer = question.example_answers(template.base_org.id).first %> <% if example_answer.present? && example_answer.text.present? %>
        <%= _('example answer')%>
        -
        <%= sanitize example_answer.text %>
        +
        + <% if q_format.textarea? %> +
        + <%= sanitize example_answer.text %> +
        + <% else %> + <%= sanitize example_answer.text %> + <% end %> +
        + <% end %> <% end %> <% guidance = question.guidance_annotation(template.base_org.id) %> <% if guidance.present? %>
        <%= _('Guidance')%>
        -
        <%= sanitize guidance.text %>
        +
        +
        + <%= sanitize guidance.text %> +
        +
        <% end %> <% themes_q = question.themes %> @@ -58,7 +83,89 @@ <% end %>
        + +
        + <% has_org_themed_guidance = false %> + <% themes_q = question.themes %> + <% if !themes_q.nil? %> +
        + <% ggs = GuidanceGroup.where(org_id: current_user.org.id) %> +

        <%= _("Themed Guidance") %>

        + + <% if ggs.length > 0 %> + <%# To determine if any themes associated with question exist. %> + <% ggs.each do |guidance_group| %> + <% themes_q.each do |theme| %> + <% theme_guidances = theme.guidances.where( + guidances: { guidance_group_id: guidance_group.id } + ) %> + <% if theme_guidances.length > 0 %> + <% has_org_themed_guidance = true %> +

        <%= _("Click the links below to view organisational guidance + related to the themes associated with this question.") %>

        + <% break %> + <% end %> + <% end %> + <% end %> + + <% if has_org_themed_guidance %> + <% ggs.each do |guidance_group| %> + <% themes_q.each do |theme| %> + <% theme_guidances = theme.guidances.where( + guidances: { guidance_group_id: guidance_group.id } + ) %> + <% if theme_guidances.length > 0 %> + <% theme_guidances.each do |guidance| %> +
        + +
        +
        +
        + <%= sanitize guidance.text %> +
        +
        +
        +
        + <% end %> + <% end %> + <% end %> + <% end %> + <% end %> + <% end %> + <% end %> +
        + <% if has_org_themed_guidance %> +
        +

        <%= _("Note: New plans will automatically display this guidance. + Users then have the ability to hide/display the guidance when editing their plan.") %>

        + <% else %> +

        <%= _("There is no organisational guidance related to the themes associated with this question.") %>

        + <% end %> +

        +
        <% if template.latest? %> @@ -68,7 +175,11 @@
        <% question.annotations_per_org(current_user.org_id).each do |annotation| %>
        <%= annotation.type.humanize %>
        -
        <%= annotation.text.present? ? sanitize(annotation.text) : _('None provided') %>
        +
        +
        + <%= annotation.text.present? ? sanitize(annotation.text) : _('None provided') %> +
        +
        <% end %>
        <% else %> @@ -107,7 +218,9 @@ <% question.annotations_per_org(current_user.org_id).each do |annotation| %>
        <%= annotation.type.humanize %>
        - <%= annotation.text.present? ? sanitize(annotation.text) : _('None provided') %> +
        + <%= annotation.text.present? ? sanitize(annotation.text) : _('None provided') %> +
        <% end %> diff --git a/app/views/orgs/_feedback_form.html.erb b/app/views/orgs/_feedback_form.html.erb index 6e88cc8..a8f2a03 100644 --- a/app/views/orgs/_feedback_form.html.erb +++ b/app/views/orgs/_feedback_form.html.erb @@ -18,11 +18,15 @@ <%= _('Request Expert Feedback - Message Displayed on Share Plan Tab:') %>
        -
        +
        <%= f.label :feedback_email_msg, _('Message'), class: "control-label" %> <%= f.text_area :feedback_email_msg, class: "form-control", "aria-required" => true %>
        +
        +

        <%= _('Sample Message') %>

        + <%= sanitize sample_message_for_org_feedback_form(org) %> +
        diff --git a/app/views/paginable/guidance_groups/_index.html.erb b/app/views/paginable/guidance_groups/_index.html.erb index 89d47ea..2d7b8b1 100644 --- a/app/views/paginable/guidance_groups/_index.html.erb +++ b/app/views/paginable/guidance_groups/_index.html.erb @@ -3,9 +3,9 @@ <%= _('Name') %> - <%= _('Status') %> <%= paginable_sort_link('published') %> - <%= _('Optional subset') %> <%= paginable_sort_link('optional_subset') %> - <%= _('Last updated') %> <%= paginable_sort_link('updated_at') %> + <%= _('Status') %> <%= paginable_sort_link('guidance_groups.published') %> + <%= _('Optional subset') %> <%= paginable_sort_link('guidance_groups.optional_subset') %> + <%= _('Last updated') %> <%= paginable_sort_link('guidance_groups.updated_at') %> <%= _('Actions') %> diff --git a/app/views/paginable/notifications/_index.html.erb b/app/views/paginable/notifications/_index.html.erb index 9a7d707..3d87903 100644 --- a/app/views/paginable/notifications/_index.html.erb +++ b/app/views/paginable/notifications/_index.html.erb @@ -1,10 +1,10 @@ - - - - + + + + diff --git a/app/views/paginable/orgs/_index.html.erb b/app/views/paginable/orgs/_index.html.erb index 15d3d5c..aebeebb 100644 --- a/app/views/paginable/orgs/_index.html.erb +++ b/app/views/paginable/orgs/_index.html.erb @@ -6,7 +6,6 @@ - @@ -16,8 +15,7 @@ - - +
        <%= _('Title') %> <%= paginable_sort_link('title') %><%= _('Level') %> <%= paginable_sort_link('level') %><%= _('Start') %> <%= paginable_sort_link('starts_at') %><%= _('Expiration') %> <%= paginable_sort_link('expires_at') %><%= _('Title') %> <%= paginable_sort_link('notifications.title') %><%= _('Level') %> <%= paginable_sort_link('notifications.level') %><%= _('Start') %> <%= paginable_sort_link('notifications.starts_at') %><%= _('Expiration') %> <%= paginable_sort_link('notifications.expires_at') %>
        <%= _('Administrator Email') %> <%= paginable_sort_link('orgs.contact_email') %> <%= _('Organisation Type(s)') %> <%= paginable_sort_link('orgs.org_type') %> <%= _('Templates') %><%= _('Users') %> <%= _('Actions') %>
        <%= org.name %> <%= org.contact_email %> <%= org.org_type_to_s %><%= org.templates.collect(&:family_id).uniq.length %><%= org.users.uniq.length %><%= org.template_count %>
        - <%= "#{template.is_default ? '* ' : ''}#{template.title}" %> + <%= link_to_customizable_template "#{template.is_default ? '* ' : ''}#{template.title}", customization, template %> <%= template.org.name %> @@ -51,39 +51,24 @@ <%= _('Actions') %> diff --git a/app/views/paginable/templates/_organisational.html.erb b/app/views/paginable/templates/_organisational.html.erb index d8dd98a..26328e3 100644 --- a/app/views/paginable/templates/_organisational.html.erb +++ b/app/views/paginable/templates/_organisational.html.erb @@ -20,7 +20,7 @@ <% scope.each do |template| %>
        - <%= template.title %> + <%= link_to "#{template.title}", edit_org_admin_template_path(template.id) %> <%= action_name == 'organisational' ? sanitize(template.description) : template.org.name %> diff --git a/app/views/paginable/themes/_index.html.erb b/app/views/paginable/themes/_index.html.erb index 813984d..dea1556 100644 --- a/app/views/paginable/themes/_index.html.erb +++ b/app/views/paginable/themes/_index.html.erb @@ -1,8 +1,8 @@ - - + + diff --git a/app/views/phases/_edit_plan_answers.html.erb b/app/views/phases/_edit_plan_answers.html.erb index 2e215ba..0981d9d 100644 --- a/app/views/phases/_edit_plan_answers.html.erb +++ b/app/views/phases/_edit_plan_answers.html.erb @@ -50,7 +50,11 @@
        -
        <%= sanitize section.description %>
        +
        +
        + <%= sanitize section.description %> +
        +
        <% section.questions.each_with_index do |question, i| %> <% # Load the answer or create a new one diff --git a/app/views/phases/_overview.html.erb b/app/views/phases/_overview.html.erb index 04a9b3b..89b9b01 100644 --- a/app/views/phases/_overview.html.erb +++ b/app/views/phases/_overview.html.erb @@ -6,7 +6,9 @@ <%= _('Write plan') %>

        - <%= sanitize(phase.description) %> +

        + <%= sanitize(phase.description) %> +

        @@ -17,7 +19,11 @@ <%= s.title %>
          <% s.questions.each do |q| %> -
        • <%= sanitize(q.text) %>
        • +
        • +
          + <%= sanitize(q.text) %> +
          +
        • <% end %>
        diff --git a/app/views/plans/_overview_details.html.erb b/app/views/plans/_overview_details.html.erb index b57b22a..0487995 100644 --- a/app/views/plans/_overview_details.html.erb +++ b/app/views/plans/_overview_details.html.erb @@ -9,7 +9,9 @@ <%= _('This plan is based on the "%{template_title}" template provided by %{org_name}.') %{ :template_title => plan.template.title, :org_name => plan.template.org.name } %>

        - <%= sanitize(plan.template.description) %> +

        + <%= sanitize(plan.template.description) %> +

        diff --git a/app/views/questions/_new_edit_question_datefield.html.erb b/app/views/questions/_new_edit_question_datefield.html.erb new file mode 100644 index 0000000..923784b --- /dev/null +++ b/app/views/questions/_new_edit_question_datefield.html.erb @@ -0,0 +1,5 @@ +<%# locals: { f, question, answer } %> +
        + <%= f.label(:text, sanitize(question.text), class: 'control-label') %> + <%= date_field_tag('answer[text]', strip_tags(answer.text || question.default_value), class: 'form-control') %> +
        \ No newline at end of file diff --git a/app/views/questions/_new_edit_question_option_based.html.erb b/app/views/questions/_new_edit_question_option_based.html.erb index 0821635..97e3498 100644 --- a/app/views/questions/_new_edit_question_option_based.html.erb +++ b/app/views/questions/_new_edit_question_option_based.html.erb @@ -40,6 +40,12 @@ <% if question.option_comment_display %> <% text = question.question_format.rda_metadata? ? answer.answer_hash['text'] : answer.text %> <%= label_tag('answer[text]', _('Additional Information'), class: 'control-label') %> - <%= text_area_tag('answer[text]', text, id: "answer-text-#{question.id}", class: "form-control tinymce_answer") %> + <% if readonly %> +
        + <%= sanitize("

        #{text}

        ") %> +
        + <% else %> + <%= text_area_tag('answer[text]', text, id: "answer-text-#{question.id}", class: "form-control tinymce_answer") %> + <% end %> <% end %> diff --git a/app/views/questions/_new_edit_question_textarea.html.erb b/app/views/questions/_new_edit_question_textarea.html.erb index c454ce5..0c12f54 100644 --- a/app/views/questions/_new_edit_question_textarea.html.erb +++ b/app/views/questions/_new_edit_question_textarea.html.erb @@ -7,10 +7,14 @@ rather cumbersome. As such, this workaround, simplifies the logic when a stale answer is found by rendering the html of the answer directly within a paragraph. %> -
        - <%= f.label(:text, sanitize(question.text), class: 'control-label') %> +
        +
        + <%= f.label(:text, sanitize(question.text), class: 'control-label') %> +
        <% if locking || readonly %> - <%= sanitize("

        #{answer.text || question.default_value}

        ") %> +
        + <%= sanitize("

        #{answer.text || question.default_value}

        ") %> +
        <% else %> <%= text_area_tag('answer[text]', answer.text || question.default_value, id: "answer-text-#{question.id}", class: "form-control tinymce_answer") %> <% end %> diff --git a/app/views/shared/export/_plan.erb b/app/views/shared/export/_plan.erb index 4c325bf..4a9cb1c 100644 --- a/app/views/shared/export/_plan.erb +++ b/app/views/shared/export/_plan.erb @@ -19,21 +19,26 @@ <% @hash[:phases].each do |phase| %> <%# Only render selected phase %> <% if phase[:title] == @selected_phase.title %> - + <%# Page break before each phase %>

        <%= download_plan_page_title(@plan, phase, @hash) %>


        <% phase[:sections].each do |section| %> <% if display_section?(@hash[:customization], section, @show_custom_sections) %> <% if @show_sections_questions %> +

        <%= section[:title] %>

        +
        <% end %> <% section[:questions].each do |question| %>
        <% if !@public_plan && @show_sections_questions%> -

        - <%= sanitize question[:text].to_s, scrubber: TableFreeScrubber.new %> -

        + <%# Hack: for DOCX export - otherwise, bold highlighting of question inconsistent. %> + <% if local_assigns[:export_format] && export_format == 'docx' %> + <%= sanitize question[:text].to_s, scrubber: TableFreeScrubber.new %> + <% else %> +
        <%= sanitize question[:text].to_s, scrubber: TableFreeScrubber.new %>
        + <% end %>
        <% end %> <% answer = @plan.answer(question[:id], false) %> @@ -41,7 +46,9 @@ <% options = answer.present? ? answer.question_options : [] %> <%# case where question has not been answered sufficiently to display%> <% if @show_unanswered && (answer.blank? || (options.blank? && blank))%> +

        <%= _('Question not answered.') -%>

        +

        <% else %> <%# case where Question has options %> @@ -63,9 +70,11 @@ <% end %>

        <%= sanitize ah['text'] %>

        +
        <%# case for displaying comments OR text %> <% elsif !blank %> -

        <%= sanitize answer.text %>

        + <%= sanitize answer.text %> +

        <% end %> <% end %>
        diff --git a/app/views/shared/export/_plan_coversheet.erb b/app/views/shared/export/_plan_coversheet.erb index 4b79f25..2817e42 100644 --- a/app/views/shared/export/_plan_coversheet.erb +++ b/app/views/shared/export/_plan_coversheet.erb @@ -1,15 +1,13 @@

        <%= @plan.title %>

        -

        - <%= _("A Data Management Plan created using ") + Rails.configuration.branding[:application][:name] %> -

        +

        <%= _("A Data Management Plan created using ") + Rails.configuration.branding[:application][:name] %>


        -

        - <%= plan_attribution(@hash[:attribution]) %> -


        - -

        <%= _("Affiliation: ") + @hash[:affiliation] %>


        + <%# Using tags as the htmltoword gem does not recognise css styles defined %> + <%# Allow raw html (==) for plan_attribution as it has tags %> +

        <%== plan_attribution(@hash[:attribution]) %>


        + +

        <%= _("Affiliation: ") %><%= @hash[:affiliation] %>


        <% if @hash[:funder].present? %>

        <%= _("Template: ") + @hash[:funder] %>


        @@ -18,22 +16,22 @@ <% end %> <% if @plan.principal_investigator_identifier.present? %> -

        <%= _("ORCID iD: ") + @plan.principal_investigator_identifier %>


        +

        <%= _("ORCID iD: ") %><%= @plan.principal_investigator_identifier %>


        <% end %> <% if @plan.grant_number.present? %> -

        <%= _("Grant number: ") + @plan.grant_number %>


        +

        <%= _("Grant number: ") %><%= @plan.grant_number %>


        <% end %> <% if @plan.description.present? %> -

        <%= _("Project abstract: ") %>

        +

        <%= _("Project abstract: ") %>

        <%= sanitize(@plan.description) %>

        <% end %> -

        <%= _("Last modified: ") + l(@plan.updated_at.to_date, formats: :short) %>


        +

        <%= _("Last modified: ") %><%= l(@plan.updated_at.to_date, formats: :short) %>


        <% if @public_plan %> -

        <%= _("Copyright information:") %>

        +

        <%= _("Copyright information:") %>

        <%= _(" The above plan creator(s) have agreed that others may use as much of the text of this plan as they would like in their own plans, and customise it as necessary. You do not need to credit the creator(s) as the source of the language used, but using any of the plan's text does not imply that the creator(s) endorse, or have any relationship to, your project or proposal") %> diff --git a/app/views/shared/export/_plan_styling.erb b/app/views/shared/export/_plan_styling.erb index 3ed931b..4eda615 100644 --- a/app/views/shared/export/_plan_styling.erb +++ b/app/views/shared/export/_plan_styling.erb @@ -5,42 +5,42 @@ font-family: @font-face; font-size: <%= font_size %>; margin: <%= margin %>; - + } h1 { - font-size: 1.5rem; - font-face: bold; + font-size: 1.5rem; + font-weight: bold; padding: 0; } h2 { - font-size: 1.3rem; - font-face: bold; - padding: 0; + font-size: 1.3rem; + font-weight: bold; + padding: 0; margin: 1em 0 0 0; } h3 { - font-size: 1.1rem; - font-face: bold; - padding: 0; + font-size: 1.1rem; + font-weight: bold; + padding: 0; margin: 1em 0 0 0; } h2 + div.question > h3 { - margin: 0; + margin: 0; } table, tr, td, th, tbody, thead, tfoot { - page-break-inside: avoid !important; + page-break-inside: avoid !important; } - table { - border-collapse: collapse; + table { + border-collapse: collapse; } - th, td { - border: 1px solid black !important; + th, td { + border: 1px solid black !important; padding: 2px; } - p { + p { margin: 0.25em 0; } .cover-page { - font-size: 1.1rem; + font-size: 1.1rem; } .question { margin-top: 15px; @@ -57,5 +57,7 @@ position: absolute; bottom: 0; } - } + .bold { + font-weight: bold; + } \ No newline at end of file diff --git a/app/views/usage/index.html.erb b/app/views/usage/index.html.erb index ef83ac4..42f31a9 100644 --- a/app/views/usage/index.html.erb +++ b/app/views/usage/index.html.erb @@ -29,7 +29,7 @@

        -

        <%= _('Run your own filter') %>

        +

        <%= _('Run your own filter') %>

        <% if current_user.api_token.present? %> <%= hidden_field_tag('api_token', current_user.api_token) %> @@ -105,10 +105,17 @@
        + +
        +
        +

        * <%= _('Move the mouse pointer over the bars of a chart to see numbers.') %>

        +
        +
        +
        -

        <%= _('No. users joined during last year') %>

        +

        <%= _('No. users joined during last year') %>

        -

        <%= _('No. plans during last year') %>

        +

        <%= _('No. plans during last year') %>

        -
        -
        -

        <%= _('No. plans by template') %>

        -
        -
        -
        -
        +
        +
        +
        +
        +
        +
        +
        +
        +
        +
        +

        <%= _('No. plans by template') %>

        +
        +
        +
        +
        • - <%= label_tag('monthly_plans_by_template', _('Time picker')) %> + <%= label_tag('monthly_plans_by_template', _('Time period')) %>
        • @@ -161,9 +176,11 @@
        -
        -
        -
        +
        +
        + +
        +
        diff --git a/app/views/user_mailer/new_comment.html.erb b/app/views/user_mailer/new_comment.html.erb index 3eafb34..d94c486 100644 --- a/app/views/user_mailer/new_comment.html.erb +++ b/app/views/user_mailer/new_comment.html.erb @@ -1,17 +1,38 @@ <% tool_name = Rails.configuration.branding[:application][:name] commenter_name = @commenter.name - plan_link = link_to(@plan.title, @plan) - user_name = @collaborator.name + plan_title = @plan.title + user_name = @plan.owner.name + question = @answer.question + question_number = question.number + section_title = question.section.title + phase_id = question.section.phase.id + phase_link = url_for(action: 'edit', controller: 'plans', id: @plan.id, phase_id: phase_id) + comment_number = @answer.notes.size %> <% FastGettext.with_locale FastGettext.default_locale do %>

        <%= _('Hello %{user_name}') %{ :user_name => user_name } %>

        - <%= raw(_('%{commenter_name} has commented on the plan %{plan_link}. To view the comments, '\ - 'please visit the My Dashboard page in %{tool_name} and open your plan or click the link above.') %{ :plan_link => plan_link, - :commenter_name => commenter_name, :tool_name => tool_name }) %> + <%= _('%{commenter_name} has commented on your plan %{plan_title}. To view the comments, '\ + 'follow the link to the DMP below, or navigate to the plan via My Dashboard page in %{tool_name}.') \ + %{ :commenter_name => commenter_name, :plan_title => plan_title, :tool_name => tool_name } %>

        +

        + <%= _('Below is a summary of the sections and questions which have comments.') %> + <%= _('You can see the comments in the right-hand panel, '\ + 'adjacent to the guidance for each question.') %> +

        +

        + <%= _('DMP: %{phase_link}') %{ :phase_link => phase_link } %> +

        +

        + <%= _('Section name: %{section_title}') %{ :section_title => section_title } %> +

        +

        + <%= _('Question: %{question_number}') %{ :question_number => question_number } %> +

        + <%= render partial: 'email_signature' %> <% end %> diff --git a/config/branding.yml.sample b/config/branding.yml.sample index f295c75..9322cad 100644 --- a/config/branding.yml.sample +++ b/config/branding.yml.sample @@ -44,7 +44,7 @@ preferences: email: users: - new_comment: true + new_comment: false admin_privileges: true added_as_coowner: true feedback_requested: true diff --git a/config/initializers/fast_gettext.rb b/config/initializers/fast_gettext.rb index 7348c06..05f69a9 100644 --- a/config/initializers/fast_gettext.rb +++ b/config/initializers/fast_gettext.rb @@ -23,7 +23,7 @@ end FastGettext.add_text_domain("app", - path: "config/locale", + path: Rails.root.join("config/locale"), type: :po, ignore_fuzzy: true, report_warning: false, diff --git a/config/webpack/environment.js b/config/webpack/environment.js index 859fcf9..b01021a 100644 --- a/config/webpack/environment.js +++ b/config/webpack/environment.js @@ -2,6 +2,7 @@ const webpack = require('webpack') const eslint = require('./loaders/eslint') +const babelLoader = require('./loaders/babel-loader') environment.plugins.append('Provide', new webpack.ProvidePlugin({ jQuery: 'jquery', @@ -11,5 +12,6 @@ })); environment.loaders.prepend('ESLint', eslint) +environment.loaders.append('Babel-Loader', babelLoader) -module.exports = environment \ No newline at end of file +module.exports = environment diff --git a/config/webpack/loaders/babel-loader.js b/config/webpack/loaders/babel-loader.js new file mode 100644 index 0000000..d464e07 --- /dev/null +++ b/config/webpack/loaders/babel-loader.js @@ -0,0 +1,6 @@ +// config/webpack/loaders/babel-loader.js +module.exports = { + test: /\.(js|jsx)$/i, + exclude: /node_modules\/(?!number-to-text)/, + loader: 'babel-loader' +} diff --git a/config/webpack/production.js b/config/webpack/production.js index be0f53a..c0ee5ac 100644 --- a/config/webpack/production.js +++ b/config/webpack/production.js @@ -1,5 +1,6 @@ process.env.NODE_ENV = process.env.NODE_ENV || 'production' const environment = require('./environment') +environment.plugins.get("UglifyJs").options.uglifyOptions.ecma = 5 module.exports = environment.toWebpackConfig() diff --git a/lib/csvable.rb b/lib/csvable.rb index 867a145..d9ca3ac 100644 --- a/lib/csvable.rb +++ b/lib/csvable.rb @@ -5,11 +5,17 @@ require "csv" class << self - def from_array_of_hashes(data = []) + def from_array_of_hashes(data = [], humanize = true) return "" unless data.first&.keys - headers = data.first.keys - .map(&:to_s) - .map(&:humanize) + if humanize + headers = data.first.keys + .map(&:to_s) + .map(&:humanize) + else + headers = data.first.keys + .map(&:to_s) + end + CSV.generate do |csv| csv << headers data.each do |row| diff --git a/lib/dmpopidor/controllers/notes.rb b/lib/dmpopidor/controllers/notes.rb index c74e84f..7fa46bd 100644 --- a/lib/dmpopidor/controllers/notes.rb +++ b/lib/dmpopidor/controllers/notes.rb @@ -44,7 +44,7 @@ collaborators = plan.users.reject { |u| u == current_user || !u.active } collaborators.uniq.each do |collaborator| deliver_if(recipients: collaborator, key: 'users.new_comment') do |r| - UserMailer.new_comment(current_user, plan, collaborator).deliver_later + UserMailer.new_comment(current_user, plan, collaborator, answer).deliver_later end end @notice = success_message(@note, _("created")) diff --git a/lib/dmpopidor/controllers/org_admin/plans.rb b/lib/dmpopidor/controllers/org_admin/plans.rb index 75d7727..baba8dc 100644 --- a/lib/dmpopidor/controllers/org_admin/plans.rb +++ b/lib/dmpopidor/controllers/org_admin/plans.rb @@ -12,7 +12,7 @@ feedback_ids = Role.where(user_id: current_user.id).reviewer.pluck(:plan_id).uniq @feedback_plans = Plan.where(id: feedback_ids) - @plans = current_user.org.plans.where.not(visibility: [Plan.visibilities[:privately_private_visible], Plan.visibilities[:is_test]]) + @plans = current_user.org.plans.where.not(visibility: [Plan.visibilities[:privately_private_visible], Plan.visibilities[:is_test]]).page(1) end # CHANGES diff --git a/lib/dmpopidor/controllers/paginable/plans.rb b/lib/dmpopidor/controllers/paginable/plans.rb index f28a8b0..72028d2 100644 --- a/lib/dmpopidor/controllers/paginable/plans.rb +++ b/lib/dmpopidor/controllers/paginable/plans.rb @@ -10,7 +10,8 @@ end paginable_renderise( partial: "org_admin", - scope: current_user.org.plans.where.not(:visibility => 4) + scope: current_user.org.plans.where.not(:visibility => 4), + query_params: { sort_field: 'plans.updated_at', sort_direction: :desc } ) end end diff --git a/lib/dmpopidor/controllers/paginable/templates.rb b/lib/dmpopidor/controllers/paginable/templates.rb index 4f47cf1..1e55f48 100644 --- a/lib/dmpopidor/controllers/paginable/templates.rb +++ b/lib/dmpopidor/controllers/paginable/templates.rb @@ -14,7 +14,8 @@ scope: Template.joins(:org) .includes(:org) .where(id: templates.uniq.flatten) - .published + .published, + query_params: { sort_field: 'templates.title', sort_direction: :asc } ) end end diff --git a/lib/dmpopidor/controllers/paginable/users.rb b/lib/dmpopidor/controllers/paginable/users.rb index cfe84c0..4a06bab 100644 --- a/lib/dmpopidor/controllers/paginable/users.rb +++ b/lib/dmpopidor/controllers/paginable/users.rb @@ -15,6 +15,7 @@ paginable_renderise( partial: "index", scope: scope, + query_params: { sort_field: 'users.surname', sort_direction: :asc }, view_all: !current_user.can_super_admin? ) end diff --git a/lib/dmpopidor/controllers/users.rb b/lib/dmpopidor/controllers/users.rb index 57b66d0..2241882 100644 --- a/lib/dmpopidor/controllers/users.rb +++ b/lib/dmpopidor/controllers/users.rb @@ -12,10 +12,10 @@ respond_to do |format| format.html do if current_user.can_super_admin? - @users = User.order("last_sign_in_at is NULL, last_sign_in_at desc").page(1) + @users = User.order("last_sign_in_at is NULL, last_sign_in_at desc").includes(:roles).page(1) @total_users = User.count else - @users = current_user.org.users.order("last_sign_in_at is NULL, last_sign_in_at desc").page(1) + @users = current_user.org.users.order("last_sign_in_at is NULL, last_sign_in_at desc").includes(:roles).page(1) @total_users = current_user.org.users.count end end diff --git a/lib/dmpopidor/mailers/user_mailer.rb b/lib/dmpopidor/mailers/user_mailer.rb deleted file mode 100644 index b51b9a3..0000000 --- a/lib/dmpopidor/mailers/user_mailer.rb +++ /dev/null @@ -1,24 +0,0 @@ -module Dmpopidor - module Mailers - module UserMailer - # Mail is sent to the collaborators instead of owner - # commenter - User who wrote the comment - # plan - Plan for which the comment is associated to - # collaborator - Collaborator to whom the email is sent - def new_comment(commenter, plan, collaborator) - if commenter.is_a?(User) && plan.is_a?(Plan) - owner = plan.owner - if owner.present? && owner.active? - @commenter = commenter - @plan = plan - @collaborator = collaborator - FastGettext.with_locale FastGettext.default_locale do - mail(to: collaborator.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 - end - end -end diff --git a/lib/tasks/upgrade.rake b/lib/tasks/upgrade.rake index 6d46d7d..bbec826 100644 --- a/lib/tasks/upgrade.rake +++ b/lib/tasks/upgrade.rake @@ -1,6 +1,11 @@ require 'set' namespace :upgrade do + desc "Upgrade to v2.1.2:" + task v2_1_2: :environment do + Rake::Task["upgrade:add_date_question_format"].execute + end + desc "Upgrade to v2.1.0:" task v2_1_0: :environment do Rake::Task["data_cleanup:deactivate_orphaned_plans"].execute @@ -640,6 +645,18 @@ end end + desc "Adds the Date question format" + task :add_date_question_format => :environment do + unless QuestionFormat.id_for(QuestionFormat.formattypes[:date]).present? + QuestionFormat.create( + title: "Date field", + description: "Date field format", + option_based: false, + formattype: QuestionFormat.formattypes[:date] + ) + end + end + private def fuzzy_match?(text_a, text_b, min = 3) diff --git a/public/tinymce/skins/lightgray/skin.min.css b/public/tinymce/skins/lightgray/skin.min.css index ba5c691..c0631ae 100644 --- a/public/tinymce/skins/lightgray/skin.min.css +++ b/public/tinymce/skins/lightgray/skin.min.css @@ -1 +1 @@ -.mce-container,.mce-container *,.mce-widget,.mce-widget *,.mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:#595959;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;-webkit-tap-highlight-color:transparent;line-height:normal;font-weight:normal;text-align:left;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr;max-width:none}.mce-widget button{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.mce-container *[unselectable]{-moz-user-select:none;-webkit-user-select:none;-o-user-select:none;user-select:none}.word-wrap{word-wrap:break-word;-ms-word-break:break-all;word-break:break-all;word-break:break-word;-ms-hyphens:auto;-moz-hyphens:auto;-webkit-hyphens:auto;hyphens:auto}.mce-fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.mce-fade.mce-in{opacity:1}.mce-tinymce{visibility:inherit !important;position:relative}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;height:100%;z-index:100}div.mce-fullscreen{position:fixed;top:0;left:0;width:100%;height:auto}.mce-tinymce{display:block;-webkit-box-shadow:0 1px 2px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 1px 2px rgba(0, 0, 0, 0.2);box-shadow:0 1px 2px rgba(0, 0, 0, 0.2)}.mce-statusbar>.mce-container-body{display:flex;padding-right:16px}.mce-statusbar>.mce-container-body .mce-path{flex:1}.mce-wordcount{font-size:inherit;text-transform:uppercase;padding:8px 0}div.mce-edit-area{background:#FFF;filter:none}.mce-statusbar{position:relative}.mce-statusbar .mce-container-body{position:relative;font-size:11px}.mce-fullscreen .mce-resizehandle{display:none}.mce-statusbar .mce-flow-layout-item{margin:0}.mce-charmap{border-collapse:collapse}.mce-charmap td{cursor:default;border:1px solid #c5c5c5;width:20px;height:20px;line-height:20px;text-align:center;vertical-align:middle;padding:2px}.mce-charmap td div{text-align:center}.mce-charmap td:hover{background:white}.mce-grid td.mce-grid-cell div{border:1px solid #c5c5c5;width:15px;height:15px;margin:0;cursor:pointer}.mce-grid td.mce-grid-cell div:focus{border-color:#91bbe9}.mce-grid td.mce-grid-cell div[disabled]{cursor:not-allowed}.mce-grid{border-spacing:2px;border-collapse:separate}.mce-grid a{display:block;border:1px solid transparent}.mce-grid a:hover,.mce-grid a:focus{border-color:#91bbe9}.mce-grid-border{margin:0 4px 0 4px}.mce-grid-border a{border-color:#c5c5c5;width:13px;height:13px}.mce-grid-border a:hover,.mce-grid-border a.mce-active{border-color:#91bbe9;background:#bdd6f2}.mce-text-center{text-align:center}div.mce-tinymce-inline{width:100%}.mce-colorbtn-trans div{text-align:center;vertical-align:middle;font-weight:bold;font-size:20px;line-height:16px;color:#8b8b8b}.mce-monospace{font-family:"Courier New",Courier,monospace}.mce-toolbar-grp .mce-flow-layout-item{margin-bottom:0}.mce-container b{font-weight:bold}.mce-container p{margin-bottom:5px}.mce-container a{cursor:pointer;color:#2276d2}.mce-container a:hover{text-decoration:underline}.mce-container ul{margin-left:15px}.mce-container .mce-table-striped{border-collapse:collapse;margin:10px}.mce-container .mce-table-striped thead>tr{background-color:#fafafa}.mce-container .mce-table-striped thead>tr th{font-weight:bold}.mce-container .mce-table-striped td,.mce-container .mce-table-striped th{padding:5px}.mce-container .mce-table-striped tr:nth-child(even){background-color:#fafafa}.mce-container .mce-table-striped tbody>tr:hover{background-color:#e1e1e1}.mce-branding{font-size:inherit;text-transform:uppercase;white-space:pre;padding:8px 0}.mce-branding a{font-size:inherit;color:inherit}.mce-top-part{position:relative}.mce-top-part::before{content:'';position:absolute;-webkit-box-shadow:0 1px 2px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 1px 2px rgba(0, 0, 0, 0.2);box-shadow:0 1px 2px rgba(0, 0, 0, 0.2);top:0;right:0;bottom:0;left:0;pointer-events:none}.mce-rtl .mce-wordcount{left:0;right:auto}.mce-rtl .mce-statusbar>.mce-container-body>*:last-child{padding-right:0;padding-left:10px}.mce-rtl .mce-path{text-align:right;padding-right:16px}.mce-croprect-container{position:absolute;top:0;left:0}.mce-croprect-handle{position:absolute;top:0;left:0;width:20px;height:20px;border:2px solid white}.mce-croprect-handle-nw{border-width:2px 0 0 2px;margin:-2px 0 0 -2px;cursor:nw-resize;top:100px;left:100px}.mce-croprect-handle-ne{border-width:2px 2px 0 0;margin:-2px 0 0 -20px;cursor:ne-resize;top:100px;left:200px}.mce-croprect-handle-sw{border-width:0 0 2px 2px;margin:-20px 2px 0 -2px;cursor:sw-resize;top:200px;left:100px}.mce-croprect-handle-se{border-width:0 2px 2px 0;margin:-20px 0 0 -20px;cursor:se-resize;top:200px;left:200px}.mce-croprect-handle-move{position:absolute;cursor:move;border:0}.mce-croprect-block{opacity:.5;filter:alpha(opacity=50);zoom:1;position:absolute;background:black}.mce-croprect-handle:focus{border-color:#2276d2}.mce-croprect-handle-move:focus{outline:1px solid #2276d2}.mce-imagepanel{overflow:auto;background:black}.mce-imagepanel-bg{position:absolute;background:url('data:image/gif;base64,R0lGODdhDAAMAIABAMzMzP///ywAAAAADAAMAAACFoQfqYeabNyDMkBQb81Uat85nxguUAEAOw==')}.mce-imagepanel img{position:absolute}.mce-imagetool.mce-btn .mce-ico{display:block;width:20px;height:20px;text-align:center;line-height:20px;font-size:20px;padding:5px}.mce-arrow-up{margin-top:12px}.mce-arrow-down{margin-top:-12px}.mce-arrow:before,.mce-arrow:after{position:absolute;left:50%;display:block;width:0;height:0;border-style:solid;border-color:transparent;content:""}.mce-arrow.mce-arrow-up:before{top:-9px;border-bottom-color:#c5c5c5;border-width:0 9px 9px;margin-left:-9px}.mce-arrow.mce-arrow-down:before{bottom:-9px;border-top-color:#c5c5c5;border-width:9px 9px 0;margin-left:-9px}.mce-arrow.mce-arrow-up:after{top:-8px;border-bottom-color:#fff;border-width:0 8px 8px;margin-left:-8px}.mce-arrow.mce-arrow-down:after{bottom:-8px;border-top-color:#fff;border-width:8px 8px 0;margin-left:-8px}.mce-arrow.mce-arrow-left:before,.mce-arrow.mce-arrow-left:after{margin:0}.mce-arrow.mce-arrow-left:before{left:8px}.mce-arrow.mce-arrow-left:after{left:9px}.mce-arrow.mce-arrow-right:before,.mce-arrow.mce-arrow-right:after{left:auto;margin:0}.mce-arrow.mce-arrow-right:before{right:8px}.mce-arrow.mce-arrow-right:after{right:9px}.mce-arrow.mce-arrow-center.mce-arrow.mce-arrow-left:before{left:-9px;top:50%;border-right-color:#c5c5c5;border-width:9px 9px 9px 0;margin-top:-9px}.mce-arrow.mce-arrow-center.mce-arrow.mce-arrow-left:after{left:-8px;top:50%;border-right-color:#fff;border-width:8px 8px 8px 0;margin-top:-8px}.mce-arrow.mce-arrow-center.mce-arrow.mce-arrow-left{margin-left:12px}.mce-arrow.mce-arrow-center.mce-arrow.mce-arrow-right:before{right:-9px;top:50%;border-left-color:#c5c5c5;border-width:9px 0 9px 9px;margin-top:-9px}.mce-arrow.mce-arrow-center.mce-arrow.mce-arrow-right:after{right:-8px;top:50%;border-left-color:#fff;border-width:8px 0 8px 8px;margin-top:-8px}.mce-arrow.mce-arrow-center.mce-arrow.mce-arrow-right{margin-left:-14px}.mce-edit-aria-container>.mce-container-body{display:flex}.mce-edit-aria-container>.mce-container-body .mce-edit-area{flex:1}.mce-edit-aria-container>.mce-container-body .mce-sidebar>.mce-container-body{display:flex;align-items:stretch;height:100%}.mce-edit-aria-container>.mce-container-body .mce-sidebar-panel{min-width:250px;max-width:250px;position:relative}.mce-edit-aria-container>.mce-container-body .mce-sidebar-panel>.mce-container-body{position:absolute;width:100%;height:100%;overflow:auto;top:0;left:0}.mce-sidebar-toolbar{border:0 solid #c5c5c5;border-left-width:1px}.mce-sidebar-toolbar .mce-btn{border-left:0;border-right:0}.mce-sidebar-toolbar .mce-btn.mce-active,.mce-sidebar-toolbar .mce-btn.mce-active:hover{background-color:#555c66}.mce-sidebar-toolbar .mce-btn.mce-active button,.mce-sidebar-toolbar .mce-btn.mce-active:hover button,.mce-sidebar-toolbar .mce-btn.mce-active button i,.mce-sidebar-toolbar .mce-btn.mce-active:hover button i{color:white;text-shadow:1px 1px none}.mce-sidebar-panel{border:0 solid #c5c5c5;border-left-width:1px}.mce-container,.mce-container-body{display:block}.mce-autoscroll{overflow:hidden}.mce-scrollbar{position:absolute;width:7px;height:100%;top:2px;right:2px;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-scrollbar-h{top:auto;right:auto;left:2px;bottom:2px;width:100%;height:7px}.mce-scrollbar-thumb{position:absolute;background-color:#000;border:1px solid #888;border-color:rgba(85,85,85,0.6);width:5px;height:100%}.mce-scrollbar-h .mce-scrollbar-thumb{width:100%;height:5px}.mce-scrollbar:hover,.mce-scrollbar.mce-active{background-color:#AAA;opacity:.6;filter:alpha(opacity=60);zoom:1}.mce-scroll{position:relative}.mce-panel{border:0 solid #f3f3f3;border:0 solid #c5c5c5;background-color:#fff}.mce-floatpanel{position:absolute;-webkit-box-shadow:0 1px 2px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 1px 2px rgba(0, 0, 0, 0.2);box-shadow:0 1px 2px rgba(0, 0, 0, 0.2)}.mce-floatpanel.mce-fixed{position:fixed}.mce-floatpanel .mce-arrow,.mce-floatpanel .mce-arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.mce-floatpanel .mce-arrow{border-width:11px}.mce-floatpanel .mce-arrow:after{border-width:10px;content:""}.mce-floatpanel.mce-popover{filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;-webkit-box-shadow:0 1px 2px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 1px 2px rgba(0, 0, 0, 0.2);box-shadow:0 1px 2px rgba(0, 0, 0, 0.2);top:0;left:0;background:#FFF;border:1px solid #c5c5c5;border:1px solid rgba(0,0,0,0.25)}.mce-floatpanel.mce-popover.mce-bottom{margin-top:10px;*margin-top:0}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#c5c5c5;border-bottom-color:rgba(0,0,0,0.25);top:-11px}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow:after{top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#FFF}.mce-floatpanel.mce-popover.mce-top{margin-top:-10px;*margin-top:0}.mce-floatpanel.mce-popover.mce-top>.mce-arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#c5c5c5;top:auto;bottom:-11px}.mce-floatpanel.mce-popover.mce-top>.mce-arrow:after{bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#FFF}.mce-floatpanel.mce-popover.mce-bottom.mce-start,.mce-floatpanel.mce-popover.mce-top.mce-start{margin-left:-22px}.mce-floatpanel.mce-popover.mce-bottom.mce-start>.mce-arrow,.mce-floatpanel.mce-popover.mce-top.mce-start>.mce-arrow{left:20px}.mce-floatpanel.mce-popover.mce-bottom.mce-end,.mce-floatpanel.mce-popover.mce-top.mce-end{margin-left:22px}.mce-floatpanel.mce-popover.mce-bottom.mce-end>.mce-arrow,.mce-floatpanel.mce-popover.mce-top.mce-end>.mce-arrow{right:10px;left:auto}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;height:100%}div.mce-fullscreen{position:fixed;top:0;left:0}#mce-modal-block{opacity:0;filter:alpha(opacity=0);zoom:1;position:fixed;left:0;top:0;width:100%;height:100%;background:#FFF}#mce-modal-block.mce-in{opacity:.5;filter:alpha(opacity=50);zoom:1}.mce-window-move{cursor:move}.mce-window{-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;background:#FFF;position:fixed;top:0;left:0;opacity:0;transform:scale(.1);transition:transform 100ms ease-in,opacity 150ms ease-in}.mce-window.mce-in{transform:scale(1);opacity:1}.mce-window-head{padding:9px 15px;border-bottom:1px solid #c5c5c5;position:relative}.mce-window-head .mce-close{position:absolute;right:0;top:0;height:38px;width:38px;text-align:center;cursor:pointer}.mce-window-head .mce-close i{color:#9b9b9b}.mce-close:hover i{color:#bdbdbd}.mce-window-head .mce-title{line-height:20px;font-size:20px;font-weight:bold;text-rendering:optimizelegibility;padding-right:20px}.mce-window .mce-container-body{display:block}.mce-foot{display:block;background-color:#FFF;border-top:1px solid #c5c5c5}.mce-window-head .mce-dragh{position:absolute;top:0;left:0;cursor:move;width:90%;height:100%}.mce-window iframe{width:100%;height:100%}.mce-window-body .mce-listbox{border-color:#e2e4e7}.mce-window .mce-btn:hover{border-color:#c5c5c5}.mce-window .mce-btn:focus{border-color:#2276d2}.mce-window-body .mce-btn,.mce-foot .mce-btn{border-color:#c5c5c5}.mce-foot .mce-btn.mce-primary{border-color:transparent}.mce-rtl .mce-window-head .mce-close{position:absolute;right:auto;left:0}.mce-rtl .mce-window-head .mce-dragh{left:auto;right:0}.mce-rtl .mce-window-head .mce-title{direction:rtl;text-align:right;padding-right:0;padding-left:20px}.mce-tooltip{position:absolute;padding:5px;opacity:.8;filter:alpha(opacity=80);zoom:1;margin-top:1px}.mce-tooltip-inner{font-size:11px;background-color:#000;color:white;max-width:200px;padding:5px 8px 4px 8px;text-align:center;white-space:normal}.mce-tooltip-inner{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-tooltip-arrow{position:absolute;width:0;height:0;line-height:0;border:5px dashed #000}.mce-tooltip-arrow-n{border-bottom-color:#000}.mce-tooltip-arrow-s{border-top-color:#000}.mce-tooltip-arrow-e{border-left-color:#000}.mce-tooltip-arrow-w{border-right-color:#000}.mce-tooltip-nw,.mce-tooltip-sw{margin-left:-14px}.mce-tooltip-ne,.mce-tooltip-se{margin-left:14px}.mce-tooltip-n .mce-tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-nw .mce-tooltip-arrow{top:0;left:10px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-ne .mce-tooltip-arrow{top:0;right:10px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-s .mce-tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-sw .mce-tooltip-arrow{bottom:0;left:10px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-se .mce-tooltip-arrow{bottom:0;right:10px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-e .mce-tooltip-arrow{right:0;top:50%;margin-top:-5px;border-left-style:solid;border-right:none;border-top-color:transparent;border-bottom-color:transparent}.mce-tooltip-w .mce-tooltip-arrow{left:0;top:50%;margin-top:-5px;border-right-style:solid;border-left:none;border-top-color:transparent;border-bottom-color:transparent}.mce-progress{display:inline-block;position:relative;height:20px}.mce-progress .mce-bar-container{display:inline-block;width:100px;height:100%;margin-right:8px;border:1px solid #ccc;overflow:hidden}.mce-progress .mce-text{display:inline-block;margin-top:auto;margin-bottom:auto;font-size:14px;width:40px;color:#595959}.mce-bar{display:block;width:0;height:100%;background-color:#dfdfdf;-webkit-transition:width .2s ease;transition:width .2s ease}.mce-notification{position:absolute;background-color:#fff;padding:5px;margin-top:5px;border-width:1px;border-style:solid;border-color:#c5c5c5;transition:transform 100ms ease-in,opacity 150ms ease-in;opacity:0;box-sizing:border-box}.mce-notification.mce-in{opacity:1}.mce-notification-success{background-color:#dff0d8;border-color:#d6e9c6}.mce-notification-info{background-color:#d9edf7;border-color:#779ECB}.mce-notification-warning{background-color:#fcf8e3;border-color:#faebcc}.mce-notification-error{background-color:#f2dede;border-color:#ebccd1}.mce-notification.mce-has-close{padding-right:15px}.mce-notification .mce-ico{margin-top:5px}.mce-notification-inner{word-wrap:break-word;-ms-word-break:break-all;word-break:break-all;word-break:break-word;-ms-hyphens:auto;-moz-hyphens:auto;-webkit-hyphens:auto;hyphens:auto;display:inline-block;font-size:14px;margin:5px 8px 4px 8px;text-align:center;white-space:normal;color:#31708f}.mce-notification-inner a{text-decoration:underline;cursor:pointer}.mce-notification .mce-progress{margin-right:8px}.mce-notification .mce-progress .mce-text{margin-top:5px}.mce-notification *,.mce-notification .mce-progress .mce-text{color:#595959}.mce-notification .mce-progress .mce-bar-container{border-color:#c5c5c5}.mce-notification .mce-progress .mce-bar-container .mce-bar{background-color:#595959}.mce-notification-success *,.mce-notification-success .mce-progress .mce-text{color:#3c763d}.mce-notification-success .mce-progress .mce-bar-container{border-color:#d6e9c6}.mce-notification-success .mce-progress .mce-bar-container .mce-bar{background-color:#3c763d}.mce-notification-info *,.mce-notification-info .mce-progress .mce-text{color:#31708f}.mce-notification-info .mce-progress .mce-bar-container{border-color:#779ECB}.mce-notification-info .mce-progress .mce-bar-container .mce-bar{background-color:#31708f}.mce-notification-warning *,.mce-notification-warning .mce-progress .mce-text{color:#8a6d3b}.mce-notification-warning .mce-progress .mce-bar-container{border-color:#faebcc}.mce-notification-warning .mce-progress .mce-bar-container .mce-bar{background-color:#8a6d3b}.mce-notification-error *,.mce-notification-error .mce-progress .mce-text{color:#a94442}.mce-notification-error .mce-progress .mce-bar-container{border-color:#ebccd1}.mce-notification-error .mce-progress .mce-bar-container .mce-bar{background-color:#a94442}.mce-notification .mce-close{position:absolute;top:6px;right:8px;font-size:20px;font-weight:bold;line-height:20px;color:#9b9b9b;cursor:pointer}.mce-abs-layout{position:relative}html .mce-abs-layout-item,.mce-abs-end{position:absolute}.mce-abs-end{width:1px;height:1px}.mce-container-body.mce-abs-layout{overflow:hidden}.mce-btn{border:1px solid #b3b3b3;border-color:transparent transparent transparent transparent;position:relative;text-shadow:0 1px 1px rgba(255,255,255,0.75);background:white;display:inline-block;*display:inline;*zoom:1;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-btn:hover,.mce-btn:active{background:white;color:#595959;border-color:#e2e4e7}.mce-btn:focus{background:white;color:#595959;border-color:#e2e4e7}.mce-btn.mce-disabled button,.mce-btn.mce-disabled:hover button{cursor:default;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-btn.mce-active,.mce-btn.mce-active:hover,.mce-btn.mce-active:focus,.mce-btn.mce-active:active{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;background:#555c66;color:white;border-color:transparent}.mce-btn.mce-active button,.mce-btn.mce-active:hover button,.mce-btn.mce-active i,.mce-btn.mce-active:hover i{color:white}.mce-btn:hover .mce-caret{border-top-color:#b5bcc2}.mce-btn.mce-active .mce-caret,.mce-btn.mce-active:hover .mce-caret{border-top-color:white}.mce-btn button{padding:4px 6px;font-size:14px;line-height:20px;*line-height:16px;cursor:pointer;color:#595959;text-align:center;overflow:visible;-webkit-appearance:none}.mce-btn button::-moz-focus-inner{border:0;padding:0}.mce-btn i{text-shadow:1px 1px none}.mce-primary.mce-btn-has-text{min-width:50px}.mce-primary{color:white;border:1px solid transparent;border-color:transparent;background-color:#2276d2}.mce-primary:hover,.mce-primary:focus{background-color:#1e6abc;border-color:transparent}.mce-primary.mce-disabled button,.mce-primary.mce-disabled:hover button{cursor:default;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-primary.mce-active,.mce-primary.mce-active:hover,.mce-primary:not(.mce-disabled):active{background-color:#1e6abc;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-primary button,.mce-primary button i{color:white;text-shadow:1px 1px none}.mce-btn .mce-txt{font-size:inherit;line-height:inherit;color:inherit}.mce-btn-large button{padding:9px 14px;font-size:16px;line-height:normal}.mce-btn-large i{margin-top:2px}.mce-btn-small button{padding:1px 5px;font-size:12px;*padding-bottom:2px}.mce-btn-small i{line-height:20px;vertical-align:top;*line-height:18px}.mce-btn .mce-caret{margin-top:8px;margin-left:0}.mce-btn-small .mce-caret{margin-top:8px;margin-left:0}.mce-caret{display:inline-block;*display:inline;*zoom:1;width:0;height:0;vertical-align:top;border-top:4px solid #b5bcc2;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.mce-disabled .mce-caret{border-top-color:#aaa}.mce-caret.mce-up{border-bottom:4px solid #b5bcc2;border-top:0}.mce-btn-flat{border:0;background:transparent;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;filter:none}.mce-btn-flat:hover,.mce-btn-flat.mce-active,.mce-btn-flat:focus,.mce-btn-flat:active{border:0;background:#e6e6e6;filter:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-btn-has-text .mce-ico{padding-right:5px}.mce-rtl .mce-btn button{direction:rtl}.mce-toolbar .mce-btn-group{margin:0;padding:2px 0}.mce-btn-group .mce-btn{border-width:1px;margin:0;margin-left:2px}.mce-btn-group:not(:first-child){border-left:1px solid #d9d9d9;padding-left:0;margin-left:2px}.mce-btn-group{margin-left:2px}.mce-btn-group .mce-btn.mce-flow-layout-item{margin:0}.mce-rtl .mce-btn-group .mce-btn{margin-left:0;margin-right:2px}.mce-rtl .mce-btn-group .mce-first{margin-right:0}.mce-rtl .mce-btn-group:not(:first-child){border-left:none;border-right:1px solid #d9d9d9;padding-right:4px;margin-right:4px}.mce-checkbox{cursor:pointer}i.mce-i-checkbox{margin:0 3px 0 0;border:1px solid #c5c5c5;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;background-color:white;text-indent:-10em;overflow:hidden}.mce-checked i.mce-i-checkbox{color:#595959;font-size:16px;line-height:16px;text-indent:0}.mce-checkbox:focus i.mce-i-checkbox,.mce-checkbox.mce-focus i.mce-i-checkbox{border:1px solid #2276d2;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-checkbox.mce-disabled .mce-label,.mce-checkbox.mce-disabled i.mce-i-checkbox{color:#bdbdbd}.mce-checkbox .mce-label{vertical-align:middle}.mce-rtl .mce-checkbox{direction:rtl;text-align:right}.mce-rtl i.mce-i-checkbox{margin:0 0 0 3px}.mce-combobox{position:relative;display:inline-block;*display:inline;*zoom:1;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;*height:32px}.mce-combobox input{border:1px solid #c5c5c5;border-right-color:#c5c5c5;height:28px}.mce-combobox.mce-disabled input{color:#bdbdbd}.mce-combobox .mce-btn{border:1px solid #c5c5c5;border-left:0;margin:0}.mce-combobox button{padding-right:8px;padding-left:8px}.mce-combobox.mce-disabled .mce-btn button{cursor:default;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-combobox .mce-status{position:absolute;right:2px;top:50%;line-height:16px;margin-top:-8px;font-size:12px;width:15px;height:15px;text-align:center;cursor:pointer}.mce-combobox.mce-has-status input{padding-right:20px}.mce-combobox.mce-has-open .mce-status{right:37px}.mce-combobox .mce-status.mce-i-warning{color:#c09853}.mce-combobox .mce-status.mce-i-checkmark{color:#468847}.mce-menu.mce-combobox-menu{border-top:0;margin-top:0;max-height:200px}.mce-menu.mce-combobox-menu .mce-menu-item{padding:4px 6px 4px 4px;font-size:11px}.mce-menu.mce-combobox-menu .mce-menu-item-sep{padding:0}.mce-menu.mce-combobox-menu .mce-text,.mce-menu.mce-combobox-menu .mce-text b{font-size:11px}.mce-menu.mce-combobox-menu .mce-menu-item-link,.mce-menu.mce-combobox-menu .mce-menu-item-link b{font-size:11px}.mce-colorbox i{border:1px solid #c5c5c5;width:14px;height:14px}.mce-colorbutton .mce-ico{position:relative}.mce-colorbutton-grid{margin:4px}.mce-colorbutton .mce-preview{padding-right:3px;display:block;position:absolute;left:50%;top:50%;margin-left:-17px;margin-top:7px;background:gray;width:13px;height:2px;overflow:hidden}.mce-colorbutton.mce-btn-small .mce-preview{margin-left:-16px;padding-right:0;width:16px}.mce-rtl .mce-colorbutton{direction:rtl}.mce-rtl .mce-colorbutton .mce-preview{margin-left:0;padding-right:0;padding-left:3px}.mce-rtl .mce-colorbutton.mce-btn-small .mce-preview{margin-left:0;padding-right:0;padding-left:2px}.mce-rtl .mce-colorbutton .mce-open{padding-left:4px;padding-right:4px;border-left:0}.mce-colorpicker{position:relative;width:250px;height:220px}.mce-colorpicker-sv{position:absolute;top:0;left:0;width:90%;height:100%;border:1px solid #c5c5c5;cursor:crosshair;overflow:hidden}.mce-colorpicker-h-chunk{width:100%}.mce-colorpicker-overlay1,.mce-colorpicker-overlay2{width:100%;height:100%;position:absolute;top:0;left:0}.mce-colorpicker-overlay1{filter:progid:DXImageTransform.Microsoft.gradient(GradientType=1, startColorstr='#ffffff', endColorstr='#00ffffff');-ms-filter:"progid:DXImageTransform.Microsoft.gradient(GradientType=1,startColorstr='#ffffff', endColorstr='#00ffffff')";background:linear-gradient(to right, #fff, rgba(255,255,255,0))}.mce-colorpicker-overlay2{filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#00000000', endColorstr='#000000');-ms-filter:"progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#00000000', endColorstr='#000000')";background:linear-gradient(to bottom, rgba(0,0,0,0), #000)}.mce-colorpicker-selector1{background:none;position:absolute;width:12px;height:12px;margin:-8px 0 0 -8px;border:1px solid black;border-radius:50%}.mce-colorpicker-selector2{position:absolute;width:10px;height:10px;border:1px solid white;border-radius:50%}.mce-colorpicker-h{position:absolute;top:0;right:0;width:6.5%;height:100%;border:1px solid #c5c5c5;cursor:crosshair}.mce-colorpicker-h-marker{margin-top:-4px;position:absolute;top:0;left:-1px;width:100%;border:1px solid black;background:white;height:4px;z-index:100}.mce-path{display:inline-block;*display:inline;*zoom:1;padding:8px;white-space:normal;font-size:inherit}.mce-path .mce-txt{display:inline-block;padding-right:3px}.mce-path .mce-path-body{display:inline-block}.mce-path-item{display:inline-block;*display:inline;*zoom:1;cursor:pointer;color:#595959;font-size:inherit;text-transform:uppercase}.mce-path-item:hover{text-decoration:underline}.mce-path-item:focus{background:#555c66;color:white}.mce-path .mce-divider{display:inline;font-size:inherit}.mce-disabled .mce-path-item{color:#aaa}.mce-rtl .mce-path{direction:rtl}.mce-fieldset{border:0 solid #9E9E9E}.mce-fieldset>.mce-container-body{margin-top:-15px}.mce-fieldset-title{margin-left:5px;padding:0 5px 0 5px}.mce-fit-layout{display:inline-block;*display:inline;*zoom:1}.mce-fit-layout-item{position:absolute}.mce-flow-layout-item{display:inline-block;*display:inline;*zoom:1}.mce-flow-layout-item{margin:2px 0 2px 2px}.mce-flow-layout-item.mce-last{margin-right:2px}.mce-flow-layout{white-space:normal}.mce-tinymce-inline .mce-flow-layout{white-space:nowrap}.mce-rtl .mce-flow-layout{text-align:right;direction:rtl}.mce-rtl .mce-flow-layout-item{margin:2px 2px 2px 0}.mce-rtl .mce-flow-layout-item.mce-last{margin-left:2px}.mce-iframe{border:0 solid #c5c5c5;width:100%;height:100%}.mce-infobox{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 1px rgba(255,255,255,0.75);overflow:hidden;border:1px solid red}.mce-infobox div{display:block;margin:5px}.mce-infobox div button{position:absolute;top:50%;right:4px;cursor:pointer;margin-top:-8px;display:none}.mce-infobox div button:focus{outline:2px solid #e2e4e7}.mce-infobox.mce-has-help div{margin-right:25px}.mce-infobox.mce-has-help button{display:block}.mce-infobox.mce-success{background:#dff0d8;border-color:#d6e9c6}.mce-infobox.mce-success div{color:#3c763d}.mce-infobox.mce-warning{background:#fcf8e3;border-color:#faebcc}.mce-infobox.mce-warning div{color:#8a6d3b}.mce-infobox.mce-error{background:#f2dede;border-color:#ebccd1}.mce-infobox.mce-error div{color:#a94442}.mce-rtl .mce-infobox div{text-align:right;direction:rtl}.mce-label{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 1px rgba(255,255,255,0.75);overflow:hidden}.mce-label.mce-autoscroll{overflow:auto}.mce-label.mce-disabled{color:#aaa}.mce-label.mce-multiline{white-space:pre-wrap}.mce-label.mce-success{color:#468847}.mce-label.mce-warning{color:#c09853}.mce-label.mce-error{color:#b94a48}.mce-rtl .mce-label{text-align:right;direction:rtl}.mce-menubar{border:1px solid #e2e4e7}.mce-menubar .mce-menubtn{border-color:transparent;background:transparent;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;filter:none}.mce-menubar .mce-menubtn button span{color:#595959}.mce-menubar .mce-caret{border-top-color:#b5bcc2}.mce-menubar .mce-active .mce-caret,.mce-menubar .mce-menubtn:hover .mce-caret{border-top-color:#b5bcc2}.mce-menubar .mce-menubtn:hover,.mce-menubar .mce-menubtn.mce-active,.mce-menubar .mce-menubtn:focus{border-color:#e2e4e7;background:white;filter:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-menubar .mce-menubtn.mce-active{border-bottom:none;z-index:65537}div.mce-menubtn.mce-opened{border-bottom-color:white;z-index:65537}.mce-menubtn button{color:#595959}.mce-menubtn.mce-btn-small span{font-size:12px}.mce-menubtn.mce-fixed-width span{display:inline-block;overflow-x:hidden;text-overflow:ellipsis;width:90px}.mce-menubtn.mce-fixed-width.mce-btn-small span{width:70px}.mce-menubtn .mce-caret{*margin-top:6px}.mce-rtl .mce-menubtn button{direction:rtl;text-align:right}.mce-rtl .mce-menubtn.mce-fixed-width span{direction:rtl;text-align:right}.mce-menu-item{display:block;padding:6px 4px 6px 4px;clear:both;font-weight:normal;line-height:20px;color:#595959;white-space:nowrap;cursor:pointer;line-height:normal;border-left:4px solid transparent;margin-bottom:1px}.mce-menu-item .mce-text,.mce-menu-item .mce-text b{line-height:1;vertical-align:initial}.mce-menu-item .mce-caret{margin-top:4px;margin-right:6px;border-top:4px solid transparent;border-bottom:4px solid transparent;border-left:4px solid #595959}.mce-menu-item .mce-menu-shortcut{display:inline-block;padding:0 10px 0 20px;color:#aaa}.mce-menu-item .mce-ico{padding-right:4px}.mce-menu-item:hover,.mce-menu-item:focus{background:#ededee}.mce-menu-item:hover .mce-menu-shortcut,.mce-menu-item:focus .mce-menu-shortcut{color:#aaa}.mce-menu-item:hover .mce-text,.mce-menu-item:focus .mce-text,.mce-menu-item:hover .mce-ico,.mce-menu-item:focus .mce-ico{color:#595959}.mce-menu-item.mce-selected{background:#ededee}.mce-menu-item.mce-selected .mce-text,.mce-menu-item.mce-selected .mce-ico{color:#595959}.mce-menu-item.mce-active.mce-menu-item-normal{background:#555c66}.mce-menu-item.mce-active.mce-menu-item-normal .mce-text,.mce-menu-item.mce-active.mce-menu-item-normal .mce-ico{color:white}.mce-menu-item.mce-active.mce-menu-item-checkbox .mce-ico{visibility:visible}.mce-menu-item.mce-disabled,.mce-menu-item.mce-disabled:hover{background:white}.mce-menu-item.mce-disabled:focus,.mce-menu-item.mce-disabled:hover:focus{background:#ededee}.mce-menu-item.mce-disabled .mce-text,.mce-menu-item.mce-disabled:hover .mce-text,.mce-menu-item.mce-disabled .mce-ico,.mce-menu-item.mce-disabled:hover .mce-ico{color:#aaa}.mce-menu-item.mce-menu-item-preview.mce-active{border-left:5px solid #555c66;background:white}.mce-menu-item.mce-menu-item-preview.mce-active .mce-text,.mce-menu-item.mce-menu-item-preview.mce-active .mce-ico{color:#595959}.mce-menu-item.mce-menu-item-preview.mce-active:hover{background:#ededee}.mce-menu-item-link{color:#093;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mce-menu-item-link b{color:#093}.mce-menu-item-ellipsis{display:block;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.mce-menu-item:hover *,.mce-menu-item.mce-selected *,.mce-menu-item:focus *{color:#595959}div.mce-menu .mce-menu-item-sep,.mce-menu-item-sep:hover{border:0;padding:0;height:1px;margin:9px 1px;overflow:hidden;background:transparent;border-bottom:1px solid rgba(0,0,0,0.1);cursor:default;filter:none}div.mce-menu .mce-menu-item b{font-weight:bold}.mce-menu-item-indent-1{padding-left:20px}.mce-menu-item-indent-2{padding-left:35px}.mce-menu-item-indent-2{padding-left:35px}.mce-menu-item-indent-3{padding-left:40px}.mce-menu-item-indent-4{padding-left:45px}.mce-menu-item-indent-5{padding-left:50px}.mce-menu-item-indent-6{padding-left:55px}.mce-menu.mce-rtl{direction:rtl}.mce-rtl .mce-menu-item{text-align:right;direction:rtl;padding:6px 12px 6px 15px}.mce-rtl .mce-menu-item .mce-caret{margin-left:6px;margin-right:0;border-right:4px solid #595959;border-left:0}.mce-rtl .mce-menu-item.mce-selected .mce-caret,.mce-rtl .mce-menu-item:focus .mce-caret,.mce-rtl .mce-menu-item:hover .mce-caret{border-left-color:transparent;border-right-color:#595959}.mce-rtl .mce-menu-item .mce-ico{padding-right:0;padding-left:4px}.mce-throbber{position:absolute;top:0;left:0;width:100%;height:100%;opacity:.6;filter:alpha(opacity=60);zoom:1;background:#fff url('img/loader.gif') no-repeat center center}.mce-throbber-inline{position:static;height:50px}.mce-menu .mce-throbber-inline{height:25px;background-size:contain}.mce-menu{position:absolute;left:0;top:0;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;z-index:1000;padding:5px 0 5px 0;margin:-1px 0 0;min-width:180px;background:white;border:1px solid #c5c9cf;border:1px solid #e2e4e7;z-index:1002;-webkit-box-shadow:0 1px 2px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 1px 2px rgba(0, 0, 0, 0.2);box-shadow:0 1px 2px rgba(0, 0, 0, 0.2);max-height:500px;overflow:auto;overflow-x:hidden}.mce-menu.mce-animate{opacity:.01;transform:rotateY(10deg) rotateX(-10deg);transform-origin:left top}.mce-menu.mce-menu-align .mce-menu-shortcut,.mce-menu.mce-menu-align .mce-caret{position:absolute;right:0}.mce-menu i{display:none}.mce-menu-has-icons i{display:inline-block}.mce-menu.mce-in.mce-animate{opacity:1;transform:rotateY(0) rotateX(0);transition:opacity .075s ease,transform .1s ease}.mce-menu-sub-tr-tl{margin:-6px 0 0 -1px}.mce-menu-sub-br-bl{margin:6px 0 0 -1px}.mce-menu-sub-tl-tr{margin:-6px 0 0 1px}.mce-menu-sub-bl-br{margin:6px 0 0 1px}.mce-rtl .mce-menu-item .mce-ico{padding-right:0;padding-left:4px}.mce-rtl.mce-menu-align .mce-caret,.mce-rtl .mce-menu-shortcut{right:auto;left:0}.mce-listbox button{text-align:left;padding-right:20px;position:relative}.mce-listbox .mce-caret{position:absolute;margin-top:-2px;right:8px;top:50%}.mce-rtl .mce-listbox .mce-caret{right:auto;left:8px}.mce-rtl .mce-listbox button{padding-right:10px;padding-left:20px}.mce-container-body .mce-resizehandle{position:absolute;right:0;bottom:0;width:16px;height:16px;visibility:visible;cursor:s-resize;margin:0}.mce-container-body .mce-resizehandle-both{cursor:se-resize}i.mce-i-resize{color:#595959}.mce-selectbox{background:#fff;border:1px solid #c5c5c5}.mce-slider{border:1px solid #c5c5c5;background:#fff;width:100px;height:10px;position:relative;display:block}.mce-slider.mce-vertical{width:10px;height:100px}.mce-slider-handle{border:1px solid #c5c5c5;background:#e6e6e6;display:block;width:13px;height:13px;position:absolute;top:0;left:0;margin-left:-1px;margin-top:-2px}.mce-slider-handle:focus{border-color:#2276d2}.mce-spacer{visibility:hidden}.mce-splitbtn:hover .mce-open{border-left:1px solid #e2e4e7}.mce-splitbtn .mce-open{border-left:1px solid transparent;padding-right:4px;padding-left:4px}.mce-splitbtn .mce-open:focus{border-left:1px solid #e2e4e7}.mce-splitbtn .mce-open:hover,.mce-splitbtn .mce-open:active{border-left:1px solid #e2e4e7}.mce-splitbtn.mce-active:hover .mce-open{border-left:1px solid white}.mce-splitbtn.mce-opened{border-color:#e2e4e7}.mce-splitbtn.mce-btn-small .mce-open{padding:0 3px 0 3px}.mce-rtl .mce-splitbtn{direction:rtl;text-align:right}.mce-rtl .mce-splitbtn button{padding-right:4px;padding-left:4px}.mce-rtl .mce-splitbtn .mce-open{border-left:0}.mce-stack-layout-item{display:block}.mce-tabs{display:block;border-bottom:1px solid #c5c5c5}.mce-tabs,.mce-tabs+.mce-container-body{background:#fff}.mce-tab{display:inline-block;*display:inline;*zoom:1;border:1px solid #c5c5c5;border-width:0 1px 0 0;background:#fff;padding:8px 15px;text-shadow:0 1px 1px rgba(255,255,255,0.75);height:13px;cursor:pointer}.mce-tab:hover{background:#FDFDFD}.mce-tab.mce-active{background:#FDFDFD;border-bottom-color:transparent;margin-bottom:-1px;height:14px}.mce-tab:focus{color:#2276d2}.mce-rtl .mce-tabs{text-align:right;direction:rtl}.mce-rtl .mce-tab{border-width:0 0 0 1px}.mce-textbox{background:#fff;border:1px solid #c5c5c5;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;display:inline-block;-webkit-transition:border linear .2s, box-shadow linear .2s;transition:border linear .2s, box-shadow linear .2s;height:28px;resize:none;padding:0 4px 0 4px;white-space:pre-wrap;*white-space:pre;color:#595959}.mce-textbox:focus,.mce-textbox.mce-focus{border-color:#2276d2;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-placeholder .mce-textbox{color:#aaa}.mce-textbox.mce-multiline{padding:4px;height:auto}.mce-textbox.mce-disabled{color:#bdbdbd}.mce-rtl .mce-textbox{text-align:right;direction:rtl}.mce-dropzone{border:3px dashed gray;text-align:center}.mce-dropzone span{text-transform:uppercase;display:inline-block;vertical-align:middle}.mce-dropzone:after{content:"";height:100%;display:inline-block;vertical-align:middle}.mce-dropzone.mce-disabled{opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-dropzone.mce-disabled.mce-dragenter{cursor:not-allowed}.mce-browsebutton{position:relative;overflow:hidden}.mce-browsebutton button{position:relative;z-index:1}.mce-browsebutton input{opacity:0;filter:alpha(opacity=0);zoom:1;position:absolute;top:0;left:0;width:100%;height:100%;z-index:0}@font-face{font-family:'tinymce';src:url('fonts/tinymce.eot');src:url('fonts/tinymce.eot?#iefix') format('embedded-opentype'),url('fonts/tinymce.woff') format('woff'),url('fonts/tinymce.ttf') format('truetype'),url('fonts/tinymce.svg#tinymce') format('svg');font-weight:normal;font-style:normal}@font-face{font-family:'tinymce-small';src:url('fonts/tinymce-small.eot');src:url('fonts/tinymce-small.eot?#iefix') format('embedded-opentype'),url('fonts/tinymce-small.woff') format('woff'),url('fonts/tinymce-small.ttf') format('truetype'),url('fonts/tinymce-small.svg#tinymce') format('svg');font-weight:normal;font-style:normal}.mce-ico{font-family:'tinymce',Arial;font-style:normal;font-weight:normal;font-variant:normal;font-size:16px;line-height:16px;speak:none;vertical-align:text-top;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:inline-block;background:transparent center center;background-size:cover;width:16px;height:16px;color:#595959}.mce-btn-small .mce-ico{font-family:'tinymce-small',Arial}.mce-i-save:before{content:"\e000"}.mce-i-newdocument:before{content:"\e001"}.mce-i-fullpage:before{content:"\e002"}.mce-i-alignleft:before{content:"\e003"}.mce-i-aligncenter:before{content:"\e004"}.mce-i-alignright:before{content:"\e005"}.mce-i-alignjustify:before{content:"\e006"}.mce-i-alignnone:before{content:"\e003"}.mce-i-cut:before{content:"\e007"}.mce-i-paste:before{content:"\e008"}.mce-i-searchreplace:before{content:"\e009"}.mce-i-bullist:before{content:"\e00a"}.mce-i-numlist:before{content:"\e00b"}.mce-i-indent:before{content:"\e00c"}.mce-i-outdent:before{content:"\e00d"}.mce-i-blockquote:before{content:"\e00e"}.mce-i-undo:before{content:"\e00f"}.mce-i-redo:before{content:"\e010"}.mce-i-link:before{content:"\e011"}.mce-i-unlink:before{content:"\e012"}.mce-i-anchor:before{content:"\e013"}.mce-i-image:before{content:"\e014"}.mce-i-media:before{content:"\e015"}.mce-i-help:before{content:"\e016"}.mce-i-code:before{content:"\e017"}.mce-i-insertdatetime:before{content:"\e018"}.mce-i-preview:before{content:"\e019"}.mce-i-forecolor:before{content:"\e01a"}.mce-i-backcolor:before{content:"\e01a"}.mce-i-table:before{content:"\e01b"}.mce-i-hr:before{content:"\e01c"}.mce-i-removeformat:before{content:"\e01d"}.mce-i-subscript:before{content:"\e01e"}.mce-i-superscript:before{content:"\e01f"}.mce-i-charmap:before{content:"\e020"}.mce-i-emoticons:before{content:"\e021"}.mce-i-print:before{content:"\e022"}.mce-i-fullscreen:before{content:"\e023"}.mce-i-spellchecker:before{content:"\e024"}.mce-i-nonbreaking:before{content:"\e025"}.mce-i-template:before{content:"\e026"}.mce-i-pagebreak:before{content:"\e027"}.mce-i-restoredraft:before{content:"\e028"}.mce-i-bold:before{content:"\e02a"}.mce-i-italic:before{content:"\e02b"}.mce-i-underline:before{content:"\e02c"}.mce-i-strikethrough:before{content:"\e02d"}.mce-i-visualchars:before{content:"\e02e"}.mce-i-visualblocks:before{content:"\e02e"}.mce-i-ltr:before{content:"\e02f"}.mce-i-rtl:before{content:"\e030"}.mce-i-copy:before{content:"\e031"}.mce-i-resize:before{content:"\e032"}.mce-i-browse:before{content:"\e034"}.mce-i-pastetext:before{content:"\e035"}.mce-i-rotateleft:before{content:"\eaa8"}.mce-i-rotateright:before{content:"\eaa9"}.mce-i-crop:before{content:"\ee78"}.mce-i-editimage:before{content:"\e915"}.mce-i-options:before{content:"\ec6a"}.mce-i-flipv:before{content:"\eaaa"}.mce-i-fliph:before{content:"\eaac"}.mce-i-zoomin:before{content:"\eb35"}.mce-i-zoomout:before{content:"\eb36"}.mce-i-sun:before{content:"\eccc"}.mce-i-moon:before{content:"\eccd"}.mce-i-arrowleft:before{content:"\edc0"}.mce-i-arrowright:before{content:"\e93c"}.mce-i-drop:before{content:"\e935"}.mce-i-contrast:before{content:"\ecd4"}.mce-i-sharpen:before{content:"\eba7"}.mce-i-resize2:before{content:"\edf9"}.mce-i-orientation:before{content:"\e601"}.mce-i-invert:before{content:"\e602"}.mce-i-gamma:before{content:"\e600"}.mce-i-remove:before{content:"\ed6a"}.mce-i-tablerowprops:before{content:"\e604"}.mce-i-tablecellprops:before{content:"\e605"}.mce-i-table2:before{content:"\e606"}.mce-i-tablemergecells:before{content:"\e607"}.mce-i-tableinsertcolbefore:before{content:"\e608"}.mce-i-tableinsertcolafter:before{content:"\e609"}.mce-i-tableinsertrowbefore:before{content:"\e60a"}.mce-i-tableinsertrowafter:before{content:"\e60b"}.mce-i-tablesplitcells:before{content:"\e60d"}.mce-i-tabledelete:before{content:"\e60e"}.mce-i-tableleftheader:before{content:"\e62a"}.mce-i-tabletopheader:before{content:"\e62b"}.mce-i-tabledeleterow:before{content:"\e800"}.mce-i-tabledeletecol:before{content:"\e801"}.mce-i-codesample:before{content:"\e603"}.mce-i-fill:before{content:"\e902"}.mce-i-borderwidth:before{content:"\e903"}.mce-i-line:before{content:"\e904"}.mce-i-count:before{content:"\e905"}.mce-i-translate:before{content:"\e907"}.mce-i-drag:before{content:"\e908"}.mce-i-home:before{content:"\e90b"}.mce-i-upload:before{content:"\e914"}.mce-i-bubble:before{content:"\e91c"}.mce-i-user:before{content:"\e91d"}.mce-i-lock:before{content:"\e926"}.mce-i-unlock:before{content:"\e927"}.mce-i-settings:before{content:"\e928"}.mce-i-remove2:before{content:"\e92a"}.mce-i-menu:before{content:"\e92d"}.mce-i-warning:before{content:"\e930"}.mce-i-question:before{content:"\e931"}.mce-i-pluscircle:before{content:"\e932"}.mce-i-info:before{content:"\e933"}.mce-i-notice:before{content:"\e934"}.mce-i-arrowup:before{content:"\e93b"}.mce-i-arrowdown:before{content:"\e93d"}.mce-i-arrowup2:before{content:"\e93f"}.mce-i-arrowdown2:before{content:"\e940"}.mce-i-menu2:before{content:"\e941"}.mce-i-newtab:before{content:"\e961"}.mce-i-a11y:before{content:"\e900"}.mce-i-plus:before{content:"\e93a"}.mce-i-insert:before{content:"\e93a"}.mce-i-minus:before{content:"\e939"}.mce-i-books:before{content:"\e911"}.mce-i-reload:before{content:"\e906"}.mce-i-toc:before{content:"\e901"}.mce-i-checkmark:before{content:"\e033"}.mce-i-checkbox:before,.mce-i-selected:before{content:"\e033"}.mce-i-insert{font-size:14px}.mce-i-selected{visibility:hidden}i.mce-i-backcolor{text-shadow:none;background:#BBB}.mce-rtl .mce-filepicker input{direction:ltr}/*# sourceMappingURL=skin.min.css.map */ \ No newline at end of file +.mce-container,.mce-container *,.mce-widget,.mce-widget *,.mce-reset{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:#595959;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;-webkit-tap-highlight-color:transparent;line-height:normal;font-weight:normal;text-align:left;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr;max-width:none}.mce-widget button{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.mce-container *[unselectable]{-moz-user-select:none;-webkit-user-select:none;-o-user-select:none;user-select:none}.word-wrap{word-wrap:break-word;-ms-word-break:break-all;word-break:break-all;word-break:break-word;-ms-hyphens:auto;-moz-hyphens:auto;-webkit-hyphens:auto;hyphens:auto}.mce-fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.mce-fade.mce-in{opacity:1}.mce-tinymce{visibility:inherit !important;position:relative}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;height:100%;z-index:100}div.mce-fullscreen{position:fixed;top:0;left:0;width:100%;height:auto}.mce-tinymce{display:block;-webkit-box-shadow:0 1px 2px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 1px 2px rgba(0, 0, 0, 0.2);box-shadow:0 1px 2px rgba(0, 0, 0, 0.2)}.mce-statusbar>.mce-container-body{display:flex;padding-right:16px}.mce-statusbar>.mce-container-body .mce-path{flex:1}.mce-wordcount{font-size:inherit;text-transform:uppercase;padding:8px 0}div.mce-edit-area{background:#FFF;filter:none}.mce-statusbar{position:relative}.mce-statusbar .mce-container-body{position:relative;font-size:11px}.mce-fullscreen .mce-resizehandle{display:none}.mce-statusbar .mce-flow-layout-item{margin:0}.mce-charmap{border-collapse:collapse}.mce-charmap td{cursor:default;border:1px solid #c5c5c5;width:20px;height:20px;line-height:20px;text-align:center;vertical-align:middle;padding:2px}.mce-charmap td div{text-align:center}.mce-charmap td:hover{background:white}.mce-grid td.mce-grid-cell div{border:1px solid #c5c5c5;width:15px;height:15px;margin:0;cursor:pointer}.mce-grid td.mce-grid-cell div:focus{border-color:#91bbe9}.mce-grid td.mce-grid-cell div[disabled]{cursor:not-allowed}.mce-grid{border-spacing:2px;border-collapse:separate}.mce-grid a{display:block;border:1px solid transparent}.mce-grid a:hover,.mce-grid a:focus{border-color:#91bbe9}.mce-grid-border{margin:0 4px 0 4px}.mce-grid-border a{border-color:#c5c5c5;width:13px;height:13px}.mce-grid-border a:hover,.mce-grid-border a.mce-active{border-color:#91bbe9;background:#bdd6f2}.mce-text-center{text-align:center}div.mce-tinymce-inline{width:100%}.mce-colorbtn-trans div{text-align:center;vertical-align:middle;font-weight:bold;font-size:20px;line-height:16px;color:#8b8b8b}.mce-monospace{font-family:"Courier New",Courier,monospace}.mce-toolbar-grp .mce-flow-layout-item{margin-bottom:0}.mce-container b{font-weight:bold}.mce-container p{margin-bottom:5px}.mce-container a{cursor:pointer;color:#2276d2}.mce-container a:hover{text-decoration:underline}.mce-container ul{margin-left:15px}.mce-container .mce-table-striped{border-collapse:collapse;margin:10px}.mce-container .mce-table-striped thead>tr{background-color:#fafafa}.mce-container .mce-table-striped thead>tr th{font-weight:bold}.mce-container .mce-table-striped td,.mce-container .mce-table-striped th{padding:5px}.mce-container .mce-table-striped tr:nth-child(even){background-color:#fafafa}.mce-container .mce-table-striped tbody>tr:hover{background-color:#e1e1e1}.mce-branding{font-size:inherit;text-transform:uppercase;white-space:pre;padding:8px 0}.mce-branding a{font-size:inherit;color:inherit}.mce-top-part{position:relative}.mce-top-part::before{content:'';position:absolute;-webkit-box-shadow:0 1px 2px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 1px 2px rgba(0, 0, 0, 0.2);box-shadow:0 1px 2px rgba(0, 0, 0, 0.2);top:0;right:0;bottom:0;left:0;pointer-events:none}.mce-rtl .mce-wordcount{left:0;right:auto}.mce-rtl .mce-statusbar>.mce-container-body>*:last-child{padding-right:0;padding-left:10px}.mce-rtl .mce-path{text-align:right;padding-right:16px}.mce-croprect-container{position:absolute;top:0;left:0}.mce-croprect-handle{position:absolute;top:0;left:0;width:20px;height:20px;border:2px solid white}.mce-croprect-handle-nw{border-width:2px 0 0 2px;margin:-2px 0 0 -2px;cursor:nw-resize;top:100px;left:100px}.mce-croprect-handle-ne{border-width:2px 2px 0 0;margin:-2px 0 0 -20px;cursor:ne-resize;top:100px;left:200px}.mce-croprect-handle-sw{border-width:0 0 2px 2px;margin:-20px 2px 0 -2px;cursor:sw-resize;top:200px;left:100px}.mce-croprect-handle-se{border-width:0 2px 2px 0;margin:-20px 0 0 -20px;cursor:se-resize;top:200px;left:200px}.mce-croprect-handle-move{position:absolute;cursor:move;border:0}.mce-croprect-block{opacity:.5;filter:alpha(opacity=50);zoom:1;position:absolute;background:black}.mce-croprect-handle:focus{border-color:#2276d2}.mce-croprect-handle-move:focus{outline:1px solid #2276d2}.mce-imagepanel{overflow:auto;background:black}.mce-imagepanel-bg{position:absolute;background:url('data:image/gif;base64,R0lGODdhDAAMAIABAMzMzP///ywAAAAADAAMAAACFoQfqYeabNyDMkBQb81Uat85nxguUAEAOw==')}.mce-imagepanel img{position:absolute}.mce-imagetool.mce-btn .mce-ico{display:block;width:20px;height:20px;text-align:center;line-height:20px;font-size:20px;padding:5px}.mce-arrow-up{margin-top:12px}.mce-arrow-down{margin-top:-12px}.mce-arrow:before,.mce-arrow:after{position:absolute;left:50%;display:block;width:0;height:0;border-style:solid;border-color:transparent;content:""}.mce-arrow.mce-arrow-up:before{top:-9px;border-bottom-color:#c5c5c5;border-width:0 9px 9px;margin-left:-9px}.mce-arrow.mce-arrow-down:before{bottom:-9px;border-top-color:#c5c5c5;border-width:9px 9px 0;margin-left:-9px}.mce-arrow.mce-arrow-up:after{top:-8px;border-bottom-color:#fff;border-width:0 8px 8px;margin-left:-8px}.mce-arrow.mce-arrow-down:after{bottom:-8px;border-top-color:#fff;border-width:8px 8px 0;margin-left:-8px}.mce-arrow.mce-arrow-left:before,.mce-arrow.mce-arrow-left:after{margin:0}.mce-arrow.mce-arrow-left:before{left:8px}.mce-arrow.mce-arrow-left:after{left:9px}.mce-arrow.mce-arrow-right:before,.mce-arrow.mce-arrow-right:after{left:auto;margin:0}.mce-arrow.mce-arrow-right:before{right:8px}.mce-arrow.mce-arrow-right:after{right:9px}.mce-arrow.mce-arrow-center.mce-arrow.mce-arrow-left:before{left:-9px;top:50%;border-right-color:#c5c5c5;border-width:9px 9px 9px 0;margin-top:-9px}.mce-arrow.mce-arrow-center.mce-arrow.mce-arrow-left:after{left:-8px;top:50%;border-right-color:#fff;border-width:8px 8px 8px 0;margin-top:-8px}.mce-arrow.mce-arrow-center.mce-arrow.mce-arrow-left{margin-left:12px}.mce-arrow.mce-arrow-center.mce-arrow.mce-arrow-right:before{right:-9px;top:50%;border-left-color:#c5c5c5;border-width:9px 0 9px 9px;margin-top:-9px}.mce-arrow.mce-arrow-center.mce-arrow.mce-arrow-right:after{right:-8px;top:50%;border-left-color:#fff;border-width:8px 0 8px 8px;margin-top:-8px}.mce-arrow.mce-arrow-center.mce-arrow.mce-arrow-right{margin-left:-14px}.mce-edit-aria-container>.mce-container-body{display:flex}.mce-edit-aria-container>.mce-container-body .mce-edit-area{flex:1}.mce-edit-aria-container>.mce-container-body .mce-sidebar>.mce-container-body{display:flex;align-items:stretch;height:100%}.mce-edit-aria-container>.mce-container-body .mce-sidebar-panel{min-width:250px;max-width:250px;position:relative}.mce-edit-aria-container>.mce-container-body .mce-sidebar-panel>.mce-container-body{position:absolute;width:100%;height:100%;overflow:auto;top:0;left:0}.mce-sidebar-toolbar{border:0 solid #c5c5c5;border-left-width:1px}.mce-sidebar-toolbar .mce-btn{border-left:0;border-right:0}.mce-sidebar-toolbar .mce-btn.mce-active,.mce-sidebar-toolbar .mce-btn.mce-active:hover{background-color:#555c66}.mce-sidebar-toolbar .mce-btn.mce-active button,.mce-sidebar-toolbar .mce-btn.mce-active:hover button,.mce-sidebar-toolbar .mce-btn.mce-active button i,.mce-sidebar-toolbar .mce-btn.mce-active:hover button i{color:white;text-shadow:1px 1px none}.mce-sidebar-panel{border:0 solid #c5c5c5;border-left-width:1px}.mce-container,.mce-container-body{display:block}.mce-autoscroll{overflow:hidden}.mce-scrollbar{position:absolute;width:7px;height:100%;top:2px;right:2px;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-scrollbar-h{top:auto;right:auto;left:2px;bottom:2px;width:100%;height:7px}.mce-scrollbar-thumb{position:absolute;background-color:#000;border:1px solid #888;border-color:rgba(85,85,85,0.6);width:5px;height:100%}.mce-scrollbar-h .mce-scrollbar-thumb{width:100%;height:5px}.mce-scrollbar:hover,.mce-scrollbar.mce-active{background-color:#AAA;opacity:.6;filter:alpha(opacity=60);zoom:1}.mce-scroll{position:relative}.mce-panel{border:0 solid #f3f3f3;border:0 solid #c5c5c5;background-color:#fff}.mce-floatpanel{position:absolute;-webkit-box-shadow:0 1px 2px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 1px 2px rgba(0, 0, 0, 0.2);box-shadow:0 1px 2px rgba(0, 0, 0, 0.2)}.mce-floatpanel.mce-fixed{position:fixed}.mce-floatpanel .mce-arrow,.mce-floatpanel .mce-arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.mce-floatpanel .mce-arrow{border-width:11px}.mce-floatpanel .mce-arrow:after{border-width:10px;content:""}.mce-floatpanel.mce-popover{filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;-webkit-box-shadow:0 1px 2px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 1px 2px rgba(0, 0, 0, 0.2);box-shadow:0 1px 2px rgba(0, 0, 0, 0.2);top:0;left:0;background:#FFF;border:1px solid #c5c5c5;border:1px solid rgba(0,0,0,0.25)}.mce-floatpanel.mce-popover.mce-bottom{margin-top:10px;*margin-top:0}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#c5c5c5;border-bottom-color:rgba(0,0,0,0.25);top:-11px}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow:after{top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#FFF}.mce-floatpanel.mce-popover.mce-top{margin-top:-10px;*margin-top:0}.mce-floatpanel.mce-popover.mce-top>.mce-arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:#c5c5c5;top:auto;bottom:-11px}.mce-floatpanel.mce-popover.mce-top>.mce-arrow:after{bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#FFF}.mce-floatpanel.mce-popover.mce-bottom.mce-start,.mce-floatpanel.mce-popover.mce-top.mce-start{margin-left:-22px}.mce-floatpanel.mce-popover.mce-bottom.mce-start>.mce-arrow,.mce-floatpanel.mce-popover.mce-top.mce-start>.mce-arrow{left:20px}.mce-floatpanel.mce-popover.mce-bottom.mce-end,.mce-floatpanel.mce-popover.mce-top.mce-end{margin-left:22px}.mce-floatpanel.mce-popover.mce-bottom.mce-end>.mce-arrow,.mce-floatpanel.mce-popover.mce-top.mce-end>.mce-arrow{right:10px;left:auto}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;height:100%}div.mce-fullscreen{position:fixed;top:0;left:0}#mce-modal-block{opacity:0;filter:alpha(opacity=0);zoom:1;position:fixed;left:0;top:0;width:100%;height:100%;background:#FFF}#mce-modal-block.mce-in{opacity:.5;filter:alpha(opacity=50);zoom:1}.mce-window-move{cursor:move}.mce-window{-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;background:#FFF;position:fixed;top:0;left:0;opacity:0;transform:scale(.1);transition:transform 100ms ease-in,opacity 150ms ease-in}.mce-window.mce-in{transform:scale(1);opacity:1}.mce-window-head{padding:9px 15px;border-bottom:1px solid #c5c5c5;position:relative}.mce-window-head .mce-close{position:absolute;right:0;top:0;height:38px;width:38px;text-align:center;cursor:pointer}.mce-window-head .mce-close i{color:#9b9b9b}.mce-close:hover i{color:#bdbdbd}.mce-window-head .mce-title{line-height:20px;font-size:20px;font-weight:bold;text-rendering:optimizelegibility;padding-right:20px}.mce-window .mce-container-body{display:block}.mce-foot{display:block;background-color:#FFF;border-top:1px solid #c5c5c5}.mce-window-head .mce-dragh{position:absolute;top:0;left:0;cursor:move;width:90%;height:100%}.mce-window iframe{width:100%;height:100%}.mce-window-body .mce-listbox{border-color:#e2e4e7}.mce-window .mce-btn:hover{border-color:#c5c5c5}.mce-window .mce-btn:focus{border-color:#2276d2}.mce-window-body .mce-btn,.mce-foot .mce-btn{border-color:#c5c5c5}.mce-foot .mce-btn.mce-primary{border-color:transparent}.mce-rtl .mce-window-head .mce-close{position:absolute;right:auto;left:0}.mce-rtl .mce-window-head .mce-dragh{left:auto;right:0}.mce-rtl .mce-window-head .mce-title{direction:rtl;text-align:right;padding-right:0;padding-left:20px}.mce-tooltip{position:absolute;padding:5px;opacity:.8;filter:alpha(opacity=80);zoom:1;margin-top:1px}.mce-tooltip-inner{font-size:11px;background-color:#000;color:white;max-width:200px;padding:5px 8px 4px 8px;text-align:center;white-space:normal}.mce-tooltip-inner{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-tooltip-arrow{position:absolute;width:0;height:0;line-height:0;border:5px dashed #000}.mce-tooltip-arrow-n{border-bottom-color:#000}.mce-tooltip-arrow-s{border-top-color:#000}.mce-tooltip-arrow-e{border-left-color:#000}.mce-tooltip-arrow-w{border-right-color:#000}.mce-tooltip-nw,.mce-tooltip-sw{margin-left:-14px}.mce-tooltip-ne,.mce-tooltip-se{margin-left:14px}.mce-tooltip-n .mce-tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-nw .mce-tooltip-arrow{top:0;left:10px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-ne .mce-tooltip-arrow{top:0;right:10px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-s .mce-tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-sw .mce-tooltip-arrow{bottom:0;left:10px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-se .mce-tooltip-arrow{bottom:0;right:10px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-e .mce-tooltip-arrow{right:0;top:50%;margin-top:-5px;border-left-style:solid;border-right:none;border-top-color:transparent;border-bottom-color:transparent}.mce-tooltip-w .mce-tooltip-arrow{left:0;top:50%;margin-top:-5px;border-right-style:solid;border-left:none;border-top-color:transparent;border-bottom-color:transparent}.mce-progress{display:inline-block;position:relative;height:20px}.mce-progress .mce-bar-container{display:inline-block;width:100px;height:100%;margin-right:8px;border:1px solid #ccc;overflow:hidden}.mce-progress .mce-text{display:inline-block;margin-top:auto;margin-bottom:auto;font-size:14px;width:40px;color:#595959}.mce-bar{display:block;width:0;height:100%;background-color:#dfdfdf;-webkit-transition:width .2s ease;transition:width .2s ease}.mce-notification{position:absolute;background-color:#fff;padding:5px;margin-top:5px;border-width:1px;border-style:solid;border-color:#c5c5c5;transition:transform 100ms ease-in,opacity 150ms ease-in;opacity:0;box-sizing:border-box}.mce-notification.mce-in{opacity:1}.mce-notification-success{background-color:#dff0d8;border-color:#d6e9c6}.mce-notification-info{background-color:#d9edf7;border-color:#779ECB}.mce-notification-warning{background-color:#fcf8e3;border-color:#faebcc}.mce-notification-error{background-color:#f2dede;border-color:#ebccd1}.mce-notification.mce-has-close{padding-right:15px}.mce-notification .mce-ico{margin-top:5px}.mce-notification-inner{word-wrap:break-word;-ms-word-break:break-all;word-break:break-all;word-break:break-word;-ms-hyphens:auto;-moz-hyphens:auto;-webkit-hyphens:auto;hyphens:auto;display:inline-block;font-size:14px;margin:5px 8px 4px 8px;text-align:center;white-space:normal;color:#31708f}.mce-notification-inner a{text-decoration:underline;cursor:pointer}.mce-notification .mce-progress{margin-right:8px}.mce-notification .mce-progress .mce-text{margin-top:5px}.mce-notification *,.mce-notification .mce-progress .mce-text{color:#595959}.mce-notification .mce-progress .mce-bar-container{border-color:#c5c5c5}.mce-notification .mce-progress .mce-bar-container .mce-bar{background-color:#595959}.mce-notification-success *,.mce-notification-success .mce-progress .mce-text{color:#3c763d}.mce-notification-success .mce-progress .mce-bar-container{border-color:#d6e9c6}.mce-notification-success .mce-progress .mce-bar-container .mce-bar{background-color:#3c763d}.mce-notification-info *,.mce-notification-info .mce-progress .mce-text{color:#31708f}.mce-notification-info .mce-progress .mce-bar-container{border-color:#779ECB}.mce-notification-info .mce-progress .mce-bar-container .mce-bar{background-color:#31708f}.mce-notification-warning *,.mce-notification-warning .mce-progress .mce-text{color:#8a6d3b}.mce-notification-warning .mce-progress .mce-bar-container{border-color:#faebcc}.mce-notification-warning .mce-progress .mce-bar-container .mce-bar{background-color:#8a6d3b}.mce-notification-error *,.mce-notification-error .mce-progress .mce-text{color:#a94442}.mce-notification-error .mce-progress .mce-bar-container{border-color:#ebccd1}.mce-notification-error .mce-progress .mce-bar-container .mce-bar{background-color:#a94442}.mce-notification .mce-close{position:absolute;top:6px;right:8px;font-size:20px;font-weight:bold;line-height:20px;color:#9b9b9b;cursor:pointer}.mce-abs-layout{position:relative}html .mce-abs-layout-item,.mce-abs-end{position:absolute}.mce-abs-end{width:1px;height:1px}.mce-container-body.mce-abs-layout{overflow:hidden}.mce-btn{border:1px solid #b3b3b3;border-color:transparent transparent transparent transparent;position:relative;text-shadow:0 1px 1px rgba(255,255,255,0.75);background:white;display:inline-block;*display:inline;*zoom:1;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-btn:hover,.mce-btn:active{background:white;color:#595959;border-color:#e2e4e7}.mce-btn:focus{background:white;color:#595959;border-color:#e2e4e7}.mce-btn.mce-disabled button,.mce-btn.mce-disabled:hover button{cursor:default;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-btn.mce-active,.mce-btn.mce-active:hover,.mce-btn.mce-active:focus,.mce-btn.mce-active:active{-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;background:#555c66;color:white;border-color:transparent}.mce-btn.mce-active button,.mce-btn.mce-active:hover button,.mce-btn.mce-active i,.mce-btn.mce-active:hover i{color:white}.mce-btn:hover .mce-caret{border-top-color:#b5bcc2}.mce-btn.mce-active .mce-caret,.mce-btn.mce-active:hover .mce-caret{border-top-color:white}.mce-btn button{padding:4px 6px;font-size:14px;line-height:20px;*line-height:16px;cursor:pointer;color:#595959;text-align:center;overflow:visible;-webkit-appearance:none}.mce-btn button::-moz-focus-inner{border:0;padding:0}.mce-btn i{text-shadow:1px 1px none}.mce-primary.mce-btn-has-text{min-width:50px}.mce-primary{color:white;border:1px solid transparent;border-color:transparent;background-color:#2276d2}.mce-primary:hover,.mce-primary:focus{background-color:#1e6abc;border-color:transparent}.mce-primary.mce-disabled button,.mce-primary.mce-disabled:hover button{cursor:default;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-primary.mce-active,.mce-primary.mce-active:hover,.mce-primary:not(.mce-disabled):active{background-color:#1e6abc;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-primary button,.mce-primary button i{color:white;text-shadow:1px 1px none}.mce-btn .mce-txt{font-size:inherit;line-height:inherit;color:inherit}.mce-btn-large button{padding:9px 14px;font-size:16px;line-height:normal}.mce-btn-large i{margin-top:2px}.mce-btn-small button{padding:1px 5px;font-size:12px;*padding-bottom:2px}.mce-btn-small i{line-height:20px;vertical-align:top;*line-height:18px}.mce-btn .mce-caret{margin-top:8px;margin-left:0}.mce-btn-small .mce-caret{margin-top:8px;margin-left:0}.mce-caret{display:inline-block;*display:inline;*zoom:1;width:0;height:0;vertical-align:top;border-top:4px solid #b5bcc2;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.mce-disabled .mce-caret{border-top-color:#aaa}.mce-caret.mce-up{border-bottom:4px solid #b5bcc2;border-top:0}.mce-btn-flat{border:0;background:transparent;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;filter:none}.mce-btn-flat:hover,.mce-btn-flat.mce-active,.mce-btn-flat:focus,.mce-btn-flat:active{border:0;background:#e6e6e6;filter:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-btn-has-text .mce-ico{padding-right:5px}.mce-rtl .mce-btn button{direction:rtl}.mce-toolbar .mce-btn-group{margin:0;padding:2px 0}.mce-btn-group .mce-btn{border-width:1px;margin:0;margin-left:2px}.mce-btn-group:not(:first-child){border-left:1px solid #d9d9d9;padding-left:0;margin-left:2px}.mce-btn-group{margin-left:2px}.mce-btn-group .mce-btn.mce-flow-layout-item{margin:0}.mce-rtl .mce-btn-group .mce-btn{margin-left:0;margin-right:2px}.mce-rtl .mce-btn-group .mce-first{margin-right:0}.mce-rtl .mce-btn-group:not(:first-child){border-left:none;border-right:1px solid #d9d9d9;padding-right:4px;margin-right:4px}.mce-checkbox{cursor:pointer}i.mce-i-checkbox{margin:0 3px 0 0;border:1px solid #c5c5c5;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;background-color:white;text-indent:-10em;overflow:hidden}.mce-checked i.mce-i-checkbox{color:#595959;font-size:16px;line-height:16px;text-indent:0}.mce-checkbox:focus i.mce-i-checkbox,.mce-checkbox.mce-focus i.mce-i-checkbox{border:1px solid #2276d2;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-checkbox.mce-disabled .mce-label,.mce-checkbox.mce-disabled i.mce-i-checkbox{color:#bdbdbd}.mce-checkbox .mce-label{vertical-align:middle}.mce-rtl .mce-checkbox{direction:rtl;text-align:right}.mce-rtl i.mce-i-checkbox{margin:0 0 0 3px}.mce-combobox{position:relative;display:inline-block;*display:inline;*zoom:1;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;*height:32px}.mce-combobox input{border:1px solid #c5c5c5;border-right-color:#c5c5c5;height:28px}.mce-combobox.mce-disabled input{color:#bdbdbd}.mce-combobox .mce-btn{border:1px solid #c5c5c5;border-left:0;margin:0}.mce-combobox button{padding-right:8px;padding-left:8px}.mce-combobox.mce-disabled .mce-btn button{cursor:default;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-combobox .mce-status{position:absolute;right:2px;top:50%;line-height:16px;margin-top:-8px;font-size:12px;width:15px;height:15px;text-align:center;cursor:pointer}.mce-combobox.mce-has-status input{padding-right:20px}.mce-combobox.mce-has-open .mce-status{right:37px}.mce-combobox .mce-status.mce-i-warning{color:#c09853}.mce-combobox .mce-status.mce-i-checkmark{color:#468847}.mce-menu.mce-combobox-menu{border-top:0;margin-top:0;max-height:200px}.mce-menu.mce-combobox-menu .mce-menu-item{padding:4px 6px 4px 4px;font-size:11px}.mce-menu.mce-combobox-menu .mce-menu-item-sep{padding:0}.mce-menu.mce-combobox-menu .mce-text,.mce-menu.mce-combobox-menu .mce-text b{font-size:11px}.mce-menu.mce-combobox-menu .mce-menu-item-link,.mce-menu.mce-combobox-menu .mce-menu-item-link b{font-size:11px}.mce-colorbox i{border:1px solid #c5c5c5;width:14px;height:14px}.mce-colorbutton .mce-ico{position:relative}.mce-colorbutton-grid{margin:4px}.mce-colorbutton .mce-preview{padding-right:3px;display:block;position:absolute;left:50%;top:50%;margin-left:-17px;margin-top:7px;background:gray;width:13px;height:2px;overflow:hidden}.mce-colorbutton.mce-btn-small .mce-preview{margin-left:-16px;padding-right:0;width:16px}.mce-rtl .mce-colorbutton{direction:rtl}.mce-rtl .mce-colorbutton .mce-preview{margin-left:0;padding-right:0;padding-left:3px}.mce-rtl .mce-colorbutton.mce-btn-small .mce-preview{margin-left:0;padding-right:0;padding-left:2px}.mce-rtl .mce-colorbutton .mce-open{padding-left:4px;padding-right:4px;border-left:0}.mce-colorpicker{position:relative;width:250px;height:220px}.mce-colorpicker-sv{position:absolute;top:0;left:0;width:90%;height:100%;border:1px solid #c5c5c5;cursor:crosshair;overflow:hidden}.mce-colorpicker-h-chunk{width:100%}.mce-colorpicker-overlay1,.mce-colorpicker-overlay2{width:100%;height:100%;position:absolute;top:0;left:0}.mce-colorpicker-overlay1{filter:progid:DXImageTransform.Microsoft.gradient(GradientType=1, startColorstr='#ffffff', endColorstr='#00ffffff');-ms-filter:"progid:DXImageTransform.Microsoft.gradient(GradientType=1,startColorstr='#ffffff', endColorstr='#00ffffff')";background:linear-gradient(to right, #fff, rgba(255,255,255,0))}.mce-colorpicker-overlay2{filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#00000000', endColorstr='#000000');-ms-filter:"progid:DXImageTransform.Microsoft.gradient(GradientType=0,startColorstr='#00000000', endColorstr='#000000')";background:linear-gradient(to bottom, rgba(0,0,0,0), #000)}.mce-colorpicker-selector1{background:none;position:absolute;width:12px;height:12px;margin:-8px 0 0 -8px;border:1px solid black;border-radius:50%}.mce-colorpicker-selector2{position:absolute;width:10px;height:10px;border:1px solid white;border-radius:50%}.mce-colorpicker-h{position:absolute;top:0;right:0;width:6.5%;height:100%;border:1px solid #c5c5c5;cursor:crosshair}.mce-colorpicker-h-marker{margin-top:-4px;position:absolute;top:0;left:-1px;width:100%;border:1px solid black;background:white;height:4px;z-index:100}.mce-path{display:inline-block;*display:inline;*zoom:1;padding:8px;white-space:normal;font-size:inherit}.mce-path .mce-txt{display:inline-block;padding-right:3px}.mce-path .mce-path-body{display:inline-block}.mce-path-item{display:inline-block;*display:inline;*zoom:1;cursor:pointer;color:#595959;font-size:inherit;text-transform:uppercase}.mce-path-item:hover{text-decoration:underline}.mce-path-item:focus{background:#555c66;color:white}.mce-path .mce-divider{display:inline;font-size:inherit}.mce-disabled .mce-path-item{color:#aaa}.mce-rtl .mce-path{direction:rtl}.mce-fieldset{border:0 solid #9E9E9E}.mce-fieldset>.mce-container-body{margin-top:-15px}.mce-fieldset-title{margin-left:5px;padding:0 5px 0 5px}.mce-fit-layout{display:inline-block;*display:inline;*zoom:1}.mce-fit-layout-item{position:absolute}.mce-flow-layout-item{display:inline-block;*display:inline;*zoom:1}.mce-flow-layout-item{margin:2px 0 2px 2px}.mce-flow-layout-item.mce-last{margin-right:2px}.mce-flow-layout{white-space:normal}.mce-tinymce-inline .mce-flow-layout{white-space:nowrap}.mce-rtl .mce-flow-layout{text-align:right;direction:rtl}.mce-rtl .mce-flow-layout-item{margin:2px 2px 2px 0}.mce-rtl .mce-flow-layout-item.mce-last{margin-left:2px}.mce-iframe{border:0 solid #c5c5c5;width:100%;height:100%}.mce-infobox{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 1px rgba(255,255,255,0.75);overflow:hidden;border:1px solid red}.mce-infobox div{display:block;margin:5px}.mce-infobox div button{position:absolute;top:50%;right:4px;cursor:pointer;margin-top:-8px;display:none}.mce-infobox div button:focus{outline:2px solid #e2e4e7}.mce-infobox.mce-has-help div{margin-right:25px}.mce-infobox.mce-has-help button{display:block}.mce-infobox.mce-success{background:#dff0d8;border-color:#d6e9c6}.mce-infobox.mce-success div{color:#3c763d}.mce-infobox.mce-warning{background:#fcf8e3;border-color:#faebcc}.mce-infobox.mce-warning div{color:#8a6d3b}.mce-infobox.mce-error{background:#f2dede;border-color:#ebccd1}.mce-infobox.mce-error div{color:#a94442}.mce-rtl .mce-infobox div{text-align:right;direction:rtl}.mce-label{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 1px rgba(255,255,255,0.75);overflow:hidden}.mce-label.mce-autoscroll{overflow:auto}.mce-label.mce-disabled{color:#aaa}.mce-label.mce-multiline{white-space:pre-wrap}.mce-label.mce-success{color:#468847}.mce-label.mce-warning{color:#c09853}.mce-label.mce-error{color:#b94a48}.mce-rtl .mce-label{text-align:right;direction:rtl}.mce-menubar{border:1px solid #e2e4e7}.mce-menubar .mce-menubtn{border-color:transparent;background:transparent;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;filter:none}.mce-menubar .mce-menubtn button span{color:#595959}.mce-menubar .mce-caret{border-top-color:#b5bcc2}.mce-menubar .mce-active .mce-caret,.mce-menubar .mce-menubtn:hover .mce-caret{border-top-color:#b5bcc2}.mce-menubar .mce-menubtn:hover,.mce-menubar .mce-menubtn.mce-active,.mce-menubar .mce-menubtn:focus{border-color:#e2e4e7;background:white;filter:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-menubar .mce-menubtn.mce-active{border-bottom:none;z-index:65537}div.mce-menubtn.mce-opened{border-bottom-color:white;z-index:65537}.mce-menubtn button{color:#595959}.mce-menubtn.mce-btn-small span{font-size:12px}.mce-menubtn.mce-fixed-width span{display:inline-block;overflow-x:hidden;text-overflow:ellipsis;width:90px}.mce-menubtn.mce-fixed-width.mce-btn-small span{width:70px}.mce-menubtn .mce-caret{*margin-top:6px}.mce-rtl .mce-menubtn button{direction:rtl;text-align:right}.mce-rtl .mce-menubtn.mce-fixed-width span{direction:rtl;text-align:right}.mce-menu-item{display:block;padding:6px 4px 6px 4px;clear:both;font-weight:normal;line-height:20px;color:#595959;white-space:nowrap;cursor:pointer;line-height:normal;border-left:4px solid transparent;margin-bottom:1px}.mce-menu-item .mce-text,.mce-menu-item .mce-text b{line-height:1;vertical-align:initial}.mce-menu-item .mce-caret{margin-top:4px;margin-right:6px;border-top:4px solid transparent;border-bottom:4px solid transparent;border-left:4px solid #595959}.mce-menu-item .mce-menu-shortcut{display:inline-block;padding:0 10px 0 20px;color:#aaa}.mce-menu-item .mce-ico{padding-right:4px}.mce-menu-item:hover,.mce-menu-item:focus{background:#ededee}.mce-menu-item:hover .mce-menu-shortcut,.mce-menu-item:focus .mce-menu-shortcut{color:#aaa}.mce-menu-item:hover .mce-text,.mce-menu-item:focus .mce-text,.mce-menu-item:hover .mce-ico,.mce-menu-item:focus .mce-ico{color:#595959}.mce-menu-item.mce-selected{background:#ededee}.mce-menu-item.mce-selected .mce-text,.mce-menu-item.mce-selected .mce-ico{color:#595959}.mce-menu-item.mce-active.mce-menu-item-normal{background:#555c66}.mce-menu-item.mce-active.mce-menu-item-normal .mce-text,.mce-menu-item.mce-active.mce-menu-item-normal .mce-ico{color:white}.mce-menu-item.mce-active.mce-menu-item-checkbox .mce-ico{visibility:visible}.mce-menu-item.mce-disabled,.mce-menu-item.mce-disabled:hover{background:white}.mce-menu-item.mce-disabled:focus,.mce-menu-item.mce-disabled:hover:focus{background:#ededee}.mce-menu-item.mce-disabled .mce-text,.mce-menu-item.mce-disabled:hover .mce-text,.mce-menu-item.mce-disabled .mce-ico,.mce-menu-item.mce-disabled:hover .mce-ico{color:#aaa}.mce-menu-item.mce-menu-item-preview.mce-active{border-left:5px solid #555c66;background:white}.mce-menu-item.mce-menu-item-preview.mce-active .mce-text,.mce-menu-item.mce-menu-item-preview.mce-active .mce-ico{color:#595959}.mce-menu-item.mce-menu-item-preview.mce-active:hover{background:#ededee}.mce-menu-item-link{color:#093;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.mce-menu-item-link b{color:#093}.mce-menu-item-ellipsis{display:block;text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.mce-menu-item:hover *,.mce-menu-item.mce-selected *,.mce-menu-item:focus *{color:#595959}div.mce-menu .mce-menu-item-sep,.mce-menu-item-sep:hover{border:0;padding:0;height:1px;margin:9px 1px;overflow:hidden;background:transparent;border-bottom:1px solid rgba(0,0,0,0.1);cursor:default;filter:none}div.mce-menu .mce-menu-item b{font-weight:bold}.mce-menu-item-indent-1{padding-left:20px}.mce-menu-item-indent-2{padding-left:35px}.mce-menu-item-indent-2{padding-left:35px}.mce-menu-item-indent-3{padding-left:40px}.mce-menu-item-indent-4{padding-left:45px}.mce-menu-item-indent-5{padding-left:50px}.mce-menu-item-indent-6{padding-left:55px}.mce-menu.mce-rtl{direction:rtl}.mce-rtl .mce-menu-item{text-align:right;direction:rtl;padding:6px 12px 6px 15px}.mce-rtl .mce-menu-item .mce-caret{margin-left:6px;margin-right:0;border-right:4px solid #595959;border-left:0}.mce-rtl .mce-menu-item.mce-selected .mce-caret,.mce-rtl .mce-menu-item:focus .mce-caret,.mce-rtl .mce-menu-item:hover .mce-caret{border-left-color:transparent;border-right-color:#595959}.mce-rtl .mce-menu-item .mce-ico{padding-right:0;padding-left:4px}.mce-throbber{position:absolute;top:0;left:0;width:100%;height:100%;opacity:.6;filter:alpha(opacity=60);zoom:1;background:#fff url('img/loader.gif') no-repeat center center}.mce-throbber-inline{position:static;height:50px}.mce-menu .mce-throbber-inline{height:25px;background-size:contain}.mce-menu{position:absolute;left:0;top:0;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;z-index:1000;padding:5px 0 5px 0;margin:-1px 0 0;min-width:180px;background:white;border:1px solid #c5c9cf;border:1px solid #e2e4e7;z-index:1002;-webkit-box-shadow:0 1px 2px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 1px 2px rgba(0, 0, 0, 0.2);box-shadow:0 1px 2px rgba(0, 0, 0, 0.2);max-height:500px;overflow:auto;overflow-x:hidden}.mce-menu.mce-animate{opacity:.01;transform:rotateY(10deg) rotateX(-10deg);transform-origin:left top}.mce-menu.mce-menu-align .mce-menu-shortcut,.mce-menu.mce-menu-align .mce-caret{position:absolute;right:0}.mce-menu i{display:none}.mce-menu-has-icons i{display:inline-block}.mce-menu.mce-in.mce-animate{opacity:1;transform:rotateY(0) rotateX(0);transition:opacity .075s ease,transform .1s ease}.mce-menu-sub-tr-tl{margin:-6px 0 0 -1px}.mce-menu-sub-br-bl{margin:6px 0 0 -1px}.mce-menu-sub-tl-tr{margin:-6px 0 0 1px}.mce-menu-sub-bl-br{margin:6px 0 0 1px}.mce-rtl .mce-menu-item .mce-ico{padding-right:0;padding-left:4px}.mce-rtl.mce-menu-align .mce-caret,.mce-rtl .mce-menu-shortcut{right:auto;left:0}.mce-listbox button{text-align:left;padding-right:20px;position:relative}.mce-listbox .mce-caret{position:absolute;margin-top:-2px;right:8px;top:50%}.mce-rtl .mce-listbox .mce-caret{right:auto;left:8px}.mce-rtl .mce-listbox button{padding-right:10px;padding-left:20px}.mce-container-body .mce-resizehandle{position:absolute;right:0;bottom:0;width:16px;height:16px;visibility:visible;cursor:s-resize;margin:0}.mce-container-body .mce-resizehandle-both{cursor:se-resize}i.mce-i-resize{color:#595959}.mce-selectbox{background:#fff;border:1px solid #c5c5c5}.mce-slider{border:1px solid #c5c5c5;background:#fff;width:100px;height:10px;position:relative;display:block}.mce-slider.mce-vertical{width:10px;height:100px}.mce-slider-handle{border:1px solid #c5c5c5;background:#e6e6e6;display:block;width:13px;height:13px;position:absolute;top:0;left:0;margin-left:-1px;margin-top:-2px}.mce-slider-handle:focus{border-color:#2276d2}.mce-spacer{visibility:hidden}.mce-splitbtn:hover .mce-open{border-left:1px solid #e2e4e7}.mce-splitbtn .mce-open{border-left:1px solid transparent;padding-right:4px;padding-left:4px}.mce-splitbtn .mce-open:focus{border-left:1px solid #e2e4e7}.mce-splitbtn .mce-open:hover,.mce-splitbtn .mce-open:active{border-left:1px solid #e2e4e7}.mce-splitbtn.mce-active:hover .mce-open{border-left:1px solid white}.mce-splitbtn.mce-opened{border-color:#e2e4e7}.mce-splitbtn.mce-btn-small .mce-open{padding:0 3px 0 3px}.mce-rtl .mce-splitbtn{direction:rtl;text-align:right}.mce-rtl .mce-splitbtn button{padding-right:4px;padding-left:4px}.mce-rtl .mce-splitbtn .mce-open{border-left:0}.mce-stack-layout-item{display:block}.mce-tabs{display:block;border-bottom:1px solid #c5c5c5}.mce-tabs,.mce-tabs+.mce-container-body{background:#fff}.mce-tab{display:inline-block;*display:inline;*zoom:1;border:1px solid #c5c5c5;border-width:0 1px 0 0;background:#fff;padding:8px 15px;text-shadow:0 1px 1px rgba(255,255,255,0.75);height:13px;cursor:pointer}.mce-tab:hover{background:#FDFDFD}.mce-tab.mce-active{background:#FDFDFD;border-bottom-color:transparent;margin-bottom:-1px;height:14px}.mce-tab:focus{color:#2276d2}.mce-rtl .mce-tabs{text-align:right;direction:rtl}.mce-rtl .mce-tab{border-width:0 0 0 1px}.mce-textbox{background:#fff;border:1px solid #c5c5c5;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;display:inline-block;-webkit-transition:border linear .2s, box-shadow linear .2s;transition:border linear .2s, box-shadow linear .2s;height:28px;resize:none;padding:0 4px 0 4px;white-space:pre-wrap;*white-space:pre;color:#595959}.mce-textbox:focus,.mce-textbox.mce-focus{border-color:#2276d2;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-placeholder .mce-textbox{color:#aaa}.mce-textbox.mce-multiline{padding:4px;height:auto}.mce-textbox.mce-disabled{color:#bdbdbd}.mce-rtl .mce-textbox{text-align:right;direction:rtl}.mce-dropzone{border:3px dashed gray;text-align:center}.mce-dropzone span{text-transform:uppercase;display:inline-block;vertical-align:middle}.mce-dropzone:after{content:"";height:100%;display:inline-block;vertical-align:middle}.mce-dropzone.mce-disabled{opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-dropzone.mce-disabled.mce-dragenter{cursor:not-allowed}.mce-browsebutton{position:relative;overflow:hidden}.mce-browsebutton button{position:relative;z-index:1}.mce-browsebutton input{opacity:0;filter:alpha(opacity=0);zoom:1;position:absolute;top:0;left:0;width:100%;height:100%;z-index:0}@font-face{font-family:'tinymce';src:url('fonts/tinymce.eot');src:url('fonts/tinymce.eot?#iefix') format('embedded-opentype'),url('fonts/tinymce.woff') format('woff'),url('fonts/tinymce.ttf') format('truetype'),url('fonts/tinymce.svg#tinymce') format('svg');font-weight:normal;font-style:normal}@font-face{font-family:'tinymce-small';src:url('fonts/tinymce-small.eot');src:url('fonts/tinymce-small.eot?#iefix') format('embedded-opentype'),url('fonts/tinymce-small.woff') format('woff'),url('fonts/tinymce-small.ttf') format('truetype'),url('fonts/tinymce-small.svg#tinymce') format('svg');font-weight:normal;font-style:normal}.mce-ico{font-family:'tinymce',Arial;font-style:normal;font-weight:normal;font-variant:normal;font-size:16px;line-height:16px;speak:none;vertical-align:text-top;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;display:inline-block;background:transparent center center;background-size:cover;width:16px;height:16px;color:#595959}.mce-btn-small .mce-ico{font-family:'tinymce-small',Arial}.mce-i-save:before{content:"\e000"}.mce-i-newdocument:before{content:"\e001"}.mce-i-fullpage:before{content:"\e002"}.mce-i-alignleft:before{content:"\e003"}.mce-i-aligncenter:before{content:"\e004"}.mce-i-alignright:before{content:"\e005"}.mce-i-alignjustify:before{content:"\e006"}.mce-i-alignnone:before{content:"\e003"}.mce-i-cut:before{content:"\e007"}.mce-i-paste:before{content:"\e008"}.mce-i-searchreplace:before{content:"\e009"}.mce-i-bullist:before{content:"\e00a"}.mce-i-numlist:before{content:"\e00b"}.mce-i-indent:before{content:"\e00c"}.mce-i-outdent:before{content:"\e00d"}.mce-i-blockquote:before{content:"\e00e"}.mce-i-undo:before{content:"\e00f"}.mce-i-redo:before{content:"\e010"}.mce-i-link:before{content:"\e011"}.mce-i-unlink:before{content:"\e012"}.mce-i-anchor:before{content:"\e013"}.mce-i-image:before{content:"\e014"}.mce-i-media:before{content:"\e015"}.mce-i-help:before{content:"\e016"}.mce-i-code:before{content:"\e017"}.mce-i-insertdatetime:before{content:"\e018"}.mce-i-preview:before{content:"\e019"}.mce-i-forecolor:before{content:"\e01a"}.mce-i-backcolor:before{content:"\e01a"}.mce-i-table:before{content:"\e01b"}.mce-i-hr:before{content:"\e01c"}.mce-i-removeformat:before{content:"\e01d"}.mce-i-subscript:before{content:"\e01e"}.mce-i-superscript:before{content:"\e01f"}.mce-i-charmap:before{content:"\e020"}.mce-i-emoticons:before{content:"\e021"}.mce-i-print:before{content:"\e022"}.mce-i-fullscreen:before{content:"\e023"}.mce-i-spellchecker:before{content:"\e024"}.mce-i-nonbreaking:before{content:"\e025"}.mce-i-template:before{content:"\e026"}.mce-i-pagebreak:before{content:"\e027"}.mce-i-restoredraft:before{content:"\e028"}.mce-i-bold:before{content:"\e02a"}.mce-i-italic:before{content:"\e02b"}.mce-i-underline:before{content:"\e02c"}.mce-i-strikethrough:before{content:"\e02d"}.mce-i-visualchars:before{content:"\e02e"}.mce-i-visualblocks:before{content:"\e02e"}.mce-i-ltr:before{content:"\e02f"}.mce-i-rtl:before{content:"\e030"}.mce-i-copy:before{content:"\e031"}.mce-i-resize:before{content:"\e032"}.mce-i-browse:before{content:"\e034"}.mce-i-pastetext:before{content:"\e035"}.mce-i-rotateleft:before{content:"\eaa8"}.mce-i-rotateright:before{content:"\eaa9"}.mce-i-crop:before{content:"\ee78"}.mce-i-editimage:before{content:"\e915"}.mce-i-options:before{content:"\ec6a"}.mce-i-flipv:before{content:"\eaaa"}.mce-i-fliph:before{content:"\eaac"}.mce-i-zoomin:before{content:"\eb35"}.mce-i-zoomout:before{content:"\eb36"}.mce-i-sun:before{content:"\eccc"}.mce-i-moon:before{content:"\eccd"}.mce-i-arrowleft:before{content:"\edc0"}.mce-i-arrowright:before{content:"\e93c"}.mce-i-drop:before{content:"\e935"}.mce-i-contrast:before{content:"\ecd4"}.mce-i-sharpen:before{content:"\eba7"}.mce-i-resize2:before{content:"\edf9"}.mce-i-orientation:before{content:"\e601"}.mce-i-invert:before{content:"\e602"}.mce-i-gamma:before{content:"\e600"}.mce-i-remove:before{content:"\ed6a"}.mce-i-tablerowprops:before{content:"\e604"}.mce-i-tablecellprops:before{content:"\e605"}.mce-i-table2:before{content:"\e606"}.mce-i-tablemergecells:before{content:"\e607"}.mce-i-tableinsertcolbefore:before{content:"\e608"}.mce-i-tableinsertcolafter:before{content:"\e609"}.mce-i-tableinsertrowbefore:before{content:"\e60a"}.mce-i-tableinsertrowafter:before{content:"\e60b"}.mce-i-tablesplitcells:before{content:"\e60d"}.mce-i-tabledelete:before{content:"\e60e"}.mce-i-tableleftheader:before{content:"\e62a"}.mce-i-tabletopheader:before{content:"\e62b"}.mce-i-tabledeleterow:before{content:"\e800"}.mce-i-tabledeletecol:before{content:"\e801"}.mce-i-codesample:before{content:"\e603"}.mce-i-fill:before{content:"\e902"}.mce-i-borderwidth:before{content:"\e903"}.mce-i-line:before{content:"\e904"}.mce-i-count:before{content:"\e905"}.mce-i-translate:before{content:"\e907"}.mce-i-drag:before{content:"\e908"}.mce-i-home:before{content:"\e90b"}.mce-i-upload:before{content:"\e914"}.mce-i-bubble:before{content:"\e91c"}.mce-i-user:before{content:"\e91d"}.mce-i-lock:before{content:"\e926"}.mce-i-unlock:before{content:"\e927"}.mce-i-settings:before{content:"\e928"}.mce-i-remove2:before{content:"\e92a"}.mce-i-menu:before{content:"\e92d"}.mce-i-warning:before{content:"\e930"}.mce-i-question:before{content:"\e931"}.mce-i-pluscircle:before{content:"\e932"}.mce-i-info:before{content:"\e933"}.mce-i-notice:before{content:"\e934"}.mce-i-arrowup:before{content:"\e93b"}.mce-i-arrowdown:before{content:"\e93d"}.mce-i-arrowup2:before{content:"\e93f"}.mce-i-arrowdown2:before{content:"\e940"}.mce-i-menu2:before{content:"\e941"}.mce-i-newtab:before{content:"\e961"}.mce-i-a11y:before{content:"\e900"}.mce-i-plus:before{content:"\e93a"}.mce-i-insert:before{content:"\e93a"}.mce-i-minus:before{content:"\e939"}.mce-i-books:before{content:"\e911"}.mce-i-reload:before{content:"\e906"}.mce-i-toc:before{content:"\e901"}.mce-i-checkmark:before{content:"\e033"}.mce-i-checkbox:before,.mce-i-selected:before{content:"\e033"}.mce-i-insert{font-size:14px}.mce-i-selected{visibility:hidden}i.mce-i-backcolor{text-shadow:none;background:#BBB}.mce-rtl .mce-filepicker input{direction:ltr} \ No newline at end of file diff --git a/spec/models/stat_created_plan_spec.rb b/spec/models/stat_created_plan_spec.rb index d1a0a9c..3327df4 100644 --- a/spec/models/stat_created_plan_spec.rb +++ b/spec/models/stat_created_plan_spec.rb @@ -1,21 +1,27 @@ -require 'rails_helper' +# frozen_string_literal: true + +require "rails_helper" RSpec.describe StatCreatedPlan, type: :model do - describe '.to_csv' do - context 'when no instances' do - it 'returns empty' do + describe ".to_csv" do + context "when no instances" do + it "returns empty" do csv = described_class.to_csv([]) expect(csv).to be_empty end end - context 'when instances' do + context "when instances" do let(:org) { FactoryBot.create(:org) } - context 'when no details' do - it 'returns counts in a comma-separated row' do - may = FactoryBot.create(:stat_created_plan, date: Date.new(2018, 05, 31), org: org, count: 20) - june = FactoryBot.create(:stat_created_plan, date: Date.new(2018, 06, 30), org: org, count: 10) + context "when no details" do + it "returns counts in a comma-separated row" do + may = FactoryBot.create(:stat_created_plan, + date: Date.new(2018, 05, 31), + org: org, count: 20) + june = FactoryBot.create(:stat_created_plan, + date: Date.new(2018, 06, 30), + org: org, count: 10) data = [may, june] csv = described_class.to_csv(data) @@ -29,26 +35,34 @@ end end - context 'when details by template is true' do - it 'returns counts by_template in a comma-separated row' do - may = FactoryBot.create(:stat_created_plan, date: Date.new(2018, 05, 31), org: org, count: 20, details: { by_template: [ - { name: 'Template1', count: 5 }, - { name: 'Template2', count: 15 } - ]}) - june = FactoryBot.create(:stat_created_plan, date: Date.new(2018, 06, 30), org: org, count: 10, details: { by_template: [ - { name: 'Template1', count: 2 }, - { name: 'Template3', count: 8 } - ]}) - july = FactoryBot.create(:stat_created_plan, date: Date.new(2018, 07, 31), org: org, count: 0) + context "when details by template is true" do + it "returns counts by_template in a comma-separated row" do + may = FactoryBot.create(:stat_created_plan, + date: Date.new(2018, 05, 31), + org: org, + count: 20, + details: { by_template: [ + { name: "Template1", count: 5 }, + { name: "Template2", count: 15 }] }) + june = FactoryBot.create(:stat_created_plan, + date: Date.new(2018, 06, 30), + org: org, count: 10, + details: { by_template: [ + { name: "Template1", count: 2 }, + { name: "Template3", count: 8 }] }) + july = FactoryBot.create(:stat_created_plan, + date: Date.new(2018, 07, 31), + org: org, + count: 0) data = [may, june, july] csv = described_class.to_csv(data, details: { by_template: true }) expected_csv = <<~HERE Date,Template1,Template2,Template3,Count - 2018-05-31,5,15,0,20 - 2018-06-30,2,0,8,10 - 2018-07-31,0,0,0,0 + May 2018,5,15,0,20 + Jun 2018,2,0,8,10 + Jul 2018,0,0,0,0 HERE expect(csv).to eq(expected_csv) end @@ -56,19 +70,26 @@ end end - describe '.serialize' do - let(:org) { FactoryBot.create(:org, name: 'An Org', contact_email: 'foo@bar.com', contact_name: 'Foo') } + describe ".serialize" do + let(:org) { FactoryBot.create(:org, + name: "An Org", + contact_email: "foo@bar.com", + contact_name: "Foo") } let(:details) do - { 'by_template' => [ - { 'name' => 'Template 1', 'count' => 10 }, - { 'name' => 'Template 2', 'count' => 10 } - ]} + { "by_template" => [ + { "name" => "Template 1", "count" => 10 }, + { "name" => "Template 2", "count" => 10 }] + } end - it 'retrieves JSON details as a hash object' do - september = FactoryBot.create(:stat_created_plan, date: '2018-09-30', org: org, count: 20, details: details) + it "retrieves JSON details as a hash object" do + september = FactoryBot.create(:stat_created_plan, + date: "2018-09-30", + org: org, + count: 20, + details: details) - json_details = described_class.find_by_date('2018-09-30').details + json_details = described_class.find_by_date("2018-09-30").details expect(json_details).to eq(details) end diff --git a/spec/requests/stat_created_plans_by_template_controller_spec.rb b/spec/requests/stat_created_plans_by_template_controller_spec.rb index e8d9ce4..631d7f2 100644 --- a/spec/requests/stat_created_plans_by_template_controller_spec.rb +++ b/spec/requests/stat_created_plans_by_template_controller_spec.rb @@ -1,101 +1,127 @@ -require 'rails_helper' +# frozen_string_literal: true -RSpec.describe '/stat_created_plan_by_template', type: :request do +require "rails_helper" + +RSpec.describe "/stat_created_plan_by_template", type: :request do def parsed_response JSON.parse(response.body, symbolize_names: true) end - describe '#index' do - let(:path) { '/stat_created_plans_by_template' } + describe "#index" do + let(:path) { "/stat_created_plans_by_template" } - it 'redirects when non-authorized user' do + it "redirects when non-authorized user" do get path expect(response).to have_http_status(:redirect) end - context 'when org_admin user' do + context "when org_admin user" do let(:org) { create(:org) } let(:org_admin) { create(:user, :org_admin, org: org) } before(:each) do sign_in(org_admin) end - it 'returns 200 status' do + it "returns 200 status" do get path - expect(response.content_type).to eq('application/json') + expect(response.content_type).to eq("application/json") expect(response).to have_http_status(:ok) end - context 'when there are no stats' do - it 'returns empty' do + context "when there are no stats" do + it "returns empty" do get path expect(parsed_response).to eq([]) end - it 'returns empty csv file' do + it "returns empty csv file" do get "#{path}.csv" - expect(response.content_type).to eq('text/csv') - expect(response.body).to eq('') + expect(response.content_type).to eq("text/csv") + expect(response.body).to eq("") end end context "when there are stats" do before do - create(:stat_created_plan, date: '2018-07-31', count: 5, org: org, details: { by_template: [{ name: 'Template1', count: 3 }, { name: 'Template2', count: 2 }]}) - create(:stat_created_plan, date: '2018-08-31', count: 10, org: org, details: { by_template: [{ name: 'Template1', count: 6 }, { name: 'Template2', count: 4 }]}) - create(:stat_created_plan, date: '2018-09-30', count: 10, org: org, details: { by_template: [{ name: 'Template1', count: 6 }, { name: 'Template2', count: 4 }]}) + create(:stat_created_plan, date: "2018-07-31", count: 5, org: org, + details: { by_template: [{ name: "Template1", count: 3 }, + { name: "Template2", count: 2 }] }) + create(:stat_created_plan, date: "2018-08-31", count: 10, org: org, + details: { by_template: [{ name: "Template1", count: 6 }, + { name: "Template2", count: 4 }] }) + create(:stat_created_plan, date: "2018-09-30", count: 10, + org: org, details: { by_template: [{ name: "Template1", count: 6 }, + { name: "Template2", count: 4 }] }) end it "returns all stats" do get path expect(parsed_response).to eq([ - { date: '2018-09-30', count: 10, by_template: [{ name: 'Template1', count: 6 }, { name: 'Template2', count: 4 }]}, - { date: '2018-08-31', count: 10, by_template: [{ name: 'Template1', count: 6 }, { name: 'Template2', count: 4 }]}, - { date: '2018-07-31', count: 5, by_template: [{ name: 'Template1', count: 3 }, { name: 'Template2', count: 2 }]} + { date: "2018-09-30", count: 10, by_template: [ + { name: "Template1", count: 6 }, + { name: "Template2", count: 4 }] }, + { date: "2018-08-31", count: 10, by_template: [ + { name: "Template1", count: 6 }, + { name: "Template2", count: 4 }] }, + { date: "2018-07-31", count: 5, by_template: [ + { name: "Template1", count: 3 }, + { name: "Template2", count: 2 }] } ]) end - it 'returns all stats csv formatted' do + it "returns all stats csv formatted" do get "#{path}.csv" expected_csv = <<~HERE Date,Template1,Template2,Count - 2018-09-30,6,4,10 - 2018-08-31,6,4,10 - 2018-07-31,3,2,5 + Sep 2018,6,4,10 + Aug 2018,6,4,10 + Jul 2018,3,2,5 HERE expect(response.body).to eq(expected_csv) end - it 'returns stats for start_date and end_date passed' do - get path, { start_date: '2018-08-31', end_date: '2018-09-30' } + it "returns stats for start_date and end_date passed" do + get path, start_date: "2018-08-31", end_date: "2018-09-30" expect(parsed_response).to eq([ - { date: '2018-09-30', count: 10, by_template: [{ name: 'Template1', count: 6 }, { name: 'Template2', count: 4 }]}, - { date: '2018-08-31', count: 10, by_template: [{ name: 'Template1', count: 6 }, { name: 'Template2', count: 4 }]} + { date: "2018-09-30", count: 10, by_template: [ + { name: "Template1", count: 6 }, + { name: "Template2", count: 4 }] }, + { date: "2018-08-31", count: 10, by_template: [ + { name: "Template1", count: 6 }, + { name: "Template2", count: 4 }] } ]) end - it 'returns stats from start_date passed' do - get path, { start_date: '2018-08-31' } + it "returns stats from start_date passed" do + get path, start_date: "2018-08-31" expect(parsed_response).to eq([ - { date: '2018-09-30', count: 10, by_template: [{ name: 'Template1', count: 6 }, { name: 'Template2', count: 4 }]}, - { date: '2018-08-31', count: 10, by_template: [{ name: 'Template1', count: 6 }, { name: 'Template2', count: 4 }]}, + { date: "2018-09-30", count: 10, by_template: [ + { name: "Template1", count: 6 }, + { name: "Template2", count: 4 }] }, + { date: "2018-08-31", count: 10, by_template: [ + { name: "Template1", count: 6 }, + { name: "Template2", count: 4 }] }, ]) end - it 'returns stats until end_date passed' do - get path, { end_date: '2018-08-31' } + it "returns stats until end_date passed" do + get path, end_date: "2018-08-31" expect(parsed_response).to eq([ - { date: '2018-08-31', count: 10, by_template: [{ name: 'Template1', count: 6 }, { name: 'Template2', count: 4 }]}, - { date: '2018-07-31', count: 5, by_template: [{ name: 'Template1', count: 3 }, { name: 'Template2', count: 2 }]} + { date: "2018-08-31", count: 10, by_template: [ + { name: "Template1", count: 6 }, + { name: "Template2", count: 4 }] }, + { date: "2018-07-31", count: 5, by_template: [ + { name: "Template1", count: 3 }, + { name: "Template2", count: 2 }] } ]) end end diff --git a/spec/services/org/create_created_plan_service_spec.rb b/spec/services/org/create_created_plan_service_spec.rb index 5955f4f..4927793 100644 --- a/spec/services/org/create_created_plan_service_spec.rb +++ b/spec/services/org/create_created_plan_service_spec.rb @@ -1,8 +1,10 @@ -require 'rails_helper' +# frozen_string_literal: true + +require "rails_helper" RSpec.describe Org::CreateCreatedPlanService do let(:org) do - FactoryBot.create(:org, created_at: DateTime.new(2018,04,01)) + FactoryBot.create(:org, created_at: DateTime.new(2018, 04, 01)) end let(:template) do FactoryBot.create(:template, org: org) @@ -16,136 +18,165 @@ let(:user2) do FactoryBot.create(:user, org: org) end - #let(:creator) { Role.access_values_for(:creator).first } - #let(:administrator) { Role.access_values_for(:administrator).first } + before(:each) do - plan = FactoryBot.create(:plan, template: template, created_at: DateTime.new(2018,04,01)) - plan2 = FactoryBot.create(:plan, template: template2, created_at: DateTime.new(2018,04,03)) - plan3 = FactoryBot.create(:plan, template: template, created_at: DateTime.new(2018,05,02)) - plan4 = FactoryBot.create(:plan, template: template, created_at: DateTime.new(2018,06,02)) - plan5 = FactoryBot.create(:plan, template: template2, created_at: DateTime.new(2018,06,03)) - FactoryBot.create(:role, :creator, plan: plan, user: user1) - FactoryBot.create(:role, :administrator, plan: plan, user: user2) - FactoryBot.create(:role, :creator, plan: plan2, user: user1) - FactoryBot.create(:role, :creator, plan: plan3, user: user1) - FactoryBot.create(:role, :administrator, plan: plan4, user: user2) - FactoryBot.create(:role, :administrator, plan: plan5, user: user2) + plan = FactoryBot.create(:plan, + template: template, + created_at: DateTime.new(2018, 04, 01)) + plan2 = FactoryBot.create(:plan, + template: template2, + created_at: DateTime.new(2018, 04, 03)) + plan3 = FactoryBot.create(:plan, + template: template, + created_at: DateTime.new(2018, 05, 02)) + plan4 = FactoryBot.create(:plan, + template: template, + created_at: DateTime.new(2018, 06, 02)) + plan5 = FactoryBot.create(:plan, + template: template2, + created_at: DateTime.new(2018, 06, 03)) + FactoryBot.create(:role, + :creator, + plan: plan, + user: user1) + FactoryBot.create(:role, + :administrator, + plan: plan, + user: user2) + FactoryBot.create(:role, + :creator, + plan: plan2, + user: user1) + FactoryBot.create(:role, + :creator, + plan: plan3, + user: user1) + FactoryBot.create(:role, + :administrator, + plan: plan4, + user: user2) + FactoryBot.create(:role, + :administrator, + plan: plan5, + user: user2) end - def find_by_dates(dates: , org_id:) + def find_by_dates(dates:, org_id:) dates.map do |date| StatCreatedPlan.find_by(date: date, org_id: org_id) end end - describe '.call' do - context 'when org is passed' do + describe ".call" do + context "when org is passed" do it "generates monthly counts since org's creation" do described_class.call(org) - april, may, june, july = find_by_dates(dates: ['2018-04-30', '2018-05-31', '2018-06-30', '2018-07-31'], org_id: org.id) + april, may, june, july = find_by_dates(dates: ["2018-04-30", + "2018-05-31", + "2018-06-30", + "2018-07-31"], + org_id: org.id) counts = [april, may, june, july].map(&:count) - expect(counts).to eq([2,1,2,0]) + expect(counts).to eq([2, 1, 2, 0]) end it "generates monthly counts by template since org's creation" do described_class.call(org) - april, may, june, july = find_by_dates(dates: ['2018-04-30', '2018-05-31', '2018-06-30', '2018-07-31'], org_id: org.id) - expect(april.details).to eq( - { - 'by_template' => [ - { 'name' => template.title, 'count' => 1 }, - { 'name' => template2.title, 'count' => 1 }, - ] - } + april, may, june, july = find_by_dates(dates: ["2018-04-30", + "2018-05-31", + "2018-06-30", + "2018-07-31"], + org_id: org.id) + expect(april.details).to match_array( + "by_template" => [ + { "name" => template.title, "count" => 1 }, + { "name" => template2.title, "count" => 1 }, + ] ) - expect(may.details).to eq( - { - 'by_template' => [ - { 'name' => template.title, 'count' => 1 }, - ] - } + expect(may.details).to match_array( + "by_template" => [ + { "name" => template.title, "count" => 1 }, + ] ) - expect(june.details).to eq( - { - 'by_template' => [ - { 'name' => template.title, 'count' => 1 }, - { 'name' => template2.title, 'count' => 1 }, - ] - } + expect(june.details).to match_array( + "by_template" => [ + { "name" => template.title, "count" => 1 }, + { "name" => template2.title, "count" => 1 }, + ] ) - expect(july.details).to eq( - { - 'by_template' => [] - } + expect(july.details).to match_array( + "by_template" => [] ) end it "monthly records are either created or updated" do described_class.call(org) - april = StatCreatedPlan.where(date: '2018-04-30', org: org) + april = StatCreatedPlan.where(date: "2018-04-30", org: org) expect(april).to have(1).items expect(april.first.count).to eq(2) - new_plan = FactoryBot.create(:plan, template: template2, created_at: DateTime.new(2018,04,03)) + new_plan = FactoryBot.create(:plan, + template: template2, + created_at: DateTime.new(2018, 04, 03)) FactoryBot.create(:role, :creator, plan: new_plan, user: user1) described_class.call(org) - april = StatCreatedPlan.where(date: '2018-04-30', org: org) + april = StatCreatedPlan.where(date: "2018-04-30", org: org) expect(april).to have(1).items expect(april.first.count).to eq(3) end end - context 'when no org is passed' do - it 'generates monthly counts for each org since their creation' do + context "when no org is passed" do + it "generates monthly counts for each org since their creation" do Org.stubs(:all).returns([org]) described_class.call - april, may, june, july = find_by_dates(dates: ['2018-04-30', '2018-05-31', '2018-06-30', '2018-07-31'], org_id: org.id) + april, may, june, july = find_by_dates(dates: ["2018-04-30", + "2018-05-31", + "2018-06-30", + "2018-07-31"], + org_id: org.id) counts = [april, may, june, july].map(&:count) - expect(counts).to eq([2,1,2,0]) + expect(counts).to eq([2, 1, 2, 0]) end - it 'generates montly counts by template for each org since their creation' do + it "generates montly counts by template for each org since their creation" do Org.stubs(:all).returns([org]) described_class.call - april, may, june, july = find_by_dates(dates: ['2018-04-30', '2018-05-31', '2018-06-30', '2018-07-31'], org_id: org.id) + april, may, june, july = find_by_dates(dates: ["2018-04-30", + "2018-05-31", + "2018-06-30", + "2018-07-31"], + org_id: org.id) - expect(april.details).to eq( - { - 'by_template' => [ - { 'name' => template.title, 'count' => 1 }, - { 'name' => template2.title, 'count' => 1 }, - ] - } + expect(april.details).to match_array( + "by_template" => [ + { "name" => template.title, "count" => 1 }, + { "name" => template2.title, "count" => 1 }, + ] ) - expect(may.details).to eq( - { - 'by_template' => [ - { 'name' => template.title, 'count' => 1 }, - ] - } + expect(may.details).to match_array( + "by_template" => [ + { "name" => template.title, "count" => 1 }, + ] ) - expect(june.details).to eq( - { - 'by_template' => [ - { 'name' => template.title, 'count' => 1 }, - { 'name' => template2.title, 'count' => 1 }, - ] - } + expect(june.details).to match_array( + "by_template" => [ + { "name" => template.title, "count" => 1 }, + { "name" => template2.title, "count" => 1 }, + ] ) - expect(july.details).to eq( - { - 'by_template' => [] - } + expect(july.details).to match_array( + "by_template" => [] ) end @@ -154,16 +185,18 @@ described_class.call - april = StatCreatedPlan.where(date: '2018-04-30', org: org) + april = StatCreatedPlan.where(date: "2018-04-30", org: org) expect(april).to have(1).items expect(april.first.count).to eq(2) - new_plan = FactoryBot.create(:plan, template: template2, created_at: DateTime.new(2018,04,03)) + new_plan = FactoryBot.create(:plan, + template: template2, + created_at: DateTime.new(2018, 04, 03)) FactoryBot.create(:role, :creator, plan: new_plan, user: user1) described_class.call - april = StatCreatedPlan.where(date: '2018-04-30', org: org) + april = StatCreatedPlan.where(date: "2018-04-30", org: org) expect(april).to have(1).items expect(april.first.count).to eq(3) end diff --git a/spec/services/org/create_last_month_created_plan_service_spec.rb b/spec/services/org/create_last_month_created_plan_service_spec.rb index 027cf3f..a20807d 100644 --- a/spec/services/org/create_last_month_created_plan_service_spec.rb +++ b/spec/services/org/create_last_month_created_plan_service_spec.rb @@ -1,8 +1,10 @@ -require 'rails_helper' +# frozen_string_literal: true + +require "rails_helper" RSpec.describe Org::CreateLastMonthCreatedPlanService do let(:org) do - FactoryBot.create(:org, created_at: DateTime.new(2018,04,01)) + FactoryBot.create(:org, created_at: DateTime.new(2018, 04, 01)) end let(:template) do FactoryBot.create(:template, org: org) @@ -19,63 +21,83 @@ let(:creator) { Role.access_values_for(:creator).first } let(:administrator) { Role.access_values_for(:administrator).first } before(:each) do - plan = FactoryBot.create(:plan, template: template, created_at: Date.today.last_month) - plan2 = FactoryBot.create(:plan, template: template, created_at: Date.today.last_month) - plan3 = FactoryBot.create(:plan, template: template2, created_at: Date.today.last_month) + plan = FactoryBot.create(:plan, + template: template, + created_at: Date.today.last_month) + plan2 = FactoryBot.create(:plan, + template: template, + created_at: Date.today.last_month) + plan3 = FactoryBot.create(:plan, + template: template2, + created_at: Date.today.last_month) FactoryBot.create(:role, :creator, plan: plan, user: user1) FactoryBot.create(:role, :administrator, plan: plan, user: user1) FactoryBot.create(:role, :creator, plan: plan2, user: user1) FactoryBot.create(:role, :creator, plan: plan3, user: user2) end - describe '.call' do - context 'when org is passed' do + describe ".call" do + context "when org is passed" do it "generates counts from today's last month" do described_class.call(org) - last_month_count = StatCreatedPlan.find_by(date: Date.today.last_month.end_of_month, org_id: org.id).count + last_month_count = StatCreatedPlan.find_by( + date: Date.today.last_month.end_of_month, + org_id: org.id).count expect(last_month_count).to eq(3) end it "generates counts by template from today's last month" do described_class.call(org) - last_month_details = StatCreatedPlan.find_by(date: Date.today.last_month.end_of_month, org_id: org.id).details - expect(last_month_details).to eq( - { - 'by_template' => [ - { 'name' => template.title, 'count' => 2 }, - { 'name' => template2.title, 'count' => 1 }, - ] - } + last_month_details = StatCreatedPlan.find_by( + date: Date.today.last_month.end_of_month, + org_id: org.id).details + + expect(last_month_details).to match_array( + "by_template" => [ + { "name" => template.title, "count" => 2 }, + { "name" => template2.title, "count" => 1 }, + ] ) end it "monthly records are either created or updated" do described_class.call(org) - last_month = StatCreatedPlan.where(date: Date.today.last_month.end_of_month, org_id: org.id) + last_month = StatCreatedPlan.where( + date: Date.today.last_month.end_of_month, + org_id: org.id) + expect(last_month).to have(1).items expect(last_month.first.count).to eq(3) - new_plan = FactoryBot.create(:plan, template: template2, created_at: Date.today.last_month.end_of_month) + new_plan = FactoryBot.create(:plan, + template: template2, + created_at: Date.today.last_month.end_of_month) FactoryBot.create(:role, :creator, plan: new_plan, user: user1) described_class.call(org) - last_month = StatCreatedPlan.where(date: Date.today.last_month.end_of_month, org_id: org.id) + last_month = StatCreatedPlan.where( + date: Date.today.last_month.end_of_month, + org_id: org.id) + expect(last_month).to have(1).items expect(last_month.first.count).to eq(4) end end - context 'when no org is passed' do + context "when no org is passed" do it "generates counts from today's last month" do Org.expects(:all).returns([org]) described_class.call - last_month_count = StatCreatedPlan.find_by(date: Date.today.last_month.end_of_month, org_id: org.id).count + last_month_count = StatCreatedPlan.find_by( + date: Date.today.last_month.end_of_month, + org_id: org.id).count + expect(last_month_count).to eq(3) end @@ -84,14 +106,15 @@ described_class.call - last_month_details = StatCreatedPlan.find_by(date: Date.today.last_month.end_of_month, org_id: org.id).details - expect(last_month_details).to eq( - { - 'by_template' => [ - { 'name' => template.title, 'count' => 2 }, - { 'name' => template2.title, 'count' => 1 }, - ] - } + last_month_details = StatCreatedPlan.find_by( + date: Date.today.last_month.end_of_month, + org_id: org.id).details + + expect(last_month_details).to match_array( + "by_template" => [ + { "name" => template.title, "count" => 2 }, + { "name" => template2.title, "count" => 1 }, + ] ) end @@ -100,16 +123,22 @@ described_class.call - last_month = StatCreatedPlan.where(date: Date.today.last_month.end_of_month, org: org) + last_month = StatCreatedPlan.where( + date: Date.today.last_month.end_of_month, + org: org) + expect(last_month).to have(1).items expect(last_month.first.count).to eq(3) - new_plan = FactoryBot.create(:plan, template: template2, created_at: Date.today.last_month.end_of_month) + new_plan = FactoryBot.create(:plan, + template: template2, + created_at: Date.today.last_month.end_of_month) FactoryBot.create(:role, :creator, plan: new_plan, user: user1) described_class.call - last_month = StatCreatedPlan.where(date: Date.today.last_month.end_of_month, org: org) + last_month = StatCreatedPlan.where(date: Date.today.last_month.end_of_month, + org: org) expect(last_month).to have(1).items expect(last_month.first.count).to eq(4) end
        <%= _('Name') %> <%= paginable_sort_link('title') %><%= _('Guidance') %> <%= paginable_sort_link('description') %><%= _('Name') %> <%= paginable_sort_link('themes.title') %><%= _('Guidance') %> <%= paginable_sort_link('themes.description') %>