From 7a2b79771f177c4deddf016f5200ba1f7dc5d0c3 Mon Sep 17 00:00:00 2001 From: gjacob24 Date: Wed, 19 Nov 2025 15:06:14 +0000 Subject: [PATCH 1/8] Add API V2 code from DMPonline service --- Gemfile | 2 + Gemfile.lock | 1454 +++++++++-------- app/controllers/api/v2/base_api_controller.rb | 95 ++ app/controllers/api/v2/plans_controller.rb | 42 + .../api/v2/templates_controller.rb | 22 + app/controllers/application_controller.rb | 14 + .../concerns/plan_permitted_params.rb | 159 ++ app/models/oauth_access_grant.rb | 19 + app/models/oauth_access_token.rb | 21 + app/models/oauth_application.rb | 19 + app/models/user.rb | 4 + app/policies/api/v2/plans_policy.rb | 35 + app/policies/api/v2/templates_policy.rb | 33 + app/presenters/api/v2/api_presenter.rb | 16 + .../api/v2/contributor_presenter.rb | 22 + app/presenters/api/v2/funding_presenter.rb | 25 + app/presenters/api/v2/language_presenter.rb | 84 + app/presenters/api/v2/org_presenter.rb | 17 + app/presenters/api/v2/pagination_presenter.rb | 50 + app/presenters/api/v2/plan_presenter.rb | 59 + .../api/v2/research_output_presenter.rb | 77 + app/presenters/api/v2/template_presenter.rb | 20 + app/services/api/v2/conversion_service.rb | 38 + .../api/v2/_standard_response.json.jbuilder | 37 + .../api/v2/contributors/_show.json.jbuilder | 37 + app/views/api/v2/datasets/_show.json.jbuilder | 84 + app/views/api/v2/error.json.jbuilder | 7 + app/views/api/v2/heartbeat.json.jbuilder | 5 + .../api/v2/identifiers/_show.json.jbuilder | 6 + app/views/api/v2/me.json.jbuilder | 27 + app/views/api/v2/orgs/_show.json.jbuilder | 14 + app/views/api/v2/plans/_cost.json.jbuilder | 8 + app/views/api/v2/plans/_funding.json.jbuilder | 41 + app/views/api/v2/plans/_project.json.jbuilder | 18 + app/views/api/v2/plans/_show.json.jbuilder | 72 + app/views/api/v2/plans/index.json.jbuilder | 9 + .../api/v2/templates/index.json.jbuilder | 25 + .../applications/_delete_form.html.erb | 6 + .../doorkeeper/applications/_form.html.erb | 42 + .../doorkeeper/applications/edit.html.erb | 5 + .../doorkeeper/applications/index.html.erb | 34 + .../doorkeeper/applications/new.html.erb | 5 + .../doorkeeper/applications/show.html.erb | 42 + .../doorkeeper/authorizations/error.html.erb | 9 + .../authorizations/form_post.html.erb | 15 + .../doorkeeper/authorizations/new.html.erb | 46 + .../doorkeeper/authorizations/show.html.erb | 7 + .../_delete_form.html.erb | 4 + .../authorized_applications/index.html.erb | 24 + config/application.rb | 8 + config/initializers/doorkeeper.rb | 72 + config/locales/doorkeeper.en.yml | 154 ++ config/routes.rb | 7 + ...20251119131055_create_doorkeeper_tables.rb | 98 ++ db/schema.rb | 48 +- 55 files changed, 2619 insertions(+), 724 deletions(-) create mode 100644 app/controllers/api/v2/base_api_controller.rb create mode 100644 app/controllers/api/v2/plans_controller.rb create mode 100644 app/controllers/api/v2/templates_controller.rb create mode 100644 app/controllers/concerns/plan_permitted_params.rb create mode 100644 app/models/oauth_access_grant.rb create mode 100644 app/models/oauth_access_token.rb create mode 100644 app/models/oauth_application.rb create mode 100644 app/policies/api/v2/plans_policy.rb create mode 100644 app/policies/api/v2/templates_policy.rb create mode 100644 app/presenters/api/v2/api_presenter.rb create mode 100644 app/presenters/api/v2/contributor_presenter.rb create mode 100644 app/presenters/api/v2/funding_presenter.rb create mode 100644 app/presenters/api/v2/language_presenter.rb create mode 100644 app/presenters/api/v2/org_presenter.rb create mode 100644 app/presenters/api/v2/pagination_presenter.rb create mode 100644 app/presenters/api/v2/plan_presenter.rb create mode 100644 app/presenters/api/v2/research_output_presenter.rb create mode 100644 app/presenters/api/v2/template_presenter.rb create mode 100644 app/services/api/v2/conversion_service.rb create mode 100644 app/views/api/v2/_standard_response.json.jbuilder create mode 100644 app/views/api/v2/contributors/_show.json.jbuilder create mode 100644 app/views/api/v2/datasets/_show.json.jbuilder create mode 100644 app/views/api/v2/error.json.jbuilder create mode 100644 app/views/api/v2/heartbeat.json.jbuilder create mode 100644 app/views/api/v2/identifiers/_show.json.jbuilder create mode 100644 app/views/api/v2/me.json.jbuilder create mode 100644 app/views/api/v2/orgs/_show.json.jbuilder create mode 100644 app/views/api/v2/plans/_cost.json.jbuilder create mode 100644 app/views/api/v2/plans/_funding.json.jbuilder create mode 100644 app/views/api/v2/plans/_project.json.jbuilder create mode 100644 app/views/api/v2/plans/_show.json.jbuilder create mode 100644 app/views/api/v2/plans/index.json.jbuilder create mode 100644 app/views/api/v2/templates/index.json.jbuilder create mode 100644 app/views/doorkeeper/applications/_delete_form.html.erb create mode 100644 app/views/doorkeeper/applications/_form.html.erb create mode 100644 app/views/doorkeeper/applications/edit.html.erb create mode 100644 app/views/doorkeeper/applications/index.html.erb create mode 100644 app/views/doorkeeper/applications/new.html.erb create mode 100644 app/views/doorkeeper/applications/show.html.erb create mode 100644 app/views/doorkeeper/authorizations/error.html.erb create mode 100644 app/views/doorkeeper/authorizations/form_post.html.erb create mode 100644 app/views/doorkeeper/authorizations/new.html.erb create mode 100644 app/views/doorkeeper/authorizations/show.html.erb create mode 100644 app/views/doorkeeper/authorized_applications/_delete_form.html.erb create mode 100644 app/views/doorkeeper/authorized_applications/index.html.erb create mode 100644 config/initializers/doorkeeper.rb create mode 100644 config/locales/doorkeeper.en.yml create mode 100644 db/migrate/20251119131055_create_doorkeeper_tables.rb diff --git a/Gemfile b/Gemfile index 2a9aa8721d..9736ddfc20 100644 --- a/Gemfile +++ b/Gemfile @@ -90,6 +90,8 @@ gem 'devise' # An invitation strategy for Devise (https://github.com/scambra/devise_invitable) gem 'devise_invitable' +gem 'doorkeeper' + # A generalized Rack framework for multiple-provider authentication. # (https://github.com/omniauth/omniauth) gem 'omniauth' diff --git a/Gemfile.lock b/Gemfile.lock index 56db857b5c..f118b37ca9 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,723 +1,731 @@ -GEM - remote: https://rubygems.org/ - specs: - actioncable (7.1.5.2) - actionpack (= 7.1.5.2) - activesupport (= 7.1.5.2) - nio4r (~> 2.0) - websocket-driver (>= 0.6.1) - zeitwerk (~> 2.6) - actionmailbox (7.1.5.2) - actionpack (= 7.1.5.2) - activejob (= 7.1.5.2) - activerecord (= 7.1.5.2) - activestorage (= 7.1.5.2) - activesupport (= 7.1.5.2) - mail (>= 2.7.1) - net-imap - net-pop - net-smtp - actionmailer (7.1.5.2) - actionpack (= 7.1.5.2) - actionview (= 7.1.5.2) - activejob (= 7.1.5.2) - activesupport (= 7.1.5.2) - mail (~> 2.5, >= 2.5.4) - net-imap - net-pop - net-smtp - rails-dom-testing (~> 2.2) - actionpack (7.1.5.2) - actionview (= 7.1.5.2) - activesupport (= 7.1.5.2) - nokogiri (>= 1.8.5) - racc - rack (>= 2.2.4) - rack-session (>= 1.0.1) - rack-test (>= 0.6.3) - rails-dom-testing (~> 2.2) - rails-html-sanitizer (~> 1.6) - actiontext (7.1.5.2) - actionpack (= 7.1.5.2) - activerecord (= 7.1.5.2) - activestorage (= 7.1.5.2) - activesupport (= 7.1.5.2) - globalid (>= 0.6.0) - nokogiri (>= 1.8.5) - actionview (7.1.5.2) - activesupport (= 7.1.5.2) - builder (~> 3.1) - erubi (~> 1.11) - rails-dom-testing (~> 2.2) - rails-html-sanitizer (~> 1.6) - activejob (7.1.5.2) - activesupport (= 7.1.5.2) - globalid (>= 0.3.6) - activemodel (7.1.5.2) - activesupport (= 7.1.5.2) - activerecord (7.1.5.2) - activemodel (= 7.1.5.2) - activesupport (= 7.1.5.2) - timeout (>= 0.4.0) - activerecord_json_validator (3.1.0) - activerecord (>= 4.2.0, < 9) - json_schemer (~> 2.2) - activestorage (7.1.5.2) - actionpack (= 7.1.5.2) - activejob (= 7.1.5.2) - activerecord (= 7.1.5.2) - activesupport (= 7.1.5.2) - marcel (~> 1.0) - activesupport (7.1.5.2) - base64 - benchmark (>= 0.3) - bigdecimal - concurrent-ruby (~> 1.0, >= 1.0.2) - connection_pool (>= 2.2.5) - drb - i18n (>= 1.6, < 2) - logger (>= 1.4.2) - minitest (>= 5.1) - mutex_m - securerandom (>= 0.3) - tzinfo (~> 2.0) - addressable (2.8.7) - public_suffix (>= 2.0.2, < 7.0) - annotate (3.2.0) - activerecord (>= 3.2, < 8.0) - rake (>= 10.4, < 14.0) - annotate_gem (0.0.14) - bundler (>= 1.1) - api-pagination (6.0.0) - ast (2.4.3) - autoprefixer-rails (10.4.21.0) - execjs (~> 2) - base64 (0.3.0) - bcrypt (3.1.20) - benchmark (0.4.1) - better_errors (2.10.1) - erubi (>= 1.0.0) - rack (>= 0.9.0) - rouge (>= 1.0.0) - bigdecimal (3.3.0) - bindex (0.8.1) - binding_of_caller (1.0.1) - debug_inspector (>= 1.2.0) - bootsnap (1.18.6) - msgpack (~> 1.2) - brakeman (7.1.0) - racc - builder (3.3.0) - bullet (8.0.8) - activesupport (>= 3.0.0) - uniform_notifier (~> 1.11) - bundle-audit (0.1.0) - bundler-audit - bundler-audit (0.9.2) - bundler (>= 1.2.0, < 3) - thor (~> 1.0) - byebug (12.0.0) - capybara (3.40.0) - addressable - matrix - mini_mime (>= 0.1.3) - nokogiri (~> 1.11) - rack (>= 1.6.0) - rack-test (>= 0.6.3) - regexp_parser (>= 1.5, < 3.0) - xpath (~> 3.2) - cgi (0.5.0) - claide (1.1.0) - claide-plugins (0.9.2) - cork - nap - open4 (~> 1.3) - coderay (1.1.3) - colored2 (3.1.2) - concurrent-ruby (1.3.5) - connection_pool (2.5.4) - contact_us (1.2.0) - rails (>= 4.2.0) - cork (0.3.0) - colored2 (~> 3.1) - crack (1.0.0) - bigdecimal - rexml - crass (1.0.6) - cssbundling-rails (1.4.3) - railties (>= 6.0.0) - csv (3.3.5) - danger (9.5.3) - base64 (~> 0.2) - claide (~> 1.0) - claide-plugins (>= 0.9.2) - colored2 (>= 3.1, < 5) - cork (~> 0.1) - faraday (>= 0.9.0, < 3.0) - faraday-http-cache (~> 2.0) - git (>= 1.13, < 3.0) - kramdown (>= 2.5.1, < 3.0) - kramdown-parser-gfm (~> 1.0) - octokit (>= 4.0) - pstore (~> 0.1) - terminal-table (>= 1, < 5) - database_cleaner (2.1.0) - database_cleaner-active_record (>= 2, < 3) - database_cleaner-active_record (2.2.2) - activerecord (>= 5.a) - database_cleaner-core (~> 2.0) - database_cleaner-core (2.0.1) - date (3.4.1) - debug_inspector (1.2.0) - devise (4.9.4) - bcrypt (~> 3.0) - orm_adapter (~> 0.1) - railties (>= 4.1.0) - responders - warden (~> 1.2.3) - devise_invitable (2.0.11) - actionmailer (>= 5.0) - devise (>= 4.6) - diff-lcs (1.6.2) - dotenv (3.1.8) - dotenv-rails (3.1.8) - dotenv (= 3.1.8) - railties (>= 6.1) - dragonfly (1.4.1) - addressable (~> 2.3) - multi_json (~> 1.0) - ostruct (~> 0.6.1) - rack (>= 1.3) - dragonfly-s3_data_store (1.3.0) - dragonfly (~> 1.0) - fog-aws - drb (2.2.3) - erb (4.0.4) - cgi (>= 0.3.3) - erubi (1.13.1) - excon (1.3.0) - logger - execjs (2.10.0) - factory_bot (6.5.5) - activesupport (>= 6.1.0) - factory_bot_rails (6.5.1) - factory_bot (~> 6.5) - railties (>= 6.1.0) - faker (3.5.2) - i18n (>= 1.8.11, < 2) - faraday (2.14.0) - faraday-net_http (>= 2.0, < 3.5) - json - logger - faraday-http-cache (2.5.1) - faraday (>= 0.8) - faraday-net_http (3.4.1) - net-http (>= 0.5.0) - ffi (1.17.2-arm64-darwin) - ffi (1.17.2-x86_64-linux-gnu) - flag_shih_tzu (0.3.23) - fog-aws (3.33.0) - base64 (>= 0.2, < 0.4) - fog-core (~> 2.6) - fog-json (~> 1.1) - fog-xml (~> 0.1) - fog-core (2.6.0) - builder - excon (~> 1.0) - formatador (>= 0.2, < 2.0) - mime-types - fog-json (1.2.0) - fog-core - multi_json (~> 1.10) - fog-xml (0.1.5) - fog-core - nokogiri (>= 1.5.11, < 2.0.0) - formatador (1.2.1) - reline - forwardable (1.3.3) - fuubar (2.5.1) - rspec-core (~> 3.0) - ruby-progressbar (~> 1.4) - gettext (3.4.9) - erubi - locale (>= 2.0.5) - prime - racc - text (>= 1.3.0) - git (2.3.3) - activesupport (>= 5.0) - addressable (~> 2.8) - process_executer (~> 1.1) - rchardet (~> 1.8) - globalid (1.3.0) - activesupport (>= 6.1) - guard (2.19.1) - formatador (>= 0.2.4) - listen (>= 2.7, < 4.0) - logger (~> 1.6) - lumberjack (>= 1.0.12, < 2.0) - nenv (~> 0.1) - notiffany (~> 0.0) - ostruct (~> 0.6) - pry (>= 0.13.0) - shellany (~> 0.0) - thor (>= 0.18.1) - hana (1.3.7) - hashdiff (1.2.1) - hashie (5.0.0) - highline (3.1.2) - reline - htmltoword (1.1.1) - actionpack - nokogiri - rubyzip (>= 1.0) - httparty (0.23.1) - csv - mini_mime (>= 1.0.0) - multi_xml (>= 0.5.2) - i18n (1.14.7) - concurrent-ruby (~> 1.0) - io-console (0.8.1) - irb (1.15.2) - pp (>= 0.6.0) - rdoc (>= 4.0.0) - reline (>= 0.4.2) - jbuilder (2.14.1) - actionview (>= 7.0.0) - activesupport (>= 7.0.0) - jsbundling-rails (1.3.1) - railties (>= 6.0.0) - json (2.15.1) - json_schemer (2.4.0) - bigdecimal - hana (~> 1.3) - regexp_parser (~> 2.0) - simpleidn (~> 0.2) - jwt (3.1.2) - base64 - kaminari (1.2.2) - activesupport (>= 4.1.0) - kaminari-actionview (= 1.2.2) - kaminari-activerecord (= 1.2.2) - kaminari-core (= 1.2.2) - kaminari-actionview (1.2.2) - actionview - kaminari-core (= 1.2.2) - kaminari-activerecord (1.2.2) - activerecord - kaminari-core (= 1.2.2) - kaminari-core (1.2.2) - kramdown (2.5.1) - rexml (>= 3.3.9) - kramdown-parser-gfm (1.1.0) - kramdown (~> 2.0) - language_server-protocol (3.17.0.5) - ledermann-rails-settings (2.6.2) - activerecord (>= 6.1) - lint_roller (1.1.0) - listen (3.9.0) - rb-fsevent (~> 0.10, >= 0.10.3) - rb-inotify (~> 0.9, >= 0.9.10) - locale (2.1.4) - logger (1.7.0) - loofah (2.24.1) - crass (~> 1.0.2) - nokogiri (>= 1.12.0) - lumberjack (1.4.2) - mail (2.7.1) - mini_mime (>= 0.1.1) - marcel (1.1.0) - matrix (0.4.3) - method_source (1.1.0) - mime-types (3.7.0) - logger - mime-types-data (~> 3.2025, >= 3.2025.0507) - mime-types-data (3.2025.0924) - mimemagic (0.4.3) - nokogiri (~> 1) - rake - mini_mime (1.1.5) - minitest (5.25.5) - mocha (2.7.1) - ruby2_keywords (>= 0.0.5) - msgpack (1.8.0) - multi_json (1.17.0) - multi_xml (0.7.1) - bigdecimal (~> 3.1) - mutex_m (0.3.0) - mysql2 (0.5.7) - bigdecimal - nap (1.1.0) - nenv (0.3.0) - net-http (0.6.0) - uri - net-imap (0.5.12) - date - net-protocol - net-pop (0.1.2) - net-protocol - net-protocol (0.2.2) - timeout - net-smtp (0.5.1) - net-protocol - nio4r (2.7.4) - nokogiri (1.18.10-arm64-darwin) - racc (~> 1.4) - nokogiri (1.18.10-x86_64-linux-gnu) - racc (~> 1.4) - notiffany (0.1.3) - nenv (~> 0.1) - shellany (~> 0.0) - oauth2 (2.0.17) - faraday (>= 0.17.3, < 4.0) - jwt (>= 1.0, < 4.0) - logger (~> 1.2) - multi_xml (~> 0.5) - rack (>= 1.2, < 4) - snaky_hash (~> 2.0, >= 2.0.3) - version_gem (~> 1.1, >= 1.1.9) - octokit (10.0.0) - faraday (>= 1, < 3) - sawyer (~> 0.9) - omniauth (2.1.4) - hashie (>= 3.4.6) - logger - rack (>= 2.2.3) - rack-protection - omniauth-oauth2 (1.8.0) - oauth2 (>= 1.4, < 3) - omniauth (~> 2.0) - omniauth-orcid (2.1.1) - omniauth-oauth2 (~> 1.3) - ruby_dig (~> 0.0.2) - omniauth-rails_csrf_protection (1.0.2) - actionpack (>= 4.2) - omniauth (~> 2.0) - omniauth-shibboleth (1.3.0) - omniauth (>= 1.0.0) - open4 (1.3.4) - options (2.3.2) - orm_adapter (0.5.0) - ostruct (0.6.3) - parallel (1.27.0) - parser (3.3.9.0) - ast (~> 2.4.1) - racc - pg (1.6.2-arm64-darwin) - pg (1.6.2-x86_64-linux) - pp (0.6.3) - prettyprint - prettyprint (0.2.0) - prime (0.1.4) - forwardable - singleton - prism (1.5.1) - process_executer (1.3.0) - progress_bar (1.3.4) - highline (>= 1.6) - options (~> 2.3.0) - pry (0.15.2) - coderay (~> 1.1) - method_source (~> 1.0) - pstore (0.2.0) - psych (5.2.6) - date - stringio - public_suffix (6.0.2) - puma (7.0.4) - nio4r (~> 2.0) - pundit (2.5.2) - activesupport (>= 3.0.0) - pundit-matchers (4.0.0) - rspec-core (~> 3.12) - rspec-expectations (~> 3.12) - rspec-mocks (~> 3.12) - rspec-support (~> 3.12) - racc (1.8.1) - rack (3.2.2) - rack-attack (6.7.0) - rack (>= 1.0, < 4) - rack-mini-profiler (4.0.1) - rack (>= 1.2.0) - rack-protection (4.1.1) - base64 (>= 0.1.0) - logger (>= 1.6.0) - rack (>= 3.0.0, < 4) - rack-session (2.1.1) - base64 (>= 0.1.0) - rack (>= 3.0.0) - rack-test (2.2.0) - rack (>= 1.3) - rackup (2.2.1) - rack (>= 3) - rails (7.1.5.2) - actioncable (= 7.1.5.2) - actionmailbox (= 7.1.5.2) - actionmailer (= 7.1.5.2) - actionpack (= 7.1.5.2) - actiontext (= 7.1.5.2) - actionview (= 7.1.5.2) - activejob (= 7.1.5.2) - activemodel (= 7.1.5.2) - activerecord (= 7.1.5.2) - activestorage (= 7.1.5.2) - activesupport (= 7.1.5.2) - bundler (>= 1.15.0) - railties (= 7.1.5.2) - rails-controller-testing (1.0.5) - actionpack (>= 5.0.1.rc1) - actionview (>= 5.0.1.rc1) - activesupport (>= 5.0.1.rc1) - rails-dom-testing (2.3.0) - activesupport (>= 5.0.0) - minitest - nokogiri (>= 1.6) - rails-html-sanitizer (1.6.2) - loofah (~> 2.21) - nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) - railties (7.1.5.2) - actionpack (= 7.1.5.2) - activesupport (= 7.1.5.2) - irb - rackup (>= 1.0.0) - rake (>= 12.2) - thor (~> 1.0, >= 1.2.2) - zeitwerk (~> 2.6) - rainbow (3.1.1) - rake (13.3.0) - rb-fsevent (0.11.2) - rb-inotify (0.11.1) - ffi (~> 1.0) - rchardet (1.10.0) - rdoc (6.15.0) - erb - psych (>= 4.0.0) - tsort - recaptcha (5.21.1) - regexp_parser (2.11.3) - reline (0.6.2) - io-console (~> 0.5) - responders (3.1.1) - actionpack (>= 5.2) - railties (>= 5.2) - rexml (3.4.4) - rollbar (3.6.2) - rouge (4.6.1) - rspec-collection_matchers (1.2.1) - rspec-expectations (>= 2.99.0.beta1) - rspec-core (3.13.5) - rspec-support (~> 3.13.0) - rspec-expectations (3.13.5) - diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.13.0) - rspec-mocks (3.13.5) - diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.13.0) - rspec-rails (7.1.1) - actionpack (>= 7.0) - activesupport (>= 7.0) - railties (>= 7.0) - rspec-core (~> 3.13) - rspec-expectations (~> 3.13) - rspec-mocks (~> 3.13) - rspec-support (~> 3.13) - rspec-support (3.13.6) - rubocop (1.81.1) - json (~> 2.3) - language_server-protocol (~> 3.17.0.2) - lint_roller (~> 1.1.0) - parallel (~> 1.10) - parser (>= 3.3.0.2) - rainbow (>= 2.2.2, < 4.0) - regexp_parser (>= 2.9.3, < 3.0) - rubocop-ast (>= 1.47.1, < 2.0) - ruby-progressbar (~> 1.7) - unicode-display_width (>= 2.4.0, < 4.0) - rubocop-ast (1.47.1) - parser (>= 3.3.7.2) - prism (~> 1.4) - rubocop-i18n (3.2.3) - lint_roller (~> 1.1) - rubocop (>= 1.72.1) - rubocop-performance (1.26.0) - lint_roller (~> 1.1) - rubocop (>= 1.75.0, < 2.0) - rubocop-ast (>= 1.44.0, < 2.0) - ruby-progressbar (1.13.0) - ruby2_keywords (0.0.5) - ruby_dig (0.0.2) - rubyzip (2.4.1) - sawyer (0.9.2) - addressable (>= 2.3.5) - faraday (>= 0.17.3, < 3) - securerandom (0.4.1) - selenium-webdriver (4.32.0) - base64 (~> 0.2) - logger (~> 1.4) - rexml (~> 3.2, >= 3.2.5) - rubyzip (>= 1.2.2, < 3.0) - websocket (~> 1.0) - shellany (0.0.1) - shoulda (4.0.0) - shoulda-context (~> 2.0) - shoulda-matchers (~> 4.0) - shoulda-context (2.0.0) - shoulda-matchers (4.5.1) - activesupport (>= 4.2.0) - simpleidn (0.2.3) - singleton (0.3.0) - snaky_hash (2.0.3) - hashie (>= 0.1.0, < 6) - version_gem (>= 1.1.8, < 3) - spring (4.4.0) - spring-commands-rspec (1.0.4) - spring (>= 0.9.1) - spring-watcher-listen (2.1.0) - listen (>= 2.7, < 4.0) - spring (>= 4) - sprockets (4.2.2) - concurrent-ruby (~> 1.0) - logger - rack (>= 2.2.4, < 4) - sprockets-rails (3.5.2) - actionpack (>= 6.1) - activesupport (>= 6.1) - sprockets (>= 3.0.0) - stringio (3.1.7) - terminal-table (4.0.0) - unicode-display_width (>= 1.1.1, < 4) - text (1.3.1) - thor (1.4.0) - timeout (0.4.3) - tomparse (0.4.2) - translation (1.41) - gettext (~> 3.2, >= 3.2.5, <= 3.4.9) - tsort (0.2.0) - turbo-rails (2.0.17) - actionpack (>= 7.1.0) - railties (>= 7.1.0) - tzinfo (2.0.6) - concurrent-ruby (~> 1.0) - unicode-display_width (3.2.0) - unicode-emoji (~> 4.1) - unicode-emoji (4.1.0) - uniform_notifier (1.18.0) - uri (1.0.4) - version_gem (1.1.9) - warden (1.2.9) - rack (>= 2.0.9) - web-console (4.2.1) - actionview (>= 6.0.0) - activemodel (>= 6.0.0) - bindex (>= 0.4.0) - railties (>= 6.0.0) - webmock (3.25.1) - addressable (>= 2.8.0) - crack (>= 0.3.2) - hashdiff (>= 0.4.0, < 2.0.0) - websocket (1.2.11) - websocket-driver (0.8.0) - base64 - websocket-extensions (>= 0.1.0) - websocket-extensions (0.1.5) - wicked_pdf (2.8.2) - activesupport - ostruct - wkhtmltopdf-binary (0.12.6.10) - xpath (3.2.0) - nokogiri (~> 1.8) - yard (0.9.37) - yard-tomdoc (0.7.1) - tomparse (>= 0.4.0) - yard - zeitwerk (2.6.18) - -PLATFORMS - arm64-darwin-21 - arm64-darwin-22 - x86_64-linux - -DEPENDENCIES - activerecord_json_validator - annotate - annotate_gem - api-pagination - autoprefixer-rails - better_errors - binding_of_caller - bootsnap - brakeman - bullet - bundle-audit - byebug - capybara - contact_us - cssbundling-rails - danger - database_cleaner - devise - devise_invitable - dotenv-rails - dragonfly - dragonfly-s3_data_store - factory_bot_rails - faker - flag_shih_tzu - fuubar - guard - htmltoword - httparty - jbuilder - jsbundling-rails - jwt - kaminari - ledermann-rails-settings - listen - mail (= 2.7.1) - mimemagic - mocha - mysql2 - net-smtp - omniauth - omniauth-orcid - omniauth-rails_csrf_protection - omniauth-shibboleth - parallel - pg - progress_bar - puma - pundit - pundit-matchers - rack-attack (~> 6.6, >= 6.6.1) - rack-mini-profiler - rails (~> 7.1) - rails-controller-testing - recaptcha - rollbar - rspec-collection_matchers - rspec-rails - rubocop - rubocop-i18n - rubocop-performance - ruby-progressbar - selenium-webdriver - shoulda - spring - spring-commands-rspec - spring-watcher-listen - sprockets-rails - text - translation - turbo-rails - web-console - webmock - wicked_pdf - wkhtmltopdf-binary - yard - yard-tomdoc - -RUBY VERSION - ruby 3.1.4p223 - -BUNDLED WITH - 2.4.17 +GEM + remote: https://rubygems.org/ + specs: + actioncable (7.1.5.2) + actionpack (= 7.1.5.2) + activesupport (= 7.1.5.2) + nio4r (~> 2.0) + websocket-driver (>= 0.6.1) + zeitwerk (~> 2.6) + actionmailbox (7.1.5.2) + actionpack (= 7.1.5.2) + activejob (= 7.1.5.2) + activerecord (= 7.1.5.2) + activestorage (= 7.1.5.2) + activesupport (= 7.1.5.2) + mail (>= 2.7.1) + net-imap + net-pop + net-smtp + actionmailer (7.1.5.2) + actionpack (= 7.1.5.2) + actionview (= 7.1.5.2) + activejob (= 7.1.5.2) + activesupport (= 7.1.5.2) + mail (~> 2.5, >= 2.5.4) + net-imap + net-pop + net-smtp + rails-dom-testing (~> 2.2) + actionpack (7.1.5.2) + actionview (= 7.1.5.2) + activesupport (= 7.1.5.2) + nokogiri (>= 1.8.5) + racc + rack (>= 2.2.4) + rack-session (>= 1.0.1) + rack-test (>= 0.6.3) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + actiontext (7.1.5.2) + actionpack (= 7.1.5.2) + activerecord (= 7.1.5.2) + activestorage (= 7.1.5.2) + activesupport (= 7.1.5.2) + globalid (>= 0.6.0) + nokogiri (>= 1.8.5) + actionview (7.1.5.2) + activesupport (= 7.1.5.2) + builder (~> 3.1) + erubi (~> 1.11) + rails-dom-testing (~> 2.2) + rails-html-sanitizer (~> 1.6) + activejob (7.1.5.2) + activesupport (= 7.1.5.2) + globalid (>= 0.3.6) + activemodel (7.1.5.2) + activesupport (= 7.1.5.2) + activerecord (7.1.5.2) + activemodel (= 7.1.5.2) + activesupport (= 7.1.5.2) + timeout (>= 0.4.0) + activerecord_json_validator (3.1.0) + activerecord (>= 4.2.0, < 9) + json_schemer (~> 2.2) + activestorage (7.1.5.2) + actionpack (= 7.1.5.2) + activejob (= 7.1.5.2) + activerecord (= 7.1.5.2) + activesupport (= 7.1.5.2) + marcel (~> 1.0) + activesupport (7.1.5.2) + base64 + benchmark (>= 0.3) + bigdecimal + concurrent-ruby (~> 1.0, >= 1.0.2) + connection_pool (>= 2.2.5) + drb + i18n (>= 1.6, < 2) + logger (>= 1.4.2) + minitest (>= 5.1) + mutex_m + securerandom (>= 0.3) + tzinfo (~> 2.0) + addressable (2.8.7) + public_suffix (>= 2.0.2, < 7.0) + annotate (3.2.0) + activerecord (>= 3.2, < 8.0) + rake (>= 10.4, < 14.0) + annotate_gem (0.0.14) + bundler (>= 1.1) + api-pagination (6.0.0) + ast (2.4.3) + autoprefixer-rails (10.4.21.0) + execjs (~> 2) + base64 (0.3.0) + bcrypt (3.1.20) + benchmark (0.4.1) + better_errors (2.10.1) + erubi (>= 1.0.0) + rack (>= 0.9.0) + rouge (>= 1.0.0) + bigdecimal (3.3.0) + bindex (0.8.1) + binding_of_caller (1.0.1) + debug_inspector (>= 1.2.0) + bootsnap (1.18.6) + msgpack (~> 1.2) + brakeman (7.1.0) + racc + builder (3.3.0) + bullet (8.0.8) + activesupport (>= 3.0.0) + uniform_notifier (~> 1.11) + bundle-audit (0.1.0) + bundler-audit + bundler-audit (0.9.2) + bundler (>= 1.2.0, < 3) + thor (~> 1.0) + byebug (12.0.0) + capybara (3.40.0) + addressable + matrix + mini_mime (>= 0.1.3) + nokogiri (~> 1.11) + rack (>= 1.6.0) + rack-test (>= 0.6.3) + regexp_parser (>= 1.5, < 3.0) + xpath (~> 3.2) + cgi (0.5.0) + claide (1.1.0) + claide-plugins (0.9.2) + cork + nap + open4 (~> 1.3) + coderay (1.1.3) + colored2 (3.1.2) + concurrent-ruby (1.3.5) + connection_pool (2.5.4) + contact_us (1.2.0) + rails (>= 4.2.0) + cork (0.3.0) + colored2 (~> 3.1) + crack (1.0.0) + bigdecimal + rexml + crass (1.0.6) + cssbundling-rails (1.4.3) + railties (>= 6.0.0) + csv (3.3.5) + danger (9.5.3) + base64 (~> 0.2) + claide (~> 1.0) + claide-plugins (>= 0.9.2) + colored2 (>= 3.1, < 5) + cork (~> 0.1) + faraday (>= 0.9.0, < 3.0) + faraday-http-cache (~> 2.0) + git (>= 1.13, < 3.0) + kramdown (>= 2.5.1, < 3.0) + kramdown-parser-gfm (~> 1.0) + octokit (>= 4.0) + pstore (~> 0.1) + terminal-table (>= 1, < 5) + database_cleaner (2.1.0) + database_cleaner-active_record (>= 2, < 3) + database_cleaner-active_record (2.2.2) + activerecord (>= 5.a) + database_cleaner-core (~> 2.0) + database_cleaner-core (2.0.1) + date (3.4.1) + debug_inspector (1.2.0) + devise (4.9.4) + bcrypt (~> 3.0) + orm_adapter (~> 0.1) + railties (>= 4.1.0) + responders + warden (~> 1.2.3) + devise_invitable (2.0.11) + actionmailer (>= 5.0) + devise (>= 4.6) + diff-lcs (1.6.2) + doorkeeper (5.8.2) + railties (>= 5) + dotenv (3.1.8) + dotenv-rails (3.1.8) + dotenv (= 3.1.8) + railties (>= 6.1) + dragonfly (1.4.1) + addressable (~> 2.3) + multi_json (~> 1.0) + ostruct (~> 0.6.1) + rack (>= 1.3) + dragonfly-s3_data_store (1.3.0) + dragonfly (~> 1.0) + fog-aws + drb (2.2.3) + erb (4.0.4) + cgi (>= 0.3.3) + erubi (1.13.1) + excon (1.3.0) + logger + execjs (2.10.0) + factory_bot (6.5.5) + activesupport (>= 6.1.0) + factory_bot_rails (6.5.1) + factory_bot (~> 6.5) + railties (>= 6.1.0) + faker (3.5.2) + i18n (>= 1.8.11, < 2) + faraday (2.14.0) + faraday-net_http (>= 2.0, < 3.5) + json + logger + faraday-http-cache (2.5.1) + faraday (>= 0.8) + faraday-net_http (3.4.1) + net-http (>= 0.5.0) + ffi (1.17.2-aarch64-linux-gnu) + ffi (1.17.2-arm64-darwin) + ffi (1.17.2-x86_64-linux-gnu) + flag_shih_tzu (0.3.23) + fog-aws (3.33.0) + base64 (>= 0.2, < 0.4) + fog-core (~> 2.6) + fog-json (~> 1.1) + fog-xml (~> 0.1) + fog-core (2.6.0) + builder + excon (~> 1.0) + formatador (>= 0.2, < 2.0) + mime-types + fog-json (1.2.0) + fog-core + multi_json (~> 1.10) + fog-xml (0.1.5) + fog-core + nokogiri (>= 1.5.11, < 2.0.0) + formatador (1.2.1) + reline + forwardable (1.3.3) + fuubar (2.5.1) + rspec-core (~> 3.0) + ruby-progressbar (~> 1.4) + gettext (3.4.9) + erubi + locale (>= 2.0.5) + prime + racc + text (>= 1.3.0) + git (2.3.3) + activesupport (>= 5.0) + addressable (~> 2.8) + process_executer (~> 1.1) + rchardet (~> 1.8) + globalid (1.3.0) + activesupport (>= 6.1) + guard (2.19.1) + formatador (>= 0.2.4) + listen (>= 2.7, < 4.0) + logger (~> 1.6) + lumberjack (>= 1.0.12, < 2.0) + nenv (~> 0.1) + notiffany (~> 0.0) + ostruct (~> 0.6) + pry (>= 0.13.0) + shellany (~> 0.0) + thor (>= 0.18.1) + hana (1.3.7) + hashdiff (1.2.1) + hashie (5.0.0) + highline (3.1.2) + reline + htmltoword (1.1.1) + actionpack + nokogiri + rubyzip (>= 1.0) + httparty (0.23.1) + csv + mini_mime (>= 1.0.0) + multi_xml (>= 0.5.2) + i18n (1.14.7) + concurrent-ruby (~> 1.0) + io-console (0.8.1) + irb (1.15.2) + pp (>= 0.6.0) + rdoc (>= 4.0.0) + reline (>= 0.4.2) + jbuilder (2.14.1) + actionview (>= 7.0.0) + activesupport (>= 7.0.0) + jsbundling-rails (1.3.1) + railties (>= 6.0.0) + json (2.15.1) + json_schemer (2.4.0) + bigdecimal + hana (~> 1.3) + regexp_parser (~> 2.0) + simpleidn (~> 0.2) + jwt (3.1.2) + base64 + kaminari (1.2.2) + activesupport (>= 4.1.0) + kaminari-actionview (= 1.2.2) + kaminari-activerecord (= 1.2.2) + kaminari-core (= 1.2.2) + kaminari-actionview (1.2.2) + actionview + kaminari-core (= 1.2.2) + kaminari-activerecord (1.2.2) + activerecord + kaminari-core (= 1.2.2) + kaminari-core (1.2.2) + kramdown (2.5.1) + rexml (>= 3.3.9) + kramdown-parser-gfm (1.1.0) + kramdown (~> 2.0) + language_server-protocol (3.17.0.5) + ledermann-rails-settings (2.6.2) + activerecord (>= 6.1) + lint_roller (1.1.0) + listen (3.9.0) + rb-fsevent (~> 0.10, >= 0.10.3) + rb-inotify (~> 0.9, >= 0.9.10) + locale (2.1.4) + logger (1.7.0) + loofah (2.24.1) + crass (~> 1.0.2) + nokogiri (>= 1.12.0) + lumberjack (1.4.2) + mail (2.7.1) + mini_mime (>= 0.1.1) + marcel (1.1.0) + matrix (0.4.3) + method_source (1.1.0) + mime-types (3.7.0) + logger + mime-types-data (~> 3.2025, >= 3.2025.0507) + mime-types-data (3.2025.0924) + mimemagic (0.4.3) + nokogiri (~> 1) + rake + mini_mime (1.1.5) + minitest (5.25.5) + mocha (2.7.1) + ruby2_keywords (>= 0.0.5) + msgpack (1.8.0) + multi_json (1.17.0) + multi_xml (0.7.1) + bigdecimal (~> 3.1) + mutex_m (0.3.0) + mysql2 (0.5.7) + bigdecimal + nap (1.1.0) + nenv (0.3.0) + net-http (0.6.0) + uri + net-imap (0.5.12) + date + net-protocol + net-pop (0.1.2) + net-protocol + net-protocol (0.2.2) + timeout + net-smtp (0.5.1) + net-protocol + nio4r (2.7.4) + nokogiri (1.18.10-aarch64-linux-gnu) + racc (~> 1.4) + nokogiri (1.18.10-arm64-darwin) + racc (~> 1.4) + nokogiri (1.18.10-x86_64-linux-gnu) + racc (~> 1.4) + notiffany (0.1.3) + nenv (~> 0.1) + shellany (~> 0.0) + oauth2 (2.0.17) + faraday (>= 0.17.3, < 4.0) + jwt (>= 1.0, < 4.0) + logger (~> 1.2) + multi_xml (~> 0.5) + rack (>= 1.2, < 4) + snaky_hash (~> 2.0, >= 2.0.3) + version_gem (~> 1.1, >= 1.1.9) + octokit (10.0.0) + faraday (>= 1, < 3) + sawyer (~> 0.9) + omniauth (2.1.4) + hashie (>= 3.4.6) + logger + rack (>= 2.2.3) + rack-protection + omniauth-oauth2 (1.8.0) + oauth2 (>= 1.4, < 3) + omniauth (~> 2.0) + omniauth-orcid (2.1.1) + omniauth-oauth2 (~> 1.3) + ruby_dig (~> 0.0.2) + omniauth-rails_csrf_protection (1.0.2) + actionpack (>= 4.2) + omniauth (~> 2.0) + omniauth-shibboleth (1.3.0) + omniauth (>= 1.0.0) + open4 (1.3.4) + options (2.3.2) + orm_adapter (0.5.0) + ostruct (0.6.3) + parallel (1.27.0) + parser (3.3.9.0) + ast (~> 2.4.1) + racc + pg (1.6.2-aarch64-linux) + pg (1.6.2-arm64-darwin) + pg (1.6.2-x86_64-linux) + pp (0.6.3) + prettyprint + prettyprint (0.2.0) + prime (0.1.4) + forwardable + singleton + prism (1.5.1) + process_executer (1.3.0) + progress_bar (1.3.4) + highline (>= 1.6) + options (~> 2.3.0) + pry (0.15.2) + coderay (~> 1.1) + method_source (~> 1.0) + pstore (0.2.0) + psych (5.2.6) + date + stringio + public_suffix (6.0.2) + puma (7.0.4) + nio4r (~> 2.0) + pundit (2.5.2) + activesupport (>= 3.0.0) + pundit-matchers (4.0.0) + rspec-core (~> 3.12) + rspec-expectations (~> 3.12) + rspec-mocks (~> 3.12) + rspec-support (~> 3.12) + racc (1.8.1) + rack (3.2.2) + rack-attack (6.7.0) + rack (>= 1.0, < 4) + rack-mini-profiler (4.0.1) + rack (>= 1.2.0) + rack-protection (4.1.1) + base64 (>= 0.1.0) + logger (>= 1.6.0) + rack (>= 3.0.0, < 4) + rack-session (2.1.1) + base64 (>= 0.1.0) + rack (>= 3.0.0) + rack-test (2.2.0) + rack (>= 1.3) + rackup (2.2.1) + rack (>= 3) + rails (7.1.5.2) + actioncable (= 7.1.5.2) + actionmailbox (= 7.1.5.2) + actionmailer (= 7.1.5.2) + actionpack (= 7.1.5.2) + actiontext (= 7.1.5.2) + actionview (= 7.1.5.2) + activejob (= 7.1.5.2) + activemodel (= 7.1.5.2) + activerecord (= 7.1.5.2) + activestorage (= 7.1.5.2) + activesupport (= 7.1.5.2) + bundler (>= 1.15.0) + railties (= 7.1.5.2) + rails-controller-testing (1.0.5) + actionpack (>= 5.0.1.rc1) + actionview (>= 5.0.1.rc1) + activesupport (>= 5.0.1.rc1) + rails-dom-testing (2.3.0) + activesupport (>= 5.0.0) + minitest + nokogiri (>= 1.6) + rails-html-sanitizer (1.6.2) + loofah (~> 2.21) + nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0) + railties (7.1.5.2) + actionpack (= 7.1.5.2) + activesupport (= 7.1.5.2) + irb + rackup (>= 1.0.0) + rake (>= 12.2) + thor (~> 1.0, >= 1.2.2) + zeitwerk (~> 2.6) + rainbow (3.1.1) + rake (13.3.0) + rb-fsevent (0.11.2) + rb-inotify (0.11.1) + ffi (~> 1.0) + rchardet (1.10.0) + rdoc (6.15.0) + erb + psych (>= 4.0.0) + tsort + recaptcha (5.21.1) + regexp_parser (2.11.3) + reline (0.6.2) + io-console (~> 0.5) + responders (3.1.1) + actionpack (>= 5.2) + railties (>= 5.2) + rexml (3.4.4) + rollbar (3.6.2) + rouge (4.6.1) + rspec-collection_matchers (1.2.1) + rspec-expectations (>= 2.99.0.beta1) + rspec-core (3.13.5) + rspec-support (~> 3.13.0) + rspec-expectations (3.13.5) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-mocks (3.13.5) + diff-lcs (>= 1.2.0, < 2.0) + rspec-support (~> 3.13.0) + rspec-rails (7.1.1) + actionpack (>= 7.0) + activesupport (>= 7.0) + railties (>= 7.0) + rspec-core (~> 3.13) + rspec-expectations (~> 3.13) + rspec-mocks (~> 3.13) + rspec-support (~> 3.13) + rspec-support (3.13.6) + rubocop (1.81.1) + json (~> 2.3) + language_server-protocol (~> 3.17.0.2) + lint_roller (~> 1.1.0) + parallel (~> 1.10) + parser (>= 3.3.0.2) + rainbow (>= 2.2.2, < 4.0) + regexp_parser (>= 2.9.3, < 3.0) + rubocop-ast (>= 1.47.1, < 2.0) + ruby-progressbar (~> 1.7) + unicode-display_width (>= 2.4.0, < 4.0) + rubocop-ast (1.47.1) + parser (>= 3.3.7.2) + prism (~> 1.4) + rubocop-i18n (3.2.3) + lint_roller (~> 1.1) + rubocop (>= 1.72.1) + rubocop-performance (1.26.0) + lint_roller (~> 1.1) + rubocop (>= 1.75.0, < 2.0) + rubocop-ast (>= 1.44.0, < 2.0) + ruby-progressbar (1.13.0) + ruby2_keywords (0.0.5) + ruby_dig (0.0.2) + rubyzip (2.4.1) + sawyer (0.9.2) + addressable (>= 2.3.5) + faraday (>= 0.17.3, < 3) + securerandom (0.4.1) + selenium-webdriver (4.32.0) + base64 (~> 0.2) + logger (~> 1.4) + rexml (~> 3.2, >= 3.2.5) + rubyzip (>= 1.2.2, < 3.0) + websocket (~> 1.0) + shellany (0.0.1) + shoulda (4.0.0) + shoulda-context (~> 2.0) + shoulda-matchers (~> 4.0) + shoulda-context (2.0.0) + shoulda-matchers (4.5.1) + activesupport (>= 4.2.0) + simpleidn (0.2.3) + singleton (0.3.0) + snaky_hash (2.0.3) + hashie (>= 0.1.0, < 6) + version_gem (>= 1.1.8, < 3) + spring (4.4.0) + spring-commands-rspec (1.0.4) + spring (>= 0.9.1) + spring-watcher-listen (2.1.0) + listen (>= 2.7, < 4.0) + spring (>= 4) + sprockets (4.2.2) + concurrent-ruby (~> 1.0) + logger + rack (>= 2.2.4, < 4) + sprockets-rails (3.5.2) + actionpack (>= 6.1) + activesupport (>= 6.1) + sprockets (>= 3.0.0) + stringio (3.1.7) + terminal-table (4.0.0) + unicode-display_width (>= 1.1.1, < 4) + text (1.3.1) + thor (1.4.0) + timeout (0.4.3) + tomparse (0.4.2) + translation (1.41) + gettext (~> 3.2, >= 3.2.5, <= 3.4.9) + tsort (0.2.0) + turbo-rails (2.0.17) + actionpack (>= 7.1.0) + railties (>= 7.1.0) + tzinfo (2.0.6) + concurrent-ruby (~> 1.0) + unicode-display_width (3.2.0) + unicode-emoji (~> 4.1) + unicode-emoji (4.1.0) + uniform_notifier (1.18.0) + uri (1.0.4) + version_gem (1.1.9) + warden (1.2.9) + rack (>= 2.0.9) + web-console (4.2.1) + actionview (>= 6.0.0) + activemodel (>= 6.0.0) + bindex (>= 0.4.0) + railties (>= 6.0.0) + webmock (3.25.1) + addressable (>= 2.8.0) + crack (>= 0.3.2) + hashdiff (>= 0.4.0, < 2.0.0) + websocket (1.2.11) + websocket-driver (0.8.0) + base64 + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.5) + wicked_pdf (2.8.2) + activesupport + ostruct + wkhtmltopdf-binary (0.12.6.10) + xpath (3.2.0) + nokogiri (~> 1.8) + yard (0.9.37) + yard-tomdoc (0.7.1) + tomparse (>= 0.4.0) + yard + zeitwerk (2.6.18) + +PLATFORMS + aarch64-linux + arm64-darwin-21 + arm64-darwin-22 + x86_64-linux + +DEPENDENCIES + activerecord_json_validator + annotate + annotate_gem + api-pagination + autoprefixer-rails + better_errors + binding_of_caller + bootsnap + brakeman + bullet + bundle-audit + byebug + capybara + contact_us + cssbundling-rails + danger + database_cleaner + devise + devise_invitable + doorkeeper + dotenv-rails + dragonfly + dragonfly-s3_data_store + factory_bot_rails + faker + flag_shih_tzu + fuubar + guard + htmltoword + httparty + jbuilder + jsbundling-rails + jwt + kaminari + ledermann-rails-settings + listen + mail (= 2.7.1) + mimemagic + mocha + mysql2 + net-smtp + omniauth + omniauth-orcid + omniauth-rails_csrf_protection + omniauth-shibboleth + parallel + pg + progress_bar + puma + pundit + pundit-matchers + rack-attack (~> 6.6, >= 6.6.1) + rack-mini-profiler + rails (~> 7.1) + rails-controller-testing + recaptcha + rollbar + rspec-collection_matchers + rspec-rails + rubocop + rubocop-i18n + rubocop-performance + ruby-progressbar + selenium-webdriver + shoulda + spring + spring-commands-rspec + spring-watcher-listen + sprockets-rails + text + translation + turbo-rails + web-console + webmock + wicked_pdf + wkhtmltopdf-binary + yard + yard-tomdoc + +RUBY VERSION + ruby 3.1.4p223 + +BUNDLED WITH + 2.4.17 diff --git a/app/controllers/api/v2/base_api_controller.rb b/app/controllers/api/v2/base_api_controller.rb new file mode 100644 index 0000000000..8b31faf221 --- /dev/null +++ b/app/controllers/api/v2/base_api_controller.rb @@ -0,0 +1,95 @@ +# frozen_string_literal: true + +module Api + module V2 + class BaseApiController < ApplicationController + + # skipping the standard rails authenticity tokens passed in the UI + skip_before_action :verify_authenticity_token + + # call doorkeeper to authorize the request + before_action :doorkeeper_authorize!, except: %i[heartbeat] + + # get details of server (e.g. DMPonline) and client app + before_action :get_client_and_server_details + + before_action :log_access + + # controller can respond to json format requests + respond_to :json + + # set up pages in response + before_action :pagination_params, except: %i[heartbeat] + + rescue_from Exception, with: :handle_exception + + # GET /api/v2/heartbeat + def heartbeat + render '/api/v2/heartbeat' + end + + # GET /me.json - recommended for doorkeeper gem + def me + respond_with @resource_owner + end + + private + + # define instance variable json and associated getter and setter methods + attr_accessor :json + + def get_client_and_server_details + @server = ApplicationService.application_name + @client = OauthApplication.find(doorkeeper_token.application_id) if doorkeeper_token + @scopes = doorkeeper_token.scopes.to_a if doorkeeper_token + @resource_owner = User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token && doorkeeper_token.resource_owner_id + end + + def log_access + Rails.logger.info "Client (OAuth) application name: #{@client.name}" + Rails.logger.info "Client (OAuth) application uid: #{@client.uid}" + Rails.logger.info "Resource owner id: #{@resource_owner.id}" if @resource_owner + end + + def handle_exception(exception) + if exception.is_a?(Pundit::NotAuthorizedError) + handle_client_not_authorized + else + handle_internal_server_error(exception) + end + end + + def handle_internal_server_error(exception) + # log server errors + Rails.logger.error "Exception message: #{exception.message}" + + # inform client of server error + message = _('There was a problem in the server.') + @payload = { message: [message] } + render '/api/v2/error', status: :internal_server_error + end + + def handle_client_not_authorized + message = _('The client is not authorized to perform this action.') + @payload = { message: [message] } + render '/api/v2/error', status: :forbidden + end + + # retrieve the requested pagination params or use defaults + # only allow 100 per page as the max + def pagination_params + max_per_page = Rails.configuration.x.application.api_max_page_size + @page = params.fetch('page', 1).to_i + @per_page = params.fetch('per_page', max_per_page).to_i + @per_page = max_per_page if @per_page > max_per_page + end + + def paginate_response(results:) + results = results.page(@page).per(@per_page) + @total_items = results.total_count + results + end + + end + end +end \ No newline at end of file diff --git a/app/controllers/api/v2/plans_controller.rb b/app/controllers/api/v2/plans_controller.rb new file mode 100644 index 0000000000..228927e4c7 --- /dev/null +++ b/app/controllers/api/v2/plans_controller.rb @@ -0,0 +1,42 @@ +# frozen_string_literal: true + +module Api + module V2 + class PlansController < BaseApiController + respond_to :json + + # GET /api/v2/plans/:id + def show + unless @scopes.include?('read') + raise Pundit::NotAuthorizedError + end + + @plan = Plan.find_by(id: params[:id]) + + unless @plan.present? + raise Pundit::NotAuthorizedError + end + + plans_policy = PlansPolicy.new(@resource_owner, @plan) + unless plans_policy.show? + raise Pundit::NotAuthorizedError + end + + @items = [@plan] + render '/api/v2/plans/index', status: :ok + end + + # GET /api/v2/plans + def index + unless @scopes.include?('read') + raise Pundit::NotAuthorizedError + end + + @plans = PlansPolicy::Scope.new(@resource_owner).resolve + @items = paginate_response(results: @plans) + render '/api/v2/plans/index', status: :ok + + end + end + end +end \ No newline at end of file diff --git a/app/controllers/api/v2/templates_controller.rb b/app/controllers/api/v2/templates_controller.rb new file mode 100644 index 0000000000..d5a62540c7 --- /dev/null +++ b/app/controllers/api/v2/templates_controller.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Api + module V2 + # provides a list of templates for API V2 + class TemplatesController < BaseApiController + respond_to :json + + # GET /api/v2/templates + # rubocop:disable Metrics/AbcSize + def index + unless @scopes.include?('read') + raise Pundit::NotAuthorizedError + end + templates = Api::V2::TemplatesPolicy::Scope.new(@resource_owner).resolve + @items = paginate_response(results: templates) + render '/api/v2/templates/index', status: :ok + end + + end + end +end \ No newline at end of file diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 1e2c29fcce..ceb5c6edbd 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -66,6 +66,11 @@ def store_location # rubocop:disable Metrics/AbcSize def after_sign_in_path_for(_resource) + # ensure oauth2 authorization flow is not interrupted + if user_is_in_oauth_flow + return session[:user_return_to] + end + referer_path = URI(request.referer).path unless request.referer.nil? if from_external_domain? || referer_path.eql?(new_user_session_path) || referer_path.eql?(new_user_registration_path) || @@ -78,6 +83,11 @@ def after_sign_in_path_for(_resource) # rubocop:enable Metrics/AbcSize def after_sign_up_path_for(_resource) + # ensure oauth2 authorization flow is not interrupted + if user_is_in_oauth_flow + return session[:user_return_to] + end + referer_path = URI(request.referer).path unless request.referer.nil? if from_external_domain? || referer_path.eql?(new_user_session_path) || @@ -197,4 +207,8 @@ def render_respond_to_format_with_error_message(msg, url_or_path, http_status, e end end end + + def user_is_in_oauth_flow + session[:user_return_to].present? && session[:user_return_to].include?('/oauth/authorize') + end end diff --git a/app/controllers/concerns/plan_permitted_params.rb b/app/controllers/concerns/plan_permitted_params.rb new file mode 100644 index 0000000000..ac15920016 --- /dev/null +++ b/app/controllers/concerns/plan_permitted_params.rb @@ -0,0 +1,159 @@ +# frozen_string_literal: true + +module PlanPermittedParams + extend ActiveSupport::Concern + + def plan_permitted_params + [ + :created, + :title, + :description, + :language, + :ethical_issues_exist, + :ethical_issues_description, + :ethical_issues_report, + { dmp_ids: identifier_permitted_params }, + { contact: contributor_permitted_params }, + { contributors: contributor_permitted_params }, + { costs: cost_permitted_params }, + { project: project_permitted_params }, + { datasets: dataset_permitted_params } + ] + end + + def identifier_permitted_params + [ + :type, + :identifier + ] + end + + def contributor_permitted_params + [ + :firstname, + :surname, + :mbox, + :role, + { affiliations: affiliation_permitted_params }, + { contributor_ids: identifier_permitted_params } + ] + end + + def affiliation_permitted_params + [ + :name, + :abbreviation, + { affiliation_ids: identifier_permitted_params } + ] + end + + def cost_permitted_params + [ + :title, + :description, + :value, + :currency_code + ] + end + + def project_permitted_params + [ + :title, + :description, + :start_on, + :end_on, + { funding: funding_permitted_params } + ] + end + + def funding_permitted_params + [ + :name, + :funding_status, + { funder_ids: identifier_permitted_params }, + { grant_ids: identifier_permitted_params } + ] + end + + def dataset_permitted_params + [ + :title, + :doi_url, + :description, + :type, + :issued, + :language, + :personal_data, + :sensitive_data, + :keywords, + :data_quality_assurance, + :preservation_statement, + { dataset_ids: identifier_permitted_params }, + { metadata: metadatum_permitted_params }, + { security_and_privacy_statements: security_and_privacy_statement_permitted_params }, + { technical_resources: technical_resource_permitted_params }, + { distributions: distribution_permitted_params } + ] + end + + def metadatum_permitted_params + [ + :description, + :language, + { identifier: identifier_permitted_params } + ] + end + + def security_and_privacy_statement_permitted_params + [ + :title, + :description + ] + end + + def technical_resource_permitted_params + [ + :description, + { identifier: identifier_permitted_params } + ] + end + + def distribution_permitted_params + [ + :title, + :description, + :format, + :byte_size, + :access_url, + :download_url, + :data_access, + :available_until, + { licenses: license_permitted_params }, + { host: host_permitted_params } + ] + end + + def license_permitted_params + [ + :license_ref, + :start_date + ] + end + + def host_permitted_params + [ + :title, + :description, + :supports_versioning, + :backup_type, + :backup_frequency, + :storage_type, + :availability, + :geo_location, + :certified_with, + :pid_system, + { host_ids: identifier_permitted_params } + ] + end + +end \ No newline at end of file diff --git a/app/models/oauth_access_grant.rb b/app/models/oauth_access_grant.rb new file mode 100644 index 0000000000..09f94bf428 --- /dev/null +++ b/app/models/oauth_access_grant.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +# == Schema Information +# +# Table name: oauth_access_grants +# +# id: :integer +# resource_owner_id: :integer +# application_id: :integer +# token: :string +# expires_in: :integer +# redirect_uri: :text +# scopes: :string +# created_at: :datetime +# revoked_at: :datetime + +class OauthAccessGrant < ApplicationRecord + +end \ No newline at end of file diff --git a/app/models/oauth_access_token.rb b/app/models/oauth_access_token.rb new file mode 100644 index 0000000000..bd309bff57 --- /dev/null +++ b/app/models/oauth_access_token.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +# == Schema Information +# +# Table name: oauth_access_tokens +# +# id: :integer +# resource_owner_id: :integer +# application_id: :integer +# token: :string +# refresh_token: :string +# expires_in: :integer +# scopes: :string +# created_at: :datetime +# revoked_at: :datetime +# previous_refresh_token: :string + + +class OauthAccessToken < ApplicationRecord + +end \ No newline at end of file diff --git a/app/models/oauth_application.rb b/app/models/oauth_application.rb new file mode 100644 index 0000000000..6786d7dca7 --- /dev/null +++ b/app/models/oauth_application.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +# == Schema Information +# +# Table name: oauth_applications +# +# id: :integer +# name: :string +# uid: :string +# secret: :string +# redirect_uri: :text +# scopes: :string +# confidential: :boolean +# created_at: :datetime +# updated_at: :datetime + +class OauthApplication < ApplicationRecord + +end \ No newline at end of file diff --git a/app/models/user.rb b/app/models/user.rb index 94d0035eec..5c5cb307ec 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -98,6 +98,10 @@ class User < ApplicationRecord has_and_belongs_to_many :notifications, dependent: :destroy, join_table: 'notification_acknowledgements' + has_many :access_grants, class_name: 'Doorkeeper::AccessGrant', foreign_key: :resource_owner_id, dependent: :delete_all + + has_many :access_tokens, class_name: 'Doorkeeper::AccessToken', foreign_key: :resource_owner_id, dependent: :delete_all + # =============== # = Validations = # =============== diff --git a/app/policies/api/v2/plans_policy.rb b/app/policies/api/v2/plans_policy.rb new file mode 100644 index 0000000000..d9c34d95df --- /dev/null +++ b/app/policies/api/v2/plans_policy.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +module Api + module V2 + # Security rules for API V2 Plan endpoints + class PlansPolicy < ApplicationPolicy + + # overriding the initializer due to resource owner / user + # not needing to be logged in for client app to make requests + def initialize(resource_owner, plan = nil) + @resource_owner = resource_owner + @plan = plan + end + + def show? + @plan.roles.where(user_id: @resource_owner.id, active: true).exists? + end + + class Scope < Scope + + def initialize(resource_owner) + @resource_owner = resource_owner + end + + def resolve + Plan.joins(:roles) + .where(roles: { user_id: @resource_owner.id, active: true }) + .distinct + end + + end + + end + end +end \ No newline at end of file diff --git a/app/policies/api/v2/templates_policy.rb b/app/policies/api/v2/templates_policy.rb new file mode 100644 index 0000000000..fbe0f892d7 --- /dev/null +++ b/app/policies/api/v2/templates_policy.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +module Api + module V2 + class TemplatesPolicy < ApplicationPolicy + class Scope < Scope + def initialize(resource_owner) + @resource_owner = resource_owner + end + + def resolve + # create the sql where clause + where_clause = <<-SQL + (visibility = 0 AND org_id = ?) OR + (visibility = 1 AND customization_of IS NULL) + SQL + + # get the templates + templates = Template. + includes(org: :identifiers). + joins(:org). + published. + where( + where_clause, + @resource_owner.org&.id + ) + .order(:title) + templates + end + end + end + end +end \ No newline at end of file diff --git a/app/presenters/api/v2/api_presenter.rb b/app/presenters/api/v2/api_presenter.rb new file mode 100644 index 0000000000..3aa4451479 --- /dev/null +++ b/app/presenters/api/v2/api_presenter.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +module Api + module V2 + # Generic helper methods for API V2 + class ApiPresenter + class << self + def boolean_to_yes_no_unknown(value:) + return 'unknown' unless value.present? + + value ? 'yes' : 'no' + end + end + end + end +end \ No newline at end of file diff --git a/app/presenters/api/v2/contributor_presenter.rb b/app/presenters/api/v2/contributor_presenter.rb new file mode 100644 index 0000000000..6220e226d4 --- /dev/null +++ b/app/presenters/api/v2/contributor_presenter.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module Api + module V2 + # Helper class for the API V2 contributors views + class ContributorPresenter + class << self + # Convert the specified role into a CRediT Taxonomy URL + def role_as_uri(role:) + return nil unless role.present? + return 'other' if role.to_s.casecmp('other').zero? + + "#{Contributor::ONTOLOGY_BASE_URL}/#{role.to_s.downcase.tr('_', '-')}" + end + + def contributor_id(identifiers:) + identifiers.find { |id| id.identifier_scheme.name == 'orcid' } + end + end + end + end +end \ No newline at end of file diff --git a/app/presenters/api/v2/funding_presenter.rb b/app/presenters/api/v2/funding_presenter.rb new file mode 100644 index 0000000000..bb07880ec1 --- /dev/null +++ b/app/presenters/api/v2/funding_presenter.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +module Api + module V2 + # Helper class for the API V2 funding section + class FundingPresenter + class << self + # If the plan has a grant number then it has been awarded/granted + # otherwise it is 'planned' + def status(plan:) + return 'planned' unless plan.present? + + case plan.funding_status + when 'funded' + 'granted' + when 'denied' + 'rejected' + else + 'planned' + end + end + end + end + end +end \ No newline at end of file diff --git a/app/presenters/api/v2/language_presenter.rb b/app/presenters/api/v2/language_presenter.rb new file mode 100644 index 0000000000..0cf280a3d0 --- /dev/null +++ b/app/presenters/api/v2/language_presenter.rb @@ -0,0 +1,84 @@ +# frozen_string_literal: true + +module Api + module V2 + # Helper class for the API V2 language values + class LanguagePresenter + class << self + LANGUAGE_MAP = { + aa: 'aar', ab: 'abk', af: 'afr', ak: 'aka', am: 'amh', ar: 'ara', an: 'arg', + as: 'asm', av: 'ava', ae: 'ave', ay: 'aym', az: 'aze', + + ba: 'bak', bm: 'bam', be: 'bel', bn: 'ben', bh: 'bih', bi: 'bis', bo: 'tib', + bs: 'bos', br: 'bre', bg: 'bul', + + ca: 'cat', cs: 'cze', ch: 'cha', ce: 'che', cu: 'chu', cv: 'chv', co: 'cos', + cr: 'cre', cy: 'wel', + + da: 'dan', de: 'deu', dv: 'div', dz: 'dzo', + + el: 'gre', en: 'eng', eo: 'epo', es: 'spa', et: 'est', eu: 'baq', ee: 'ewe', + + fo: 'fao', fa: 'per', fj: 'fij', fi: 'fin', fr: 'fre', fy: 'fry', ff: 'ful', + + gd: 'gla', ga: 'gle', gl: 'glg', gv: 'glv', gn: 'grn', gu: 'guj', + + ht: 'hat', ha: 'hau', he: 'heb', hz: 'her', hi: 'hin', ho: 'hmo', hr: 'hrv', + hu: 'hun', hy: 'arm', + + ig: 'ibo', io: 'ido', ii: 'iii', iu: 'iku', ie: 'ile', ia: 'ina', id: 'ind', + ik: 'ipk', is: 'ice', it: 'ita', + + jv: 'jav', ja: 'jpn', + + kl: 'kal', kn: 'kan', ks: 'kas', kr: 'kau', kk: 'kaz', km: 'khm', ki: 'kik', + ky: 'kir', kv: 'kom', kg: 'kon', ko: 'kor', kj: 'kua', ku: 'kur', ka: 'geo', + kw: 'cor', + + lo: 'lao', la: 'lat', lv: 'lav', li: 'lim', ln: 'lin', lt: 'lit', lb: 'ltz', + lu: 'lub', lg: 'lug', + + mk: 'mac', mh: 'mah', ml: 'mal', mi: 'mao', mr: 'mar', ms: 'may', mg: 'mlg', + mt: 'mlt', mn: 'mon', my: 'bur', + + na: 'nau', nv: 'nav', nr: 'nbl', nd: 'nde', ng: 'ndo', ne: 'nep', nl: 'dut', + nn: 'nno', nb: 'nob', no: 'nor', ny: 'nya', + + oc: 'oci', oj: 'oji', or: 'ori', om: 'orm', os: 'oss', + + pa: 'pan', pi: 'pli', pl: 'pol', pt: 'por', ps: 'pus', + + qu: 'que', + + rm: 'roh', ro: 'rum', rn: 'run', ru: 'rus', rw: 'kin', + + sg: 'sag', sa: 'san', si: 'sin', sk: 'slo', sl: 'slv', se: 'sme', sm: 'smo', + sn: 'sna', sd: 'snd', so: 'som', st: 'sot', sq: 'alb', sc: 'srd', sr: 'srp', + ss: 'ssw', su: 'sun', sw: 'swa', sv: 'swe', + + ty: 'tah', ta: 'tam', tt: 'tat', te: 'tel', tg: 'tgk', tl: 'tgl', th: 'tha', + ti: 'tir', to: 'ton', tn: 'tsn', ts: 'tso', tk: 'tuk', tr: 'tur', tw: 'twi', + + ug: 'uig', uk: 'ukr', ur: 'urd', uz: 'uzb', + + ve: 'ven', vi: 'vie', vo: 'vol', + + wa: 'wln', wo: 'wol', + + xh: 'xho', + + yi: 'yid', yo: 'yor', + + za: 'zha', zh: 'chi', zu: 'zul' + }.freeze + + # Convert the incoming 2 (e.g. en - ISO 639-1) or 2+region (e.g. en-UK) + # into the 3 character code (e.g. eng - ISO 639-2) + def three_char_code(lang:) + two_char_code = lang.to_s.split('-').first + LANGUAGE_MAP[two_char_code.to_sym] + end + end + end + end +end \ No newline at end of file diff --git a/app/presenters/api/v2/org_presenter.rb b/app/presenters/api/v2/org_presenter.rb new file mode 100644 index 0000000000..2e954706b3 --- /dev/null +++ b/app/presenters/api/v2/org_presenter.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +module Api + module V2 + # Helper class for the API V2 affiliation sections + class OrgPresenter + class << self + def affiliation_id(identifiers:) + ident = identifiers.find { |id| id.identifier_scheme&.name == 'ror' } + return ident if ident.present? + + identifiers.find { |id| id.identifier_scheme&.name == 'fundref' } + end + end + end + end +end \ No newline at end of file diff --git a/app/presenters/api/v2/pagination_presenter.rb b/app/presenters/api/v2/pagination_presenter.rb new file mode 100644 index 0000000000..9b4b2426ab --- /dev/null +++ b/app/presenters/api/v2/pagination_presenter.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +module Api + module V2 + # Helper class for genewric API V2 pagination + class PaginationPresenter + def initialize(current_url:, per_page:, total_items:, current_page: 1) + @url = current_url + @per_page = per_page + @total_items = total_items + @page = current_page + end + + def url_without_pagination + return nil unless @url.present? && @url.is_a?(String) + + url = @url.gsub(/per_page=\d+/, '') + .gsub(/page=\d+/, '') + .gsub(/(&)+$/, '').gsub(/\?$/, '') + + (url.include?('?') ? "#{url}&" : "#{url}?") + end + + def prev_page? + total_pages > 1 && @page != 1 + end + + def next_page? + total_pages > 1 && @page < total_pages + end + + def prev_page_link + "#{url_without_pagination}page=#{@page - 1}&per_page=#{@per_page}" + end + + def next_page_link + "#{url_without_pagination}page=#{@page + 1}&per_page=#{@per_page}" + end + + private + + def total_pages + return 1 unless @total_items.present? && @per_page.present? && + @total_items.positive? && @per_page.positive? + + (@total_items.to_f / @per_page).ceil + end + end + end +end \ No newline at end of file diff --git a/app/presenters/api/v2/plan_presenter.rb b/app/presenters/api/v2/plan_presenter.rb new file mode 100644 index 0000000000..83061c637f --- /dev/null +++ b/app/presenters/api/v2/plan_presenter.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +module Api + module V2 + # Helper class for the API V2 project / DMP + class PlanPresenter + attr_reader :data_contact, :contributors, :costs + + def initialize(plan:) + @contributors = [] + return unless plan.present? + + @plan = plan + + @data_contact = @plan.owner + + # Attach the first data_curation role as the data_contact, otherwise + # add the contributor to the contributors array + @plan.contributors.each do |contributor| + @data_contact = contributor if contributor.data_curation? && @data_contact.nil? + @contributors << contributor + end + + @costs = plan_costs(plan: @plan) + end + + # Extract the ARK or DOI for the DMP OR use its URL if none exists + def identifier + doi = @plan.identifiers.select do |id| + ::Plan::DMP_ID_TYPES.include?(id.identifier_format) + end + return doi.first if doi.first.present? + + # if no DOI then use the URL for the API's 'show' method + Identifier.new(value: Rails.application.routes.url_helpers.api_v2_plan_url(@plan)) + end + + private + + # Retrieve the answers that have the Budget theme + def plan_costs(plan:) + theme = Theme.where(title: 'Cost').first + return [] unless theme.present? + + # TODO: define a new 'Currency' question type that includes a float field + # any currency type selector (e.g GBP or USD) + answers = plan.answers.includes(question: :themes).select do |answer| + answer.question.themes.include?(theme) + end + + answers.map do |answer| + # TODO: Investigate whether question level guidance should be the description + { title: answer.question.text, description: nil, + currency_code: 'usd', value: answer.text } + end + end + end + end +end \ No newline at end of file diff --git a/app/presenters/api/v2/research_output_presenter.rb b/app/presenters/api/v2/research_output_presenter.rb new file mode 100644 index 0000000000..ae5112ac12 --- /dev/null +++ b/app/presenters/api/v2/research_output_presenter.rb @@ -0,0 +1,77 @@ +# frozen_string_literal: true + +module Api + module V2 + # Helper methods for research outputs + class ResearchOutputPresenter + attr_reader :dataset_id, :preservation_statement, :security_and_privacy, :license_start_date, + :data_quality_assurance, :distributions, :metadata, :technical_resources + + def initialize(output:) + @research_output = output + return unless output.is_a?(ResearchOutput) + + @plan = output.plan + @dataset_id = identifier + + load_narrative_content + + @license_start_date = determine_license_start_date(output: output) + end + + private + + def identifier + Identifier.new(identifiable: @research_output, value: @research_output.id) + end + + def determine_license_start_date(output:) + return nil unless output.present? + return output.release_date.to_formatted_s(:iso8601) if output.release_date.present? + + output.created_at.to_formatted_s(:iso8601) + end + + def load_narrative_content + @preservation_statement = '' + @security_and_privacy = [] + @data_quality_assurance = '' + + # Disabling rubocop here since a guard clause would make the line too long + # rubocop:disable Style/GuardClause + if Rails.configuration.x.madmp.extract_preservation_statements_from_themed_questions + @preservation_statement = fetch_q_and_a_as_single_statement(themes: %w[Preservation]) + end + if Rails.configuration.x.madmp.extract_security_privacy_statements_from_themed_questions + @security_and_privacy = fetch_q_and_a(themes: ['Ethics & privacy', 'Storage & security']) + end + if Rails.configuration.x.madmp.extract_data_quality_statements_from_themed_questions + @data_quality_assurance = fetch_q_and_a_as_single_statement(themes: ['Data Collection']) + end + # rubocop:enable Style/GuardClause + end + + def fetch_q_and_a_as_single_statement(themes:) + fetch_q_and_a(themes: themes).collect { |item| item[:description] }.join('
') + end + + # rubocop:disable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity + def fetch_q_and_a(themes:) + return [] unless themes.is_a?(Array) && themes.any? + + ret = themes.map do |theme| + qs = @plan.questions.select { |q| q.themes.collect(&:title).include?(theme) } + descr = qs.map do |q| + a = @plan.answers.find { |ans| ans.question_id = q.id } + next unless a.present? && !a.blank? + + "Question: #{q.text}
Answer: #{a.text}" + end + { title: theme, description: descr } + end + ret.select { |item| item[:description].present? } + end + # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity + end + end +end \ No newline at end of file diff --git a/app/presenters/api/v2/template_presenter.rb b/app/presenters/api/v2/template_presenter.rb new file mode 100644 index 0000000000..ef518f24d9 --- /dev/null +++ b/app/presenters/api/v2/template_presenter.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +module Api + module V2 + # Helper class for the API V2 template info + class TemplatePresenter + def initialize(template:) + @template = template + end + + # If the plan has a grant number then it has been awarded/granted + # otherwise it is 'planned' + def title + return @template.title unless @template.customization_of.present? + + "#{@template.title} - with additional questions for #{@template.org.name}" + end + end + end +end \ No newline at end of file diff --git a/app/services/api/v2/conversion_service.rb b/app/services/api/v2/conversion_service.rb new file mode 100644 index 0000000000..2bbe580a0e --- /dev/null +++ b/app/services/api/v2/conversion_service.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +module Api + module V2 + # Helper service that translates to/from the RDA common standard + class ConversionService + class << self + # Converts a boolean field to [yes, no, unknown] + def boolean_to_yes_no_unknown(value) + return 'yes' if [true, 1].include?(value) + + return 'no' if [false, 0].include?(value) + + 'unknown' + end + + # Converts a [yes, no, unknown] field to boolean (or nil) + def yes_no_unknown_to_boolean(value) + return true if value&.downcase == 'yes' + + return nil if value.blank? || value&.downcase == 'unknown' + + false + end + + # Converts the context and value into an Identifier with a psuedo + # IdentifierScheme for display in JSON partials. Which will result in: + # { type: 'context', identifier: 'value' } + def to_identifier(context:, value:) + return nil unless value.present? && context.present? + + scheme = IdentifierScheme.new(name: context) + Identifier.new(value: value, identifier_scheme: scheme) + end + end + end + end +end \ No newline at end of file diff --git a/app/views/api/v2/_standard_response.json.jbuilder b/app/views/api/v2/_standard_response.json.jbuilder new file mode 100644 index 0000000000..798ff3a35a --- /dev/null +++ b/app/views/api/v2/_standard_response.json.jbuilder @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +# locals: response, request, total_items + +total_items ||= 0 + +paginator = Api::V2::PaginationPresenter.new(current_url: request.path, + per_page: @per_page, + total_items: total_items, + current_page: @page) + +json.prettify! +json.ignore_nil! + +json.server @server +json.source "#{request.method} #{request.path}" +json.time Time.now.to_formatted_s(:iso8601) +json.client @client.name +json.code response.status +json.message Rack::Utils::HTTP_STATUS_CODES[response.status] + +if response.status == 200 + + # Pagination Links + if total_items.positive? + json.page @page + json.per_page @per_page + json.total_items total_items + + # Prepare the base URL by removing the old pagination params + json.prev paginator.prev_page_link if paginator.prev_page? + json.next paginator.next_page_link if paginator.next_page? + else + json.total_items 0 + end + +end \ No newline at end of file diff --git a/app/views/api/v2/contributors/_show.json.jbuilder b/app/views/api/v2/contributors/_show.json.jbuilder new file mode 100644 index 0000000000..ce6f84dfc6 --- /dev/null +++ b/app/views/api/v2/contributors/_show.json.jbuilder @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +# locals: contributor, is_contact + +is_contact ||= false + +json.name contributor.is_a?(User) ? contributor.name(false) : contributor.name +json.mbox contributor.email + +if !is_contact && contributor.selected_roles.any? + roles = contributor.selected_roles.map do |role| + Api::V2::ContributorPresenter.role_as_uri(role: role) + end + json.role roles if roles.any? +end + +if contributor.org.present? + json.affiliation do + json.partial! 'api/v2/orgs/show', org: contributor.org + end +end + +orcid = contributor.identifier_for_scheme(scheme: 'orcid') +if orcid.present? + id = Api::V2::ContributorPresenter.contributor_id( + identifiers: contributor.identifiers + ) + if is_contact + json.contact_id do + json.partial! 'api/v2/identifiers/show', identifier: id + end + else + json.contributor_id do + json.partial! 'api/v2/identifiers/show', identifier: id + end + end +end \ No newline at end of file diff --git a/app/views/api/v2/datasets/_show.json.jbuilder b/app/views/api/v2/datasets/_show.json.jbuilder new file mode 100644 index 0000000000..a23f2fb598 --- /dev/null +++ b/app/views/api/v2/datasets/_show.json.jbuilder @@ -0,0 +1,84 @@ +# frozen_string_literal: true + +# locals: output + +if output.is_a?(ResearchOutput) + presenter = Api::V2::ResearchOutputPresenter.new(output: output) + + json.type output.output_type + json.title output.title + json.doi_url output.doi_url + json.description output.description + json.personal_data Api::V2::ApiPresenter.boolean_to_yes_no_unknown(value: output.personal_data) + json.sensitive_data Api::V2::ApiPresenter.boolean_to_yes_no_unknown(value: output.sensitive_data) + json.issued output.release_date&.to_formatted_s(:iso8601) + + json.preservation_statement presenter.preservation_statement + json.security_and_privacy presenter.security_and_privacy + json.data_quality_assurance presenter.data_quality_assurance + + json.dataset_id do + json.partial! "api/v2/identifiers/show", identifier: presenter.dataset_id + end + + json.distribution output.repositories do |repository| + json.title "Anticipated distribution for #{output.title}" + json.byte_size output.byte_size + json.data_access output.access + + json.host do + json.title repository.name + json.description repository.description + json.url repository.homepage + + # DMPTool extensions to the RDA common metadata standard + json.dmproadmap_host_id do + json.type "url" + json.identifier repository.uri + end + end + + if output.license.present? + json.license [output.license] do |license| + json.license_ref license.uri + json.start_date presenter.license_start_date + end + end + end + + json.metadata output.metadata_standards do |metadata_standard| + website = metadata_standard.locations.find { |loc| loc["type"] == "website" } + website = { url: "" } unless website.present? + + descr_array = [metadata_standard.title, metadata_standard.description, website["url"]] + json.description descr_array.join(" - ") + + json.metadata_standard_id do + json.type "url" + json.identifier metadata_standard.uri + end + end + + json.technical_resource [] + + if output.plan.research_domain_id.present? + research_domain = ResearchDomain.find_by(id: output.plan.research_domain_id) + if research_domain.present? + combined = "#{research_domain.identifier} - #{research_domain.label}" + json.keyword [research_domain.label, combined] + end + end + +else + json.type "dataset" + json.title "Generic dataset" + json.description "No individual datasets have been defined for this DMP." + + if output.research_domain_id.present? + research_domain = ResearchDomain.find_by(id: output.research_domain_id) + if research_domain.present? + combined = "#{research_domain.identifier} - #{research_domain.label}" + json.keyword [research_domain.label, combined] + end + end +end \ No newline at end of file diff --git a/app/views/api/v2/error.json.jbuilder b/app/views/api/v2/error.json.jbuilder new file mode 100644 index 0000000000..dd7f362f30 --- /dev/null +++ b/app/views/api/v2/error.json.jbuilder @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +json.partial! 'api/v2/standard_response' + +# json.items [] +json.message @payload[:message] +json.details @payload[:details] \ No newline at end of file diff --git a/app/views/api/v2/heartbeat.json.jbuilder b/app/views/api/v2/heartbeat.json.jbuilder new file mode 100644 index 0000000000..e254c72e8e --- /dev/null +++ b/app/views/api/v2/heartbeat.json.jbuilder @@ -0,0 +1,5 @@ +# frozen_string_literal: true + +json.partial! 'api/v2/standard_response' + +json.items [] \ No newline at end of file diff --git a/app/views/api/v2/identifiers/_show.json.jbuilder b/app/views/api/v2/identifiers/_show.json.jbuilder new file mode 100644 index 0000000000..174426cf14 --- /dev/null +++ b/app/views/api/v2/identifiers/_show.json.jbuilder @@ -0,0 +1,6 @@ +# frozen_string_literal: true + +# locals: identifier + +json.type identifier&.identifier_format +json.identifier identifier&.value \ No newline at end of file diff --git a/app/views/api/v2/me.json.jbuilder b/app/views/api/v2/me.json.jbuilder new file mode 100644 index 0000000000..48314f0439 --- /dev/null +++ b/app/views/api/v2/me.json.jbuilder @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +json.partial! 'api/v2/standard_response' + +if current_user.present? + json.items [current_user] do |user| + json.name [user.surname, user.firstname].join(', ') + json.mbox user.email + json.token user.ui_token + + if user.org.present? && ['No funder', 'Non Partner Institution'].exclude?(user.org.name) + json.affiliation do + json.partial! 'api/v2/orgs/show', org: user.org + end + end + + orcid = user.identifier_for_scheme(scheme: 'orcid') + if orcid.present? + json.user_id do + json.partial! 'api/v2/identifiers/show', identifier: orcid + end + end + end + +else + json.items [] +end \ No newline at end of file diff --git a/app/views/api/v2/orgs/_show.json.jbuilder b/app/views/api/v2/orgs/_show.json.jbuilder new file mode 100644 index 0000000000..29cfb30577 --- /dev/null +++ b/app/views/api/v2/orgs/_show.json.jbuilder @@ -0,0 +1,14 @@ +# frozen_string_literal: true + +# locals: org + +json.name org.name +json.abbreviation org.abbreviation +json.region org.region&.abbreviation + +if org.identifiers.any? + json.affiliation_id do + id = Api::V2::OrgPresenter.affiliation_id(identifiers: org.identifiers) + json.partial! 'api/v2/identifiers/show', identifier: id + end +end \ No newline at end of file diff --git a/app/views/api/v2/plans/_cost.json.jbuilder b/app/views/api/v2/plans/_cost.json.jbuilder new file mode 100644 index 0000000000..32a0cfbaa7 --- /dev/null +++ b/app/views/api/v2/plans/_cost.json.jbuilder @@ -0,0 +1,8 @@ +# frozen_string_literal: true + +# locals: cost + +json.title cost[:title] +json.description cost[:description] +json.currency_code cost[:currency_code] +json.value cost[:value] \ No newline at end of file diff --git a/app/views/api/v2/plans/_funding.json.jbuilder b/app/views/api/v2/plans/_funding.json.jbuilder new file mode 100644 index 0000000000..9006186d86 --- /dev/null +++ b/app/views/api/v2/plans/_funding.json.jbuilder @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +# locals: plan + +json.name plan.funder&.name + +if plan.funder.present? + id = Api::V2::OrgPresenter.affiliation_id(identifiers: plan.funder.identifiers) + + if id.present? + json.funder_id do + json.partial! 'api/v2/identifiers/show', identifier: id + end + end +end + +if plan.grant_id.present? && plan.grant.present? + json.grant_id do + json.partial! 'api/v2/identifiers/show', identifier: plan.grant + end +end + +json.funding_status Api::V2::FundingPresenter.status(plan: plan) + +# DMPTool extensions to the RDA common metadata standard +# ------------------------------------------------------ + +# We collect a user entered ID on the form, so this is a way to convey it to other systems +# The ID would typically be something relevant to the funder or research organization +if plan.identifier.present? + json.dmproadmap_funding_opportunity_id do + json.partial! 'api/v2/identifiers/show', identifier: Identifier.new(identifiable: plan, + value: plan.identifier) + end +end + +# Since the Plan owner (aka contact) and contributor orgs could be different than the +# one associated with the Plan, we add it here. +json.dmproadmap_funded_affiliations [plan.org] do |funded_org| + json.partial! 'api/v2/orgs/show', org: funded_org +end \ No newline at end of file diff --git a/app/views/api/v2/plans/_project.json.jbuilder b/app/views/api/v2/plans/_project.json.jbuilder new file mode 100644 index 0000000000..7397815365 --- /dev/null +++ b/app/views/api/v2/plans/_project.json.jbuilder @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +# locals: plan + +json.title plan.title +json.description plan.description + +start_date = plan.start_date || Time.now +json.start start_date.to_formatted_s(:iso8601) + +end_date = plan.end_date || (Time.now + 2.years) +json.end end_date&.to_formatted_s(:iso8601) + +if plan.funder.present? || plan.grant_id.present? + json.funding [plan] do + json.partial! 'api/v2/plans/funding', plan: plan + end +end \ No newline at end of file diff --git a/app/views/api/v2/plans/_show.json.jbuilder b/app/views/api/v2/plans/_show.json.jbuilder new file mode 100644 index 0000000000..e6eb96684d --- /dev/null +++ b/app/views/api/v2/plans/_show.json.jbuilder @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +# locals: plan + +json.schema 'https://github.com/RDA-DMP-Common/RDA-DMP-Common-Standard/tree/master/examples/JSON/JSON-schema/1.0' + +presenter = Api::V2::PlanPresenter.new(plan: plan) + +# Note the symbol of the dmproadmap json object +# nested in extensions which is the container for the json template object, etc. + +# A JSON representation of a Data Management Plan in the +# RDA Common Standard format +json.title plan.title +json.description plan.description +json.language Api::V2::LanguagePresenter.three_char_code( + lang: LocaleService.default_locale +) +json.created plan.created_at.to_formatted_s(:iso8601) +json.modified plan.updated_at.to_formatted_s(:iso8601) + +json.ethical_issues_exist Api::V2::ConversionService.boolean_to_yes_no_unknown(plan.ethical_issues) +json.ethical_issues_description plan.ethical_issues_description +json.ethical_issues_report plan.ethical_issues_report + +id = presenter.identifier +if id.present? + json.dmp_id do + json.partial! 'api/v2/identifiers/show', identifier: id + end +end + +if presenter.data_contact.present? + json.contact do + json.partial! 'api/v2/contributors/show', contributor: presenter.data_contact, + is_contact: true + end +end + +unless @minimal + if presenter.contributors.any? + json.contributor presenter.contributors do |contributor| + json.partial! 'api/v2/contributors/show', contributor: contributor, + is_contact: false + end + end + + if presenter.costs.any? + json.cost presenter.costs do |cost| + json.partial! 'api/v2/plans/cost', cost: cost + end + end + + json.project [plan] do |pln| + json.partial! 'api/v2/plans/project', plan: pln + end + + outputs = plan.research_outputs.any? ? plan.research_outputs : [plan] + + json.dataset outputs do |output| + json.partial! "api/v2/datasets/show", output: output + end + + json.extension [plan.template] do |template| + json.set! :dmproadmap do + json.template do + json.id template.id + json.title template.title + end + end + end +end \ No newline at end of file diff --git a/app/views/api/v2/plans/index.json.jbuilder b/app/views/api/v2/plans/index.json.jbuilder new file mode 100644 index 0000000000..125e5f14db --- /dev/null +++ b/app/views/api/v2/plans/index.json.jbuilder @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +json.partial! 'api/v2/standard_response', total_items: @total_items + +json.items @items do |item| + json.dmp do + json.partial! 'api/v2/plans/show', plan: item + end +end \ No newline at end of file diff --git a/app/views/api/v2/templates/index.json.jbuilder b/app/views/api/v2/templates/index.json.jbuilder new file mode 100644 index 0000000000..8255f5c342 --- /dev/null +++ b/app/views/api/v2/templates/index.json.jbuilder @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +json.partial! 'api/v2/standard_response', total_items: @total_items + +json.items @items do |template| + presenter = Api::V2::TemplatePresenter.new(template: template) + + json.dmp_template do + json.title presenter.title + json.description template.description + json.version template.version + json.created template.created_at.to_formatted_s(:iso8601) + json.modified template.updated_at.to_formatted_s(:iso8601) + + json.affiliation do + json.partial! 'api/v2/orgs/show', org: template.org + end + + json.template_id do + identifier = Api::V2::ConversionService.to_identifier(context: @application, + value: template.id) + json.partial! 'api/v2/identifiers/show', identifier: identifier + end + end +end \ No newline at end of file diff --git a/app/views/doorkeeper/applications/_delete_form.html.erb b/app/views/doorkeeper/applications/_delete_form.html.erb new file mode 100644 index 0000000000..b6377d35f5 --- /dev/null +++ b/app/views/doorkeeper/applications/_delete_form.html.erb @@ -0,0 +1,6 @@ +<%- submit_btn_css ||= 'btn btn-link' %> +<%= form_tag oauth_application_path(application), method: :delete do %> + <%= submit_tag t('doorkeeper.applications.buttons.destroy'), + onclick: "return confirm('#{ t('doorkeeper.applications.confirmations.destroy') }')", + class: submit_btn_css, style: "border-radius: 0;" %> +<% end %> \ No newline at end of file diff --git a/app/views/doorkeeper/applications/_form.html.erb b/app/views/doorkeeper/applications/_form.html.erb new file mode 100644 index 0000000000..5aeeeaf9ab --- /dev/null +++ b/app/views/doorkeeper/applications/_form.html.erb @@ -0,0 +1,42 @@ +<%= form_for application, url: doorkeeper_submit_path(application), as: :doorkeeper_application, html: { role: 'form' } do |f| %> + <% if application.errors.any? %> +

<%= t('doorkeeper.applications.form.error') %>

+ <% end %> + +
+ <%= f.label :name, class: 'col-sm-2 col-form-label font-weight-bold' %> +
+ <%= f.text_field :name, class: "form-control #{ 'is-invalid' if application.errors[:name].present? }", required: true, style: "border: 1px solid #ced4da;" %> + <%= doorkeeper_errors_for application, :name %> +
+
+ +
+ <%= f.label "Scope(s)", class: 'col-sm-2 col-form-label font-weight-bold' %> +
+ <%= f.text_field :scopes, class: "form-control #{ 'has-error' if application.errors[:scopes].present? }", style: "border: 1px solid #ced4da;" %> + <%= doorkeeper_errors_for application, :scopes %> + + <%= "Separate multiple scopes with spaces." %> + +
+
+ +
+ <%= f.label nil, 'Redirect URI(s)'.html_safe, class: 'col-sm-2 col-form-label font-weight-bold' %> +
+ <%= f.text_area :redirect_uri, class: "form-control #{ 'is-invalid' if application.errors[:redirect_uri].present? }", style: "border: 1px solid #ced4da;" %> + <%= doorkeeper_errors_for application, :redirect_uri %> + + <%= "Separate multiple URIs with spaces." %> + +
+
+ +
+
+ <%= f.submit t('doorkeeper.applications.buttons.submit'), class: 'btn btn-primary' %> + <%= link_to t('doorkeeper.applications.buttons.cancel'), oauth_applications_path, class: 'btn btn-secondary' %> +
+
+<% end %> \ No newline at end of file diff --git a/app/views/doorkeeper/applications/edit.html.erb b/app/views/doorkeeper/applications/edit.html.erb new file mode 100644 index 0000000000..95fb9ab2d5 --- /dev/null +++ b/app/views/doorkeeper/applications/edit.html.erb @@ -0,0 +1,5 @@ +
+

<%= t('.title') %>

+
+ +<%= render 'form', application: @application %> \ No newline at end of file diff --git a/app/views/doorkeeper/applications/index.html.erb b/app/views/doorkeeper/applications/index.html.erb new file mode 100644 index 0000000000..835e0d917f --- /dev/null +++ b/app/views/doorkeeper/applications/index.html.erb @@ -0,0 +1,34 @@ +
+

<%= t('.title') %>

+
+ +

<%= link_to t('.new'), new_oauth_application_path, class: 'btn btn-secondary', style: "border-radius: 0;" %>

+ + + + + + + + + + + + <% @applications.each do |application| %> + + + + + + + <% end %> + +
<%= t('.name') %><%= t('.callback_url') %><%= t('.actions') %>
+ <%= link_to application.name, oauth_application_path(application) %> + + <%= simple_format(application.redirect_uri) %> + + <%= link_to t('doorkeeper.applications.buttons.edit'), edit_oauth_application_path(application), class: 'btn btn-link' %> + + <%= render 'delete_form', application: application %> +
\ No newline at end of file diff --git a/app/views/doorkeeper/applications/new.html.erb b/app/views/doorkeeper/applications/new.html.erb new file mode 100644 index 0000000000..95fb9ab2d5 --- /dev/null +++ b/app/views/doorkeeper/applications/new.html.erb @@ -0,0 +1,5 @@ +
+

<%= t('.title') %>

+
+ +<%= render 'form', application: @application %> \ No newline at end of file diff --git a/app/views/doorkeeper/applications/show.html.erb b/app/views/doorkeeper/applications/show.html.erb new file mode 100644 index 0000000000..71e06b573e --- /dev/null +++ b/app/views/doorkeeper/applications/show.html.erb @@ -0,0 +1,42 @@ +<%= fields_for @application, as: :doorkeeper_application, html: { role: 'form' } do |f| %> +
+ <%= f.label :name, class: 'col-sm-2 col-form-label font-weight-bold' %> +
+ <%= f.text_field :name, class: "form-control", required: true, style: "border: 1px solid #ced4da;", readonly: true %> +
+
+ +
+ <%= f.label nil, "Client ID".html_safe, class: 'col-sm-2 col-form-label font-weight-bold' %> +
+ <%= f.text_field :uid, class: "form-control", required: true, style: "border: 1px solid #ced4da;", readonly: true %> +
+
+ +
+ <%= f.label nil, "Client secret".html_safe, class: 'col-sm-2 col-form-label font-weight-bold' %> +
+ <%= f.text_field :secret, class: "form-control", required: true, style: "border: 1px solid #ced4da;", readonly: true %> +
+
+ +
+ <%= f.label "Scope(s)", class: 'col-sm-2 col-form-label font-weight-bold' %> +
+ <%= f.text_field :scopes, class: "form-control", style: "border: 1px solid #ced4da;", readonly: true %> +
+
+ +
+ <%= f.label nil, 'Redirect URI(s)'.html_safe, class: 'col-sm-2 col-form-label font-weight-bold' %> +
+ <%= f.text_area :redirect_uri, class: "form-control", style: "border: 1px solid #ced4da;", readonly: true %> +
+
+ +
+
+ <%= link_to "Back", oauth_applications_path, class: 'btn btn-secondary' %> +
+
+<% end %> \ No newline at end of file diff --git a/app/views/doorkeeper/authorizations/error.html.erb b/app/views/doorkeeper/authorizations/error.html.erb new file mode 100644 index 0000000000..4173caf8f2 --- /dev/null +++ b/app/views/doorkeeper/authorizations/error.html.erb @@ -0,0 +1,9 @@ +
+

<%= t('doorkeeper.authorizations.error.title') %>

+
+ +
+
+    <%= (local_assigns[:error_response] ? error_response : @pre_auth.error_response).body[:error_description] %>
+  
+
\ No newline at end of file diff --git a/app/views/doorkeeper/authorizations/form_post.html.erb b/app/views/doorkeeper/authorizations/form_post.html.erb new file mode 100644 index 0000000000..4b0df6c0c6 --- /dev/null +++ b/app/views/doorkeeper/authorizations/form_post.html.erb @@ -0,0 +1,15 @@ + + +<%= form_tag @pre_auth.redirect_uri, method: :post, name: :redirect_form, authenticity_token: false do %> + <% auth.body.compact.each do |key, value| %> + <%= hidden_field_tag key, value %> + <% end %> +<% end %> + + \ No newline at end of file diff --git a/app/views/doorkeeper/authorizations/new.html.erb b/app/views/doorkeeper/authorizations/new.html.erb new file mode 100644 index 0000000000..c7b8d0f224 --- /dev/null +++ b/app/views/doorkeeper/authorizations/new.html.erb @@ -0,0 +1,46 @@ + + +
+

+ <%= raw t('.prompt', client_name: content_tag(:strong, class: 'text-info') { @pre_auth.client.name }) %> +

+ + <% if @pre_auth.scopes.count > 0 %> +
+

<%= t('.able_to') %>:

+ +
    + <% @pre_auth.scopes.each do |scope| %> +
  • <%= t(scope, scope: [:doorkeeper, :scopes]) + " your plans" %>
  • + <% end %> +
+
+ <% end %> + +
+ <%= form_tag oauth_authorization_path, method: :post do %> + <%= hidden_field_tag :client_id, @pre_auth.client.uid, id: nil %> + <%= hidden_field_tag :redirect_uri, @pre_auth.redirect_uri, id: nil %> + <%= hidden_field_tag :state, @pre_auth.state, id: nil %> + <%= hidden_field_tag :response_type, @pre_auth.response_type, id: nil %> + <%= hidden_field_tag :response_mode, @pre_auth.response_mode, id: nil %> + <%= hidden_field_tag :scope, @pre_auth.scope, id: nil %> + <%= hidden_field_tag :code_challenge, @pre_auth.code_challenge, id: nil %> + <%= hidden_field_tag :code_challenge_method, @pre_auth.code_challenge_method, id: nil %> + <%= submit_tag t('doorkeeper.authorizations.buttons.authorize'), class: "btn btn-success mt-3 mb-3", style: "border-radius: 0;" %> + <% end %> + <%= form_tag oauth_authorization_path, method: :delete do %> + <%= hidden_field_tag :client_id, @pre_auth.client.uid, id: nil %> + <%= hidden_field_tag :redirect_uri, @pre_auth.redirect_uri, id: nil %> + <%= hidden_field_tag :state, @pre_auth.state, id: nil %> + <%= hidden_field_tag :response_type, @pre_auth.response_type, id: nil %> + <%= hidden_field_tag :response_mode, @pre_auth.response_mode, id: nil %> + <%= hidden_field_tag :scope, @pre_auth.scope, id: nil %> + <%= hidden_field_tag :code_challenge, @pre_auth.code_challenge, id: nil %> + <%= hidden_field_tag :code_challenge_method, @pre_auth.code_challenge_method, id: nil %> + <%= submit_tag t('doorkeeper.authorizations.buttons.deny'), class: "btn btn-danger", style: "border-radius: 0;" %> + <% end %> +
+
\ No newline at end of file diff --git a/app/views/doorkeeper/authorizations/show.html.erb b/app/views/doorkeeper/authorizations/show.html.erb new file mode 100644 index 0000000000..385fc9f24b --- /dev/null +++ b/app/views/doorkeeper/authorizations/show.html.erb @@ -0,0 +1,7 @@ + + +
+ <%= params[:code] %> +
\ No newline at end of file diff --git a/app/views/doorkeeper/authorized_applications/_delete_form.html.erb b/app/views/doorkeeper/authorized_applications/_delete_form.html.erb new file mode 100644 index 0000000000..b39ef93edb --- /dev/null +++ b/app/views/doorkeeper/authorized_applications/_delete_form.html.erb @@ -0,0 +1,4 @@ +<%- submit_btn_css ||= 'btn btn-link' %> +<%= form_tag oauth_authorized_application_path(application), method: :delete do %> + <%= submit_tag t('doorkeeper.authorized_applications.buttons.revoke'), onclick: "return confirm('#{ t('doorkeeper.authorized_applications.confirmations.revoke') }')", class: submit_btn_css %> +<% end %> \ No newline at end of file diff --git a/app/views/doorkeeper/authorized_applications/index.html.erb b/app/views/doorkeeper/authorized_applications/index.html.erb new file mode 100644 index 0000000000..08e8429fd2 --- /dev/null +++ b/app/views/doorkeeper/authorized_applications/index.html.erb @@ -0,0 +1,24 @@ + + +
+ + + + + + + + + + <% @applications.each do |application| %> + + + + + + <% end %> + +
<%= t('doorkeeper.authorized_applications.index.application') %><%= t('doorkeeper.authorized_applications.index.created_at') %>
<%= application.name %><%= application.created_at.strftime(t('doorkeeper.authorized_applications.index.date_format')) %><%= render 'delete_form', application: application %>
+
\ No newline at end of file diff --git a/config/application.rb b/config/application.rb index 882ebb0def..503b977a6e 100644 --- a/config/application.rb +++ b/config/application.rb @@ -53,5 +53,13 @@ class Application < Rails::Application # Set the default host for mailer URLs config.action_mailer.default_url_options = { host: Socket.gethostname.to_s } + + # apply application styling to doorkeeper views + config.to_prepare do + Doorkeeper::ApplicationsController.layout "application" + Doorkeeper::AuthorizationsController.layout "application" + Doorkeeper::AuthorizedApplicationsController.layout "application" + end + end end diff --git a/config/initializers/doorkeeper.rb b/config/initializers/doorkeeper.rb new file mode 100644 index 0000000000..33e2c47c10 --- /dev/null +++ b/config/initializers/doorkeeper.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +Doorkeeper.configure do + # set the object-relational-model (ORM) + orm :active_record + + # ensure resource owner is authenticated + resource_owner_authenticator do + if user_signed_in? + if request.path == "/oauth/authorize/native" + # the /oauth/authorize/native path is only used for mobile devices + # and so it is better to deactivate it + redirect_to root_path, alert: "You are not authorized to perform this action." + else + current_user + end + else + # preserve oauth2 request url before redirecting to login + session[:user_return_to] = request.fullpath if request.get? + + # redirect user to login page + redirect_to new_user_session_url + end + end + + # ensure only super-admins can manage oauth applications + admin_authenticator do |_routes| + if current_user + unless current_user.can_super_admin? + redirect_to root_path, alert: "You are not authorized to perform this action." + end + else + warden.authenticate!(scope: :user) + end + end + + # grant flows enabled + # Authorization Code Grant Flow (ACGF) + grant_flows %w[authorization_code client_credentials] + + # allow for redirect-uri to be blank + # (required for client_credentials apps for org-admins) + allow_blank_redirect_uri true + + # scopes enabled + default_scopes :read + + # ensure client apps cannot ask for scopes outwith those specified here + enforce_configured_scopes + + # set the token endpoint configurations + access_token_expires_in 2.hours + reuse_access_token + + # enable refresh tokens of duration 90 days + use_refresh_token expiry: 90.days + + # enable ssl requirement for redirect url + force_ssl_in_redirect_uri true + +end + +# add support for dmp_multi_tenancy if available +Rails.application.config.to_prepare do + if defined?(Roadmap::Extension::TenantLookup) + [Doorkeeper::ApplicationsController, + Doorkeeper::AuthorizationsController, + Doorkeeper::AuthorizedApplicationsController].each do |controller| + controller.include Roadmap::Extension::TenantLookup + end + end +end \ No newline at end of file diff --git a/config/locales/doorkeeper.en.yml b/config/locales/doorkeeper.en.yml new file mode 100644 index 0000000000..b3c4b2c660 --- /dev/null +++ b/config/locales/doorkeeper.en.yml @@ -0,0 +1,154 @@ +en: + activerecord: + attributes: + doorkeeper/application: + name: 'Name' + redirect_uri: 'Redirect URI' + errors: + models: + doorkeeper/application: + attributes: + redirect_uri: + fragment_present: 'cannot contain a fragment.' + invalid_uri: 'must be a valid URI.' + unspecified_scheme: 'must specify a scheme.' + relative_uri: 'must be an absolute URI.' + secured_uri: 'must be an HTTPS/SSL URI.' + forbidden_uri: 'is forbidden by the server.' + scopes: + not_match_configured: "doesn't match configured on the server." + + doorkeeper: + applications: + confirmations: + destroy: 'Are you sure?' + buttons: + edit: 'Edit' + destroy: 'Destroy' + submit: 'Submit' + cancel: 'Cancel' + authorize: 'Authorize' + form: + error: 'Whoops! Check your form for possible errors' + help: + confidential: 'Application will be used where the client secret can be kept confidential. Native mobile apps and Single Page Apps are considered non-confidential.' + redirect_uri: 'Use one line per URI' + blank_redirect_uri: "Leave it blank if you configured your provider to use Client Credentials, Resource Owner Password Credentials or any other grant type that doesn't require redirect URI." + scopes: 'Separate scopes with spaces. Leave blank to use the default scopes.' + edit: + title: 'Edit application' + index: + title: 'Your applications' + new: 'New Application' + name: 'Name' + callback_url: 'Callback URL' + confidential: 'Confidential?' + actions: 'Actions' + confidentiality: + 'yes': 'Yes' + 'no': 'No' + new: + title: 'New Application' + show: + title: 'Application: %{name}' + application_id: 'UID' + secret: 'Secret' + secret_hashed: 'Secret hashed' + scopes: 'Scopes' + confidential: 'Confidential' + callback_urls: 'Callback urls' + actions: 'Actions' + not_defined: 'Not defined' + + authorizations: + buttons: + authorize: 'Authorize' + deny: 'Deny' + error: + title: 'An error has occurred' + new: + title: 'Authorization required' + prompt: 'Authorize %{client_name} to use your account?' + able_to: 'This application will be able to' + show: + title: 'Authorization code' + form_post: + title: 'Submit this form' + + authorized_applications: + confirmations: + revoke: 'Are you sure?' + buttons: + revoke: 'Revoke' + index: + title: 'Your authorized applications' + application: 'Application' + created_at: 'Created At' + date_format: '%Y-%m-%d %H:%M:%S' + + pre_authorization: + status: 'Pre-authorization' + + errors: + messages: + # Common error messages + invalid_request: + unknown: 'The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed.' + missing_param: 'Missing required parameter: %{value}.' + request_not_authorized: 'Request need to be authorized. Required parameter for authorizing request is missing or invalid.' + invalid_redirect_uri: "The requested redirect uri is malformed or doesn't match client redirect URI." + unauthorized_client: 'The client is not authorized to perform this request using this method.' + access_denied: 'The resource owner or authorization server denied the request.' + invalid_scope: 'The requested scope is invalid, unknown, or malformed.' + invalid_code_challenge_method: + zero: 'The authorization server does not support PKCE as there are no accepted code_challenge_method values.' + one: 'The code_challenge_method must be %{challenge_methods}.' + other: 'The code_challenge_method must be one of %{challenge_methods}.' + server_error: 'The authorization server encountered an unexpected condition which prevented it from fulfilling the request.' + temporarily_unavailable: 'The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server.' + + # Configuration error messages + credential_flow_not_configured: 'Resource Owner Password Credentials flow failed due to Doorkeeper.configure.resource_owner_from_credentials being unconfigured.' + resource_owner_authenticator_not_configured: 'Resource Owner find failed due to Doorkeeper.configure.resource_owner_authenticator being unconfigured.' + admin_authenticator_not_configured: 'Access to admin panel is forbidden due to Doorkeeper.configure.admin_authenticator being unconfigured.' + + # Access grant errors + unsupported_response_type: 'The authorization server does not support this response type.' + unsupported_response_mode: 'The authorization server does not support this response mode.' + + # Access token errors + invalid_client: 'Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method.' + invalid_grant: 'The provided authorization grant is invalid, expired, revoked, does not match the redirection URI used in the authorization request, or was issued to another client.' + unsupported_grant_type: 'The authorization grant type is not supported by the authorization server.' + + invalid_token: + revoked: "The access token was revoked" + expired: "The access token expired" + unknown: "The access token is invalid" + revoke: + unauthorized: "You are not authorized to revoke this token" + + forbidden_token: + missing_scope: 'Access to this resource requires scope "%{oauth_scopes}".' + + flash: + applications: + create: + notice: 'Application created.' + destroy: + notice: 'Application deleted.' + update: + notice: 'Application updated.' + authorized_applications: + destroy: + notice: 'Application revoked.' + + layouts: + admin: + title: 'Doorkeeper' + nav: + oauth2_provider: 'OAuth2 Provider' + applications: 'Applications' + home: 'Home' + application: + title: 'OAuth authorization required' diff --git a/config/routes.rb b/config/routes.rb index 5954d44591..a3c21925d6 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -203,6 +203,13 @@ resources :plans, only: %i[create show index] resources :templates, only: [:index] end + + namespace :v2 do + get :heartbeat, controller: :base_api + get :me, controller: :base_api + + resources :plans, only: [:index, :show] + end end namespace :paginable do diff --git a/db/migrate/20251119131055_create_doorkeeper_tables.rb b/db/migrate/20251119131055_create_doorkeeper_tables.rb new file mode 100644 index 0000000000..c7ee41b979 --- /dev/null +++ b/db/migrate/20251119131055_create_doorkeeper_tables.rb @@ -0,0 +1,98 @@ +# frozen_string_literal: true + +class CreateDoorkeeperTables < ActiveRecord::Migration[7.1] + def change + create_table :oauth_applications do |t| + t.string :name, null: false + t.string :uid, null: false + t.string :secret, null: false + + # Remove `null: false` if you are planning to use grant flows + # that doesn't require redirect URI to be used during authorization + # like Client Credentials flow or Resource Owner Password. + t.text :redirect_uri, null: false + t.string :scopes, null: false, default: '' + t.boolean :confidential, null: false, default: true + t.timestamps null: false + end + + add_index :oauth_applications, :uid, unique: true + + create_table :oauth_access_grants do |t| + t.references :resource_owner, null: false + t.references :application, null: false + t.string :token, null: false + t.integer :expires_in, null: false + t.text :redirect_uri, null: false + t.string :scopes, null: false, default: '' + t.datetime :created_at, null: false + t.datetime :revoked_at + end + + add_index :oauth_access_grants, :token, unique: true + add_foreign_key( + :oauth_access_grants, + :oauth_applications, + column: :application_id + ) + + create_table :oauth_access_tokens do |t| + t.references :resource_owner, index: true + + # Remove `null: false` if you are planning to use Password + # Credentials Grant flow that doesn't require an application. + t.references :application, null: false + + # If you use a custom token generator you may need to change this column + # from string to text, so that it accepts tokens larger than 255 + # characters. More info on custom token generators in: + # https://github.com/doorkeeper-gem/doorkeeper/tree/v3.0.0.rc1#custom-access-token-generator + # + # t.text :token, null: false + t.string :token, null: false + + t.string :refresh_token + t.integer :expires_in + t.string :scopes + t.datetime :created_at, null: false + t.datetime :revoked_at + + # The authorization server MAY issue a new refresh token, in which case + # *the client MUST discard the old refresh token* and replace it with the + # new refresh token. The authorization server MAY revoke the old + # refresh token after issuing a new refresh token to the client. + # @see https://datatracker.ietf.org/doc/html/rfc6749#section-6 + # + # Doorkeeper implementation: if there is a `previous_refresh_token` column, + # refresh tokens will be revoked after a related access token is used. + # If there is no `previous_refresh_token` column, previous tokens are + # revoked as soon as a new access token is created. + # + # Comment out this line if you want refresh tokens to be instantly + # revoked after use. + t.string :previous_refresh_token, null: false, default: "" + end + + add_index :oauth_access_tokens, :token, unique: true + + # See https://github.com/doorkeeper-gem/doorkeeper/issues/1592 + if ActiveRecord::Base.connection.adapter_name == "SQLServer" + execute <<~SQL.squish + CREATE UNIQUE NONCLUSTERED INDEX index_oauth_access_tokens_on_refresh_token ON oauth_access_tokens(refresh_token) + WHERE refresh_token IS NOT NULL + SQL + else + add_index :oauth_access_tokens, :refresh_token, unique: true + end + + add_foreign_key( + :oauth_access_tokens, + :oauth_applications, + column: :application_id + ) + + # Uncomment below to ensure a valid reference to the resource owner's table + add_foreign_key :oauth_access_grants, :users, column: :resource_owner_id + add_foreign_key :oauth_access_tokens, :users, column: :resource_owner_id + end +end \ No newline at end of file diff --git a/db/schema.rb b/db/schema.rb index 3b6036f2bf..f96170db11 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.1].define(version: 2025_01_15_102816) do +ActiveRecord::Schema[7.1].define(version: 2025_11_19_131055) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -246,6 +246,48 @@ t.boolean "enabled", default: true end + create_table "oauth_access_grants", force: :cascade do |t| + t.bigint "resource_owner_id", null: false + t.bigint "application_id", null: false + t.string "token", null: false + t.integer "expires_in", null: false + t.text "redirect_uri", null: false + t.string "scopes", default: "", null: false + t.datetime "created_at", null: false + t.datetime "revoked_at" + t.index ["application_id"], name: "index_oauth_access_grants_on_application_id" + t.index ["resource_owner_id"], name: "index_oauth_access_grants_on_resource_owner_id" + t.index ["token"], name: "index_oauth_access_grants_on_token", unique: true + end + + create_table "oauth_access_tokens", force: :cascade do |t| + t.bigint "resource_owner_id" + t.bigint "application_id", null: false + t.string "token", null: false + t.string "refresh_token" + t.integer "expires_in" + t.string "scopes" + t.datetime "created_at", null: false + t.datetime "revoked_at" + t.string "previous_refresh_token", default: "", null: false + t.index ["application_id"], name: "index_oauth_access_tokens_on_application_id" + t.index ["refresh_token"], name: "index_oauth_access_tokens_on_refresh_token", unique: true + t.index ["resource_owner_id"], name: "index_oauth_access_tokens_on_resource_owner_id" + t.index ["token"], name: "index_oauth_access_tokens_on_token", unique: true + end + + create_table "oauth_applications", force: :cascade do |t| + t.string "name", null: false + t.string "uid", null: false + t.string "secret", null: false + t.text "redirect_uri", null: false + t.string "scopes", default: "", null: false + t.boolean "confidential", default: true, null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["uid"], name: "index_oauth_applications_on_uid", unique: true + end + create_table "org_token_permissions", id: :serial, force: :cascade do |t| t.integer "org_id" t.integer "token_permission_type_id" @@ -644,6 +686,10 @@ add_foreign_key "notes", "users" add_foreign_key "notification_acknowledgements", "notifications" add_foreign_key "notification_acknowledgements", "users" + add_foreign_key "oauth_access_grants", "oauth_applications", column: "application_id" + add_foreign_key "oauth_access_grants", "users", column: "resource_owner_id" + add_foreign_key "oauth_access_tokens", "oauth_applications", column: "application_id" + add_foreign_key "oauth_access_tokens", "users", column: "resource_owner_id" add_foreign_key "org_token_permissions", "orgs" add_foreign_key "org_token_permissions", "token_permission_types" add_foreign_key "orgs", "languages" From 63b65c23d356b82583e6b5087abda9af03632ee9 Mon Sep 17 00:00:00 2001 From: Marta Nicholson Date: Fri, 21 Nov 2025 16:23:02 +0000 Subject: [PATCH 2/8] add doorkeeper to routes --- config/routes.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/config/routes.rb b/config/routes.rb index a3c21925d6..2f70978cea 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2,6 +2,8 @@ # rubocop:disable Metrics/BlockLength Rails.application.routes.draw do + + use_doorkeeper # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html devise_for(:users, controllers: { From 10380faa2704befc2da34f90e7db45d6df32e2fb Mon Sep 17 00:00:00 2001 From: gjacob24 Date: Mon, 1 Dec 2025 12:24:44 +0000 Subject: [PATCH 3/8] Add rubocop fixes --- app/controllers/api/v2/base_api_controller.rb | 19 +++-- app/controllers/api/v2/plans_controller.rb | 27 +++---- .../api/v2/templates_controller.rb | 11 ++- app/controllers/application_controller.rb | 14 ++-- .../concerns/plan_permitted_params.rb | 71 +++++++++---------- app/models/oauth_access_grant.rb | 11 ++- app/models/oauth_access_token.rb | 4 +- app/models/oauth_application.rb | 15 ++-- app/models/user.rb | 10 +-- app/policies/api/v2/plans_policy.rb | 20 +++--- app/policies/api/v2/templates_policy.rb | 21 +++--- app/presenters/api/v2/api_presenter.rb | 2 +- .../api/v2/contributor_presenter.rb | 2 +- app/presenters/api/v2/funding_presenter.rb | 2 +- app/presenters/api/v2/language_presenter.rb | 2 +- app/presenters/api/v2/org_presenter.rb | 2 +- app/presenters/api/v2/pagination_presenter.rb | 2 +- app/presenters/api/v2/plan_presenter.rb | 2 +- .../api/v2/research_output_presenter.rb | 2 +- app/presenters/api/v2/template_presenter.rb | 2 +- app/services/api/v2/conversion_service.rb | 2 +- .../api/v2/_standard_response.json.jbuilder | 2 +- .../api/v2/contributors/_show.json.jbuilder | 2 +- app/views/api/v2/datasets/_show.json.jbuilder | 2 +- app/views/api/v2/error.json.jbuilder | 2 +- app/views/api/v2/heartbeat.json.jbuilder | 2 +- .../api/v2/identifiers/_show.json.jbuilder | 2 +- app/views/api/v2/me.json.jbuilder | 2 +- app/views/api/v2/orgs/_show.json.jbuilder | 2 +- app/views/api/v2/plans/_cost.json.jbuilder | 2 +- app/views/api/v2/plans/_funding.json.jbuilder | 2 +- app/views/api/v2/plans/_project.json.jbuilder | 2 +- app/views/api/v2/plans/_show.json.jbuilder | 2 +- app/views/api/v2/plans/index.json.jbuilder | 2 +- .../api/v2/templates/index.json.jbuilder | 2 +- config/application.rb | 3 +- config/initializers/doorkeeper.rb | 39 +++++----- config/routes.rb | 9 ++- 38 files changed, 147 insertions(+), 175 deletions(-) diff --git a/app/controllers/api/v2/base_api_controller.rb b/app/controllers/api/v2/base_api_controller.rb index 8b31faf221..6cd7f0564e 100644 --- a/app/controllers/api/v2/base_api_controller.rb +++ b/app/controllers/api/v2/base_api_controller.rb @@ -2,21 +2,19 @@ module Api module V2 - class BaseApiController < ApplicationController - + class BaseApiController < ApplicationController # rubocop:todo Style/Documentation # skipping the standard rails authenticity tokens passed in the UI skip_before_action :verify_authenticity_token # call doorkeeper to authorize the request before_action :doorkeeper_authorize!, except: %i[heartbeat] - # get details of server (e.g. DMPonline) and client app before_action :get_client_and_server_details before_action :log_access # controller can respond to json format requests - respond_to :json + respond_to :json # set up pages in response before_action :pagination_params, except: %i[heartbeat] @@ -38,11 +36,13 @@ def me # define instance variable json and associated getter and setter methods attr_accessor :json - def get_client_and_server_details + def get_client_and_server_details # rubocop:todo Naming/AccessorMethodName @server = ApplicationService.application_name @client = OauthApplication.find(doorkeeper_token.application_id) if doorkeeper_token @scopes = doorkeeper_token.scopes.to_a if doorkeeper_token - @resource_owner = User.find(doorkeeper_token.resource_owner_id) if doorkeeper_token && doorkeeper_token.resource_owner_id + return unless doorkeeper_token&.resource_owner_id + + @resource_owner = User.find(doorkeeper_token.resource_owner_id) end def log_access @@ -79,8 +79,8 @@ def handle_client_not_authorized # only allow 100 per page as the max def pagination_params max_per_page = Rails.configuration.x.application.api_max_page_size - @page = params.fetch('page', 1).to_i - @per_page = params.fetch('per_page', max_per_page).to_i + @page = params.fetch('page', 1).to_i + @per_page = params.fetch('per_page', max_per_page).to_i @per_page = max_per_page if @per_page > max_per_page end @@ -89,7 +89,6 @@ def paginate_response(results:) @total_items = results.total_count results end - end end -end \ No newline at end of file +end diff --git a/app/controllers/api/v2/plans_controller.rb b/app/controllers/api/v2/plans_controller.rb index 228927e4c7..7714e9c892 100644 --- a/app/controllers/api/v2/plans_controller.rb +++ b/app/controllers/api/v2/plans_controller.rb @@ -1,26 +1,20 @@ # frozen_string_literal: true -module Api - module V2 - class PlansController < BaseApiController - respond_to :json +module Api + module V2 + class PlansController < BaseApiController # rubocop:todo Style/Documentation + respond_to :json # GET /api/v2/plans/:id def show - unless @scopes.include?('read') - raise Pundit::NotAuthorizedError - end + raise Pundit::NotAuthorizedError unless @scopes.include?('read') @plan = Plan.find_by(id: params[:id]) - unless @plan.present? - raise Pundit::NotAuthorizedError - end + raise Pundit::NotAuthorizedError unless @plan.present? plans_policy = PlansPolicy.new(@resource_owner, @plan) - unless plans_policy.show? - raise Pundit::NotAuthorizedError - end + raise Pundit::NotAuthorizedError unless plans_policy.show? @items = [@plan] render '/api/v2/plans/index', status: :ok @@ -28,15 +22,12 @@ def show # GET /api/v2/plans def index - unless @scopes.include?('read') - raise Pundit::NotAuthorizedError - end + raise Pundit::NotAuthorizedError unless @scopes.include?('read') @plans = PlansPolicy::Scope.new(@resource_owner).resolve @items = paginate_response(results: @plans) render '/api/v2/plans/index', status: :ok - end end end -end \ No newline at end of file +end diff --git a/app/controllers/api/v2/templates_controller.rb b/app/controllers/api/v2/templates_controller.rb index d5a62540c7..5e732506dc 100644 --- a/app/controllers/api/v2/templates_controller.rb +++ b/app/controllers/api/v2/templates_controller.rb @@ -4,19 +4,16 @@ module Api module V2 # provides a list of templates for API V2 class TemplatesController < BaseApiController - respond_to :json + respond_to :json # GET /api/v2/templates - # rubocop:disable Metrics/AbcSize def index - unless @scopes.include?('read') - raise Pundit::NotAuthorizedError - end + raise Pundit::NotAuthorizedError unless @scopes.include?('read') + templates = Api::V2::TemplatesPolicy::Scope.new(@resource_owner).resolve @items = paginate_response(results: templates) render '/api/v2/templates/index', status: :ok end - end end -end \ No newline at end of file +end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index ceb5c6edbd..e5d2421e76 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -66,10 +66,8 @@ def store_location # rubocop:disable Metrics/AbcSize def after_sign_in_path_for(_resource) - # ensure oauth2 authorization flow is not interrupted - if user_is_in_oauth_flow - return session[:user_return_to] - end + # ensure oauth2 authorization flow is not interrupted + return session[:user_return_to] if user_is_in_oauth_flow referer_path = URI(request.referer).path unless request.referer.nil? if from_external_domain? || referer_path.eql?(new_user_session_path) || @@ -82,11 +80,9 @@ def after_sign_in_path_for(_resource) end # rubocop:enable Metrics/AbcSize - def after_sign_up_path_for(_resource) - # ensure oauth2 authorization flow is not interrupted - if user_is_in_oauth_flow - return session[:user_return_to] - end + def after_sign_up_path_for(_resource) # rubocop:todo Metrics/AbcSize + # ensure oauth2 authorization flow is not interrupted + return session[:user_return_to] if user_is_in_oauth_flow referer_path = URI(request.referer).path unless request.referer.nil? if from_external_domain? || diff --git a/app/controllers/concerns/plan_permitted_params.rb b/app/controllers/concerns/plan_permitted_params.rb index ac15920016..90363f9de8 100644 --- a/app/controllers/concerns/plan_permitted_params.rb +++ b/app/controllers/concerns/plan_permitted_params.rb @@ -1,14 +1,14 @@ # frozen_string_literal: true -module PlanPermittedParams +module PlanPermittedParams # rubocop:todo Metrics/ModuleLength, Style/Documentation extend ActiveSupport::Concern def plan_permitted_params [ :created, - :title, - :description, - :language, + :title, + :description, + :language, :ethical_issues_exist, :ethical_issues_description, :ethical_issues_report, @@ -22,17 +22,17 @@ def plan_permitted_params end def identifier_permitted_params - [ - :type, - :identifier + %i[ + type + identifier ] end def contributor_permitted_params [ - :firstname, - :surname, - :mbox, + :firstname, + :surname, + :mbox, :role, { affiliations: affiliation_permitted_params }, { contributor_ids: identifier_permitted_params } @@ -41,26 +41,26 @@ def contributor_permitted_params def affiliation_permitted_params [ - :name, + :name, :abbreviation, { affiliation_ids: identifier_permitted_params } ] end def cost_permitted_params - [ - :title, - :description, - :value, - :currency_code + %i[ + title + description + value + currency_code ] end def project_permitted_params [ - :title, - :description, - :start_on, + :title, + :description, + :start_on, :end_on, { funding: funding_permitted_params } ] @@ -79,14 +79,14 @@ def dataset_permitted_params [ :title, :doi_url, - :description, - :type, - :issued, - :language, - :personal_data, + :description, + :type, + :issued, + :language, + :personal_data, :sensitive_data, :keywords, - :data_quality_assurance, + :data_quality_assurance, :preservation_statement, { dataset_ids: identifier_permitted_params }, { metadata: metadatum_permitted_params }, @@ -105,9 +105,9 @@ def metadatum_permitted_params end def security_and_privacy_statement_permitted_params - [ - :title, - :description + %i[ + title + description ] end @@ -123,20 +123,20 @@ def distribution_permitted_params :title, :description, :format, - :byte_size, - :access_url, + :byte_size, + :access_url, :download_url, :data_access, :available_until, - { licenses: license_permitted_params }, + { licenses: license_permitted_params }, { host: host_permitted_params } ] end def license_permitted_params - [ - :license_ref, - :start_date + %i[ + license_ref + start_date ] end @@ -155,5 +155,4 @@ def host_permitted_params { host_ids: identifier_permitted_params } ] end - -end \ No newline at end of file +end diff --git a/app/models/oauth_access_grant.rb b/app/models/oauth_access_grant.rb index 09f94bf428..f39c307af9 100644 --- a/app/models/oauth_access_grant.rb +++ b/app/models/oauth_access_grant.rb @@ -4,16 +4,15 @@ # # Table name: oauth_access_grants # -# id: :integer -# resource_owner_id: :integer +# id: :integer +# resource_owner_id: :integer # application_id: :integer # token: :string -# expires_in: :integer +# expires_in: :integer # redirect_uri: :text # scopes: :string -# created_at: :datetime +# created_at: :datetime # revoked_at: :datetime class OauthAccessGrant < ApplicationRecord - -end \ No newline at end of file +end diff --git a/app/models/oauth_access_token.rb b/app/models/oauth_access_token.rb index bd309bff57..b17e824e72 100644 --- a/app/models/oauth_access_token.rb +++ b/app/models/oauth_access_token.rb @@ -15,7 +15,5 @@ # revoked_at: :datetime # previous_refresh_token: :string - class OauthAccessToken < ApplicationRecord - -end \ No newline at end of file +end diff --git a/app/models/oauth_application.rb b/app/models/oauth_application.rb index 6786d7dca7..4779e53cc4 100644 --- a/app/models/oauth_application.rb +++ b/app/models/oauth_application.rb @@ -5,15 +5,14 @@ # Table name: oauth_applications # # id: :integer -# name: :string -# uid: :string -# secret: :string -# redirect_uri: :text +# name: :string +# uid: :string +# secret: :string +# redirect_uri: :text # scopes: :string -# confidential: :boolean -# created_at: :datetime +# confidential: :boolean +# created_at: :datetime # updated_at: :datetime class OauthApplication < ApplicationRecord - -end \ No newline at end of file +end diff --git a/app/models/user.rb b/app/models/user.rb index 5c5cb307ec..8732c2f770 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -98,10 +98,12 @@ class User < ApplicationRecord has_and_belongs_to_many :notifications, dependent: :destroy, join_table: 'notification_acknowledgements' - has_many :access_grants, class_name: 'Doorkeeper::AccessGrant', foreign_key: :resource_owner_id, dependent: :delete_all - - has_many :access_tokens, class_name: 'Doorkeeper::AccessToken', foreign_key: :resource_owner_id, dependent: :delete_all - + has_many :access_grants, class_name: 'Doorkeeper::AccessGrant', foreign_key: :resource_owner_id, + dependent: :delete_all + + has_many :access_tokens, class_name: 'Doorkeeper::AccessToken', foreign_key: :resource_owner_id, + dependent: :delete_all + # =============== # = Validations = # =============== diff --git a/app/policies/api/v2/plans_policy.rb b/app/policies/api/v2/plans_policy.rb index d9c34d95df..98a22a5025 100644 --- a/app/policies/api/v2/plans_policy.rb +++ b/app/policies/api/v2/plans_policy.rb @@ -4,32 +4,28 @@ module Api module V2 # Security rules for API V2 Plan endpoints class PlansPolicy < ApplicationPolicy - # overriding the initializer due to resource owner / user # not needing to be logged in for client app to make requests - def initialize(resource_owner, plan = nil) - @resource_owner = resource_owner - @plan = plan + def initialize(resource_owner, plan = nil) # rubocop:todo Lint/MissingSuper + @resource_owner = resource_owner + @plan = plan end def show? @plan.roles.where(user_id: @resource_owner.id, active: true).exists? end - - class Scope < Scope - def initialize(resource_owner) - @resource_owner = resource_owner + class Scope < Scope # rubocop:todo Style/Documentation + def initialize(resource_owner) # rubocop:todo Lint/MissingSuper + @resource_owner = resource_owner end - def resolve + def resolve Plan.joins(:roles) .where(roles: { user_id: @resource_owner.id, active: true }) .distinct end - end - end end -end \ No newline at end of file +end diff --git a/app/policies/api/v2/templates_policy.rb b/app/policies/api/v2/templates_policy.rb index fbe0f892d7..dacdfe48a2 100644 --- a/app/policies/api/v2/templates_policy.rb +++ b/app/policies/api/v2/templates_policy.rb @@ -1,10 +1,10 @@ # frozen_string_literal: true -module Api +module Api module V2 class TemplatesPolicy < ApplicationPolicy - class Scope < Scope - def initialize(resource_owner) + class Scope < Scope # rubocop:todo Style/Documentation + def initialize(resource_owner) # rubocop:todo Lint/MissingSuper @resource_owner = resource_owner end @@ -16,18 +16,17 @@ def resolve SQL # get the templates - templates = Template. - includes(org: :identifiers). - joins(:org). - published. - where( - where_clause, + Template + .includes(org: :identifiers) + .joins(:org) + .published + .where( + where_clause, @resource_owner.org&.id ) .order(:title) - templates end end end end -end \ No newline at end of file +end diff --git a/app/presenters/api/v2/api_presenter.rb b/app/presenters/api/v2/api_presenter.rb index 3aa4451479..1ad7290ab6 100644 --- a/app/presenters/api/v2/api_presenter.rb +++ b/app/presenters/api/v2/api_presenter.rb @@ -13,4 +13,4 @@ def boolean_to_yes_no_unknown(value:) end end end -end \ No newline at end of file +end diff --git a/app/presenters/api/v2/contributor_presenter.rb b/app/presenters/api/v2/contributor_presenter.rb index 6220e226d4..77232c2838 100644 --- a/app/presenters/api/v2/contributor_presenter.rb +++ b/app/presenters/api/v2/contributor_presenter.rb @@ -19,4 +19,4 @@ def contributor_id(identifiers:) end end end -end \ No newline at end of file +end diff --git a/app/presenters/api/v2/funding_presenter.rb b/app/presenters/api/v2/funding_presenter.rb index bb07880ec1..c878daadb6 100644 --- a/app/presenters/api/v2/funding_presenter.rb +++ b/app/presenters/api/v2/funding_presenter.rb @@ -22,4 +22,4 @@ def status(plan:) end end end -end \ No newline at end of file +end diff --git a/app/presenters/api/v2/language_presenter.rb b/app/presenters/api/v2/language_presenter.rb index 0cf280a3d0..1b9d8aebce 100644 --- a/app/presenters/api/v2/language_presenter.rb +++ b/app/presenters/api/v2/language_presenter.rb @@ -81,4 +81,4 @@ def three_char_code(lang:) end end end -end \ No newline at end of file +end diff --git a/app/presenters/api/v2/org_presenter.rb b/app/presenters/api/v2/org_presenter.rb index 2e954706b3..5302acb7a7 100644 --- a/app/presenters/api/v2/org_presenter.rb +++ b/app/presenters/api/v2/org_presenter.rb @@ -14,4 +14,4 @@ def affiliation_id(identifiers:) end end end -end \ No newline at end of file +end diff --git a/app/presenters/api/v2/pagination_presenter.rb b/app/presenters/api/v2/pagination_presenter.rb index 9b4b2426ab..1b8fbc1109 100644 --- a/app/presenters/api/v2/pagination_presenter.rb +++ b/app/presenters/api/v2/pagination_presenter.rb @@ -47,4 +47,4 @@ def total_pages end end end -end \ No newline at end of file +end diff --git a/app/presenters/api/v2/plan_presenter.rb b/app/presenters/api/v2/plan_presenter.rb index 83061c637f..204cd68011 100644 --- a/app/presenters/api/v2/plan_presenter.rb +++ b/app/presenters/api/v2/plan_presenter.rb @@ -56,4 +56,4 @@ def plan_costs(plan:) end end end -end \ No newline at end of file +end diff --git a/app/presenters/api/v2/research_output_presenter.rb b/app/presenters/api/v2/research_output_presenter.rb index ae5112ac12..fc44055b2d 100644 --- a/app/presenters/api/v2/research_output_presenter.rb +++ b/app/presenters/api/v2/research_output_presenter.rb @@ -74,4 +74,4 @@ def fetch_q_and_a(themes:) # rubocop:enable Metrics/AbcSize, Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity end end -end \ No newline at end of file +end diff --git a/app/presenters/api/v2/template_presenter.rb b/app/presenters/api/v2/template_presenter.rb index ef518f24d9..2d32a45d37 100644 --- a/app/presenters/api/v2/template_presenter.rb +++ b/app/presenters/api/v2/template_presenter.rb @@ -17,4 +17,4 @@ def title end end end -end \ No newline at end of file +end diff --git a/app/services/api/v2/conversion_service.rb b/app/services/api/v2/conversion_service.rb index 2bbe580a0e..4a9a932878 100644 --- a/app/services/api/v2/conversion_service.rb +++ b/app/services/api/v2/conversion_service.rb @@ -35,4 +35,4 @@ def to_identifier(context:, value:) end end end -end \ No newline at end of file +end diff --git a/app/views/api/v2/_standard_response.json.jbuilder b/app/views/api/v2/_standard_response.json.jbuilder index 798ff3a35a..c979fec01e 100644 --- a/app/views/api/v2/_standard_response.json.jbuilder +++ b/app/views/api/v2/_standard_response.json.jbuilder @@ -34,4 +34,4 @@ if response.status == 200 json.total_items 0 end -end \ No newline at end of file +end diff --git a/app/views/api/v2/contributors/_show.json.jbuilder b/app/views/api/v2/contributors/_show.json.jbuilder index ce6f84dfc6..267ff7e3d2 100644 --- a/app/views/api/v2/contributors/_show.json.jbuilder +++ b/app/views/api/v2/contributors/_show.json.jbuilder @@ -34,4 +34,4 @@ if orcid.present? json.partial! 'api/v2/identifiers/show', identifier: id end end -end \ No newline at end of file +end diff --git a/app/views/api/v2/datasets/_show.json.jbuilder b/app/views/api/v2/datasets/_show.json.jbuilder index a23f2fb598..1581dff785 100644 --- a/app/views/api/v2/datasets/_show.json.jbuilder +++ b/app/views/api/v2/datasets/_show.json.jbuilder @@ -81,4 +81,4 @@ else json.keyword [research_domain.label, combined] end end -end \ No newline at end of file +end diff --git a/app/views/api/v2/error.json.jbuilder b/app/views/api/v2/error.json.jbuilder index dd7f362f30..ac08f26d9f 100644 --- a/app/views/api/v2/error.json.jbuilder +++ b/app/views/api/v2/error.json.jbuilder @@ -4,4 +4,4 @@ json.partial! 'api/v2/standard_response' # json.items [] json.message @payload[:message] -json.details @payload[:details] \ No newline at end of file +json.details @payload[:details] diff --git a/app/views/api/v2/heartbeat.json.jbuilder b/app/views/api/v2/heartbeat.json.jbuilder index e254c72e8e..70b165b95d 100644 --- a/app/views/api/v2/heartbeat.json.jbuilder +++ b/app/views/api/v2/heartbeat.json.jbuilder @@ -2,4 +2,4 @@ json.partial! 'api/v2/standard_response' -json.items [] \ No newline at end of file +json.items [] diff --git a/app/views/api/v2/identifiers/_show.json.jbuilder b/app/views/api/v2/identifiers/_show.json.jbuilder index 174426cf14..c219222aee 100644 --- a/app/views/api/v2/identifiers/_show.json.jbuilder +++ b/app/views/api/v2/identifiers/_show.json.jbuilder @@ -3,4 +3,4 @@ # locals: identifier json.type identifier&.identifier_format -json.identifier identifier&.value \ No newline at end of file +json.identifier identifier&.value diff --git a/app/views/api/v2/me.json.jbuilder b/app/views/api/v2/me.json.jbuilder index 48314f0439..18a1e7c114 100644 --- a/app/views/api/v2/me.json.jbuilder +++ b/app/views/api/v2/me.json.jbuilder @@ -24,4 +24,4 @@ if current_user.present? else json.items [] -end \ No newline at end of file +end diff --git a/app/views/api/v2/orgs/_show.json.jbuilder b/app/views/api/v2/orgs/_show.json.jbuilder index 29cfb30577..934e429a17 100644 --- a/app/views/api/v2/orgs/_show.json.jbuilder +++ b/app/views/api/v2/orgs/_show.json.jbuilder @@ -11,4 +11,4 @@ if org.identifiers.any? id = Api::V2::OrgPresenter.affiliation_id(identifiers: org.identifiers) json.partial! 'api/v2/identifiers/show', identifier: id end -end \ No newline at end of file +end diff --git a/app/views/api/v2/plans/_cost.json.jbuilder b/app/views/api/v2/plans/_cost.json.jbuilder index 32a0cfbaa7..ad36e3540e 100644 --- a/app/views/api/v2/plans/_cost.json.jbuilder +++ b/app/views/api/v2/plans/_cost.json.jbuilder @@ -5,4 +5,4 @@ json.title cost[:title] json.description cost[:description] json.currency_code cost[:currency_code] -json.value cost[:value] \ No newline at end of file +json.value cost[:value] diff --git a/app/views/api/v2/plans/_funding.json.jbuilder b/app/views/api/v2/plans/_funding.json.jbuilder index 9006186d86..35786ac2dc 100644 --- a/app/views/api/v2/plans/_funding.json.jbuilder +++ b/app/views/api/v2/plans/_funding.json.jbuilder @@ -38,4 +38,4 @@ end # one associated with the Plan, we add it here. json.dmproadmap_funded_affiliations [plan.org] do |funded_org| json.partial! 'api/v2/orgs/show', org: funded_org -end \ No newline at end of file +end diff --git a/app/views/api/v2/plans/_project.json.jbuilder b/app/views/api/v2/plans/_project.json.jbuilder index 7397815365..9bf3f97fea 100644 --- a/app/views/api/v2/plans/_project.json.jbuilder +++ b/app/views/api/v2/plans/_project.json.jbuilder @@ -15,4 +15,4 @@ if plan.funder.present? || plan.grant_id.present? json.funding [plan] do json.partial! 'api/v2/plans/funding', plan: plan end -end \ No newline at end of file +end diff --git a/app/views/api/v2/plans/_show.json.jbuilder b/app/views/api/v2/plans/_show.json.jbuilder index e6eb96684d..0de52775a3 100644 --- a/app/views/api/v2/plans/_show.json.jbuilder +++ b/app/views/api/v2/plans/_show.json.jbuilder @@ -69,4 +69,4 @@ unless @minimal end end end -end \ No newline at end of file +end diff --git a/app/views/api/v2/plans/index.json.jbuilder b/app/views/api/v2/plans/index.json.jbuilder index 125e5f14db..f19f41d1dc 100644 --- a/app/views/api/v2/plans/index.json.jbuilder +++ b/app/views/api/v2/plans/index.json.jbuilder @@ -6,4 +6,4 @@ json.items @items do |item| json.dmp do json.partial! 'api/v2/plans/show', plan: item end -end \ No newline at end of file +end diff --git a/app/views/api/v2/templates/index.json.jbuilder b/app/views/api/v2/templates/index.json.jbuilder index 8255f5c342..cdb35f54fb 100644 --- a/app/views/api/v2/templates/index.json.jbuilder +++ b/app/views/api/v2/templates/index.json.jbuilder @@ -22,4 +22,4 @@ json.items @items do |template| json.partial! 'api/v2/identifiers/show', identifier: identifier end end -end \ No newline at end of file +end diff --git a/config/application.rb b/config/application.rb index 503b977a6e..db4975c352 100644 --- a/config/application.rb +++ b/config/application.rb @@ -55,11 +55,10 @@ class Application < Rails::Application config.action_mailer.default_url_options = { host: Socket.gethostname.to_s } # apply application styling to doorkeeper views - config.to_prepare do + config.to_prepare do Doorkeeper::ApplicationsController.layout "application" Doorkeeper::AuthorizationsController.layout "application" Doorkeeper::AuthorizedApplicationsController.layout "application" end - end end diff --git a/config/initializers/doorkeeper.rb b/config/initializers/doorkeeper.rb index 33e2c47c10..306741a770 100644 --- a/config/initializers/doorkeeper.rb +++ b/config/initializers/doorkeeper.rb @@ -1,9 +1,9 @@ # frozen_string_literal: true - -Doorkeeper.configure do + +Doorkeeper.configure do # rubocop:todo Metrics/BlockLength # set the object-relational-model (ORM) orm :active_record - + # ensure resource owner is authenticated resource_owner_authenticator do if user_signed_in? @@ -15,49 +15,48 @@ current_user end else - # preserve oauth2 request url before redirecting to login - session[:user_return_to] = request.fullpath if request.get? + # preserve oauth2 request url before redirecting to login + session[:user_return_to] = request.fullpath if request.get? - # redirect user to login page - redirect_to new_user_session_url + # redirect user to login page + redirect_to new_user_session_url end end - + # ensure only super-admins can manage oauth applications admin_authenticator do |_routes| if current_user unless current_user.can_super_admin? - redirect_to root_path, alert: "You are not authorized to perform this action." + redirect_to root_path, alert: "You are not authorized to perform this action." end else warden.authenticate!(scope: :user) end end - + # grant flows enabled # Authorization Code Grant Flow (ACGF) grant_flows %w[authorization_code client_credentials] - - # allow for redirect-uri to be blank + + # allow for redirect-uri to be blank # (required for client_credentials apps for org-admins) allow_blank_redirect_uri true # scopes enabled default_scopes :read - + # ensure client apps cannot ask for scopes outwith those specified here enforce_configured_scopes - + # set the token endpoint configurations access_token_expires_in 2.hours reuse_access_token - + # enable refresh tokens of duration 90 days use_refresh_token expiry: 90.days - + # enable ssl requirement for redirect url force_ssl_in_redirect_uri true - end # add support for dmp_multi_tenancy if available @@ -65,8 +64,8 @@ if defined?(Roadmap::Extension::TenantLookup) [Doorkeeper::ApplicationsController, Doorkeeper::AuthorizationsController, - Doorkeeper::AuthorizedApplicationsController].each do |controller| - controller.include Roadmap::Extension::TenantLookup + Doorkeeper::AuthorizedApplicationsController].each do |controller| + controller.include Roadmap::Extension::TenantLookup end end -end \ No newline at end of file +end diff --git a/config/routes.rb b/config/routes.rb index 2f70978cea..152c4a327d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2,7 +2,6 @@ # rubocop:disable Metrics/BlockLength Rails.application.routes.draw do - use_doorkeeper # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html @@ -205,12 +204,12 @@ resources :plans, only: %i[create show index] resources :templates, only: [:index] end - - namespace :v2 do - get :heartbeat, controller: :base_api + + namespace :v2 do + get :heartbeat, controller: :base_api get :me, controller: :base_api - resources :plans, only: [:index, :show] + resources :plans, only: %i[index show] end end From 650863318cc8bd4f096e3236ddd56e1539dfface Mon Sep 17 00:00:00 2001 From: gjacob24 Date: Mon, 22 Dec 2025 15:50:17 +0000 Subject: [PATCH 4/8] Remove DMPonline specific code from doorkeeper initializer Co-Authored-By: gjacob24 <97518971+gjacob24@users.noreply.github.com> --- config/initializers/doorkeeper.rb | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/config/initializers/doorkeeper.rb b/config/initializers/doorkeeper.rb index 306741a770..a7da6540f0 100644 --- a/config/initializers/doorkeeper.rb +++ b/config/initializers/doorkeeper.rb @@ -58,14 +58,3 @@ # enable ssl requirement for redirect url force_ssl_in_redirect_uri true end - -# add support for dmp_multi_tenancy if available -Rails.application.config.to_prepare do - if defined?(Roadmap::Extension::TenantLookup) - [Doorkeeper::ApplicationsController, - Doorkeeper::AuthorizationsController, - Doorkeeper::AuthorizedApplicationsController].each do |controller| - controller.include Roadmap::Extension::TenantLookup - end - end -end From a04513bdcdd3aa4fe1865dce4af58629184bcba0 Mon Sep 17 00:00:00 2001 From: aaronskiba Date: Tue, 27 Jan 2026 12:53:00 -0700 Subject: [PATCH 5/8] Fix `@client` bug & rename server/client JSON keys Fix crashes when `@client` is nil (e.g., on heartbeat endpoint where doorkeeper_token is not present). - `@client = doorkeeper_token&.application` simplifies `@client` assignment. - Guard log_access and add `@caller` for safe JSON output Align JSON response keys with V1 - server -> application - client -> caller Co-Authored-By: gjacob24 <97518971+gjacob24@users.noreply.github.com> Co-Authored-By: John Pinto <8876215+johnpinto1@users.noreply.github.com> --- app/controllers/api/v2/base_api_controller.rb | 15 +++++++++------ app/views/api/v2/_standard_response.json.jbuilder | 4 ++-- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/app/controllers/api/v2/base_api_controller.rb b/app/controllers/api/v2/base_api_controller.rb index 6cd7f0564e..fa9e0143e0 100644 --- a/app/controllers/api/v2/base_api_controller.rb +++ b/app/controllers/api/v2/base_api_controller.rb @@ -9,7 +9,7 @@ class BaseApiController < ApplicationController # rubocop:todo Style/Documentati # call doorkeeper to authorize the request before_action :doorkeeper_authorize!, except: %i[heartbeat] # get details of server (e.g. DMPonline) and client app - before_action :get_client_and_server_details + before_action :base_response_content before_action :log_access @@ -36,9 +36,10 @@ def me # define instance variable json and associated getter and setter methods attr_accessor :json - def get_client_and_server_details # rubocop:todo Naming/AccessorMethodName - @server = ApplicationService.application_name - @client = OauthApplication.find(doorkeeper_token.application_id) if doorkeeper_token + def base_response_content + @application = ApplicationService.application_name + @client = doorkeeper_token&.application + @caller = @client&.name || request.remote_ip @scopes = doorkeeper_token.scopes.to_a if doorkeeper_token return unless doorkeeper_token&.resource_owner_id @@ -46,8 +47,10 @@ def get_client_and_server_details # rubocop:todo Naming/AccessorMethodName end def log_access - Rails.logger.info "Client (OAuth) application name: #{@client.name}" - Rails.logger.info "Client (OAuth) application uid: #{@client.uid}" + if @client.present? + Rails.logger.info "Client (OAuth) application name: #{@client.name}" + Rails.logger.info "Client (OAuth) application uid: #{@client.uid}" + end Rails.logger.info "Resource owner id: #{@resource_owner.id}" if @resource_owner end diff --git a/app/views/api/v2/_standard_response.json.jbuilder b/app/views/api/v2/_standard_response.json.jbuilder index c979fec01e..372c42cb31 100644 --- a/app/views/api/v2/_standard_response.json.jbuilder +++ b/app/views/api/v2/_standard_response.json.jbuilder @@ -12,10 +12,10 @@ paginator = Api::V2::PaginationPresenter.new(current_url: request.path, json.prettify! json.ignore_nil! -json.server @server +json.application @application json.source "#{request.method} #{request.path}" json.time Time.now.to_formatted_s(:iso8601) -json.client @client.name +json.caller @caller json.code response.status json.message Rack::Utils::HTTP_STATUS_CODES[response.status] From 3e949be3f98b550d20cf1cdb5b581ee086c8e445 Mon Sep 17 00:00:00 2001 From: aaronskiba Date: Tue, 16 Dec 2025 11:40:40 -0700 Subject: [PATCH 6/8] Add v2 API test coverage This test suite was adapted from the v2 API tests in CDLUC3/dmptool. The original request and view specs were copied and then refactored to align with our v2 API. Supporting factories and spec helper files were updated as needed to accommodate the new coverage. --- spec/factories/identifier_schemes.rb | 14 ++ spec/factories/oauth_access_grants.rb | 36 +++ spec/factories/oauth_access_tokens.rb | 38 ++++ spec/factories/oauth_applications.rb | 25 ++ spec/factories/research_domains.rb | 1 - spec/requests/api/v2/plans_controller_spec.rb | 126 ++++++++++ .../api/v2/templates_controller_spec.rb | 120 ++++++++++ spec/support/helpers/api.rb | 40 ++++ spec/support/mocks/api_v2_json_samples.rb | 215 ++++++++++++++++++ .../_standard_response.json_jbuilder_spec.rb | 184 +++++++++++++++ .../contributors/_show.json.jbuilder_spec.rb | 90 ++++++++ .../v2/datasets/_show.json.jbuilder_spec.rb | 196 ++++++++++++++++ spec/views/api/v2/error.json.jbuilder_spec.rb | 29 +++ .../api/v2/heartbeat.json.jbuilder_spec.rb | 18 ++ .../identifiers/_show.json.jbuilder_spec.rb | 23 ++ .../api/v2/orgs/_show.json.jbuilder_spec.rb | 43 ++++ .../api/v2/plans/_cost.json.jbuilder_spec.rb | 37 +++ .../v2/plans/_funding.json.jbuilder_spec.rb | 58 +++++ .../v2/plans/_project.json.jbuilder_spec.rb | 33 +++ .../api/v2/plans/_show.json.jbuilder_spec.rb | 113 +++++++++ .../api/v2/plans/index.json.jbuilder_spec.rb | 25 ++ .../v2/templates/index.json.jbuilder_spec.rb | 78 +++++++ 22 files changed, 1541 insertions(+), 1 deletion(-) create mode 100644 spec/factories/oauth_access_grants.rb create mode 100644 spec/factories/oauth_access_tokens.rb create mode 100644 spec/factories/oauth_applications.rb create mode 100644 spec/requests/api/v2/plans_controller_spec.rb create mode 100644 spec/requests/api/v2/templates_controller_spec.rb create mode 100644 spec/support/mocks/api_v2_json_samples.rb create mode 100644 spec/views/api/v2/_standard_response.json_jbuilder_spec.rb create mode 100644 spec/views/api/v2/contributors/_show.json.jbuilder_spec.rb create mode 100644 spec/views/api/v2/datasets/_show.json.jbuilder_spec.rb create mode 100644 spec/views/api/v2/error.json.jbuilder_spec.rb create mode 100644 spec/views/api/v2/heartbeat.json.jbuilder_spec.rb create mode 100644 spec/views/api/v2/identifiers/_show.json.jbuilder_spec.rb create mode 100644 spec/views/api/v2/orgs/_show.json.jbuilder_spec.rb create mode 100644 spec/views/api/v2/plans/_cost.json.jbuilder_spec.rb create mode 100644 spec/views/api/v2/plans/_funding.json.jbuilder_spec.rb create mode 100644 spec/views/api/v2/plans/_project.json.jbuilder_spec.rb create mode 100644 spec/views/api/v2/plans/_show.json.jbuilder_spec.rb create mode 100644 spec/views/api/v2/plans/index.json.jbuilder_spec.rb create mode 100644 spec/views/api/v2/templates/index.json.jbuilder_spec.rb diff --git a/spec/factories/identifier_schemes.rb b/spec/factories/identifier_schemes.rb index 3e52d43b66..3e24252c61 100644 --- a/spec/factories/identifier_schemes.rb +++ b/spec/factories/identifier_schemes.rb @@ -32,5 +32,19 @@ identifier_scheme.update("#{identifier_scheme.all_context[idx]}": true) end end + + %i[ + authentication + orgs + plans + users + contributors + identification + research_outputs + ].each do |context| + trait :"for_#{context}" do + add_attribute(:"for_#{context}") { true } + end + end end end diff --git a/spec/factories/oauth_access_grants.rb b/spec/factories/oauth_access_grants.rb new file mode 100644 index 0000000000..2cd8dc8875 --- /dev/null +++ b/spec/factories/oauth_access_grants.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +# == Schema Information +# +# Table name: oauth_access_grants +# +# id :integer not null, primary key +# resource_owner_id :integer not null +# application_id :integer not null +# token :string not null +# expires_in :integer +# revoked_at :datetime +# created_at :datetime not null +# scopes :string not null +# +# Indexes +# +# index_oauth_access_grants_on_token (token) +# +# Foreign Keys +# +# fk_rails_... (resource_owner_id => users.id) +# fk_rails_... (application_id => oauth_applications.id) + +FactoryBot.define do + factory :oauth_access_grant, class: 'doorkeeper/access_grant' do + token { SecureRandom.uuid } + expires_in { Faker::Number.number(digits: 8) } + scopes { Doorkeeper.config.default_scopes + Doorkeeper.config.optional_scopes } + redirect_uri { Faker::Internet.url } + + trait :revoked do + revoked_at { 2.hours.ago } + end + end +end diff --git a/spec/factories/oauth_access_tokens.rb b/spec/factories/oauth_access_tokens.rb new file mode 100644 index 0000000000..aa94d6b373 --- /dev/null +++ b/spec/factories/oauth_access_tokens.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +# == Schema Information +# +# Table name: oauth_access_tokens +# +# id :integer not null, primary key +# resource_owner_id :integer not null +# application_id :integer not null +# token :string not null +# refresh_token :string +# expires_in :integer +# revoked_at :datetime +# created_at :datetime not null +# scopes :string not null +# previous_refresh_token :string +# +# Indexes +# +# index_oauth_access_tokens_on_token (token) +# +# Foreign Keys +# +# fk_rails_... (resource_owner_id => users.id) +# fk_rails_... (application_id => oauth_applications.id) + +FactoryBot.define do + factory :oauth_access_token, class: 'doorkeeper/access_token' do + token { SecureRandom.uuid } + refresh_token { SecureRandom.uuid } + expires_in { Faker::Number.number(digits: 8) } + scopes { Doorkeeper.config.default_scopes + Doorkeeper.config.optional_scopes } + + trait :revoked do + revoked_at { 2.hours.ago } + end + end +end diff --git a/spec/factories/oauth_applications.rb b/spec/factories/oauth_applications.rb new file mode 100644 index 0000000000..469dd66269 --- /dev/null +++ b/spec/factories/oauth_applications.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +# == Schema Information +# +# Table name: oauth_application +# +# id: :integer +# name: :string +# uid: :string +# secret: :string +# redirect_uri: :text +# scopes: :string +# confidential: :boolean +# created_at: :datetime +# updated_at: :datetime + +FactoryBot.define do + factory :oauth_application, class: 'doorkeeper/application' do + name { Faker::Lorem.unique.word } + uid { SecureRandom.uuid } + secret { SecureRandom.uuid } + redirect_uri { "https://#{Faker::Internet.unique.domain_name}/callback" } + scopes { 'read' } + end +end diff --git a/spec/factories/research_domains.rb b/spec/factories/research_domains.rb index 7d4017f924..23049903be 100644 --- a/spec/factories/research_domains.rb +++ b/spec/factories/research_domains.rb @@ -23,6 +23,5 @@ factory :research_domain do identifier { SecureRandom.uuid } label { Faker::Lorem.unique.word } - uri { Faker::Internet.url } end end diff --git a/spec/requests/api/v2/plans_controller_spec.rb b/spec/requests/api/v2/plans_controller_spec.rb new file mode 100644 index 0000000000..bd951e42be --- /dev/null +++ b/spec/requests/api/v2/plans_controller_spec.rb @@ -0,0 +1,126 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Api::V2::PlansController do + include ApiHelper + include Mocks::ApiV2JsonSamples + include Webmocks + include IdentifierHelper + + context 'OAuth (authorization_code grant type) — on behalf of a user' do + before do + @user = create(:user) + @client = create(:oauth_application) + token = mock_authorization_code_token(oauth_application: @client, user: @user).token + + @headers = { + Accept: 'application/json', + 'Content-Type': 'application/json', + Authorization: "Bearer #{token}" + } + end + + def fetch_plans_json_response + get(api_v2_plans_path, headers: @headers) + expect(response).to render_template('api/v2/_standard_response') + expect(response).to render_template('api/v2/plans/index') + JSON.parse(response.body).with_indifferent_access + end + + describe 'GET /api/v2/plans (index)' do + context 'an invalid API token is included' do + it 'returns a 401 and the expected Oauth 2.0 headers' do + # Swap actual token with a random string + @headers['Authorization'] = "Bearer #{SecureRandom.uuid}" + get(api_v2_plans_path, headers: @headers) + + expect(response.code).to eql('401') + expect(response.body).to be_empty + + # Expect Doorkeeper to return the standard OAuth 2.0 WWW-Authenticate header for invalid tokens + expect(response.headers['WWW-Authenticate']).to match( + /Bearer realm="Doorkeeper", error="invalid_token", error_description="The access token is invalid"/ + ) + end + end + + context 'a valid API token is included' do + let(:json) { fetch_plans_json_response } + it 'returns a 200 and the expected response body' do + # Items array is empty + expect(json[:items]).to eq([]) + + # total_items reflects that nothing is returned + expect(json[:total_items]).to eq(0) + + # Status code and message are correct + expect(json[:code]).to eq(200) + expect(json[:message]).to eq('OK') + + # Application and source are present and sensible + expect(json[:application]).to eq(ApplicationService.application_name) + expect(json[:source]).to eq('GET /api/v2/plans') + + # Time is present and parseable + expect { Time.iso8601(json[:time]) }.not_to raise_error + + # Caller is included + expect(json[:caller]).to eq(@client.name) + end + + it 'returns an empty array if no plans are available' do + # Items array is empty + expect(json[:items]).to eq([]) + + # total_items reflects that nothing is returned + expect(json[:total_items]).to eq(0) + end + + it 'returns the expected plans' do + # See `app/policies/api/v2/plans_policy.rb for plans included/excluded via `GET api/v2/plans` + + # Create the included plans + included_plans = [create(:plan, org: @user.org), create(:plan)] + included_plans[0].add_user!(@user.id, :creator) + # Add multiple roles for testing (ensure duplicate plans will not returned) + included_plans[1].add_user!(@user.id, :editor) + included_plans[1].add_user!(@user.id, :commenter) + + # Created the excluded plans + create(:plan, :creator, org: @user.org) + inactive_plan = create(:plan, :creator) + inactive_plan.add_user!(@user.id, :editor) + Role.where(plan_id: inactive_plan.id, user_id: @user.id).update!(active: false) + + expect(json[:items].length).to be(included_plans.length) + + # Api::V2::PlanPresenter.identifier uses api_v2_plan_url(@plan) to set the "identifier". + # That url is constructed using `request.host` / "www.example.com" + # api_v2_plan_url(@plan) within this test will construct the url via + # default_url_options[:host] / "example.org" + # Because the urls are misaligned, we will only compare the paths here. + # TODO: Consider aligning default_url_options[:host] (in test.rb) with `request.host` + returned_identifiers = json[:items].map { |item| item[:dmp][:dmp_id][:identifier] } + returned_paths = returned_identifiers.map { |url| URI(url).path } + expected_paths = included_plans.map { |plan| api_v2_plan_path(plan) } + expect(returned_paths).to eq(expected_paths) + end + + it 'allows for paging' do + original_page_size = Rails.configuration.x.application.api_max_page_size + Rails.configuration.x.application.api_max_page_size = 10 + + create_list(:plan, 11, :publicly_visible) do |plan| + plan.add_user!(@user.id, :commenter) + end + json = fetch_plans_json_response + + test_paging(json: json, headers: @headers) + + Rails.configuration.x.application.api_max_page_size = original_page_size + end + end + end + end +end diff --git a/spec/requests/api/v2/templates_controller_spec.rb b/spec/requests/api/v2/templates_controller_spec.rb new file mode 100644 index 0000000000..6b447d33a0 --- /dev/null +++ b/spec/requests/api/v2/templates_controller_spec.rb @@ -0,0 +1,120 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Api::V2::TemplatesController do + include ApiHelper + + before do + @user = create(:user) + @client = create(:oauth_application) + token = mock_authorization_code_token(oauth_application: @client, user: @user).token + + @headers = { + Accept: 'application/json', + 'Content-Type': 'application/json', + Authorization: "Bearer #{token}" + } + end + + def fetch_templates_json_response + get(api_v2_templates_path, headers: @headers) + expect(response).to render_template('api/v2/_standard_response') + expect(response).to render_template('api/v2/templates/index') + JSON.parse(response.body).with_indifferent_access + end + + describe 'GET /api/v2/templates (index)' do + context 'an invalid API token is included' do + it 'returns 401 if the token is invalid' do + @headers['Authorization'] = "Bearer #{SecureRandom.uuid}" + get(api_v2_templates_path, headers: @headers) + + expect(response.code).to eql('401') + expect(response.body).to be_empty + + # Expect Doorkeeper to return the standard OAuth 2.0 WWW-Authenticate header for invalid tokens + expect(response.headers['WWW-Authenticate']).to match( + /Bearer realm="Doorkeeper", error="invalid_token", error_description="The access token is invalid"/ + ) + end + end + + context 'a valid API token is included' do + it 'returns a 200 and the expected response body' do + json = fetch_templates_json_response + + # Items array is empty + expect(json[:items]).to eq([]) + + # total_items reflects that nothing is returned + expect(json[:total_items]).to eq(0) + + # Status code and message are correct + expect(json[:code]).to eq(200) + expect(json[:message]).to eq('OK') + + # Application and source are present and sensible + expect(json[:application]).to eq(ApplicationService.application_name) + expect(json[:source]).to eq('GET /api/v2/templates') + + # Time is present and parseable + expect { Time.iso8601(json[:time]) }.not_to raise_error + + # Caller is included + expect(json[:caller]).to eq(@client.name) + end + + it 'returns an empty array if no templates are available' do + get(api_v2_templates_path, headers: @headers) + + expect(response.code).to eql('200') + expect(response).to render_template('api/v2/_standard_response') + expect(response).to render_template('api/v2/templates/index') + + json = JSON.parse(response.body).with_indifferent_access + expect(json[:items].empty?).to be(true) + expect(json[:errors].nil?).to be(true) + end + + it 'returns the expected templates' do + # See `app/policies/api/v2/templates_policy.rb for templates included/excluded via `GET api/v2/templates` + + # All included templates must be published and are either: + # - 1) organisationally_visible and template.org_id == user.org_id + # - 2) publicly_visible and customization of == nil + + public_template = create(:template, :publicly_visible, published: true) + + included_templates = [ + public_template, + create(:template, :organisationally_visible, published: true, org: @user.org) + ] + + # excluded_templates + # unpublished template + create(:template, :publicly_visible, published: false, org: @user.org) + # organisationally_visible and template.org_id != user.org_id + create(:template, :organisationally_visible, published: true) + # publicly_visible and customization of != nil + create(:template, :publicly_visible, published: true, customization_of: public_template.family_id) + + json = fetch_templates_json_response + + expect(json[:items].length).to be(2) + template_ids = json[:items].map { |item| item[:dmp_template][:template_id][:identifier] } + expect(template_ids).to match_array(included_templates.map { |t| t.id.to_s }) + end + + it 'allows for paging' do + original_page_size = Rails.configuration.x.application.api_max_page_size + Rails.configuration.x.application.api_max_page_size = 10 + create_list(:template, 11, visibility: 1, published: true) + get(api_v2_templates_path, headers: @headers) + + test_paging(json: JSON.parse(response.body), headers: @headers) + Rails.configuration.x.application.api_max_page_size = original_page_size + end + end + end +end diff --git a/spec/support/helpers/api.rb b/spec/support/helpers/api.rb index c87931c12e..2a2398dfe7 100644 --- a/spec/support/helpers/api.rb +++ b/spec/support/helpers/api.rb @@ -18,4 +18,44 @@ def mock_authorization_for_user(user: nil) Api::V1::BaseApiController.any_instance.stubs(:authorize_request).returns(true) Api::V1::BaseApiController.any_instance.stubs(:client).returns(user) end + + # API V2+ - Oauth authorization_code grant flow (on behalf of a user) + def mock_authorization_code_token(oauth_application: create(:oauth_application), user: create(:user), + scopes: 'read') + create(:oauth_access_grant, application_id: oauth_application.id, resource_owner_id: user.id, scopes: scopes) + create(:oauth_access_token, application: oauth_application, resource_owner_id: user.id, scopes: scopes) + end + + # Tests the standard pagination functionality + # rubocop:disable Metrics/AbcSize, Metrics/MethodLength + def test_paging(json: {}, headers: {}) + json = json.with_indifferent_access + original = json[:items].first + if json[:next].present? + # Move to the next page + get(json[:next], headers: headers) + expect(response.code).to eql('200') + next_json = JSON.parse(response.body).with_indifferent_access + expect(next_json[:prev].present?).to be(true) + expect(next_json[:items].first).not_to eql(original) + # Move back to previous page + get(next_json[:prev], headers: headers) + expect(response.code).to eql('200') + prev_json = JSON.parse(response.body).with_indifferent_access + expect(prev_json[:items].first).to eql(original) + elsif json[:prev].present? + get(json[:prev], headers: headers) + expect(response.code).to eql('200') + prev_json = JSON.parse(response.body).with_indifferent_access + expect(prev_json[:next].present?).to be(true) + expect(next_json[:items].first).not_to eql(original) + get(prev_json[:next], headers: headers) + expect(response.code).to eql('200') + next_json = JSON.parse(response.body).with_indifferent_access + expect(next_json[:items].first).to eql(original) + else + raise StandardError, 'Expected to test API pagination but there are not enough items!' + end + end + # rubocop:enable Metrics/AbcSize, Metrics/MethodLength end diff --git a/spec/support/mocks/api_v2_json_samples.rb b/spec/support/mocks/api_v2_json_samples.rb new file mode 100644 index 0000000000..aaec320811 --- /dev/null +++ b/spec/support/mocks/api_v2_json_samples.rb @@ -0,0 +1,215 @@ +# frozen_string_literal: true + +# Mock JSON submissions +module Mocks + # Disabling rubocop checks here since its basically just large hashes and + # would be difficult to read if broken up into multiple smaller functions. + # One option might be to store them as .json files and then just load them here + # but we would lose the use of Faker + + # rubocop:disable Metrics/ModuleLength, Metrics/MethodLength + module ApiV2JsonSamples + ROLES = %w[Investigation Project_administration Data_curation].freeze + + def mock_identifier_schemes + create(:identifier_scheme, name: 'ror') + create(:identifier_scheme, name: 'fundref') + create(:identifier_scheme, name: 'orcid') + create(:identifier_scheme, name: 'grant') + end + + def minimal_update_json + { + total_items: 1, + items: [ + { + dmp: { + title: Faker::Lorem.sentence, + contact: { + mbox: Faker::Internet.email, + affiliation: { name: Faker::Movies::StarWars.planet } + }, + dataset: [{ + title: Faker::Lorem.sentence + }], + dmp_id: { + type: 'doi', + identifier: SecureRandom.uuid + } + } + } + ] + }.to_json + end + + def minimal_create_json + { + dmp: { + title: Faker::Lorem.sentence, + contact: { + mbox: Faker::Internet.email, + affiliation: { name: Faker::Movies::StarWars.planet } + }, + dataset: [{ + title: Faker::Lorem.sentence + }], + extension: [ + "#{ApplicationService.application_name.split('-').first}": { + template: { + id: Template.last.id, + title: Faker::Lorem.sentence + } + } + ] + } + }.to_json + end + + # rubocop:disable Metrics/AbcSize + def complete_create_json(client: nil) + template = create(:template, :published, :publicly_visible) + lang = Language.all.pluck(:abbreviation).sample || 'en-UK' + ror_scheme = IdentifierScheme.find_or_create_by(name: 'ror') + fundref_scheme = IdentifierScheme.find_or_create_by(name: 'fundref') + ror = create(:identifier, identifiable: create(:org), identifier_scheme: ror_scheme) + fundref = create(:identifier, identifiable: create(:org), identifier_scheme: fundref_scheme) + + contact = { + name: [ + Faker::TvShows::Simpsons.character.split.first, + Faker::TvShows::Simpsons.character.split.last + ].join(' '), + email: Faker::Internet.email, + id: SecureRandom.uuid + } + + { + dmp: { + created: 3.months.ago.to_formatted_s(:iso8601), + title: Faker::Lorem.sentence, + description: Faker::Lorem.paragraph, + language: Api::V1::LanguagePresenter.three_char_code(lang: lang), + ethical_issues_exist: %w[yes no unknown].sample, + ethical_issues_description: Faker::Lorem.paragraph, + ethical_issues_report: Faker::Internet.url, + dmp_id: { + type: client.present? ? client.name.downcase : 'other', + identifier: SecureRandom.uuid + }, + contact: { + name: contact[:name], + mbox: contact[:email], + affiliation: { + name: ror.identifiable.name, + abbreviation: ror.identifiable.abbreviation, + region: Faker::Space.planet, + affiliation_id: { + type: 'ror', + identifier: ror.value + } + }, + contact_id: { + type: 'orcid', + identifier: contact[:id] + } + }, + contributor: [{ + role: [ + 'http://credit.niso.org/contributor-roles/project-administration', + 'http://credit.niso.org/contributor-roles/investigation', + 'other' + ], + name: Faker::Movies::StarWars.character, + mbox: Faker::Internet.email, + affiliation: { + name: Faker::Movies::StarWars.planet, + abbreviation: Faker::Lorem.word.upcase, + affiliation_id: { + type: 'ror', + identifier: SecureRandom.uuid + } + }, + contributor_id: { + type: 'orcid', + identifier: SecureRandom.uuid + } + }, { + role: [ + 'http://credit.niso.org/contributor-roles/investigation' + ], + name: contact[:name], + mbox: contact[:email], + affiliation: { + name: ror.identifiable.name, + abbreviation: ror.identifiable.abbreviation, + affiliation_id: { + type: 'ror', + identifier: ror.value + } + }, + contributor_id: { + type: 'orcid', + identifier: contact[:id] + } + }], + project: [{ + title: Faker::Lorem.sentence, + description: Faker::Lorem.paragraph, + start: 3.months.from_now.to_formatted_s(:iso8601), + end: 2.years.from_now.to_formatted_s(:iso8601), + funding: [{ + name: fundref.identifiable.name, + funder_id: { + type: 'fundref', + identifier: fundref.value + }, + grant_id: { + type: 'other', + identifier: SecureRandom.uuid + }, + dmproadmap_funding_opportunity_id: { + type: 'other', + identifier: SecureRandom.uuid + }, + funding_status: %w[planned rejected granted].sample + }] + }], + dataset: [{ + title: Faker::Lorem.sentence, + description: Faker::Lorem.paragraph, + personal_data: %w[yes no unknown].sample, + sensitive_data: %w[yes no unknown].sample, + issued: 6.months.from_now.to_formatted_s(:iso8601), + dataset_id: { + type: 'url', + identifier: Faker::Internet.url + }, + distribution: [{ + title: Faker::Lorem.sentence, + byte_size: Faker::Number.number(digits: 6), + data_access: %w[open embargoed restricted closed].sample, + host: { + title: Faker::Company.name, + description: Faker::Lorem.paragraph, + url: Faker::Internet.url, + dmproadmap_host_id: { + type: 'url', + identifier: Faker::Internet.url + } + }, + license: [ + { + license_ref: 'http://spdx.org/licenses/CC0-1.0.json', + start_date: 6.months.from_now.to_formatted_s(:iso8601) + } + ] + }] + }], + dmproadmap_template: { id: template.family_id, title: template.title } + } + }.to_json + end + # rubocop:enable Metrics/AbcSize + end + # rubocop:enable Metrics/ModuleLength, Metrics/MethodLength +end diff --git a/spec/views/api/v2/_standard_response.json_jbuilder_spec.rb b/spec/views/api/v2/_standard_response.json_jbuilder_spec.rb new file mode 100644 index 0000000000..2758d51d22 --- /dev/null +++ b/spec/views/api/v2/_standard_response.json_jbuilder_spec.rb @@ -0,0 +1,184 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'api/v2/_standard_response.json.jbuilder' do + before do + @application = Faker::Lorem.word + # @caller = Faker::Lorem.word + @url = Faker::Internet.url + @code = 200 + + assign :application, @application + # assign :caller, @caller + + @response = OpenStruct.new(status: @code) + @request = Net::HTTPGenericRequest.new('GET', nil, nil, @url) + end + + describe 'standard response items - Also the same as: GET /heartbeat' do + before do + render partial: 'api/v2/standard_response', + locals: { response: @response, request: @request } + @json = JSON.parse(rendered).with_indifferent_access + end + + it 'includes the :code' do + expect(@json[:code]).to eql(@code) + end + + it 'includes the :message' do + expect(@json[:message]).to eql(Rack::Utils::HTTP_STATUS_CODES[@code]) + end + + it 'includes the :time' do + expect(@json[:time].present?).to be(true) + end + + it ':time is in UTC format' do + expect(Date.parse(@json[:time]).is_a?(Date)).to be(true) + end + + # it 'includes the :caller' do + # expect(@json[:caller]).to eql(@caller) + # end + + it 'includes the :source' do + expect(@json[:source].include?(@url)).to be(true) + end + + it 'includes the :total_items' do + expect(@json[:total_items]).to be(0) + end + end + + context 'responses with pagination' do + describe 'On the 1st page and there is only one page' do + before do + assign :page, 1 + assign :per_page, 3 + + render partial: 'api/v2/standard_response', + locals: { response: @response, request: @request, + total_items: 3 } + @json = JSON.parse(rendered).with_indifferent_access + end + + it 'shows the correct page number' do + expect(@json[:page]).to be(1) + end + + it 'includes the per_page number' do + expect(@json[:per_page]).to be(3) + end + + it 'includes the :total_items' do + expect(@json[:total_items]).to be(3) + end + + it "does not show a 'prev' page link" do + expect(@json[:prev].present?).to be(false) + end + + it "does not show a 'next' page link" do + expect(@json[:prev].present?).to be(false) + end + end + + describe 'On the 1st page and there multiple pages' do + before do + assign :page, 1 + assign :per_page, 3 + + render partial: 'api/v2/standard_response', + locals: { response: @response, request: @request, + total_items: 4 } + @json = JSON.parse(rendered).with_indifferent_access + end + + it 'shows the correct page number' do + expect(@json[:page]).to be(1) + end + + it 'includes the per_page number' do + expect(@json[:per_page]).to be(3) + end + + it 'includes the :total_items' do + expect(@json[:total_items]).to be(4) + end + + it "does not show a 'prev' page link" do + expect(@json[:prev].present?).to be(false) + end + + it "does not show a 'next' page link" do + expect(@json[:next].present?).to be(true) + end + end + + describe 'On the 2nd page and there more than 2 pages' do + before do + assign :page, 2 + assign :per_page, 3 + + render partial: 'api/v2/standard_response', + locals: { response: @response, request: @request, + total_items: 7 } + @json = JSON.parse(rendered).with_indifferent_access + end + + it 'shows the correct page number' do + expect(@json[:page]).to be(2) + end + + it 'includes the per_page number' do + expect(@json[:per_page]).to be(3) + end + + it 'includes the :total_items' do + expect(@json[:total_items]).to be(7) + end + + it "does not show a 'prev' page link" do + expect(@json[:prev].present?).to be(true) + end + + it "does not show a 'next' page link" do + expect(@json[:next].present?).to be(true) + end + end + + describe 'On the last page' do + before do + assign :page, 2 + assign :per_page, 3 + + render partial: 'api/v2/standard_response', + locals: { response: @response, request: @request, + total_items: 5 } + @json = JSON.parse(rendered).with_indifferent_access + end + + it 'shows the correct page number' do + expect(@json[:page]).to be(2) + end + + it 'includes the per_page number' do + expect(@json[:per_page]).to be(3) + end + + it 'includes the :total_items' do + expect(@json[:total_items]).to be(5) + end + + it "does not show a 'prev' page link" do + expect(@json[:prev].present?).to be(true) + end + + it "does not show a 'next' page link" do + expect(@json[:next].present?).to be(false) + end + end + end +end diff --git a/spec/views/api/v2/contributors/_show.json.jbuilder_spec.rb b/spec/views/api/v2/contributors/_show.json.jbuilder_spec.rb new file mode 100644 index 0000000000..c2652decaf --- /dev/null +++ b/spec/views/api/v2/contributors/_show.json.jbuilder_spec.rb @@ -0,0 +1,90 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'api/v2/contributors/_show.json.jbuilder' do + before do + @plan = create(:plan) + scheme = create(:identifier_scheme, name: 'orcid') + @contact = create(:contributor, org: create(:org), plan: @plan, roles_count: 0, + data_curation: true) + @ident = create(:identifier, identifiable: @contact, value: Faker::Lorem.word, + identifier_scheme: scheme) + @contact.reload + end + + describe 'includes all of the Contributor attributes' do + before do + render partial: 'api/v2/contributors/show', locals: { contributor: @contact } + @json = JSON.parse(rendered).with_indifferent_access + end + + it 'includes the :name' do + expect(@json[:name]).to eql(@contact.name) + end + + it 'includes the :mbox' do + expect(@json[:mbox]).to eql(@contact.email) + end + + it 'includes the :role' do + expect(@json[:role].first.ends_with?('data-curation')).to be(true) + end + + it 'includes :affiliation' do + expect(@json[:affiliation][:name]).to eql(@contact.org.name) + end + + it 'includes :contributor_id' do + expect(@json[:contributor_id][:type]).to eql(@ident.identifier_format) + expect(@json[:contributor_id][:identifier]).to eql(@ident.value) + end + + it 'ignores non-orcid identifiers :contributor_id' do + scheme = create(:identifier_scheme, name: 'shibboleth') + create(:identifier, value: Faker::Lorem.word, identifiable: @contact, + identifier_scheme: scheme) + @contact.reload + expect(@json[:contributor_id][:type]).to eql(@ident.identifier_format) + expect(@json[:contributor_id][:identifier]).to eql(@ident.value) + end + end + + describe 'includes all of the Contact attributes' do + before do + render partial: 'api/v2/contributors/show', locals: { contributor: @contact, + is_contact: true } + @json = JSON.parse(rendered).with_indifferent_access + end + + it 'includes the :name' do + expect(@json[:name]).to eql(@contact.name) + end + + it 'includes the :mbox' do + expect(@json[:mbox]).to eql(@contact.email) + end + + it 'does NOT include the :role' do + expect(@json[:role]).to be_nil + end + + it 'includes :affiliation' do + expect(@json[:affiliation][:name]).to eql(@contact.org.name) + end + + it 'includes :contact_id' do + expect(@json[:contact_id][:type]).to eql(@ident.identifier_format) + expect(@json[:contact_id][:identifier]).to eql(@ident.value) + end + + it 'ignores non-orcid identifiers :contact_id' do + scheme = create(:identifier_scheme, name: 'shibboleth') + create(:identifier, value: Faker::Lorem.word, identifiable: @contact, + identifier_scheme: scheme) + @contact.reload + expect(@json[:contact_id][:type]).to eql(@ident.identifier_format) + expect(@json[:contact_id][:identifier]).to eql(@ident.value) + end + end +end diff --git a/spec/views/api/v2/datasets/_show.json.jbuilder_spec.rb b/spec/views/api/v2/datasets/_show.json.jbuilder_spec.rb new file mode 100644 index 0000000000..fc1b7d4e7b --- /dev/null +++ b/spec/views/api/v2/datasets/_show.json.jbuilder_spec.rb @@ -0,0 +1,196 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'api/v2/datasets/_show.json.jbuilder' do + context ':output is a ResearchOutput' do + describe 'includes all of the dataset attributes' do + before do + @research_output = create(:research_output, plan: create(:plan)) + @presenter = Api::V2::ResearchOutputPresenter.new(output: @research_output) + end + + describe 'base :dataset attributes' do + before do + render partial: 'api/v2/datasets/show', locals: { output: @research_output } + @json = JSON.parse(rendered).with_indifferent_access + end + + it 'includes :type' do + expect(@json[:type]).to eql(@research_output.output_type) + end + + it 'includes :title' do + expect(@json[:title]).to eql(@research_output.title) + end + + it 'includes :description' do + expect(@json[:description]).to eql(@research_output.description) + end + + it 'includes :personal_data' do + val = Api::V2::ApiPresenter.boolean_to_yes_no_unknown(value: @research_output.personal_data) + expect(@json[:personal_data]).to eql(val) + end + + it 'includes :sensitive_data' do + val = Api::V2::ApiPresenter.boolean_to_yes_no_unknown(value: @research_output.sensitive_data) + expect(@json[:sensitive_data]).to eql(val) + end + + it 'includes :issued' do + expect(@json[:issued]).to eql(@research_output.release_date.to_formatted_s(:iso8601)) + end + + it 'includes :preservation_statement' do + expect(@json[:preservation_statement]).to eql(@presenter.preservation_statement) + end + + it 'includes :security_and_privacy' do + expect(@json[:security_and_privacy]).to eql(@presenter.security_and_privacy) + end + + it 'includes :data_quality_assurance' do + expect(@json[:data_quality_assurance]).to eql(@presenter.data_quality_assurance) + end + end + + describe ':distribution' do + before do + @repo = @research_output.repositories.first + @license = create(:license) + @research_output.license_id = @license.id + + render partial: 'api/v2/datasets/show', locals: { output: @research_output } + @json = JSON.parse(rendered).with_indifferent_access + end + + it 'includes :distributions' do + expect(@json[:distribution].any?).to be(true) + end + + it 'includes :title' do + expected = "Anticipated distribution for #{@research_output.title}" + expect(@json[:distribution].first[:title]).to eql(expected) + end + + it 'includes :byte_size' do + expect(@json[:distribution].first[:byte_size]).to eql(@research_output.byte_size) + end + + it 'includes :data_access' do + expect(@json[:distribution].first[:data_access]).to eql(@research_output.access) + end + + it 'includes host[:title]' do + expect(@json[:distribution].first[:host][:title]).to eql(@repo.name) + end + + it 'includes host[:description]' do + expect(@json[:distribution].first[:host][:description]).to eql(@repo.description) + end + + it 'includes host[:url]' do + expect(@json[:distribution].first[:host][:url]).to eql(@repo.homepage) + end + + it 'includes host[:dmproadmap_host_id]' do + result = @json[:distribution].first[:host][:dmproadmap_host_id][:identifier] + expect(result).to eql(@repo.uri) + end + + it 'includes license[:license_ref]' do + expect(@json[:distribution].first[:license].first[:license_ref]).to eql(@license.uri) + end + + it 'includes license[:start_date]' do + expected = @research_output.release_date.to_formatted_s(:iso8601) + expect(@json[:distribution].first[:license].first[:start_date]).to eql(expected) + end + end + + describe ':metadata' do + before do + @standard = create(:metadata_standard) + @research_output.metadata_standards << @standard + + render partial: 'api/v2/datasets/show', locals: { output: @research_output } + @json = JSON.parse(rendered).with_indifferent_access + end + + it 'includes :metadata' do + expect(@json[:metadata].any?).to be(true) + end + + it 'includes :description' do + uri = @standard.uri + metadata = @json[:metadata].select { |ms| ms[:metadata_standard_id][:identifier] == uri } + expected = "#{@standard.title} - #{@standard.description}" + expect(metadata.first[:description].start_with?(expected)).to be(true) + expect(metadata.first[:metadata_standard_id].present?).to be(true) + expect(metadata.first[:metadata_standard_id][:type]).to eql('url') + expect(metadata.first[:metadata_standard_id][:identifier]).to eql(uri) + end + end + + describe ':technical_resources' do + it 'is always an empty array because this has not been implemented' do + render partial: 'api/v2/datasets/show', locals: { output: @research_output } + @json = JSON.parse(rendered).with_indifferent_access + expect(@json[:technical_resource].any?).to be(false) + end + end + + describe ':keyword' do + it 'includes the ResearchDomain' do + research_domain = create(:research_domain) + @research_output.plan.research_domain_id = research_domain.id + render partial: 'api/v2/datasets/show', locals: { output: @research_output } + @json = JSON.parse(rendered).with_indifferent_access + expect(@json[:keyword].any?).to be(true) + expect(@json[:keyword].include?(research_domain.label)) + expect(@json[:keyword].include?("#{research_domain.identifier} - #{research_domain.label}")) + end + + it 'is not included if no ResearchDomain is defined' do + render partial: 'api/v2/datasets/show', locals: { output: @research_output } + @json = JSON.parse(rendered).with_indifferent_access + expect(@json[:keyword].present?).to be(false) + end + end + end + end + + context ':output is a Plan' do + describe 'includes all of the dataset attributes' do + before do + @plan = create(:plan) + @research_domain = create(:research_domain) + @plan.research_domain_id = @research_domain.id + + render partial: 'api/v2/datasets/show', locals: { output: @plan } + @json = JSON.parse(rendered).with_indifferent_access + end + + it 'includes :type' do + expect(@json[:type]).to eql('dataset') + end + + it 'includes :title' do + expect(@json[:title]).to eql('Generic dataset') + end + + it 'includes :description' do + expect(@json[:description]).to eql('No individual datasets have been defined for this DMP.') + end + + describe ':keyword' do + it 'includes the ResearchDomain' do + expect(@json[:keyword].any?).to be(true) + expect(@json[:keyword].include?(@research_domain.label)) + expect(@json[:keyword].include?("#{@research_domain.identifier} - #{@research_domain.label}")) + end + end + end + end +end diff --git a/spec/views/api/v2/error.json.jbuilder_spec.rb b/spec/views/api/v2/error.json.jbuilder_spec.rb new file mode 100644 index 0000000000..ca2337ff6d --- /dev/null +++ b/spec/views/api/v2/error.json.jbuilder_spec.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'api/v2/error.json.jbuilder' do + before do + @url = Faker::Internet.url + @code = [200, 400, 404, 500].sample + @errors = [Faker::Lorem.sentence, Faker::Lorem.sentence] + + assign :payload, { message: @errors } + + @resp = OpenStruct.new(status: @code) + @req = Net::HTTPGenericRequest.new('GET', nil, nil, @url) + + render template: 'api/v2/error', locals: { response: @resp, request: @req } + @json = JSON.parse(rendered).with_indifferent_access + end + + describe 'error responses from controllers' do + it 'renders the standard_response partial' do + expect(response).to render_template(partial: 'api/v2/_standard_response') + end + + it ':errors contains an array of error messages' do + expect(@json[:message]).to eql(@errors) + end + end +end diff --git a/spec/views/api/v2/heartbeat.json.jbuilder_spec.rb b/spec/views/api/v2/heartbeat.json.jbuilder_spec.rb new file mode 100644 index 0000000000..1808117b19 --- /dev/null +++ b/spec/views/api/v2/heartbeat.json.jbuilder_spec.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'api/v2/heartbeat.json.jbuilder' do + before do + render template: 'api/v2/heartbeat', locals: { response: @resp, request: @req } + @json = JSON.parse(rendered).with_indifferent_access + end + + it 'renders the _standard_response template' do + expect(response).to render_template('api/v2/_standard_response') + end + + it ':items array to be empty' do + expect(@json[:items]).to eql([]) + end +end diff --git a/spec/views/api/v2/identifiers/_show.json.jbuilder_spec.rb b/spec/views/api/v2/identifiers/_show.json.jbuilder_spec.rb new file mode 100644 index 0000000000..602169fd75 --- /dev/null +++ b/spec/views/api/v2/identifiers/_show.json.jbuilder_spec.rb @@ -0,0 +1,23 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'api/v2/identifiers/_show.json.jbuilder' do + before do + @scheme = create(:identifier_scheme) + @identifier = create(:identifier, value: Faker::Lorem.word, + identifier_scheme: @scheme) + render partial: 'api/v2/identifiers/show', locals: { identifier: @identifier } + @json = JSON.parse(rendered).with_indifferent_access + end + + describe 'includes all of the identifier attributes' do + it 'includes :type' do + expect(@json[:type]).to eql(@identifier.identifier_format) + end + + it 'includes :identifier' do + expect(@json[:identifier]).to eql(@identifier.value) + end + end +end diff --git a/spec/views/api/v2/orgs/_show.json.jbuilder_spec.rb b/spec/views/api/v2/orgs/_show.json.jbuilder_spec.rb new file mode 100644 index 0000000000..5480ae0ee1 --- /dev/null +++ b/spec/views/api/v2/orgs/_show.json.jbuilder_spec.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'api/v2/orgs/_show.json.jbuilder' do + before do + scheme = create(:identifier_scheme, name: 'ror') + @org = create(:org) + @ident = create(:identifier, value: Faker::Lorem.word, identifiable: @org, + identifier_scheme: scheme) + @org.reload + render partial: 'api/v2/orgs/show', locals: { org: @org } + @json = JSON.parse(rendered).with_indifferent_access + end + + describe 'includes all of the org attributes' do + it 'includes :name' do + expect(@json[:name]).to eql(@org.name) + end + + it 'includes :abbreviation' do + expect(@json[:abbreviation]).to eql(@org.abbreviation) + end + + it 'includes :region' do + expect(@json[:region]).to eql(@org.region.abbreviation) + end + + it 'includes :affiliation_id' do + expect(@json[:affiliation_id][:type]).to eql(@ident.identifier_format) + expect(@json[:affiliation_id][:identifier]).to eql(@ident.value) + end + + it 'uses the ROR over the FundRef :affiliation_id' do + scheme = create(:identifier_scheme, name: 'fundref') + create(:identifier, value: Faker::Lorem.word, identifiable: @org, + identifier_scheme: scheme) + @org.reload + expect(@json[:affiliation_id][:type]).to eql(@ident.identifier_format) + expect(@json[:affiliation_id][:identifier]).to eql(@ident.value) + end + end +end diff --git a/spec/views/api/v2/plans/_cost.json.jbuilder_spec.rb b/spec/views/api/v2/plans/_cost.json.jbuilder_spec.rb new file mode 100644 index 0000000000..712e9300e9 --- /dev/null +++ b/spec/views/api/v2/plans/_cost.json.jbuilder_spec.rb @@ -0,0 +1,37 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'api/v2/plans/_cost.json.jbuilder' do + before do + # TODO: Implement this once the Currency question and Cost theme are in place + # and the PlanPresenter is extracting the info + @cost = { + title: Faker::Lorem.sentence, + description: Faker::Lorem.paragraph, + currency_code: Faker::Currency.code, + value: Faker::Number.decimal(l_digits: 2) + }.with_indifferent_access + + render partial: 'api/v2/plans/cost', locals: { cost: @cost } + @json = JSON.parse(rendered).with_indifferent_access + end + + describe 'includes all of the cost attributes' do + it 'includes :title' do + expect(@json[:title]).to eql(@cost[:title]) + end + + it 'includes :description' do + expect(@json[:description]).to eql(@cost[:description]) + end + + it 'includes :currency_code' do + expect(@json[:currency_code]).to eql(@cost[:currency_code]) + end + + it 'includes :value' do + expect(@json[:value]).to eql(@cost[:value]) + end + end +end diff --git a/spec/views/api/v2/plans/_funding.json.jbuilder_spec.rb b/spec/views/api/v2/plans/_funding.json.jbuilder_spec.rb new file mode 100644 index 0000000000..e764e142b3 --- /dev/null +++ b/spec/views/api/v2/plans/_funding.json.jbuilder_spec.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'api/v2/plans/_funding.json.jbuilder' do + before do + @funder = create(:org, :funder) + create(:identifier, identifiable: @funder, + identifier_scheme: create(:identifier_scheme, name: 'fundref')) + @funder.reload + @plan = create(:plan, funder: @funder, org: create(:org), identifier: SecureRandom.uuid) + create(:identifier, identifiable: @plan.org, + identifier_scheme: create(:identifier_scheme, name: 'ror')) + @grant = create(:identifier, identifiable: @plan) + @plan.update(grant_id: @grant.id, funding_status: 'funded') + @plan.reload + + render partial: 'api/v2/plans/funding', locals: { plan: @plan } + @json = JSON.parse(rendered).with_indifferent_access + end + + describe 'includes all of the funding attributes' do + it 'includes :name' do + expect(@json[:name]).to eql(@funder.name) + end + + it 'includes :funding_status' do + expected = Api::V1::FundingPresenter.status(plan: @plan) + expect(@json[:funding_status]).to eql(expected) + end + + it 'includes :funder_ids' do + id = @funder.identifiers.first + expect(@json[:funder_id][:type]).to eql(id.identifier_format) + expect(@json[:funder_id][:identifier]).to eql(id.value) + end + + it 'includes :dmproadmap_funding_opportunity_identifier' do + identifier = @plan.identifier + expect(@json[:dmproadmap_funding_opportunity_id][:type]).to eql('other') + expect(@json[:dmproadmap_funding_opportunity_id][:identifier]).to eql(identifier) + end + + it 'includes :grant_ids' do + expect(@json[:grant_id][:type]).to eql(@grant.identifier_format) + expect(@json[:grant_id][:identifier]).to eql(@grant.value) + end + + it 'includes :dmproadmap_funded_affiliations' do + org = @plan.org + expect(@json[:dmproadmap_funded_affiliations].any?).to be(true) + affil = @json[:dmproadmap_funded_affiliations].last + expect(affil[:name]).to eql(org.name) + expect(affil[:affiliation_id][:type]).to eql(org.identifiers.last.identifier_format) + expect(affil[:affiliation_id][:identifier]).to eql(org.identifiers.last.value) + end + end +end diff --git a/spec/views/api/v2/plans/_project.json.jbuilder_spec.rb b/spec/views/api/v2/plans/_project.json.jbuilder_spec.rb new file mode 100644 index 0000000000..53af088379 --- /dev/null +++ b/spec/views/api/v2/plans/_project.json.jbuilder_spec.rb @@ -0,0 +1,33 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'api/v2/plans/_project.json.jbuilder' do + before do + @plan = build(:plan, funder: build(:org, :funder)) + render partial: 'api/v2/plans/project', locals: { plan: @plan } + @json = JSON.parse(rendered).with_indifferent_access + end + + describe 'includes all of the project attributes' do + it 'includes :title' do + expect(@json[:title]).to eql(@plan.title) + end + + it 'includes :description' do + expect(@json[:description]).to eql(@plan.description) + end + + it 'includes :start' do + expect(@json[:start]).to eql(@plan.start_date.to_formatted_s(:iso8601)) + end + + it 'includes :end' do + expect(@json[:end]).to eql(@plan.end_date.to_formatted_s(:iso8601)) + end + + it 'includes the :funder' do + expect(@json[:funding].length).to be(1) + end + end +end diff --git a/spec/views/api/v2/plans/_show.json.jbuilder_spec.rb b/spec/views/api/v2/plans/_show.json.jbuilder_spec.rb new file mode 100644 index 0000000000..989a2f638b --- /dev/null +++ b/spec/views/api/v2/plans/_show.json.jbuilder_spec.rb @@ -0,0 +1,113 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'api/v2/plans/_show.json.jbuilder' do + before do + Rails.configuration.x.madmp.enable_dmp_id_registration = true + + @plan = create(:plan) + @data_contact = create(:contributor, data_curation: true, plan: @plan) + @pi = create(:contributor, investigation: true, plan: @plan) + @plan.contributors = [@data_contact, @pi] + create(:identifier, identifiable: @plan) + + # Create an Api Client and connect it to the Plan + @client = create(:api_client) + scheme = create(:identifier_scheme, :for_plans, name: @client.name.downcase) + @client_identifier = create(:identifier, identifier_scheme: scheme, identifiable: @plan) + + @plan.save + @plan.reload + @presenter = Api::V2::PlanPresenter.new(plan: @plan) + end + + describe 'includes all of the DMP attributes' do + before do + render partial: 'api/v2/plans/show', locals: { client: @client, plan: @plan } + @json = JSON.parse(rendered).with_indifferent_access + end + + it 'includes the :title' do + expect(@json[:title]).to eql(@plan.title) + end + + it 'includes the :description' do + expect(@json[:description]).to eql(@plan.description) + end + + it 'includes the :language' do + expected = Api::V1::LanguagePresenter.three_char_code( + lang: LocaleService.default_locale + ) + expect(@json[:language]).to eql(expected) + end + + it 'includes the :created' do + expect(@json[:created]).to eql(@plan.created_at.to_formatted_s(:iso8601)) + end + + it 'includes the :modified' do + expect(@json[:modified]).to eql(@plan.updated_at.to_formatted_s(:iso8601)) + end + + it 'includes :ethical_issues' do + expected = Api::V1::ConversionService.boolean_to_yes_no_unknown(@plan.ethical_issues) + expect(@json[:ethical_issues_exist]).to eql(expected) + end + + it 'includes :ethical_issues_description' do + expect(@json[:ethical_issues_description]).to eql(@plan.ethical_issues_description) + end + + it 'includes :ethical_issues_report' do + expect(@json[:ethical_issues_report]).to eql(@plan.ethical_issues_report) + end + + it 'returns the URL of the plan as the :dmp_id if no DMP ID is defined' do + expected = Rails.application.routes.url_helpers.api_v2_plan_url(@plan) + expect(@json[:dmp_id][:type]).to eql('url') + expect(@json[:dmp_id][:identifier]).to eql(expected) + end + + it 'includes the :contact' do + expect(@json[:contact][:mbox]).to eql(@data_contact.email) + end + + it 'includes the :contributors' do + emails = @json[:contributor].pluck(:mbox) + expect(emails.include?(@pi.email)).to be(true) + end + + # TODO: make sure this is working once the new Cost theme and Currency + # question type have been implemented + it 'includes the :cost' do + expect(@json[:cost]).to be_nil + end + + it 'includes the :project' do + expect(@json[:project].length).to be(1) + end + + it 'includes the :dataset' do + expect(@json[:dataset].length).to be(1) + end + end + + describe 'when the system mints DMP IDs', skip: 'DmpIdService not implemented' do + before do + scheme = create(:identifier_scheme) + DmpIdService.expects(:identifier_scheme).at_least(1).returns(scheme) + @doi = create(:identifier, value: '10.9999/123abc.zy/x23', identifiable: @plan, + identifier_scheme: scheme) + @plan.reload + render partial: 'api/v2/plans/show', locals: { client: @client, plan: @plan } + @json = JSON.parse(rendered).with_indifferent_access + end + + it 'returns the DMP ID for the :dmp_id if one is present' do + expect(@json[:dmp_id][:type]).to eql('doi') + expect(@json[:dmp_id][:identifier]).to eql(@doi.value) + end + end +end diff --git a/spec/views/api/v2/plans/index.json.jbuilder_spec.rb b/spec/views/api/v2/plans/index.json.jbuilder_spec.rb new file mode 100644 index 0000000000..5d47770c52 --- /dev/null +++ b/spec/views/api/v2/plans/index.json.jbuilder_spec.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'api/v2/plans/index.json.jbuilder' do + before do + @plan = create(:plan) + + @client = create(:api_client) + @items = [@plan] + @total_items = 1 + + render template: 'api/v2/plans/index' + @json = JSON.parse(rendered).with_indifferent_access + end + + it 'renders the _standard_response template' do + expect(response).to render_template('api/v2/_standard_response') + end + + it ':items array to be empty' do + expect(@json[:items].length).to be(1) + expect(@json[:items].first[:dmp][:title]).to eql(@plan.title) + end +end diff --git a/spec/views/api/v2/templates/index.json.jbuilder_spec.rb b/spec/views/api/v2/templates/index.json.jbuilder_spec.rb new file mode 100644 index 0000000000..99b35375ec --- /dev/null +++ b/spec/views/api/v2/templates/index.json.jbuilder_spec.rb @@ -0,0 +1,78 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe 'api/v2/templates/index.json.jbuilder' do + before do + @application = Faker::Lorem.word + @url = Faker::Internet.url + @code = [200, 400, 404, 500].sample + + @template1 = create(:template, :published, org: create(:org), phases: 1) + @template2 = create(:template, :published) + + assign :server, @application + assign :items, [@template1, @template2] + + @resp = OpenStruct.new(status: @code) + @req = Net::HTTPGenericRequest.new('GET', nil, nil, @url) + end + + describe 'includes all of the Template attributes' do + before do + render template: 'api/v2/templates/index', + locals: { response: @resp, request: @req } + @json = JSON.parse(rendered).with_indifferent_access + + @template = @json[:items].first[:dmp_template] + end + + it 'includes both templates' do + expect(@json[:items].length).to be(2) + end + + it 'includes the :title' do + expect(@template[:title]).to eql(@template1.title) + end + + it 'includes the :description' do + expect(@template[:description]).to eql(@template1.description) + end + + it 'includes the :version' do + expect(@template[:version]).to eql(@template1.version) + end + + it 'includes the :created' do + expect(@template[:created]).to eql(@template1.created_at.to_formatted_s(:iso8601)) + end + + it 'includes the :modified' do + expect(@template[:modified]).to eql(@template1.updated_at.to_formatted_s(:iso8601)) + end + + it 'includes the :affiliation' do + expect(@template[:affiliation][:name]).to eql(@template1.org.name) + end + + it 'includes the :template_ids' do + expect(@template[:template_id][:identifier]).to eql(@template1.id.to_s) + expect(@template[:template_id][:type]).to eql('other') + end + + # The show_url parameter is either false or not included + it 'includes the :phases' do + expect(@json[:items].first[:dmp_template][:phases]).to be_nil + end + end + + # The show_url parameter is true + describe 'when the show_phases url parameter is true' do + before do + @show_phases = true + render template: 'api/v2/templates/index', + locals: { response: @resp, request: @req, show_phases: @show_phases } + @json = JSON.parse(rendered).with_indifferent_access + end + end +end From b5440795ba70305c896d1db5e56219a32ef5946e Mon Sep 17 00:00:00 2001 From: aaronskiba Date: Tue, 16 Dec 2025 13:05:14 -0700 Subject: [PATCH 7/8] Fix bugs uncovered by v2 API test coverage These changes resolve the following issues uncovered via the API v2 tests: - app/views/api/v2/datasets/_show.json.jbuilder - Failure rendering output.doi_url when output is present (undefined method `doi_url`) - config/routes.rb - Spec failures due to undefined route helpers in test context (e.g., `api_v2_templates_path`) --- app/views/api/v2/datasets/_show.json.jbuilder | 1 - config/routes.rb | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/api/v2/datasets/_show.json.jbuilder b/app/views/api/v2/datasets/_show.json.jbuilder index 1581dff785..6e856019cd 100644 --- a/app/views/api/v2/datasets/_show.json.jbuilder +++ b/app/views/api/v2/datasets/_show.json.jbuilder @@ -7,7 +7,6 @@ if output.is_a?(ResearchOutput) json.type output.output_type json.title output.title - json.doi_url output.doi_url json.description output.description json.personal_data Api::V2::ApiPresenter.boolean_to_yes_no_unknown(value: output.personal_data) json.sensitive_data Api::V2::ApiPresenter.boolean_to_yes_no_unknown(value: output.sensitive_data) diff --git a/config/routes.rb b/config/routes.rb index 152c4a327d..274c494d1d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -210,6 +210,7 @@ get :me, controller: :base_api resources :plans, only: %i[index show] + resources :templates, only: :index end end From 6ed3d2d789407a3d00a25b2742e691f12c4f3231 Mon Sep 17 00:00:00 2001 From: aaronskiba Date: Tue, 23 Dec 2025 08:38:56 -0700 Subject: [PATCH 8/8] Execute `translation:sync` with yaml enabled Executed `bundle exec rake translation:sync` while `config.disable_yaml = true`, allowing us to sync the doorkeeper translations. --- config/locale/app.pot | 218 ++++++++++++------------ config/locale/de/LC_MESSAGES/app.mo | Bin 154658 -> 154658 bytes config/locale/de/app.po | 218 ++++++++++++------------ config/locale/en/LC_MESSAGES/app.mo | Bin 145726 -> 145934 bytes config/locale/en/app.po | 218 ++++++++++++------------ config/locale/en_CA/LC_MESSAGES/app.mo | Bin 757 -> 1007 bytes config/locale/en_CA/app.po | 224 +++++++++++++------------ config/locale/en_GB/LC_MESSAGES/app.mo | Bin 1929 -> 1929 bytes config/locale/en_GB/app.po | 218 ++++++++++++------------ config/locale/en_US/LC_MESSAGES/app.mo | Bin 23808 -> 23808 bytes config/locale/en_US/app.po | 218 ++++++++++++------------ config/locale/es/LC_MESSAGES/app.mo | Bin 151602 -> 151602 bytes config/locale/es/app.po | 218 ++++++++++++------------ config/locale/fi/LC_MESSAGES/app.mo | Bin 146522 -> 146724 bytes config/locale/fi/app.po | 218 ++++++++++++------------ config/locale/fr_CA/LC_MESSAGES/app.mo | Bin 128820 -> 128820 bytes config/locale/fr_CA/app.po | 218 ++++++++++++------------ config/locale/fr_FR/LC_MESSAGES/app.mo | Bin 155277 -> 155277 bytes config/locale/fr_FR/app.po | 218 ++++++++++++------------ config/locale/pt_BR/LC_MESSAGES/app.mo | Bin 150739 -> 150739 bytes config/locale/pt_BR/app.po | 218 ++++++++++++------------ config/locale/sv_FI/LC_MESSAGES/app.mo | Bin 146009 -> 146009 bytes config/locale/sv_FI/app.po | 218 ++++++++++++------------ config/locale/tr_TR/LC_MESSAGES/app.mo | Bin 151768 -> 151768 bytes config/locale/tr_TR/app.po | 218 ++++++++++++------------ config/locales/.translation_io | 2 +- config/locales/translation.de.yml | 160 ++++++++++++++++++ config/locales/translation.en-CA.yml | 156 ++++++++++++++++- config/locales/translation.en-GB.yml | 156 ++++++++++++++++- config/locales/translation.en-US.yml | 153 +++++++++++++++++ config/locales/translation.es.yml | 157 +++++++++++++++++ config/locales/translation.fi.yml | 156 +++++++++++++++++ config/locales/translation.fr-CA.yml | 164 +++++++++++++++++- config/locales/translation.fr-FR.yml | 161 ++++++++++++++++++ config/locales/translation.pt-BR.yml | 156 +++++++++++++++++ config/locales/translation.sv-FI.yml | 136 +++++++++++++++ config/locales/translation.tr-TR.yml | 136 +++++++++++++++ 37 files changed, 3161 insertions(+), 1372 deletions(-) diff --git a/config/locale/app.pot b/config/locale/app.pot index 2d2bda03d4..24563216d5 100644 --- a/config/locale/app.pot +++ b/config/locale/app.pot @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: roadmap_upstream 1.0\n" "Report-Msgid-Bugs-To: contact@translation.io\n" -"POT-Creation-Date: 2025-04-10 13:28-0600\n" -"PO-Revision-Date: 2025-04-10 13:28-0600\n" +"POT-Creation-Date: 2025-12-23 08:33-0700\n" +"PO-Revision-Date: 2025-12-23 08:33-0700\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" @@ -123,87 +123,95 @@ msgstr "" msgid "No Plans found" msgstr "" -#: ../../app/controllers/application_controller.rb:36 +#: ../../app/controllers/api/v2/base_api_controller.rb:72 +msgid "There was a problem in the server." +msgstr "" + +#: ../../app/controllers/api/v2/base_api_controller.rb:78 +msgid "The client is not authorized to perform this action." +msgstr "" + +#: ../../app/controllers/application_controller.rb:37 msgid "You are not authorized to perform this action." msgstr "" -#: ../../app/controllers/application_controller.rb:40 +#: ../../app/controllers/application_controller.rb:41 msgid "You need to sign in or sign up before continuing." msgstr "" -#: ../../app/controllers/application_controller.rb:108 +#: ../../app/controllers/application_controller.rb:115 msgid "Unable to %{action} the %{object}. %{errors}" msgstr "" -#: ../../app/controllers/application_controller.rb:114 +#: ../../app/controllers/application_controller.rb:121 msgid "Successfully %{action} the %{object}." msgstr "" -#: ../../app/controllers/application_controller.rb:127 +#: ../../app/controllers/application_controller.rb:134 msgid "API client" msgstr "" -#: ../../app/controllers/application_controller.rb:128 +#: ../../app/controllers/application_controller.rb:135 msgid "plan" msgstr "" -#: ../../app/controllers/application_controller.rb:129 +#: ../../app/controllers/application_controller.rb:136 msgid "guidance group" msgstr "" -#: ../../app/controllers/application_controller.rb:130 +#: ../../app/controllers/application_controller.rb:137 msgid "comment" msgstr "" -#: ../../app/controllers/application_controller.rb:131 +#: ../../app/controllers/application_controller.rb:138 msgid "organisation" msgstr "" -#: ../../app/controllers/application_controller.rb:132 +#: ../../app/controllers/application_controller.rb:139 msgid "permission" msgstr "" -#: ../../app/controllers/application_controller.rb:133 +#: ../../app/controllers/application_controller.rb:140 msgid "preferences" msgstr "" -#: ../../app/controllers/application_controller.rb:134 +#: ../../app/controllers/application_controller.rb:141 msgid "profile" msgstr "" -#: ../../app/controllers/application_controller.rb:134 +#: ../../app/controllers/application_controller.rb:141 msgid "user" msgstr "" -#: ../../app/controllers/application_controller.rb:135 +#: ../../app/controllers/application_controller.rb:142 msgid "question option" msgstr "" -#: ../../app/controllers/application_controller.rb:181 +#: ../../app/controllers/application_controller.rb:188 msgid "Record Not Found" msgstr "" -#: ../../app/controllers/concerns/paginable.rb:45 +#: ../../app/controllers/concerns/paginable.rb:46 msgid "scope should be an ActiveRecord::Relation object" msgstr "" -#: ../../app/controllers/concerns/paginable.rb:47 +#: ../../app/controllers/concerns/paginable.rb:48 msgid "path_params should be a Hash object" msgstr "" -#: ../../app/controllers/concerns/paginable.rb:48 +#: ../../app/controllers/concerns/paginable.rb:49 msgid "query_params should be a Hash object" msgstr "" -#: ../../app/controllers/concerns/paginable.rb:49 +#: ../../app/controllers/concerns/paginable.rb:50 msgid "locals should be a Hash object" msgstr "" -#: ../../app/controllers/concerns/paginable.rb:70 +#: ../../app/controllers/concerns/paginable.rb:71 msgid "Restricted access to View All the records" msgstr "" -#: ../../app/controllers/concerns/paginable.rb:183 +#: ../../app/controllers/concerns/paginable.rb:184 msgid "Sort by %{sort_field}" msgstr "" @@ -244,77 +252,77 @@ msgstr "" msgid "Unable to submit your request" msgstr "" -#: ../../app/controllers/contributors_controller.rb:40 -#: ../../app/controllers/contributors_controller.rb:56 +#: ../../app/controllers/contributors_controller.rb:41 +#: ../../app/controllers/contributors_controller.rb:57 #: ../../app/controllers/research_outputs_controller.rb:42 msgid "add" msgstr "" -#: ../../app/controllers/contributors_controller.rb:54 +#: ../../app/controllers/contributors_controller.rb:55 #: ../../app/controllers/research_outputs_controller.rb:40 msgid "added" msgstr "" -#: ../../app/controllers/contributors_controller.rb:72 +#: ../../app/controllers/contributors_controller.rb:73 #: ../../app/controllers/guidance_groups_controller.rb:55 #: ../../app/controllers/guidances_controller.rb:75 -#: ../../app/controllers/notes_controller.rb:88 +#: ../../app/controllers/notes_controller.rb:89 #: ../../app/controllers/org_admin/departments_controller.rb:50 #: ../../app/controllers/org_admin/sections_controller.rb:103 #: ../../app/controllers/org_admin/templates_controller.rb:210 #: ../../app/controllers/orgs_controller.rb:92 -#: ../../app/controllers/plans_controller.rb:280 -#: ../../app/controllers/plans_controller.rb:283 +#: ../../app/controllers/plans_controller.rb:281 +#: ../../app/controllers/plans_controller.rb:284 #: ../../app/controllers/registrations_controller.rb:249 #: ../../app/controllers/registrations_controller.rb:253 #: ../../app/controllers/registrations_controller.rb:280 #: ../../app/controllers/registrations_controller.rb:284 #: ../../app/controllers/research_outputs_controller.rb:60 -#: ../../app/controllers/users_controller.rb:103 -#: ../../app/controllers/users_controller.rb:131 +#: ../../app/controllers/users_controller.rb:104 +#: ../../app/controllers/users_controller.rb:132 msgid "saved" msgstr "" -#: ../../app/controllers/contributors_controller.rb:74 +#: ../../app/controllers/contributors_controller.rb:75 #: ../../app/controllers/guidance_groups_controller.rb:57 #: ../../app/controllers/guidances_controller.rb:77 -#: ../../app/controllers/notes_controller.rb:106 +#: ../../app/controllers/notes_controller.rb:107 #: ../../app/controllers/org_admin/departments_controller.rb:52 #: ../../app/controllers/org_admin/sections_controller.rb:105 #: ../../app/controllers/org_admin/templates_controller.rb:215 #: ../../app/controllers/orgs_controller.rb:94 -#: ../../app/controllers/plans_controller.rb:289 -#: ../../app/controllers/plans_controller.rb:292 -#: ../../app/controllers/plans_controller.rb:296 -#: ../../app/controllers/plans_controller.rb:299 +#: ../../app/controllers/plans_controller.rb:290 +#: ../../app/controllers/plans_controller.rb:293 +#: ../../app/controllers/plans_controller.rb:297 +#: ../../app/controllers/plans_controller.rb:300 #: ../../app/controllers/registrations_controller.rb:256 #: ../../app/controllers/registrations_controller.rb:287 #: ../../app/controllers/research_outputs_controller.rb:63 msgid "save" msgstr "" -#: ../../app/controllers/contributors_controller.rb:83 -#: ../../app/controllers/notes_controller.rb:130 +#: ../../app/controllers/contributors_controller.rb:84 +#: ../../app/controllers/notes_controller.rb:131 #: ../../app/controllers/org_admin/templates_controller.rb:243 #: ../../app/controllers/research_outputs_controller.rb:74 #: ../../app/controllers/super_admin/orgs_controller.rb:94 msgid "removed" msgstr "" -#: ../../app/controllers/contributors_controller.rb:86 -#: ../../app/controllers/notes_controller.rb:148 +#: ../../app/controllers/contributors_controller.rb:87 +#: ../../app/controllers/notes_controller.rb:149 #: ../../app/controllers/org_admin/templates_controller.rb:245 #: ../../app/controllers/research_outputs_controller.rb:77 #: ../../app/controllers/super_admin/orgs_controller.rb:97 msgid "remove" msgstr "" -#: ../../app/controllers/contributors_controller.rb:160 +#: ../../app/controllers/contributors_controller.rb:161 #: ../../app/controllers/research_outputs_controller.rb:208 msgid "plan not found" msgstr "" -#: ../../app/controllers/contributors_controller.rb:168 +#: ../../app/controllers/contributors_controller.rb:169 msgid "contributor not found" msgstr "" @@ -328,7 +336,7 @@ msgstr "" #: ../../app/controllers/guidance_groups_controller.rb:31 #: ../../app/controllers/guidances_controller.rb:53 -#: ../../app/controllers/notes_controller.rb:47 +#: ../../app/controllers/notes_controller.rb:48 #: ../../app/controllers/org_admin/departments_controller.rb:26 #: ../../app/controllers/org_admin/phases_controller.rb:121 #: ../../app/controllers/org_admin/questions_controller.rb:94 @@ -344,7 +352,7 @@ msgstr "" #: ../../app/controllers/guidance_groups_controller.rb:34 #: ../../app/controllers/guidances_controller.rb:55 -#: ../../app/controllers/notes_controller.rb:66 +#: ../../app/controllers/notes_controller.rb:67 #: ../../app/controllers/org_admin/departments_controller.rb:30 #: ../../app/controllers/org_admin/phases_controller.rb:123 #: ../../app/controllers/org_admin/questions_controller.rb:96 @@ -383,7 +391,7 @@ msgstr "" #: ../../app/controllers/org_admin/question_options_controller.rb:24 #: ../../app/controllers/org_admin/questions_controller.rb:197 #: ../../app/controllers/org_admin/sections_controller.rb:128 -#: ../../app/controllers/plans_controller.rb:342 +#: ../../app/controllers/plans_controller.rb:343 #: ../../app/controllers/super_admin/api_clients_controller.rb:81 #: ../../app/controllers/super_admin/notifications_controller.rb:85 #: ../../app/controllers/super_admin/themes_controller.rb:51 @@ -397,7 +405,7 @@ msgstr "" #: ../../app/controllers/org_admin/question_options_controller.rb:26 #: ../../app/controllers/org_admin/questions_controller.rb:199 #: ../../app/controllers/org_admin/sections_controller.rb:130 -#: ../../app/controllers/plans_controller.rb:347 +#: ../../app/controllers/plans_controller.rb:348 #: ../../app/controllers/super_admin/api_clients_controller.rb:84 #: ../../app/controllers/super_admin/notifications_controller.rb:88 #: ../../app/controllers/super_admin/themes_controller.rb:54 @@ -438,19 +446,19 @@ msgstr "" #: ../../app/controllers/org_admin/phases_controller.rb:147 #: ../../app/controllers/org_admin/questions_controller.rb:166 #: ../../app/controllers/org_admin/users_controller.rb:30 -#: ../../app/controllers/plans_controller.rb:416 +#: ../../app/controllers/plans_controller.rb:417 #: ../../app/controllers/super_admin/api_clients_controller.rb:68 #: ../../app/controllers/super_admin/notifications_controller.rb:52 #: ../../app/controllers/super_admin/themes_controller.rb:39 #: ../../app/controllers/super_admin/users_controller.rb:54 -#: ../../app/controllers/users_controller.rb:108 +#: ../../app/controllers/users_controller.rb:109 msgid "updated" msgstr "" #: ../../app/controllers/org_admin/phases_controller.rb:149 #: ../../app/controllers/org_admin/questions_controller.rb:169 #: ../../app/controllers/org_admin/users_controller.rb:32 -#: ../../app/controllers/plans_controller.rb:419 +#: ../../app/controllers/plans_controller.rb:420 #: ../../app/controllers/super_admin/api_clients_controller.rb:70 #: ../../app/controllers/super_admin/notifications_controller.rb:55 #: ../../app/controllers/super_admin/themes_controller.rb:41 @@ -540,7 +548,7 @@ msgid "Unable to delete this version of the template." msgstr "" #: ../../app/controllers/org_admin/template_copies_controller.rb:20 -#: ../../app/controllers/plans_controller.rb:395 +#: ../../app/controllers/plans_controller.rb:396 msgid "copy" msgstr "" @@ -549,11 +557,11 @@ msgstr "" msgid "That template is no longer customizable." msgstr "" -#: ../../app/controllers/org_admin/template_customizations_controller.rb:21 +#: ../../app/controllers/org_admin/template_customizations_controller.rb:22 msgid "Unable to customize that template." msgstr "" -#: ../../app/controllers/org_admin/template_customizations_controller.rb:24 +#: ../../app/controllers/org_admin/template_customizations_controller.rb:25 msgid "That template is not customizable." msgstr "" @@ -643,33 +651,33 @@ msgstr "" msgid "template with customisations by the" msgstr "" -#: ../../app/controllers/plans_controller.rb:393 +#: ../../app/controllers/plans_controller.rb:394 msgid "copied" msgstr "" -#: ../../app/controllers/plans_controller.rb:424 +#: ../../app/controllers/plans_controller.rb:425 msgid "" "Unable to change the plan's status since it is needed at least %{percentage} p" "ercentage responded" msgstr "" -#: ../../app/controllers/plans_controller.rb:430 +#: ../../app/controllers/plans_controller.rb:431 msgid "Unable to find plan id %{plan_id}" msgstr "" -#: ../../app/controllers/plans_controller.rb:445 +#: ../../app/controllers/plans_controller.rb:446 msgid "Your project is now a test." msgstr "" -#: ../../app/controllers/plans_controller.rb:445 +#: ../../app/controllers/plans_controller.rb:446 msgid "Your project is no longer a test." msgstr "" -#: ../../app/controllers/plans_controller.rb:449 +#: ../../app/controllers/plans_controller.rb:450 msgid "Unable to change the plan's test status" msgstr "" -#: ../../app/controllers/plans_controller.rb:462 +#: ../../app/controllers/plans_controller.rb:463 msgid "There is no plan associated with id %{s" msgstr "" @@ -754,7 +762,7 @@ msgstr "" msgid "research output not found" msgstr "" -#: ../../app/controllers/roles_controller.rb:26 +#: ../../app/controllers/roles_controller.rb:27 msgid "" "Cannot share plan with %{email} since that email matches\n" " with the owner of the plan." @@ -917,27 +925,27 @@ msgstr "" msgid "Unable to link your account to %{scheme}." msgstr "" -#: ../../app/controllers/users_controller.rb:149 +#: ../../app/controllers/users_controller.rb:150 msgid "Successfully %{action} %{username}'s account." msgstr "" -#: ../../app/controllers/users_controller.rb:150 +#: ../../app/controllers/users_controller.rb:151 msgid "activated" msgstr "" -#: ../../app/controllers/users_controller.rb:150 +#: ../../app/controllers/users_controller.rb:151 msgid "deactivated" msgstr "" -#: ../../app/controllers/users_controller.rb:156 +#: ../../app/controllers/users_controller.rb:157 msgid "Unable to %{action} %{username}" msgstr "" -#: ../../app/controllers/users_controller.rb:157 +#: ../../app/controllers/users_controller.rb:158 msgid "activate" msgstr "" -#: ../../app/controllers/users_controller.rb:157 +#: ../../app/controllers/users_controller.rb:158 msgid "deactivate" msgstr "" @@ -1217,50 +1225,50 @@ msgstr "" msgid "Last 12 months" msgstr "" -#: ../../app/mailers/user_mailer.rb:17 +#: ../../app/mailers/user_mailer.rb:18 #: ../../app/views/devise/mailer/invitation_instructions.html.erb:5 #: ../../app/views/devise/mailer/reset_password_instructions.html.erb:5 #: ../../app/views/user_mailer/_email_signature.html.erb:2 msgid "Query or feedback related to %{tool_name}" msgstr "" -#: ../../app/mailers/user_mailer.rb:25 +#: ../../app/mailers/user_mailer.rb:26 msgid "Welcome to %{tool_name}" msgstr "" -#: ../../app/mailers/user_mailer.rb:62 +#: ../../app/mailers/user_mailer.rb:63 msgid "A Data Management Plan in %{tool_name} has been shared with you" msgstr "" -#: ../../app/mailers/user_mailer.rb:79 +#: ../../app/mailers/user_mailer.rb:80 msgid "Changed permissions on a Data Management Plan in %{tool_name}" msgstr "" -#: ../../app/mailers/user_mailer.rb:94 +#: ../../app/mailers/user_mailer.rb:95 msgid "Permissions removed on a DMP in %{tool_name}" msgstr "" -#: ../../app/mailers/user_mailer.rb:112 +#: ../../app/mailers/user_mailer.rb:113 msgid "%{user_name} has requested feedback on a %{tool_name} plan" msgstr "" -#: ../../app/mailers/user_mailer.rb:135 +#: ../../app/mailers/user_mailer.rb:136 msgid "%{tool_name}: Expert feedback has been provided for %{plan_title}" msgstr "" -#: ../../app/mailers/user_mailer.rb:153 +#: ../../app/mailers/user_mailer.rb:154 msgid "DMP Visibility Changed: %{plan_title}" msgstr "" -#: ../../app/mailers/user_mailer.rb:182 +#: ../../app/mailers/user_mailer.rb:183 msgid "%{tool_name}: A new comment was added to %{plan_title}" msgstr "" -#: ../../app/mailers/user_mailer.rb:198 +#: ../../app/mailers/user_mailer.rb:199 msgid "Administrator privileges granted in %{tool_name}" msgstr "" -#: ../../app/mailers/user_mailer.rb:216 +#: ../../app/mailers/user_mailer.rb:217 msgid "%{tool_name} API changes" msgstr "" @@ -1490,15 +1498,15 @@ msgstr "" msgid "already assigned a value" msgstr "" -#: ../../app/models/org.rb:46 +#: ../../app/models/org.rb:47 msgid "Feedback email message" msgstr "" -#: ../../app/models/org.rb:123 +#: ../../app/models/org.rb:124 msgid "must be one of the following formats: jpeg, jpg, png, gif, bmp" msgstr "" -#: ../../app/models/org.rb:128 +#: ../../app/models/org.rb:129 msgid "can't be larger than 500KB" msgstr "" @@ -1622,7 +1630,7 @@ msgstr "" msgid "Conditions in the template refer backwards" msgstr "" -#: ../../app/models/user.rb:380 +#: ../../app/models/user.rb:386 msgid "A Data Management Plan in %{application_name} has been shared with you" msgstr "" @@ -2032,7 +2040,7 @@ msgstr "" #: ../../app/views/paginable/templates/_organisational.html.erb:87 #: ../../app/views/paginable/templates/_publicly_visible.html.erb:29 #: ../../app/views/paginable/templates/_publicly_visible.html.erb:36 -#: ../../app/views/plans/_download_form.html.erb:130 +#: ../../app/views/plans/_download_form.html.erb:133 #: ../../app/views/static_pages/about_us.html.erb:22 #: ../../app/views/static_pages/about_us.html.erb:29 #: ../../app/views/static_pages/termsuse.html.erb:46 @@ -4351,7 +4359,7 @@ msgstr "" msgid "Instructions" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:6 +#: ../../app/views/plans/_download_form.html.erb:5 msgid "Format" msgstr "" @@ -4359,71 +4367,71 @@ msgstr "" msgid "Download settings" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:19 -msgid "Select phase to download" -msgstr "" - -#: ../../app/views/plans/_download_form.html.erb:26 +#: ../../app/views/plans/_download_form.html.erb:21 msgid "Optional plan components" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:30 +#: ../../app/views/plans/_download_form.html.erb:25 msgid "project details coversheet" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:36 +#: ../../app/views/plans/_download_form.html.erb:31 msgid "question text and section headings" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:42 +#: ../../app/views/plans/_download_form.html.erb:37 msgid "unanswered questions" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:49 +#: ../../app/views/plans/_download_form.html.erb:44 msgid "research outputs" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:57 +#: ../../app/views/plans/_download_form.html.erb:52 msgid "supplementary section(s) not requested by funding organisation" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:65 +#: ../../app/views/plans/_download_form.html.erb:61 +msgid "Select phase to download" +msgstr "" + +#: ../../app/views/plans/_download_form.html.erb:70 msgid "PDF formatting" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:68 +#: ../../app/views/plans/_download_form.html.erb:73 msgid "Font" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:71 +#: ../../app/views/plans/_download_form.html.erb:76 msgid "Margin (mm)" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:76 +#: ../../app/views/plans/_download_form.html.erb:81 msgid "Face" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:84 +#: ../../app/views/plans/_download_form.html.erb:89 msgid "Size" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:92 +#: ../../app/views/plans/_download_form.html.erb:96 msgid "Top" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:101 +#: ../../app/views/plans/_download_form.html.erb:105 msgid "Bottom" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:110 +#: ../../app/views/plans/_download_form.html.erb:114 msgid "Left" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:119 +#: ../../app/views/plans/_download_form.html.erb:123 msgid "Right" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:130 +#: ../../app/views/plans/_download_form.html.erb:133 msgid "" "Download Plan (new window)%{open_in_new_window_text}" diff --git a/config/locale/de/LC_MESSAGES/app.mo b/config/locale/de/LC_MESSAGES/app.mo index 24a717f3c7a5a62e7b102947f50b52c94ddadf1a..7d1cecb7bcdf67c7cf5961ed8d98b8b8cb38f91c 100644 GIT binary patch delta 56 zcmZ3qgLBai&W0_FXFd1~jdYES6$~t_jE!{-%%|V>V3dN28JYscv<(c}nLQb|GkY@0 G3j+Y%a}Hzx delta 56 zcmZ3qgLBai&W0_FXFd1~Omqzm6by~6j4X5w%%\n" "Language-Team: German\n" "Language: de\n" @@ -129,87 +129,95 @@ msgstr "Ungültiger JSON" msgid "No Plans found" msgstr "Keine Pläne gefunden" -#: ../../app/controllers/application_controller.rb:36 +#: ../../app/controllers/api/v2/base_api_controller.rb:72 +msgid "There was a problem in the server." +msgstr "" + +#: ../../app/controllers/api/v2/base_api_controller.rb:78 +msgid "The client is not authorized to perform this action." +msgstr "" + +#: ../../app/controllers/application_controller.rb:37 msgid "You are not authorized to perform this action." msgstr "Sie sind nicht berechtigt, diese Aktion durchzuführen." -#: ../../app/controllers/application_controller.rb:40 +#: ../../app/controllers/application_controller.rb:41 msgid "You need to sign in or sign up before continuing." msgstr "Bitte melden Sie sich an oder registrieren Sie sich bevor Sie fortfahren." -#: ../../app/controllers/application_controller.rb:108 +#: ../../app/controllers/application_controller.rb:115 msgid "Unable to %{action} the %{object}. %{errors}" msgstr "%{action} %{object} kann nicht ausgeführt werden. %{errors}" -#: ../../app/controllers/application_controller.rb:114 +#: ../../app/controllers/application_controller.rb:121 msgid "Successfully %{action} the %{object}." msgstr "Erfolgreich %{action} das %{object}." -#: ../../app/controllers/application_controller.rb:127 +#: ../../app/controllers/application_controller.rb:134 msgid "API client" msgstr "API-Client" -#: ../../app/controllers/application_controller.rb:128 +#: ../../app/controllers/application_controller.rb:135 msgid "plan" msgstr "Plan" -#: ../../app/controllers/application_controller.rb:129 +#: ../../app/controllers/application_controller.rb:136 msgid "guidance group" msgstr "Hinweisgruppe" -#: ../../app/controllers/application_controller.rb:130 +#: ../../app/controllers/application_controller.rb:137 msgid "comment" msgstr "Kommentar" -#: ../../app/controllers/application_controller.rb:131 +#: ../../app/controllers/application_controller.rb:138 msgid "organisation" msgstr "Organisation" -#: ../../app/controllers/application_controller.rb:132 +#: ../../app/controllers/application_controller.rb:139 msgid "permission" msgstr "Berechtigung" -#: ../../app/controllers/application_controller.rb:133 +#: ../../app/controllers/application_controller.rb:140 msgid "preferences" msgstr "Einstellungen" -#: ../../app/controllers/application_controller.rb:134 +#: ../../app/controllers/application_controller.rb:141 msgid "profile" msgstr "Profil" -#: ../../app/controllers/application_controller.rb:134 +#: ../../app/controllers/application_controller.rb:141 msgid "user" msgstr "Nutzer/in" -#: ../../app/controllers/application_controller.rb:135 +#: ../../app/controllers/application_controller.rb:142 msgid "question option" msgstr "Frage Option" -#: ../../app/controllers/application_controller.rb:181 +#: ../../app/controllers/application_controller.rb:188 msgid "Record Not Found" msgstr "Aufnahme nicht gefunden" -#: ../../app/controllers/concerns/paginable.rb:45 +#: ../../app/controllers/concerns/paginable.rb:46 msgid "scope should be an ActiveRecord::Relation object" msgstr "Der Bereich sollte ein ActiveRecord :: Relation-Objekt sein" -#: ../../app/controllers/concerns/paginable.rb:47 +#: ../../app/controllers/concerns/paginable.rb:48 msgid "path_params should be a Hash object" msgstr "path_params sollte ein Hash-Objekt sein" -#: ../../app/controllers/concerns/paginable.rb:48 +#: ../../app/controllers/concerns/paginable.rb:49 msgid "query_params should be a Hash object" msgstr "query_params sollte ein Hash-Objekt sein" -#: ../../app/controllers/concerns/paginable.rb:49 +#: ../../app/controllers/concerns/paginable.rb:50 msgid "locals should be a Hash object" msgstr "Einheimische sollten ein Hash-Objekt sein" -#: ../../app/controllers/concerns/paginable.rb:70 +#: ../../app/controllers/concerns/paginable.rb:71 msgid "Restricted access to View All the records" msgstr "Eingeschränkter Zugriff auf Alle Datensätze anzeigen" -#: ../../app/controllers/concerns/paginable.rb:183 +#: ../../app/controllers/concerns/paginable.rb:184 msgid "Sort by %{sort_field}" msgstr "Sortieren nach %{sort_field}" @@ -252,77 +260,77 @@ msgstr "Die Nachricht wurde erfolgreich versendet." msgid "Unable to submit your request" msgstr "Ihre Anfrage konnte nicht gesendet werden" -#: ../../app/controllers/contributors_controller.rb:40 -#: ../../app/controllers/contributors_controller.rb:56 +#: ../../app/controllers/contributors_controller.rb:41 +#: ../../app/controllers/contributors_controller.rb:57 #: ../../app/controllers/research_outputs_controller.rb:42 msgid "add" msgstr "Hinzufügen" -#: ../../app/controllers/contributors_controller.rb:54 +#: ../../app/controllers/contributors_controller.rb:55 #: ../../app/controllers/research_outputs_controller.rb:40 msgid "added" msgstr "Hinzugefügt" -#: ../../app/controllers/contributors_controller.rb:72 +#: ../../app/controllers/contributors_controller.rb:73 #: ../../app/controllers/guidance_groups_controller.rb:55 #: ../../app/controllers/guidances_controller.rb:75 -#: ../../app/controllers/notes_controller.rb:88 +#: ../../app/controllers/notes_controller.rb:89 #: ../../app/controllers/org_admin/departments_controller.rb:50 #: ../../app/controllers/org_admin/sections_controller.rb:103 #: ../../app/controllers/org_admin/templates_controller.rb:210 #: ../../app/controllers/orgs_controller.rb:92 -#: ../../app/controllers/plans_controller.rb:280 -#: ../../app/controllers/plans_controller.rb:283 +#: ../../app/controllers/plans_controller.rb:281 +#: ../../app/controllers/plans_controller.rb:284 #: ../../app/controllers/registrations_controller.rb:249 #: ../../app/controllers/registrations_controller.rb:253 #: ../../app/controllers/registrations_controller.rb:280 #: ../../app/controllers/registrations_controller.rb:284 #: ../../app/controllers/research_outputs_controller.rb:60 -#: ../../app/controllers/users_controller.rb:103 -#: ../../app/controllers/users_controller.rb:131 +#: ../../app/controllers/users_controller.rb:104 +#: ../../app/controllers/users_controller.rb:132 msgid "saved" msgstr "gespeichert" -#: ../../app/controllers/contributors_controller.rb:74 +#: ../../app/controllers/contributors_controller.rb:75 #: ../../app/controllers/guidance_groups_controller.rb:57 #: ../../app/controllers/guidances_controller.rb:77 -#: ../../app/controllers/notes_controller.rb:106 +#: ../../app/controllers/notes_controller.rb:107 #: ../../app/controllers/org_admin/departments_controller.rb:52 #: ../../app/controllers/org_admin/sections_controller.rb:105 #: ../../app/controllers/org_admin/templates_controller.rb:215 #: ../../app/controllers/orgs_controller.rb:94 -#: ../../app/controllers/plans_controller.rb:289 -#: ../../app/controllers/plans_controller.rb:292 -#: ../../app/controllers/plans_controller.rb:296 -#: ../../app/controllers/plans_controller.rb:299 +#: ../../app/controllers/plans_controller.rb:290 +#: ../../app/controllers/plans_controller.rb:293 +#: ../../app/controllers/plans_controller.rb:297 +#: ../../app/controllers/plans_controller.rb:300 #: ../../app/controllers/registrations_controller.rb:256 #: ../../app/controllers/registrations_controller.rb:287 #: ../../app/controllers/research_outputs_controller.rb:63 msgid "save" msgstr "Speichern" -#: ../../app/controllers/contributors_controller.rb:83 -#: ../../app/controllers/notes_controller.rb:130 +#: ../../app/controllers/contributors_controller.rb:84 +#: ../../app/controllers/notes_controller.rb:131 #: ../../app/controllers/org_admin/templates_controller.rb:243 #: ../../app/controllers/research_outputs_controller.rb:74 #: ../../app/controllers/super_admin/orgs_controller.rb:94 msgid "removed" msgstr "entfernt" -#: ../../app/controllers/contributors_controller.rb:86 -#: ../../app/controllers/notes_controller.rb:148 +#: ../../app/controllers/contributors_controller.rb:87 +#: ../../app/controllers/notes_controller.rb:149 #: ../../app/controllers/org_admin/templates_controller.rb:245 #: ../../app/controllers/research_outputs_controller.rb:77 #: ../../app/controllers/super_admin/orgs_controller.rb:97 msgid "remove" msgstr "entfernen" -#: ../../app/controllers/contributors_controller.rb:160 +#: ../../app/controllers/contributors_controller.rb:161 #: ../../app/controllers/research_outputs_controller.rb:208 msgid "plan not found" msgstr "Plan nicht gefunden" -#: ../../app/controllers/contributors_controller.rb:168 +#: ../../app/controllers/contributors_controller.rb:169 msgid "contributor not found" msgstr "Mitwirkender nicht gefunden" @@ -336,7 +344,7 @@ msgstr "Bei der Anforderung von Feedback für diesen Plan ist ein Fehler aufgetr #: ../../app/controllers/guidance_groups_controller.rb:31 #: ../../app/controllers/guidances_controller.rb:53 -#: ../../app/controllers/notes_controller.rb:47 +#: ../../app/controllers/notes_controller.rb:48 #: ../../app/controllers/org_admin/departments_controller.rb:26 #: ../../app/controllers/org_admin/phases_controller.rb:121 #: ../../app/controllers/org_admin/questions_controller.rb:94 @@ -352,7 +360,7 @@ msgstr "Erstellt" #: ../../app/controllers/guidance_groups_controller.rb:34 #: ../../app/controllers/guidances_controller.rb:55 -#: ../../app/controllers/notes_controller.rb:66 +#: ../../app/controllers/notes_controller.rb:67 #: ../../app/controllers/org_admin/departments_controller.rb:30 #: ../../app/controllers/org_admin/phases_controller.rb:123 #: ../../app/controllers/org_admin/questions_controller.rb:96 @@ -395,7 +403,7 @@ msgstr "Veröffentlichung zurückziehen" #: ../../app/controllers/org_admin/question_options_controller.rb:24 #: ../../app/controllers/org_admin/questions_controller.rb:197 #: ../../app/controllers/org_admin/sections_controller.rb:128 -#: ../../app/controllers/plans_controller.rb:342 +#: ../../app/controllers/plans_controller.rb:343 #: ../../app/controllers/super_admin/api_clients_controller.rb:81 #: ../../app/controllers/super_admin/notifications_controller.rb:85 #: ../../app/controllers/super_admin/themes_controller.rb:51 @@ -409,7 +417,7 @@ msgstr "Gelöscht" #: ../../app/controllers/org_admin/question_options_controller.rb:26 #: ../../app/controllers/org_admin/questions_controller.rb:199 #: ../../app/controllers/org_admin/sections_controller.rb:130 -#: ../../app/controllers/plans_controller.rb:347 +#: ../../app/controllers/plans_controller.rb:348 #: ../../app/controllers/super_admin/api_clients_controller.rb:84 #: ../../app/controllers/super_admin/notifications_controller.rb:88 #: ../../app/controllers/super_admin/themes_controller.rb:54 @@ -454,19 +462,19 @@ msgstr "Es kann keine neue Version dieser Vorlage erstellt werden.
" #: ../../app/controllers/org_admin/phases_controller.rb:147 #: ../../app/controllers/org_admin/questions_controller.rb:166 #: ../../app/controllers/org_admin/users_controller.rb:30 -#: ../../app/controllers/plans_controller.rb:416 +#: ../../app/controllers/plans_controller.rb:417 #: ../../app/controllers/super_admin/api_clients_controller.rb:68 #: ../../app/controllers/super_admin/notifications_controller.rb:52 #: ../../app/controllers/super_admin/themes_controller.rb:39 #: ../../app/controllers/super_admin/users_controller.rb:54 -#: ../../app/controllers/users_controller.rb:108 +#: ../../app/controllers/users_controller.rb:109 msgid "updated" msgstr "aktualisiert" #: ../../app/controllers/org_admin/phases_controller.rb:149 #: ../../app/controllers/org_admin/questions_controller.rb:169 #: ../../app/controllers/org_admin/users_controller.rb:32 -#: ../../app/controllers/plans_controller.rb:419 +#: ../../app/controllers/plans_controller.rb:420 #: ../../app/controllers/super_admin/api_clients_controller.rb:70 #: ../../app/controllers/super_admin/notifications_controller.rb:55 #: ../../app/controllers/super_admin/themes_controller.rb:41 @@ -562,7 +570,7 @@ msgid "Unable to delete this version of the template." msgstr "Diese Version der Vorlage kann nicht gelöscht werden." #: ../../app/controllers/org_admin/template_copies_controller.rb:20 -#: ../../app/controllers/plans_controller.rb:395 +#: ../../app/controllers/plans_controller.rb:396 msgid "copy" msgstr "Kopieren" @@ -571,11 +579,11 @@ msgstr "Kopieren" msgid "That template is no longer customizable." msgstr "Diese Vorlage ist nicht mehr anpassbar." -#: ../../app/controllers/org_admin/template_customizations_controller.rb:21 +#: ../../app/controllers/org_admin/template_customizations_controller.rb:22 msgid "Unable to customize that template." msgstr "Diese Vorlage kann nicht angepasst werden." -#: ../../app/controllers/org_admin/template_customizations_controller.rb:24 +#: ../../app/controllers/org_admin/template_customizations_controller.rb:25 msgid "That template is not customizable." msgstr "Diese Vorlage ist nicht anpassbar." @@ -667,11 +675,11 @@ msgstr "Dieser Plan basiert auf dem" msgid "template with customisations by the" msgstr "Vorlage mit Anpassungen durch die" -#: ../../app/controllers/plans_controller.rb:393 +#: ../../app/controllers/plans_controller.rb:394 msgid "copied" msgstr "Kopiert" -#: ../../app/controllers/plans_controller.rb:424 +#: ../../app/controllers/plans_controller.rb:425 msgid "" "Unable to change the plan's status since it is needed at least %{percentage} p" "ercentage responded" @@ -679,23 +687,23 @@ msgstr "" "Der Status des Plans konnte nicht geändert werden, da mindestens %{percentage}" " Prozentsatz angefordert wurde" -#: ../../app/controllers/plans_controller.rb:430 +#: ../../app/controllers/plans_controller.rb:431 msgid "Unable to find plan id %{plan_id}" msgstr "Plan-ID konnte nicht gefunden werden %{plan_id}" -#: ../../app/controllers/plans_controller.rb:445 +#: ../../app/controllers/plans_controller.rb:446 msgid "Your project is now a test." msgstr "Ihr Projekt ist jetzt ein Test." -#: ../../app/controllers/plans_controller.rb:445 +#: ../../app/controllers/plans_controller.rb:446 msgid "Your project is no longer a test." msgstr "Ihr Projekt ist kein Test mehr." -#: ../../app/controllers/plans_controller.rb:449 +#: ../../app/controllers/plans_controller.rb:450 msgid "Unable to change the plan's test status" msgstr "Der Teststatus des Plans konnte nicht geändert werden" -#: ../../app/controllers/plans_controller.rb:462 +#: ../../app/controllers/plans_controller.rb:463 msgid "There is no plan associated with id %{s" msgstr "ID %{ ist kein Plan zugeordnet S" @@ -792,7 +800,7 @@ msgstr "Passwort und Bestätigung müssen übereinstimmen" msgid "research output not found" msgstr "Forschungsergebnis nicht gefunden" -#: ../../app/controllers/roles_controller.rb:26 +#: ../../app/controllers/roles_controller.rb:27 msgid "" "Cannot share plan with %{email} since that email matches\n" " with the owner of the plan." @@ -973,27 +981,27 @@ msgstr "Ihr Konto wurde erfolgreich mit %{scheme} verknüpft." msgid "Unable to link your account to %{scheme}." msgstr "Ihr Konto konnte nicht mit %{scheme} verknüpft werden." -#: ../../app/controllers/users_controller.rb:149 +#: ../../app/controllers/users_controller.rb:150 msgid "Successfully %{action} %{username}'s account." msgstr "Erfolgreich %{action} %{username} Konto." -#: ../../app/controllers/users_controller.rb:150 +#: ../../app/controllers/users_controller.rb:151 msgid "activated" msgstr "Aktiviert" -#: ../../app/controllers/users_controller.rb:150 +#: ../../app/controllers/users_controller.rb:151 msgid "deactivated" msgstr "Deaktiviert" -#: ../../app/controllers/users_controller.rb:156 +#: ../../app/controllers/users_controller.rb:157 msgid "Unable to %{action} %{username}" msgstr "Kann nicht zu %{action} %{username}" -#: ../../app/controllers/users_controller.rb:157 +#: ../../app/controllers/users_controller.rb:158 msgid "activate" msgstr "Aktivieren" -#: ../../app/controllers/users_controller.rb:157 +#: ../../app/controllers/users_controller.rb:158 msgid "deactivate" msgstr "Deaktivieren" @@ -1286,50 +1294,50 @@ msgstr "Letzte 9 Monate" msgid "Last 12 months" msgstr "Letzte 12 Monate" -#: ../../app/mailers/user_mailer.rb:17 +#: ../../app/mailers/user_mailer.rb:18 #: ../../app/views/devise/mailer/invitation_instructions.html.erb:5 #: ../../app/views/devise/mailer/reset_password_instructions.html.erb:5 #: ../../app/views/user_mailer/_email_signature.html.erb:2 msgid "Query or feedback related to %{tool_name}" msgstr "Abfrage oder Feedback zu %{tool_name}" -#: ../../app/mailers/user_mailer.rb:25 +#: ../../app/mailers/user_mailer.rb:26 msgid "Welcome to %{tool_name}" msgstr "Willkommen bei %{tool_name}" -#: ../../app/mailers/user_mailer.rb:62 +#: ../../app/mailers/user_mailer.rb:63 msgid "A Data Management Plan in %{tool_name} has been shared with you" msgstr "Ein Datenverwaltungsplan in %{tool_name} wurde mit Ihnen geteilt" -#: ../../app/mailers/user_mailer.rb:79 +#: ../../app/mailers/user_mailer.rb:80 msgid "Changed permissions on a Data Management Plan in %{tool_name}" msgstr "Berechtigungen für einen Datenverwaltungsplan in %{tool_name} geändert" -#: ../../app/mailers/user_mailer.rb:94 +#: ../../app/mailers/user_mailer.rb:95 msgid "Permissions removed on a DMP in %{tool_name}" msgstr "Berechtigungen für ein DMP in %{tool_name} entfernt" -#: ../../app/mailers/user_mailer.rb:112 +#: ../../app/mailers/user_mailer.rb:113 msgid "%{user_name} has requested feedback on a %{tool_name} plan" msgstr "%{user_name} hat um Feedback zu einem %{tool_name}-Plan gebeten" -#: ../../app/mailers/user_mailer.rb:135 +#: ../../app/mailers/user_mailer.rb:136 msgid "%{tool_name}: Expert feedback has been provided for %{plan_title}" msgstr "%{tool_name}: Es wurde Experten-Feedback für %{plan_title} gegeben." -#: ../../app/mailers/user_mailer.rb:153 +#: ../../app/mailers/user_mailer.rb:154 msgid "DMP Visibility Changed: %{plan_title}" msgstr "DMP-Sichtbarkeit geändert: %{plan_title}" -#: ../../app/mailers/user_mailer.rb:182 +#: ../../app/mailers/user_mailer.rb:183 msgid "%{tool_name}: A new comment was added to %{plan_title}" msgstr "%{tool_name}: Ein neuer Kommentar wurde zu %{plan_title} hinzugefügt." -#: ../../app/mailers/user_mailer.rb:198 +#: ../../app/mailers/user_mailer.rb:199 msgid "Administrator privileges granted in %{tool_name}" msgstr "Administratorrechte in erteilt %{tool_name}" -#: ../../app/mailers/user_mailer.rb:216 +#: ../../app/mailers/user_mailer.rb:217 msgid "%{tool_name} API changes" msgstr "%{tool_name} API-Änderungen" @@ -1569,15 +1577,15 @@ msgstr "" msgid "already assigned a value" msgstr "bereits einen Wert zugewiesen" -#: ../../app/models/org.rb:46 +#: ../../app/models/org.rb:47 msgid "Feedback email message" msgstr "Feedback-Nachricht" -#: ../../app/models/org.rb:123 +#: ../../app/models/org.rb:124 msgid "must be one of the following formats: jpeg, jpg, png, gif, bmp" msgstr "muss eines der folgenden Formate sein: jpeg, jpg, png, gif, bmp" -#: ../../app/models/org.rb:128 +#: ../../app/models/org.rb:129 msgid "can't be larger than 500KB" msgstr "kann nicht größer als 500KB sein" @@ -1703,7 +1711,7 @@ msgstr "Sie können keine Vorlage veröffentlichen, die Abschnitte ohne Fragen e msgid "Conditions in the template refer backwards" msgstr "Die Bedingungen in der Vorlage beziehen sich rückwärts" -#: ../../app/models/user.rb:380 +#: ../../app/models/user.rb:386 msgid "A Data Management Plan in %{application_name} has been shared with you" msgstr "Ein Datenmanagementplan in %{application_name} wurde für Sie freigegeben" @@ -2133,7 +2141,7 @@ msgstr "" #: ../../app/views/paginable/templates/_organisational.html.erb:87 #: ../../app/views/paginable/templates/_publicly_visible.html.erb:29 #: ../../app/views/paginable/templates/_publicly_visible.html.erb:36 -#: ../../app/views/plans/_download_form.html.erb:130 +#: ../../app/views/plans/_download_form.html.erb:133 #: ../../app/views/static_pages/about_us.html.erb:22 #: ../../app/views/static_pages/about_us.html.erb:29 #: ../../app/views/static_pages/termsuse.html.erb:46 @@ -4667,7 +4675,7 @@ msgstr "Kommentare & Anleitung" msgid "Instructions" msgstr "Anleitung" -#: ../../app/views/plans/_download_form.html.erb:6 +#: ../../app/views/plans/_download_form.html.erb:5 msgid "Format" msgstr "Format" @@ -4675,73 +4683,73 @@ msgstr "Format" msgid "Download settings" msgstr "Einstellungen herunterladen" -#: ../../app/views/plans/_download_form.html.erb:19 -msgid "Select phase to download" -msgstr "Wählen Sie die Phase zum Herunterladen aus" - -#: ../../app/views/plans/_download_form.html.erb:26 +#: ../../app/views/plans/_download_form.html.erb:21 msgid "Optional plan components" msgstr "Optionale Plankomponenten" -#: ../../app/views/plans/_download_form.html.erb:30 +#: ../../app/views/plans/_download_form.html.erb:25 msgid "project details coversheet" msgstr "Deckblatt Projektdetails" -#: ../../app/views/plans/_download_form.html.erb:36 +#: ../../app/views/plans/_download_form.html.erb:31 msgid "question text and section headings" msgstr "Fragetext und Abschnittsüberschriften" -#: ../../app/views/plans/_download_form.html.erb:42 +#: ../../app/views/plans/_download_form.html.erb:37 msgid "unanswered questions" msgstr "unbeantwortete Fragen" -#: ../../app/views/plans/_download_form.html.erb:49 +#: ../../app/views/plans/_download_form.html.erb:44 msgid "research outputs" msgstr "Forschungsergebnisse" -#: ../../app/views/plans/_download_form.html.erb:57 +#: ../../app/views/plans/_download_form.html.erb:52 msgid "supplementary section(s) not requested by funding organisation" msgstr "" "ergänzende(r) Abschnitt(e), die von der Förderorganisation nicht gefordert wer" "den" -#: ../../app/views/plans/_download_form.html.erb:65 +#: ../../app/views/plans/_download_form.html.erb:61 +msgid "Select phase to download" +msgstr "Wählen Sie die Phase zum Herunterladen aus" + +#: ../../app/views/plans/_download_form.html.erb:70 msgid "PDF formatting" msgstr "PDF-Formatierung" -#: ../../app/views/plans/_download_form.html.erb:68 +#: ../../app/views/plans/_download_form.html.erb:73 msgid "Font" msgstr "Schrift" -#: ../../app/views/plans/_download_form.html.erb:71 +#: ../../app/views/plans/_download_form.html.erb:76 msgid "Margin (mm)" msgstr "Rand (mm)" -#: ../../app/views/plans/_download_form.html.erb:76 +#: ../../app/views/plans/_download_form.html.erb:81 msgid "Face" msgstr "Schriftart" -#: ../../app/views/plans/_download_form.html.erb:84 +#: ../../app/views/plans/_download_form.html.erb:89 msgid "Size" msgstr "Größe" -#: ../../app/views/plans/_download_form.html.erb:92 +#: ../../app/views/plans/_download_form.html.erb:96 msgid "Top" msgstr "Oben" -#: ../../app/views/plans/_download_form.html.erb:101 +#: ../../app/views/plans/_download_form.html.erb:105 msgid "Bottom" msgstr "Seitenende" -#: ../../app/views/plans/_download_form.html.erb:110 +#: ../../app/views/plans/_download_form.html.erb:114 msgid "Left" msgstr "Links" -#: ../../app/views/plans/_download_form.html.erb:119 +#: ../../app/views/plans/_download_form.html.erb:123 msgid "Right" msgstr "Rechts" -#: ../../app/views/plans/_download_form.html.erb:130 +#: ../../app/views/plans/_download_form.html.erb:133 msgid "" "Download Plan (new window)%{open_in_new_window_text}" diff --git a/config/locale/en/LC_MESSAGES/app.mo b/config/locale/en/LC_MESSAGES/app.mo index 83532d79fa24309ff266f3207090c4f867c54836..a5667b9c27eaedae3930511e83fd0982587ecf30 100644 GIT binary patch delta 23339 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 G%ltoSsth3j diff --git a/config/locale/en/app.po b/config/locale/en/app.po index 90661f9691..5833e9b41d 100644 --- a/config/locale/en/app.po +++ b/config/locale/en/app.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: roadmap_upstream 1.0\n" "Report-Msgid-Bugs-To: contact@translation.io\n" -"POT-Creation-Date: 2025-04-10 13:28-0600\n" -"PO-Revision-Date: 2025-04-10 13:28-0600\n" +"POT-Creation-Date: 2025-12-23 08:33-0700\n" +"PO-Revision-Date: 2025-12-23 08:33-0700\n" "Last-Translator: FULL NAME \n" "Language-Team: English\n" "Language: en\n" @@ -127,87 +127,95 @@ msgstr "Invalid JSON" msgid "No Plans found" msgstr "No Plans found" -#: ../../app/controllers/application_controller.rb:36 +#: ../../app/controllers/api/v2/base_api_controller.rb:72 +msgid "There was a problem in the server." +msgstr "There was a problem in the server." + +#: ../../app/controllers/api/v2/base_api_controller.rb:78 +msgid "The client is not authorized to perform this action." +msgstr "The client is not authorized to perform this action." + +#: ../../app/controllers/application_controller.rb:37 msgid "You are not authorized to perform this action." msgstr "You are not authorized to perform this action." -#: ../../app/controllers/application_controller.rb:40 +#: ../../app/controllers/application_controller.rb:41 msgid "You need to sign in or sign up before continuing." msgstr "You need to sign in or sign up before continuing." -#: ../../app/controllers/application_controller.rb:108 +#: ../../app/controllers/application_controller.rb:115 msgid "Unable to %{action} the %{object}. %{errors}" msgstr "Unable to %{action} the %{object}. %{errors}" -#: ../../app/controllers/application_controller.rb:114 +#: ../../app/controllers/application_controller.rb:121 msgid "Successfully %{action} the %{object}." msgstr "Successfully %{action} the %{object}." -#: ../../app/controllers/application_controller.rb:127 +#: ../../app/controllers/application_controller.rb:134 msgid "API client" msgstr "API client" -#: ../../app/controllers/application_controller.rb:128 +#: ../../app/controllers/application_controller.rb:135 msgid "plan" msgstr "plan" -#: ../../app/controllers/application_controller.rb:129 +#: ../../app/controllers/application_controller.rb:136 msgid "guidance group" msgstr "guidance group" -#: ../../app/controllers/application_controller.rb:130 +#: ../../app/controllers/application_controller.rb:137 msgid "comment" msgstr "comment" -#: ../../app/controllers/application_controller.rb:131 +#: ../../app/controllers/application_controller.rb:138 msgid "organisation" msgstr "organisation" -#: ../../app/controllers/application_controller.rb:132 +#: ../../app/controllers/application_controller.rb:139 msgid "permission" msgstr "permission" -#: ../../app/controllers/application_controller.rb:133 +#: ../../app/controllers/application_controller.rb:140 msgid "preferences" msgstr "preferences" -#: ../../app/controllers/application_controller.rb:134 +#: ../../app/controllers/application_controller.rb:141 msgid "profile" msgstr "profile" -#: ../../app/controllers/application_controller.rb:134 +#: ../../app/controllers/application_controller.rb:141 msgid "user" msgstr "user" -#: ../../app/controllers/application_controller.rb:135 +#: ../../app/controllers/application_controller.rb:142 msgid "question option" msgstr "question option" -#: ../../app/controllers/application_controller.rb:181 +#: ../../app/controllers/application_controller.rb:188 msgid "Record Not Found" msgstr "Record Not Found" -#: ../../app/controllers/concerns/paginable.rb:45 +#: ../../app/controllers/concerns/paginable.rb:46 msgid "scope should be an ActiveRecord::Relation object" msgstr "scope should be an ActiveRecord::Relation object" -#: ../../app/controllers/concerns/paginable.rb:47 +#: ../../app/controllers/concerns/paginable.rb:48 msgid "path_params should be a Hash object" msgstr "path_params should be a Hash object" -#: ../../app/controllers/concerns/paginable.rb:48 +#: ../../app/controllers/concerns/paginable.rb:49 msgid "query_params should be a Hash object" msgstr "query_params should be a Hash object" -#: ../../app/controllers/concerns/paginable.rb:49 +#: ../../app/controllers/concerns/paginable.rb:50 msgid "locals should be a Hash object" msgstr "locals should be a Hash object" -#: ../../app/controllers/concerns/paginable.rb:70 +#: ../../app/controllers/concerns/paginable.rb:71 msgid "Restricted access to View All the records" msgstr "Restricted access to View All the records" -#: ../../app/controllers/concerns/paginable.rb:183 +#: ../../app/controllers/concerns/paginable.rb:184 msgid "Sort by %{sort_field}" msgstr "Sort by %{sort_field}" @@ -248,77 +256,77 @@ msgstr "Contact email was successfully sent." msgid "Unable to submit your request" msgstr "Unable to submit your request" -#: ../../app/controllers/contributors_controller.rb:40 -#: ../../app/controllers/contributors_controller.rb:56 +#: ../../app/controllers/contributors_controller.rb:41 +#: ../../app/controllers/contributors_controller.rb:57 #: ../../app/controllers/research_outputs_controller.rb:42 msgid "add" msgstr "add" -#: ../../app/controllers/contributors_controller.rb:54 +#: ../../app/controllers/contributors_controller.rb:55 #: ../../app/controllers/research_outputs_controller.rb:40 msgid "added" msgstr "added" -#: ../../app/controllers/contributors_controller.rb:72 +#: ../../app/controllers/contributors_controller.rb:73 #: ../../app/controllers/guidance_groups_controller.rb:55 #: ../../app/controllers/guidances_controller.rb:75 -#: ../../app/controllers/notes_controller.rb:88 +#: ../../app/controllers/notes_controller.rb:89 #: ../../app/controllers/org_admin/departments_controller.rb:50 #: ../../app/controllers/org_admin/sections_controller.rb:103 #: ../../app/controllers/org_admin/templates_controller.rb:210 #: ../../app/controllers/orgs_controller.rb:92 -#: ../../app/controllers/plans_controller.rb:280 -#: ../../app/controllers/plans_controller.rb:283 +#: ../../app/controllers/plans_controller.rb:281 +#: ../../app/controllers/plans_controller.rb:284 #: ../../app/controllers/registrations_controller.rb:249 #: ../../app/controllers/registrations_controller.rb:253 #: ../../app/controllers/registrations_controller.rb:280 #: ../../app/controllers/registrations_controller.rb:284 #: ../../app/controllers/research_outputs_controller.rb:60 -#: ../../app/controllers/users_controller.rb:103 -#: ../../app/controllers/users_controller.rb:131 +#: ../../app/controllers/users_controller.rb:104 +#: ../../app/controllers/users_controller.rb:132 msgid "saved" msgstr "saved" -#: ../../app/controllers/contributors_controller.rb:74 +#: ../../app/controllers/contributors_controller.rb:75 #: ../../app/controllers/guidance_groups_controller.rb:57 #: ../../app/controllers/guidances_controller.rb:77 -#: ../../app/controllers/notes_controller.rb:106 +#: ../../app/controllers/notes_controller.rb:107 #: ../../app/controllers/org_admin/departments_controller.rb:52 #: ../../app/controllers/org_admin/sections_controller.rb:105 #: ../../app/controllers/org_admin/templates_controller.rb:215 #: ../../app/controllers/orgs_controller.rb:94 -#: ../../app/controllers/plans_controller.rb:289 -#: ../../app/controllers/plans_controller.rb:292 -#: ../../app/controllers/plans_controller.rb:296 -#: ../../app/controllers/plans_controller.rb:299 +#: ../../app/controllers/plans_controller.rb:290 +#: ../../app/controllers/plans_controller.rb:293 +#: ../../app/controllers/plans_controller.rb:297 +#: ../../app/controllers/plans_controller.rb:300 #: ../../app/controllers/registrations_controller.rb:256 #: ../../app/controllers/registrations_controller.rb:287 #: ../../app/controllers/research_outputs_controller.rb:63 msgid "save" msgstr "save" -#: ../../app/controllers/contributors_controller.rb:83 -#: ../../app/controllers/notes_controller.rb:130 +#: ../../app/controllers/contributors_controller.rb:84 +#: ../../app/controllers/notes_controller.rb:131 #: ../../app/controllers/org_admin/templates_controller.rb:243 #: ../../app/controllers/research_outputs_controller.rb:74 #: ../../app/controllers/super_admin/orgs_controller.rb:94 msgid "removed" msgstr "removed" -#: ../../app/controllers/contributors_controller.rb:86 -#: ../../app/controllers/notes_controller.rb:148 +#: ../../app/controllers/contributors_controller.rb:87 +#: ../../app/controllers/notes_controller.rb:149 #: ../../app/controllers/org_admin/templates_controller.rb:245 #: ../../app/controllers/research_outputs_controller.rb:77 #: ../../app/controllers/super_admin/orgs_controller.rb:97 msgid "remove" msgstr "remove" -#: ../../app/controllers/contributors_controller.rb:160 +#: ../../app/controllers/contributors_controller.rb:161 #: ../../app/controllers/research_outputs_controller.rb:208 msgid "plan not found" msgstr "plan not found" -#: ../../app/controllers/contributors_controller.rb:168 +#: ../../app/controllers/contributors_controller.rb:169 msgid "contributor not found" msgstr "contributor not found" @@ -332,7 +340,7 @@ msgstr "An error occurred when requesting feedback for this plan." #: ../../app/controllers/guidance_groups_controller.rb:31 #: ../../app/controllers/guidances_controller.rb:53 -#: ../../app/controllers/notes_controller.rb:47 +#: ../../app/controllers/notes_controller.rb:48 #: ../../app/controllers/org_admin/departments_controller.rb:26 #: ../../app/controllers/org_admin/phases_controller.rb:121 #: ../../app/controllers/org_admin/questions_controller.rb:94 @@ -348,7 +356,7 @@ msgstr "created" #: ../../app/controllers/guidance_groups_controller.rb:34 #: ../../app/controllers/guidances_controller.rb:55 -#: ../../app/controllers/notes_controller.rb:66 +#: ../../app/controllers/notes_controller.rb:67 #: ../../app/controllers/org_admin/departments_controller.rb:30 #: ../../app/controllers/org_admin/phases_controller.rb:123 #: ../../app/controllers/org_admin/questions_controller.rb:96 @@ -387,7 +395,7 @@ msgstr "unpublish" #: ../../app/controllers/org_admin/question_options_controller.rb:24 #: ../../app/controllers/org_admin/questions_controller.rb:197 #: ../../app/controllers/org_admin/sections_controller.rb:128 -#: ../../app/controllers/plans_controller.rb:342 +#: ../../app/controllers/plans_controller.rb:343 #: ../../app/controllers/super_admin/api_clients_controller.rb:81 #: ../../app/controllers/super_admin/notifications_controller.rb:85 #: ../../app/controllers/super_admin/themes_controller.rb:51 @@ -401,7 +409,7 @@ msgstr "deleted" #: ../../app/controllers/org_admin/question_options_controller.rb:26 #: ../../app/controllers/org_admin/questions_controller.rb:199 #: ../../app/controllers/org_admin/sections_controller.rb:130 -#: ../../app/controllers/plans_controller.rb:347 +#: ../../app/controllers/plans_controller.rb:348 #: ../../app/controllers/super_admin/api_clients_controller.rb:84 #: ../../app/controllers/super_admin/notifications_controller.rb:88 #: ../../app/controllers/super_admin/themes_controller.rb:54 @@ -444,19 +452,19 @@ msgstr "Unable to create a new version of this template.
" #: ../../app/controllers/org_admin/phases_controller.rb:147 #: ../../app/controllers/org_admin/questions_controller.rb:166 #: ../../app/controllers/org_admin/users_controller.rb:30 -#: ../../app/controllers/plans_controller.rb:416 +#: ../../app/controllers/plans_controller.rb:417 #: ../../app/controllers/super_admin/api_clients_controller.rb:68 #: ../../app/controllers/super_admin/notifications_controller.rb:52 #: ../../app/controllers/super_admin/themes_controller.rb:39 #: ../../app/controllers/super_admin/users_controller.rb:54 -#: ../../app/controllers/users_controller.rb:108 +#: ../../app/controllers/users_controller.rb:109 msgid "updated" msgstr "updated" #: ../../app/controllers/org_admin/phases_controller.rb:149 #: ../../app/controllers/org_admin/questions_controller.rb:169 #: ../../app/controllers/org_admin/users_controller.rb:32 -#: ../../app/controllers/plans_controller.rb:419 +#: ../../app/controllers/plans_controller.rb:420 #: ../../app/controllers/super_admin/api_clients_controller.rb:70 #: ../../app/controllers/super_admin/notifications_controller.rb:55 #: ../../app/controllers/super_admin/themes_controller.rb:41 @@ -546,7 +554,7 @@ msgid "Unable to delete this version of the template." msgstr "Unable to delete this version of the template." #: ../../app/controllers/org_admin/template_copies_controller.rb:20 -#: ../../app/controllers/plans_controller.rb:395 +#: ../../app/controllers/plans_controller.rb:396 msgid "copy" msgstr "copy" @@ -555,11 +563,11 @@ msgstr "copy" msgid "That template is no longer customizable." msgstr "That template is no longer customizable." -#: ../../app/controllers/org_admin/template_customizations_controller.rb:21 +#: ../../app/controllers/org_admin/template_customizations_controller.rb:22 msgid "Unable to customize that template." msgstr "Unable to customize that template." -#: ../../app/controllers/org_admin/template_customizations_controller.rb:24 +#: ../../app/controllers/org_admin/template_customizations_controller.rb:25 msgid "That template is not customizable." msgstr "That template is not customizable." @@ -649,11 +657,11 @@ msgstr "This plan is based on the" msgid "template with customisations by the" msgstr "template with customisations by the" -#: ../../app/controllers/plans_controller.rb:393 +#: ../../app/controllers/plans_controller.rb:394 msgid "copied" msgstr "copied" -#: ../../app/controllers/plans_controller.rb:424 +#: ../../app/controllers/plans_controller.rb:425 msgid "" "Unable to change the plan's status since it is needed at least %{percentage} p" "ercentage responded" @@ -661,23 +669,23 @@ msgstr "" "Unable to change the plan's status since it is needed at least %{percentage} p" "ercentage responded" -#: ../../app/controllers/plans_controller.rb:430 +#: ../../app/controllers/plans_controller.rb:431 msgid "Unable to find plan id %{plan_id}" msgstr "Unable to find plan id %{plan_id}" -#: ../../app/controllers/plans_controller.rb:445 +#: ../../app/controllers/plans_controller.rb:446 msgid "Your project is now a test." msgstr "Your project is now a test." -#: ../../app/controllers/plans_controller.rb:445 +#: ../../app/controllers/plans_controller.rb:446 msgid "Your project is no longer a test." msgstr "Your project is no longer a test." -#: ../../app/controllers/plans_controller.rb:449 +#: ../../app/controllers/plans_controller.rb:450 msgid "Unable to change the plan's test status" msgstr "Unable to change the plan's test status" -#: ../../app/controllers/plans_controller.rb:462 +#: ../../app/controllers/plans_controller.rb:463 msgid "There is no plan associated with id %{s" msgstr "There is no plan associated with id %{s" @@ -775,7 +783,7 @@ msgstr "Password and comfirmation must match" msgid "research output not found" msgstr "research output not found" -#: ../../app/controllers/roles_controller.rb:26 +#: ../../app/controllers/roles_controller.rb:27 msgid "" "Cannot share plan with %{email} since that email matches\n" " with the owner of the plan." @@ -952,27 +960,27 @@ msgstr "Your account has been successfully linked to %{scheme}." msgid "Unable to link your account to %{scheme}." msgstr "Unable to link your account to %{scheme}." -#: ../../app/controllers/users_controller.rb:149 +#: ../../app/controllers/users_controller.rb:150 msgid "Successfully %{action} %{username}'s account." msgstr "Successfully %{action} %{username}'s account." -#: ../../app/controllers/users_controller.rb:150 +#: ../../app/controllers/users_controller.rb:151 msgid "activated" msgstr "activated" -#: ../../app/controllers/users_controller.rb:150 +#: ../../app/controllers/users_controller.rb:151 msgid "deactivated" msgstr "deactivated" -#: ../../app/controllers/users_controller.rb:156 +#: ../../app/controllers/users_controller.rb:157 msgid "Unable to %{action} %{username}" msgstr "Unable to %{action} %{username}" -#: ../../app/controllers/users_controller.rb:157 +#: ../../app/controllers/users_controller.rb:158 msgid "activate" msgstr "activate" -#: ../../app/controllers/users_controller.rb:157 +#: ../../app/controllers/users_controller.rb:158 msgid "deactivate" msgstr "deactivate" @@ -1266,50 +1274,50 @@ msgstr "Last 9 months" msgid "Last 12 months" msgstr "Last 12 months" -#: ../../app/mailers/user_mailer.rb:17 +#: ../../app/mailers/user_mailer.rb:18 #: ../../app/views/devise/mailer/invitation_instructions.html.erb:5 #: ../../app/views/devise/mailer/reset_password_instructions.html.erb:5 #: ../../app/views/user_mailer/_email_signature.html.erb:2 msgid "Query or feedback related to %{tool_name}" msgstr "Query or feedback related to %{tool_name}" -#: ../../app/mailers/user_mailer.rb:25 +#: ../../app/mailers/user_mailer.rb:26 msgid "Welcome to %{tool_name}" msgstr "Welcome to %{tool_name}" -#: ../../app/mailers/user_mailer.rb:62 +#: ../../app/mailers/user_mailer.rb:63 msgid "A Data Management Plan in %{tool_name} has been shared with you" msgstr "A Data Management Plan in %{tool_name} has been shared with you" -#: ../../app/mailers/user_mailer.rb:79 +#: ../../app/mailers/user_mailer.rb:80 msgid "Changed permissions on a Data Management Plan in %{tool_name}" msgstr "Changed permissions on a Data Management Plan in %{tool_name}" -#: ../../app/mailers/user_mailer.rb:94 +#: ../../app/mailers/user_mailer.rb:95 msgid "Permissions removed on a DMP in %{tool_name}" msgstr "Permissions removed on a DMP in %{tool_name}" -#: ../../app/mailers/user_mailer.rb:112 +#: ../../app/mailers/user_mailer.rb:113 msgid "%{user_name} has requested feedback on a %{tool_name} plan" msgstr "%{user_name} has requested feedback on a %{tool_name} plan" -#: ../../app/mailers/user_mailer.rb:135 +#: ../../app/mailers/user_mailer.rb:136 msgid "%{tool_name}: Expert feedback has been provided for %{plan_title}" msgstr "%{tool_name}: Expert feedback has been provided for %{plan_title}" -#: ../../app/mailers/user_mailer.rb:153 +#: ../../app/mailers/user_mailer.rb:154 msgid "DMP Visibility Changed: %{plan_title}" msgstr "DMP Visibility Changed: %{plan_title}" -#: ../../app/mailers/user_mailer.rb:182 +#: ../../app/mailers/user_mailer.rb:183 msgid "%{tool_name}: A new comment was added to %{plan_title}" msgstr "%{tool_name}: A new comment was added to %{plan_title}" -#: ../../app/mailers/user_mailer.rb:198 +#: ../../app/mailers/user_mailer.rb:199 msgid "Administrator privileges granted in %{tool_name}" msgstr "Administrator privileges granted in %{tool_name}" -#: ../../app/mailers/user_mailer.rb:216 +#: ../../app/mailers/user_mailer.rb:217 msgid "%{tool_name} API changes" msgstr "%{tool_name} API changes" @@ -1549,15 +1557,15 @@ msgstr "Question not answered.\\n" msgid "already assigned a value" msgstr "already assigned a value" -#: ../../app/models/org.rb:46 +#: ../../app/models/org.rb:47 msgid "Feedback email message" msgstr "Feedback email message" -#: ../../app/models/org.rb:123 +#: ../../app/models/org.rb:124 msgid "must be one of the following formats: jpeg, jpg, png, gif, bmp" msgstr "must be one of the following formats: jpeg, jpg, png, gif, bmp" -#: ../../app/models/org.rb:128 +#: ../../app/models/org.rb:129 msgid "can't be larger than 500KB" msgstr "can't be larger than 500KB" @@ -1681,7 +1689,7 @@ msgstr "You can not publish a template without questions in a section. " msgid "Conditions in the template refer backwards" msgstr "Conditions in the template refer backwards" -#: ../../app/models/user.rb:380 +#: ../../app/models/user.rb:386 msgid "A Data Management Plan in %{application_name} has been shared with you" msgstr "A Data Management Plan in %{application_name} has been shared with you" @@ -2114,7 +2122,7 @@ msgstr "" #: ../../app/views/paginable/templates/_organisational.html.erb:87 #: ../../app/views/paginable/templates/_publicly_visible.html.erb:29 #: ../../app/views/paginable/templates/_publicly_visible.html.erb:36 -#: ../../app/views/plans/_download_form.html.erb:130 +#: ../../app/views/plans/_download_form.html.erb:133 #: ../../app/views/static_pages/about_us.html.erb:22 #: ../../app/views/static_pages/about_us.html.erb:29 #: ../../app/views/static_pages/termsuse.html.erb:46 @@ -4612,7 +4620,7 @@ msgstr "Comments & Guidance" msgid "Instructions" msgstr "Instructions" -#: ../../app/views/plans/_download_form.html.erb:6 +#: ../../app/views/plans/_download_form.html.erb:5 msgid "Format" msgstr "Format" @@ -4620,71 +4628,71 @@ msgstr "Format" msgid "Download settings" msgstr "Download settings" -#: ../../app/views/plans/_download_form.html.erb:19 -msgid "Select phase to download" -msgstr "Select phase to download" - -#: ../../app/views/plans/_download_form.html.erb:26 +#: ../../app/views/plans/_download_form.html.erb:21 msgid "Optional plan components" msgstr "Optional plan components" -#: ../../app/views/plans/_download_form.html.erb:30 +#: ../../app/views/plans/_download_form.html.erb:25 msgid "project details coversheet" msgstr "project details coversheet" -#: ../../app/views/plans/_download_form.html.erb:36 +#: ../../app/views/plans/_download_form.html.erb:31 msgid "question text and section headings" msgstr "question text and section headings" -#: ../../app/views/plans/_download_form.html.erb:42 +#: ../../app/views/plans/_download_form.html.erb:37 msgid "unanswered questions" msgstr "unanswered questions" -#: ../../app/views/plans/_download_form.html.erb:49 +#: ../../app/views/plans/_download_form.html.erb:44 msgid "research outputs" msgstr "research outputs" -#: ../../app/views/plans/_download_form.html.erb:57 +#: ../../app/views/plans/_download_form.html.erb:52 msgid "supplementary section(s) not requested by funding organisation" msgstr "supplementary section(s) not requested by funding organisation" -#: ../../app/views/plans/_download_form.html.erb:65 +#: ../../app/views/plans/_download_form.html.erb:61 +msgid "Select phase to download" +msgstr "Select phase to download" + +#: ../../app/views/plans/_download_form.html.erb:70 msgid "PDF formatting" msgstr "PDF formatting" -#: ../../app/views/plans/_download_form.html.erb:68 +#: ../../app/views/plans/_download_form.html.erb:73 msgid "Font" msgstr "Font" -#: ../../app/views/plans/_download_form.html.erb:71 +#: ../../app/views/plans/_download_form.html.erb:76 msgid "Margin (mm)" msgstr "Margin (mm)" -#: ../../app/views/plans/_download_form.html.erb:76 +#: ../../app/views/plans/_download_form.html.erb:81 msgid "Face" msgstr "Face" -#: ../../app/views/plans/_download_form.html.erb:84 +#: ../../app/views/plans/_download_form.html.erb:89 msgid "Size" msgstr "Size" -#: ../../app/views/plans/_download_form.html.erb:92 +#: ../../app/views/plans/_download_form.html.erb:96 msgid "Top" msgstr "Top" -#: ../../app/views/plans/_download_form.html.erb:101 +#: ../../app/views/plans/_download_form.html.erb:105 msgid "Bottom" msgstr "Bottom" -#: ../../app/views/plans/_download_form.html.erb:110 +#: ../../app/views/plans/_download_form.html.erb:114 msgid "Left" msgstr "Left" -#: ../../app/views/plans/_download_form.html.erb:119 +#: ../../app/views/plans/_download_form.html.erb:123 msgid "Right" msgstr "Right" -#: ../../app/views/plans/_download_form.html.erb:130 +#: ../../app/views/plans/_download_form.html.erb:133 msgid "" "Download Plan (new window)%{open_in_new_window_text}" diff --git a/config/locale/en_CA/LC_MESSAGES/app.mo b/config/locale/en_CA/LC_MESSAGES/app.mo index bf9d6b2adf91e649c36ed9cba603eab774eb9b35..aa7816ac0c07074f9f0cbdc668002935e9cfeb24 100644 GIT binary patch delta 449 zcmey$`kuZ1o)F7a1|Z-7Vi_Qg0b*_-o&&@nZ~}-Wf%qg4vjXvBAQlDUmq4ro#Q%ZV z0K{fwU@!#Iu|S#+NcRKjY9O8m#321r%n*E0kF86X2{fi%c~bwC1$ z1_M@EUF^aNCHV?PscD&csS1_(r9}$Gsfk6&8F~}@9`YF)=^7a;7+6>t8|xaFPp)N@ Zf(jX$0)?~<3??sSypcqfV@PyMF#yQhVUqv= delta 204 zcmaFQ{*|@dj_O|O2B{_N(0sNGXTXISU>{4`FSN7lWUlZC(mQd o<1;YPH8fB#G`2Fb&^0idEX5=R6*4je3TYb{O?G0s!3x&{0DEd2>i_@% diff --git a/config/locale/en_CA/app.po b/config/locale/en_CA/app.po index 8ab07d0dae..9481090fbb 100644 --- a/config/locale/en_CA/app.po +++ b/config/locale/en_CA/app.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: roadmap_upstream 1.0\n" "Report-Msgid-Bugs-To: contact@translation.io\n" -"POT-Creation-Date: 2025-04-10 13:28-0600\n" -"PO-Revision-Date: 2025-04-10 21:28+0200\n" +"POT-Creation-Date: 2025-12-23 08:33-0700\n" +"PO-Revision-Date: 2025-12-23 15:33+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: English\n" "Language: en_CA\n" @@ -123,87 +123,95 @@ msgstr "" msgid "No Plans found" msgstr "" -#: ../../app/controllers/application_controller.rb:36 +#: ../../app/controllers/api/v2/base_api_controller.rb:72 +msgid "There was a problem in the server." +msgstr "" + +#: ../../app/controllers/api/v2/base_api_controller.rb:78 +msgid "The client is not authorized to perform this action." +msgstr "" + +#: ../../app/controllers/application_controller.rb:37 msgid "You are not authorized to perform this action." msgstr "" -#: ../../app/controllers/application_controller.rb:40 +#: ../../app/controllers/application_controller.rb:41 msgid "You need to sign in or sign up before continuing." msgstr "You need to sign in or sign up before continuing." -#: ../../app/controllers/application_controller.rb:108 +#: ../../app/controllers/application_controller.rb:115 msgid "Unable to %{action} the %{object}. %{errors}" msgstr "" -#: ../../app/controllers/application_controller.rb:114 +#: ../../app/controllers/application_controller.rb:121 msgid "Successfully %{action} the %{object}." msgstr "" -#: ../../app/controllers/application_controller.rb:127 +#: ../../app/controllers/application_controller.rb:134 msgid "API client" msgstr "" -#: ../../app/controllers/application_controller.rb:128 +#: ../../app/controllers/application_controller.rb:135 msgid "plan" msgstr "" -#: ../../app/controllers/application_controller.rb:129 +#: ../../app/controllers/application_controller.rb:136 msgid "guidance group" msgstr "" -#: ../../app/controllers/application_controller.rb:130 +#: ../../app/controllers/application_controller.rb:137 msgid "comment" msgstr "" -#: ../../app/controllers/application_controller.rb:131 +#: ../../app/controllers/application_controller.rb:138 msgid "organisation" msgstr "" -#: ../../app/controllers/application_controller.rb:132 +#: ../../app/controllers/application_controller.rb:139 msgid "permission" msgstr "" -#: ../../app/controllers/application_controller.rb:133 +#: ../../app/controllers/application_controller.rb:140 msgid "preferences" msgstr "" -#: ../../app/controllers/application_controller.rb:134 +#: ../../app/controllers/application_controller.rb:141 msgid "profile" msgstr "" -#: ../../app/controllers/application_controller.rb:134 +#: ../../app/controllers/application_controller.rb:141 msgid "user" msgstr "" -#: ../../app/controllers/application_controller.rb:135 +#: ../../app/controllers/application_controller.rb:142 msgid "question option" msgstr "" -#: ../../app/controllers/application_controller.rb:181 +#: ../../app/controllers/application_controller.rb:188 msgid "Record Not Found" msgstr "" -#: ../../app/controllers/concerns/paginable.rb:45 +#: ../../app/controllers/concerns/paginable.rb:46 msgid "scope should be an ActiveRecord::Relation object" msgstr "" -#: ../../app/controllers/concerns/paginable.rb:47 +#: ../../app/controllers/concerns/paginable.rb:48 msgid "path_params should be a Hash object" msgstr "" -#: ../../app/controllers/concerns/paginable.rb:48 +#: ../../app/controllers/concerns/paginable.rb:49 msgid "query_params should be a Hash object" msgstr "" -#: ../../app/controllers/concerns/paginable.rb:49 +#: ../../app/controllers/concerns/paginable.rb:50 msgid "locals should be a Hash object" msgstr "" -#: ../../app/controllers/concerns/paginable.rb:70 +#: ../../app/controllers/concerns/paginable.rb:71 msgid "Restricted access to View All the records" msgstr "" -#: ../../app/controllers/concerns/paginable.rb:183 +#: ../../app/controllers/concerns/paginable.rb:184 msgid "Sort by %{sort_field}" msgstr "" @@ -244,77 +252,77 @@ msgstr "" msgid "Unable to submit your request" msgstr "" -#: ../../app/controllers/contributors_controller.rb:40 -#: ../../app/controllers/contributors_controller.rb:56 +#: ../../app/controllers/contributors_controller.rb:41 +#: ../../app/controllers/contributors_controller.rb:57 #: ../../app/controllers/research_outputs_controller.rb:42 msgid "add" msgstr "" -#: ../../app/controllers/contributors_controller.rb:54 +#: ../../app/controllers/contributors_controller.rb:55 #: ../../app/controllers/research_outputs_controller.rb:40 msgid "added" msgstr "" -#: ../../app/controllers/contributors_controller.rb:72 +#: ../../app/controllers/contributors_controller.rb:73 #: ../../app/controllers/guidance_groups_controller.rb:55 #: ../../app/controllers/guidances_controller.rb:75 -#: ../../app/controllers/notes_controller.rb:88 +#: ../../app/controllers/notes_controller.rb:89 #: ../../app/controllers/org_admin/departments_controller.rb:50 #: ../../app/controllers/org_admin/sections_controller.rb:103 #: ../../app/controllers/org_admin/templates_controller.rb:210 #: ../../app/controllers/orgs_controller.rb:92 -#: ../../app/controllers/plans_controller.rb:280 -#: ../../app/controllers/plans_controller.rb:283 +#: ../../app/controllers/plans_controller.rb:281 +#: ../../app/controllers/plans_controller.rb:284 #: ../../app/controllers/registrations_controller.rb:249 #: ../../app/controllers/registrations_controller.rb:253 #: ../../app/controllers/registrations_controller.rb:280 #: ../../app/controllers/registrations_controller.rb:284 #: ../../app/controllers/research_outputs_controller.rb:60 -#: ../../app/controllers/users_controller.rb:103 -#: ../../app/controllers/users_controller.rb:131 +#: ../../app/controllers/users_controller.rb:104 +#: ../../app/controllers/users_controller.rb:132 msgid "saved" msgstr "" -#: ../../app/controllers/contributors_controller.rb:74 +#: ../../app/controllers/contributors_controller.rb:75 #: ../../app/controllers/guidance_groups_controller.rb:57 #: ../../app/controllers/guidances_controller.rb:77 -#: ../../app/controllers/notes_controller.rb:106 +#: ../../app/controllers/notes_controller.rb:107 #: ../../app/controllers/org_admin/departments_controller.rb:52 #: ../../app/controllers/org_admin/sections_controller.rb:105 #: ../../app/controllers/org_admin/templates_controller.rb:215 #: ../../app/controllers/orgs_controller.rb:94 -#: ../../app/controllers/plans_controller.rb:289 -#: ../../app/controllers/plans_controller.rb:292 -#: ../../app/controllers/plans_controller.rb:296 -#: ../../app/controllers/plans_controller.rb:299 +#: ../../app/controllers/plans_controller.rb:290 +#: ../../app/controllers/plans_controller.rb:293 +#: ../../app/controllers/plans_controller.rb:297 +#: ../../app/controllers/plans_controller.rb:300 #: ../../app/controllers/registrations_controller.rb:256 #: ../../app/controllers/registrations_controller.rb:287 #: ../../app/controllers/research_outputs_controller.rb:63 msgid "save" msgstr "" -#: ../../app/controllers/contributors_controller.rb:83 -#: ../../app/controllers/notes_controller.rb:130 +#: ../../app/controllers/contributors_controller.rb:84 +#: ../../app/controllers/notes_controller.rb:131 #: ../../app/controllers/org_admin/templates_controller.rb:243 #: ../../app/controllers/research_outputs_controller.rb:74 #: ../../app/controllers/super_admin/orgs_controller.rb:94 msgid "removed" msgstr "" -#: ../../app/controllers/contributors_controller.rb:86 -#: ../../app/controllers/notes_controller.rb:148 +#: ../../app/controllers/contributors_controller.rb:87 +#: ../../app/controllers/notes_controller.rb:149 #: ../../app/controllers/org_admin/templates_controller.rb:245 #: ../../app/controllers/research_outputs_controller.rb:77 #: ../../app/controllers/super_admin/orgs_controller.rb:97 msgid "remove" msgstr "" -#: ../../app/controllers/contributors_controller.rb:160 +#: ../../app/controllers/contributors_controller.rb:161 #: ../../app/controllers/research_outputs_controller.rb:208 msgid "plan not found" msgstr "" -#: ../../app/controllers/contributors_controller.rb:168 +#: ../../app/controllers/contributors_controller.rb:169 msgid "contributor not found" msgstr "" @@ -328,7 +336,7 @@ msgstr "" #: ../../app/controllers/guidance_groups_controller.rb:31 #: ../../app/controllers/guidances_controller.rb:53 -#: ../../app/controllers/notes_controller.rb:47 +#: ../../app/controllers/notes_controller.rb:48 #: ../../app/controllers/org_admin/departments_controller.rb:26 #: ../../app/controllers/org_admin/phases_controller.rb:121 #: ../../app/controllers/org_admin/questions_controller.rb:94 @@ -344,7 +352,7 @@ msgstr "" #: ../../app/controllers/guidance_groups_controller.rb:34 #: ../../app/controllers/guidances_controller.rb:55 -#: ../../app/controllers/notes_controller.rb:66 +#: ../../app/controllers/notes_controller.rb:67 #: ../../app/controllers/org_admin/departments_controller.rb:30 #: ../../app/controllers/org_admin/phases_controller.rb:123 #: ../../app/controllers/org_admin/questions_controller.rb:96 @@ -383,7 +391,7 @@ msgstr "" #: ../../app/controllers/org_admin/question_options_controller.rb:24 #: ../../app/controllers/org_admin/questions_controller.rb:197 #: ../../app/controllers/org_admin/sections_controller.rb:128 -#: ../../app/controllers/plans_controller.rb:342 +#: ../../app/controllers/plans_controller.rb:343 #: ../../app/controllers/super_admin/api_clients_controller.rb:81 #: ../../app/controllers/super_admin/notifications_controller.rb:85 #: ../../app/controllers/super_admin/themes_controller.rb:51 @@ -397,7 +405,7 @@ msgstr "" #: ../../app/controllers/org_admin/question_options_controller.rb:26 #: ../../app/controllers/org_admin/questions_controller.rb:199 #: ../../app/controllers/org_admin/sections_controller.rb:130 -#: ../../app/controllers/plans_controller.rb:347 +#: ../../app/controllers/plans_controller.rb:348 #: ../../app/controllers/super_admin/api_clients_controller.rb:84 #: ../../app/controllers/super_admin/notifications_controller.rb:88 #: ../../app/controllers/super_admin/themes_controller.rb:54 @@ -438,19 +446,19 @@ msgstr "" #: ../../app/controllers/org_admin/phases_controller.rb:147 #: ../../app/controllers/org_admin/questions_controller.rb:166 #: ../../app/controllers/org_admin/users_controller.rb:30 -#: ../../app/controllers/plans_controller.rb:416 +#: ../../app/controllers/plans_controller.rb:417 #: ../../app/controllers/super_admin/api_clients_controller.rb:68 #: ../../app/controllers/super_admin/notifications_controller.rb:52 #: ../../app/controllers/super_admin/themes_controller.rb:39 #: ../../app/controllers/super_admin/users_controller.rb:54 -#: ../../app/controllers/users_controller.rb:108 +#: ../../app/controllers/users_controller.rb:109 msgid "updated" msgstr "" #: ../../app/controllers/org_admin/phases_controller.rb:149 #: ../../app/controllers/org_admin/questions_controller.rb:169 #: ../../app/controllers/org_admin/users_controller.rb:32 -#: ../../app/controllers/plans_controller.rb:419 +#: ../../app/controllers/plans_controller.rb:420 #: ../../app/controllers/super_admin/api_clients_controller.rb:70 #: ../../app/controllers/super_admin/notifications_controller.rb:55 #: ../../app/controllers/super_admin/themes_controller.rb:41 @@ -540,7 +548,7 @@ msgid "Unable to delete this version of the template." msgstr "" #: ../../app/controllers/org_admin/template_copies_controller.rb:20 -#: ../../app/controllers/plans_controller.rb:395 +#: ../../app/controllers/plans_controller.rb:396 msgid "copy" msgstr "" @@ -549,11 +557,11 @@ msgstr "" msgid "That template is no longer customizable." msgstr "" -#: ../../app/controllers/org_admin/template_customizations_controller.rb:21 +#: ../../app/controllers/org_admin/template_customizations_controller.rb:22 msgid "Unable to customize that template." msgstr "" -#: ../../app/controllers/org_admin/template_customizations_controller.rb:24 +#: ../../app/controllers/org_admin/template_customizations_controller.rb:25 msgid "That template is not customizable." msgstr "" @@ -643,33 +651,33 @@ msgstr "" msgid "template with customisations by the" msgstr "" -#: ../../app/controllers/plans_controller.rb:393 +#: ../../app/controllers/plans_controller.rb:394 msgid "copied" msgstr "" -#: ../../app/controllers/plans_controller.rb:424 +#: ../../app/controllers/plans_controller.rb:425 msgid "" "Unable to change the plan's status since it is needed at least %{percentage} p" "ercentage responded" msgstr "" -#: ../../app/controllers/plans_controller.rb:430 +#: ../../app/controllers/plans_controller.rb:431 msgid "Unable to find plan id %{plan_id}" msgstr "" -#: ../../app/controllers/plans_controller.rb:445 +#: ../../app/controllers/plans_controller.rb:446 msgid "Your project is now a test." msgstr "" -#: ../../app/controllers/plans_controller.rb:445 +#: ../../app/controllers/plans_controller.rb:446 msgid "Your project is no longer a test." msgstr "" -#: ../../app/controllers/plans_controller.rb:449 +#: ../../app/controllers/plans_controller.rb:450 msgid "Unable to change the plan's test status" msgstr "" -#: ../../app/controllers/plans_controller.rb:462 +#: ../../app/controllers/plans_controller.rb:463 msgid "There is no plan associated with id %{s" msgstr "" @@ -754,7 +762,7 @@ msgstr "" msgid "research output not found" msgstr "" -#: ../../app/controllers/roles_controller.rb:26 +#: ../../app/controllers/roles_controller.rb:27 msgid "" "Cannot share plan with %{email} since that email matches\n" " with the owner of the plan." @@ -917,27 +925,27 @@ msgstr "" msgid "Unable to link your account to %{scheme}." msgstr "" -#: ../../app/controllers/users_controller.rb:149 +#: ../../app/controllers/users_controller.rb:150 msgid "Successfully %{action} %{username}'s account." msgstr "" -#: ../../app/controllers/users_controller.rb:150 +#: ../../app/controllers/users_controller.rb:151 msgid "activated" msgstr "" -#: ../../app/controllers/users_controller.rb:150 +#: ../../app/controllers/users_controller.rb:151 msgid "deactivated" msgstr "" -#: ../../app/controllers/users_controller.rb:156 +#: ../../app/controllers/users_controller.rb:157 msgid "Unable to %{action} %{username}" msgstr "" -#: ../../app/controllers/users_controller.rb:157 +#: ../../app/controllers/users_controller.rb:158 msgid "activate" msgstr "" -#: ../../app/controllers/users_controller.rb:157 +#: ../../app/controllers/users_controller.rb:158 msgid "deactivate" msgstr "" @@ -1217,50 +1225,50 @@ msgstr "" msgid "Last 12 months" msgstr "" -#: ../../app/mailers/user_mailer.rb:17 +#: ../../app/mailers/user_mailer.rb:18 #: ../../app/views/devise/mailer/invitation_instructions.html.erb:5 #: ../../app/views/devise/mailer/reset_password_instructions.html.erb:5 #: ../../app/views/user_mailer/_email_signature.html.erb:2 msgid "Query or feedback related to %{tool_name}" msgstr "" -#: ../../app/mailers/user_mailer.rb:25 +#: ../../app/mailers/user_mailer.rb:26 msgid "Welcome to %{tool_name}" msgstr "" -#: ../../app/mailers/user_mailer.rb:62 +#: ../../app/mailers/user_mailer.rb:63 msgid "A Data Management Plan in %{tool_name} has been shared with you" msgstr "" -#: ../../app/mailers/user_mailer.rb:79 +#: ../../app/mailers/user_mailer.rb:80 msgid "Changed permissions on a Data Management Plan in %{tool_name}" msgstr "" -#: ../../app/mailers/user_mailer.rb:94 +#: ../../app/mailers/user_mailer.rb:95 msgid "Permissions removed on a DMP in %{tool_name}" msgstr "" -#: ../../app/mailers/user_mailer.rb:112 +#: ../../app/mailers/user_mailer.rb:113 msgid "%{user_name} has requested feedback on a %{tool_name} plan" msgstr "" -#: ../../app/mailers/user_mailer.rb:135 +#: ../../app/mailers/user_mailer.rb:136 msgid "%{tool_name}: Expert feedback has been provided for %{plan_title}" msgstr "" -#: ../../app/mailers/user_mailer.rb:153 +#: ../../app/mailers/user_mailer.rb:154 msgid "DMP Visibility Changed: %{plan_title}" msgstr "" -#: ../../app/mailers/user_mailer.rb:182 +#: ../../app/mailers/user_mailer.rb:183 msgid "%{tool_name}: A new comment was added to %{plan_title}" msgstr "" -#: ../../app/mailers/user_mailer.rb:198 +#: ../../app/mailers/user_mailer.rb:199 msgid "Administrator privileges granted in %{tool_name}" msgstr "" -#: ../../app/mailers/user_mailer.rb:216 +#: ../../app/mailers/user_mailer.rb:217 msgid "%{tool_name} API changes" msgstr "" @@ -1490,15 +1498,15 @@ msgstr "" msgid "already assigned a value" msgstr "" -#: ../../app/models/org.rb:46 +#: ../../app/models/org.rb:47 msgid "Feedback email message" msgstr "" -#: ../../app/models/org.rb:123 +#: ../../app/models/org.rb:124 msgid "must be one of the following formats: jpeg, jpg, png, gif, bmp" msgstr "" -#: ../../app/models/org.rb:128 +#: ../../app/models/org.rb:129 msgid "can't be larger than 500KB" msgstr "" @@ -1622,7 +1630,7 @@ msgstr "" msgid "Conditions in the template refer backwards" msgstr "" -#: ../../app/models/user.rb:380 +#: ../../app/models/user.rb:386 msgid "A Data Management Plan in %{application_name} has been shared with you" msgstr "" @@ -2032,7 +2040,7 @@ msgstr "" #: ../../app/views/paginable/templates/_organisational.html.erb:87 #: ../../app/views/paginable/templates/_publicly_visible.html.erb:29 #: ../../app/views/paginable/templates/_publicly_visible.html.erb:36 -#: ../../app/views/plans/_download_form.html.erb:130 +#: ../../app/views/plans/_download_form.html.erb:133 #: ../../app/views/static_pages/about_us.html.erb:22 #: ../../app/views/static_pages/about_us.html.erb:29 #: ../../app/views/static_pages/termsuse.html.erb:46 @@ -4351,7 +4359,7 @@ msgstr "" msgid "Instructions" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:6 +#: ../../app/views/plans/_download_form.html.erb:5 msgid "Format" msgstr "" @@ -4359,71 +4367,71 @@ msgstr "" msgid "Download settings" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:19 -msgid "Select phase to download" -msgstr "" - -#: ../../app/views/plans/_download_form.html.erb:26 +#: ../../app/views/plans/_download_form.html.erb:21 msgid "Optional plan components" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:30 +#: ../../app/views/plans/_download_form.html.erb:25 msgid "project details coversheet" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:36 +#: ../../app/views/plans/_download_form.html.erb:31 msgid "question text and section headings" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:42 +#: ../../app/views/plans/_download_form.html.erb:37 msgid "unanswered questions" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:49 +#: ../../app/views/plans/_download_form.html.erb:44 msgid "research outputs" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:57 +#: ../../app/views/plans/_download_form.html.erb:52 msgid "supplementary section(s) not requested by funding organisation" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:65 +#: ../../app/views/plans/_download_form.html.erb:61 +msgid "Select phase to download" +msgstr "" + +#: ../../app/views/plans/_download_form.html.erb:70 msgid "PDF formatting" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:68 +#: ../../app/views/plans/_download_form.html.erb:73 msgid "Font" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:71 +#: ../../app/views/plans/_download_form.html.erb:76 msgid "Margin (mm)" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:76 +#: ../../app/views/plans/_download_form.html.erb:81 msgid "Face" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:84 +#: ../../app/views/plans/_download_form.html.erb:89 msgid "Size" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:92 +#: ../../app/views/plans/_download_form.html.erb:96 msgid "Top" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:101 +#: ../../app/views/plans/_download_form.html.erb:105 msgid "Bottom" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:110 +#: ../../app/views/plans/_download_form.html.erb:114 msgid "Left" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:119 +#: ../../app/views/plans/_download_form.html.erb:123 msgid "Right" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:130 +#: ../../app/views/plans/_download_form.html.erb:133 msgid "" "Download Plan (new window)%{open_in_new_window_text}" @@ -4965,15 +4973,15 @@ msgstr "" #: ../../app/views/research_outputs/repositories/_search.html.erb:6 msgid "Select a subject area to refine your search." -msgstr "" +msgstr "Select a subject area to refine your search." #: ../../app/views/research_outputs/repositories/_search.html.erb:12 msgid "- Select a subject area -" -msgstr "" +msgstr "- Select a subject area -" #: ../../app/views/research_outputs/repositories/_search.html.erb:14 msgid "Select a subject area" -msgstr "" +msgstr "Select a subject area" #: ../../app/views/research_outputs/repositories/_search.html.erb:22 msgid "- Select a repository type -" diff --git a/config/locale/en_GB/LC_MESSAGES/app.mo b/config/locale/en_GB/LC_MESSAGES/app.mo index eca3c2e99f20ac5efa594c6586b6caff48d0ae5f..21dda0e1668b89a11f643fdb99bfdd2ad887b0c4 100644 GIT binary patch delta 46 vcmeC=@8sW5$iio6q-$iXU|?ZoY^-ZwKDnMn3Myo13KY^dFxb4D\n" "Language-Team: English\n" "Language: en_GB\n" @@ -123,87 +123,95 @@ msgstr "" msgid "No Plans found" msgstr "" -#: ../../app/controllers/application_controller.rb:36 +#: ../../app/controllers/api/v2/base_api_controller.rb:72 +msgid "There was a problem in the server." +msgstr "" + +#: ../../app/controllers/api/v2/base_api_controller.rb:78 +msgid "The client is not authorized to perform this action." +msgstr "" + +#: ../../app/controllers/application_controller.rb:37 msgid "You are not authorized to perform this action." msgstr "" -#: ../../app/controllers/application_controller.rb:40 +#: ../../app/controllers/application_controller.rb:41 msgid "You need to sign in or sign up before continuing." msgstr "You need to sign in or sign up before continuing." -#: ../../app/controllers/application_controller.rb:108 +#: ../../app/controllers/application_controller.rb:115 msgid "Unable to %{action} the %{object}. %{errors}" msgstr "" -#: ../../app/controllers/application_controller.rb:114 +#: ../../app/controllers/application_controller.rb:121 msgid "Successfully %{action} the %{object}." msgstr "" -#: ../../app/controllers/application_controller.rb:127 +#: ../../app/controllers/application_controller.rb:134 msgid "API client" msgstr "" -#: ../../app/controllers/application_controller.rb:128 +#: ../../app/controllers/application_controller.rb:135 msgid "plan" msgstr "" -#: ../../app/controllers/application_controller.rb:129 +#: ../../app/controllers/application_controller.rb:136 msgid "guidance group" msgstr "" -#: ../../app/controllers/application_controller.rb:130 +#: ../../app/controllers/application_controller.rb:137 msgid "comment" msgstr "" -#: ../../app/controllers/application_controller.rb:131 +#: ../../app/controllers/application_controller.rb:138 msgid "organisation" msgstr "" -#: ../../app/controllers/application_controller.rb:132 +#: ../../app/controllers/application_controller.rb:139 msgid "permission" msgstr "" -#: ../../app/controllers/application_controller.rb:133 +#: ../../app/controllers/application_controller.rb:140 msgid "preferences" msgstr "" -#: ../../app/controllers/application_controller.rb:134 +#: ../../app/controllers/application_controller.rb:141 msgid "profile" msgstr "" -#: ../../app/controllers/application_controller.rb:134 +#: ../../app/controllers/application_controller.rb:141 msgid "user" msgstr "" -#: ../../app/controllers/application_controller.rb:135 +#: ../../app/controllers/application_controller.rb:142 msgid "question option" msgstr "" -#: ../../app/controllers/application_controller.rb:181 +#: ../../app/controllers/application_controller.rb:188 msgid "Record Not Found" msgstr "" -#: ../../app/controllers/concerns/paginable.rb:45 +#: ../../app/controllers/concerns/paginable.rb:46 msgid "scope should be an ActiveRecord::Relation object" msgstr "" -#: ../../app/controllers/concerns/paginable.rb:47 +#: ../../app/controllers/concerns/paginable.rb:48 msgid "path_params should be a Hash object" msgstr "" -#: ../../app/controllers/concerns/paginable.rb:48 +#: ../../app/controllers/concerns/paginable.rb:49 msgid "query_params should be a Hash object" msgstr "" -#: ../../app/controllers/concerns/paginable.rb:49 +#: ../../app/controllers/concerns/paginable.rb:50 msgid "locals should be a Hash object" msgstr "" -#: ../../app/controllers/concerns/paginable.rb:70 +#: ../../app/controllers/concerns/paginable.rb:71 msgid "Restricted access to View All the records" msgstr "" -#: ../../app/controllers/concerns/paginable.rb:183 +#: ../../app/controllers/concerns/paginable.rb:184 msgid "Sort by %{sort_field}" msgstr "" @@ -244,77 +252,77 @@ msgstr "Contact email was successfully sent." msgid "Unable to submit your request" msgstr "" -#: ../../app/controllers/contributors_controller.rb:40 -#: ../../app/controllers/contributors_controller.rb:56 +#: ../../app/controllers/contributors_controller.rb:41 +#: ../../app/controllers/contributors_controller.rb:57 #: ../../app/controllers/research_outputs_controller.rb:42 msgid "add" msgstr "" -#: ../../app/controllers/contributors_controller.rb:54 +#: ../../app/controllers/contributors_controller.rb:55 #: ../../app/controllers/research_outputs_controller.rb:40 msgid "added" msgstr "" -#: ../../app/controllers/contributors_controller.rb:72 +#: ../../app/controllers/contributors_controller.rb:73 #: ../../app/controllers/guidance_groups_controller.rb:55 #: ../../app/controllers/guidances_controller.rb:75 -#: ../../app/controllers/notes_controller.rb:88 +#: ../../app/controllers/notes_controller.rb:89 #: ../../app/controllers/org_admin/departments_controller.rb:50 #: ../../app/controllers/org_admin/sections_controller.rb:103 #: ../../app/controllers/org_admin/templates_controller.rb:210 #: ../../app/controllers/orgs_controller.rb:92 -#: ../../app/controllers/plans_controller.rb:280 -#: ../../app/controllers/plans_controller.rb:283 +#: ../../app/controllers/plans_controller.rb:281 +#: ../../app/controllers/plans_controller.rb:284 #: ../../app/controllers/registrations_controller.rb:249 #: ../../app/controllers/registrations_controller.rb:253 #: ../../app/controllers/registrations_controller.rb:280 #: ../../app/controllers/registrations_controller.rb:284 #: ../../app/controllers/research_outputs_controller.rb:60 -#: ../../app/controllers/users_controller.rb:103 -#: ../../app/controllers/users_controller.rb:131 +#: ../../app/controllers/users_controller.rb:104 +#: ../../app/controllers/users_controller.rb:132 msgid "saved" msgstr "" -#: ../../app/controllers/contributors_controller.rb:74 +#: ../../app/controllers/contributors_controller.rb:75 #: ../../app/controllers/guidance_groups_controller.rb:57 #: ../../app/controllers/guidances_controller.rb:77 -#: ../../app/controllers/notes_controller.rb:106 +#: ../../app/controllers/notes_controller.rb:107 #: ../../app/controllers/org_admin/departments_controller.rb:52 #: ../../app/controllers/org_admin/sections_controller.rb:105 #: ../../app/controllers/org_admin/templates_controller.rb:215 #: ../../app/controllers/orgs_controller.rb:94 -#: ../../app/controllers/plans_controller.rb:289 -#: ../../app/controllers/plans_controller.rb:292 -#: ../../app/controllers/plans_controller.rb:296 -#: ../../app/controllers/plans_controller.rb:299 +#: ../../app/controllers/plans_controller.rb:290 +#: ../../app/controllers/plans_controller.rb:293 +#: ../../app/controllers/plans_controller.rb:297 +#: ../../app/controllers/plans_controller.rb:300 #: ../../app/controllers/registrations_controller.rb:256 #: ../../app/controllers/registrations_controller.rb:287 #: ../../app/controllers/research_outputs_controller.rb:63 msgid "save" msgstr "" -#: ../../app/controllers/contributors_controller.rb:83 -#: ../../app/controllers/notes_controller.rb:130 +#: ../../app/controllers/contributors_controller.rb:84 +#: ../../app/controllers/notes_controller.rb:131 #: ../../app/controllers/org_admin/templates_controller.rb:243 #: ../../app/controllers/research_outputs_controller.rb:74 #: ../../app/controllers/super_admin/orgs_controller.rb:94 msgid "removed" msgstr "" -#: ../../app/controllers/contributors_controller.rb:86 -#: ../../app/controllers/notes_controller.rb:148 +#: ../../app/controllers/contributors_controller.rb:87 +#: ../../app/controllers/notes_controller.rb:149 #: ../../app/controllers/org_admin/templates_controller.rb:245 #: ../../app/controllers/research_outputs_controller.rb:77 #: ../../app/controllers/super_admin/orgs_controller.rb:97 msgid "remove" msgstr "" -#: ../../app/controllers/contributors_controller.rb:160 +#: ../../app/controllers/contributors_controller.rb:161 #: ../../app/controllers/research_outputs_controller.rb:208 msgid "plan not found" msgstr "" -#: ../../app/controllers/contributors_controller.rb:168 +#: ../../app/controllers/contributors_controller.rb:169 msgid "contributor not found" msgstr "" @@ -328,7 +336,7 @@ msgstr "" #: ../../app/controllers/guidance_groups_controller.rb:31 #: ../../app/controllers/guidances_controller.rb:53 -#: ../../app/controllers/notes_controller.rb:47 +#: ../../app/controllers/notes_controller.rb:48 #: ../../app/controllers/org_admin/departments_controller.rb:26 #: ../../app/controllers/org_admin/phases_controller.rb:121 #: ../../app/controllers/org_admin/questions_controller.rb:94 @@ -344,7 +352,7 @@ msgstr "" #: ../../app/controllers/guidance_groups_controller.rb:34 #: ../../app/controllers/guidances_controller.rb:55 -#: ../../app/controllers/notes_controller.rb:66 +#: ../../app/controllers/notes_controller.rb:67 #: ../../app/controllers/org_admin/departments_controller.rb:30 #: ../../app/controllers/org_admin/phases_controller.rb:123 #: ../../app/controllers/org_admin/questions_controller.rb:96 @@ -383,7 +391,7 @@ msgstr "" #: ../../app/controllers/org_admin/question_options_controller.rb:24 #: ../../app/controllers/org_admin/questions_controller.rb:197 #: ../../app/controllers/org_admin/sections_controller.rb:128 -#: ../../app/controllers/plans_controller.rb:342 +#: ../../app/controllers/plans_controller.rb:343 #: ../../app/controllers/super_admin/api_clients_controller.rb:81 #: ../../app/controllers/super_admin/notifications_controller.rb:85 #: ../../app/controllers/super_admin/themes_controller.rb:51 @@ -397,7 +405,7 @@ msgstr "" #: ../../app/controllers/org_admin/question_options_controller.rb:26 #: ../../app/controllers/org_admin/questions_controller.rb:199 #: ../../app/controllers/org_admin/sections_controller.rb:130 -#: ../../app/controllers/plans_controller.rb:347 +#: ../../app/controllers/plans_controller.rb:348 #: ../../app/controllers/super_admin/api_clients_controller.rb:84 #: ../../app/controllers/super_admin/notifications_controller.rb:88 #: ../../app/controllers/super_admin/themes_controller.rb:54 @@ -438,19 +446,19 @@ msgstr "" #: ../../app/controllers/org_admin/phases_controller.rb:147 #: ../../app/controllers/org_admin/questions_controller.rb:166 #: ../../app/controllers/org_admin/users_controller.rb:30 -#: ../../app/controllers/plans_controller.rb:416 +#: ../../app/controllers/plans_controller.rb:417 #: ../../app/controllers/super_admin/api_clients_controller.rb:68 #: ../../app/controllers/super_admin/notifications_controller.rb:52 #: ../../app/controllers/super_admin/themes_controller.rb:39 #: ../../app/controllers/super_admin/users_controller.rb:54 -#: ../../app/controllers/users_controller.rb:108 +#: ../../app/controllers/users_controller.rb:109 msgid "updated" msgstr "" #: ../../app/controllers/org_admin/phases_controller.rb:149 #: ../../app/controllers/org_admin/questions_controller.rb:169 #: ../../app/controllers/org_admin/users_controller.rb:32 -#: ../../app/controllers/plans_controller.rb:419 +#: ../../app/controllers/plans_controller.rb:420 #: ../../app/controllers/super_admin/api_clients_controller.rb:70 #: ../../app/controllers/super_admin/notifications_controller.rb:55 #: ../../app/controllers/super_admin/themes_controller.rb:41 @@ -540,7 +548,7 @@ msgid "Unable to delete this version of the template." msgstr "" #: ../../app/controllers/org_admin/template_copies_controller.rb:20 -#: ../../app/controllers/plans_controller.rb:395 +#: ../../app/controllers/plans_controller.rb:396 msgid "copy" msgstr "" @@ -549,11 +557,11 @@ msgstr "" msgid "That template is no longer customizable." msgstr "That template is no longer customisable." -#: ../../app/controllers/org_admin/template_customizations_controller.rb:21 +#: ../../app/controllers/org_admin/template_customizations_controller.rb:22 msgid "Unable to customize that template." msgstr "Unable to customise that template" -#: ../../app/controllers/org_admin/template_customizations_controller.rb:24 +#: ../../app/controllers/org_admin/template_customizations_controller.rb:25 msgid "That template is not customizable." msgstr "That template is not customisable" @@ -643,33 +651,33 @@ msgstr "" msgid "template with customisations by the" msgstr "" -#: ../../app/controllers/plans_controller.rb:393 +#: ../../app/controllers/plans_controller.rb:394 msgid "copied" msgstr "" -#: ../../app/controllers/plans_controller.rb:424 +#: ../../app/controllers/plans_controller.rb:425 msgid "" "Unable to change the plan's status since it is needed at least %{percentage} p" "ercentage responded" msgstr "" -#: ../../app/controllers/plans_controller.rb:430 +#: ../../app/controllers/plans_controller.rb:431 msgid "Unable to find plan id %{plan_id}" msgstr "" -#: ../../app/controllers/plans_controller.rb:445 +#: ../../app/controllers/plans_controller.rb:446 msgid "Your project is now a test." msgstr "" -#: ../../app/controllers/plans_controller.rb:445 +#: ../../app/controllers/plans_controller.rb:446 msgid "Your project is no longer a test." msgstr "" -#: ../../app/controllers/plans_controller.rb:449 +#: ../../app/controllers/plans_controller.rb:450 msgid "Unable to change the plan's test status" msgstr "" -#: ../../app/controllers/plans_controller.rb:462 +#: ../../app/controllers/plans_controller.rb:463 msgid "There is no plan associated with id %{s" msgstr "" @@ -754,7 +762,7 @@ msgstr "" msgid "research output not found" msgstr "" -#: ../../app/controllers/roles_controller.rb:26 +#: ../../app/controllers/roles_controller.rb:27 msgid "" "Cannot share plan with %{email} since that email matches\n" " with the owner of the plan." @@ -917,27 +925,27 @@ msgstr "" msgid "Unable to link your account to %{scheme}." msgstr "" -#: ../../app/controllers/users_controller.rb:149 +#: ../../app/controllers/users_controller.rb:150 msgid "Successfully %{action} %{username}'s account." msgstr "" -#: ../../app/controllers/users_controller.rb:150 +#: ../../app/controllers/users_controller.rb:151 msgid "activated" msgstr "" -#: ../../app/controllers/users_controller.rb:150 +#: ../../app/controllers/users_controller.rb:151 msgid "deactivated" msgstr "" -#: ../../app/controllers/users_controller.rb:156 +#: ../../app/controllers/users_controller.rb:157 msgid "Unable to %{action} %{username}" msgstr "" -#: ../../app/controllers/users_controller.rb:157 +#: ../../app/controllers/users_controller.rb:158 msgid "activate" msgstr "" -#: ../../app/controllers/users_controller.rb:157 +#: ../../app/controllers/users_controller.rb:158 msgid "deactivate" msgstr "" @@ -1217,50 +1225,50 @@ msgstr "" msgid "Last 12 months" msgstr "" -#: ../../app/mailers/user_mailer.rb:17 +#: ../../app/mailers/user_mailer.rb:18 #: ../../app/views/devise/mailer/invitation_instructions.html.erb:5 #: ../../app/views/devise/mailer/reset_password_instructions.html.erb:5 #: ../../app/views/user_mailer/_email_signature.html.erb:2 msgid "Query or feedback related to %{tool_name}" msgstr "" -#: ../../app/mailers/user_mailer.rb:25 +#: ../../app/mailers/user_mailer.rb:26 msgid "Welcome to %{tool_name}" msgstr "" -#: ../../app/mailers/user_mailer.rb:62 +#: ../../app/mailers/user_mailer.rb:63 msgid "A Data Management Plan in %{tool_name} has been shared with you" msgstr "" -#: ../../app/mailers/user_mailer.rb:79 +#: ../../app/mailers/user_mailer.rb:80 msgid "Changed permissions on a Data Management Plan in %{tool_name}" msgstr "" -#: ../../app/mailers/user_mailer.rb:94 +#: ../../app/mailers/user_mailer.rb:95 msgid "Permissions removed on a DMP in %{tool_name}" msgstr "" -#: ../../app/mailers/user_mailer.rb:112 +#: ../../app/mailers/user_mailer.rb:113 msgid "%{user_name} has requested feedback on a %{tool_name} plan" msgstr "" -#: ../../app/mailers/user_mailer.rb:135 +#: ../../app/mailers/user_mailer.rb:136 msgid "%{tool_name}: Expert feedback has been provided for %{plan_title}" msgstr "" -#: ../../app/mailers/user_mailer.rb:153 +#: ../../app/mailers/user_mailer.rb:154 msgid "DMP Visibility Changed: %{plan_title}" msgstr "" -#: ../../app/mailers/user_mailer.rb:182 +#: ../../app/mailers/user_mailer.rb:183 msgid "%{tool_name}: A new comment was added to %{plan_title}" msgstr "" -#: ../../app/mailers/user_mailer.rb:198 +#: ../../app/mailers/user_mailer.rb:199 msgid "Administrator privileges granted in %{tool_name}" msgstr "" -#: ../../app/mailers/user_mailer.rb:216 +#: ../../app/mailers/user_mailer.rb:217 msgid "%{tool_name} API changes" msgstr "" @@ -1490,15 +1498,15 @@ msgstr "" msgid "already assigned a value" msgstr "" -#: ../../app/models/org.rb:46 +#: ../../app/models/org.rb:47 msgid "Feedback email message" msgstr "" -#: ../../app/models/org.rb:123 +#: ../../app/models/org.rb:124 msgid "must be one of the following formats: jpeg, jpg, png, gif, bmp" msgstr "" -#: ../../app/models/org.rb:128 +#: ../../app/models/org.rb:129 msgid "can't be larger than 500KB" msgstr "" @@ -1622,7 +1630,7 @@ msgstr "" msgid "Conditions in the template refer backwards" msgstr "" -#: ../../app/models/user.rb:380 +#: ../../app/models/user.rb:386 msgid "A Data Management Plan in %{application_name} has been shared with you" msgstr "" @@ -2032,7 +2040,7 @@ msgstr "" #: ../../app/views/paginable/templates/_organisational.html.erb:87 #: ../../app/views/paginable/templates/_publicly_visible.html.erb:29 #: ../../app/views/paginable/templates/_publicly_visible.html.erb:36 -#: ../../app/views/plans/_download_form.html.erb:130 +#: ../../app/views/plans/_download_form.html.erb:133 #: ../../app/views/static_pages/about_us.html.erb:22 #: ../../app/views/static_pages/about_us.html.erb:29 #: ../../app/views/static_pages/termsuse.html.erb:46 @@ -4353,7 +4361,7 @@ msgstr "" msgid "Instructions" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:6 +#: ../../app/views/plans/_download_form.html.erb:5 msgid "Format" msgstr "" @@ -4361,71 +4369,71 @@ msgstr "" msgid "Download settings" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:19 -msgid "Select phase to download" -msgstr "" - -#: ../../app/views/plans/_download_form.html.erb:26 +#: ../../app/views/plans/_download_form.html.erb:21 msgid "Optional plan components" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:30 +#: ../../app/views/plans/_download_form.html.erb:25 msgid "project details coversheet" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:36 +#: ../../app/views/plans/_download_form.html.erb:31 msgid "question text and section headings" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:42 +#: ../../app/views/plans/_download_form.html.erb:37 msgid "unanswered questions" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:49 +#: ../../app/views/plans/_download_form.html.erb:44 msgid "research outputs" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:57 +#: ../../app/views/plans/_download_form.html.erb:52 msgid "supplementary section(s) not requested by funding organisation" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:65 +#: ../../app/views/plans/_download_form.html.erb:61 +msgid "Select phase to download" +msgstr "" + +#: ../../app/views/plans/_download_form.html.erb:70 msgid "PDF formatting" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:68 +#: ../../app/views/plans/_download_form.html.erb:73 msgid "Font" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:71 +#: ../../app/views/plans/_download_form.html.erb:76 msgid "Margin (mm)" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:76 +#: ../../app/views/plans/_download_form.html.erb:81 msgid "Face" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:84 +#: ../../app/views/plans/_download_form.html.erb:89 msgid "Size" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:92 +#: ../../app/views/plans/_download_form.html.erb:96 msgid "Top" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:101 +#: ../../app/views/plans/_download_form.html.erb:105 msgid "Bottom" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:110 +#: ../../app/views/plans/_download_form.html.erb:114 msgid "Left" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:119 +#: ../../app/views/plans/_download_form.html.erb:123 msgid "Right" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:130 +#: ../../app/views/plans/_download_form.html.erb:133 msgid "" "Download Plan (new window)%{open_in_new_window_text}" diff --git a/config/locale/en_US/LC_MESSAGES/app.mo b/config/locale/en_US/LC_MESSAGES/app.mo index 431212627465a78c0fb1d14b350c23194301fe18..e5c4383c22e1f16731b759a17b4764890dcc17fc 100644 GIT binary patch delta 48 xcmZqJ#n`Zmal->+K0_m2BVz>v3oBz|T?6yU?~J9OLWZV5A#DSL&0;36Gyr1D4T=B& delta 48 xcmZqJ#n`Zmal->+J_8e7LjwgvV=E&IT?4bp?~J9OLPmx_A#DSr&0;36Gyq~D4Tb;! diff --git a/config/locale/en_US/app.po b/config/locale/en_US/app.po index 1626c14e2e..321ef003b5 100644 --- a/config/locale/en_US/app.po +++ b/config/locale/en_US/app.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: roadmap_upstream 1.0\n" "Report-Msgid-Bugs-To: contact@translation.io\n" -"POT-Creation-Date: 2025-04-10 13:28-0600\n" -"PO-Revision-Date: 2025-04-10 21:28+0200\n" +"POT-Creation-Date: 2025-12-23 08:33-0700\n" +"PO-Revision-Date: 2025-12-23 15:33+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: English\n" "Language: en_US\n" @@ -123,87 +123,95 @@ msgstr "" msgid "No Plans found" msgstr "" -#: ../../app/controllers/application_controller.rb:36 +#: ../../app/controllers/api/v2/base_api_controller.rb:72 +msgid "There was a problem in the server." +msgstr "" + +#: ../../app/controllers/api/v2/base_api_controller.rb:78 +msgid "The client is not authorized to perform this action." +msgstr "" + +#: ../../app/controllers/application_controller.rb:37 msgid "You are not authorized to perform this action." msgstr "" -#: ../../app/controllers/application_controller.rb:40 +#: ../../app/controllers/application_controller.rb:41 msgid "You need to sign in or sign up before continuing." msgstr "You need to sign in or sign up before continuing." -#: ../../app/controllers/application_controller.rb:108 +#: ../../app/controllers/application_controller.rb:115 msgid "Unable to %{action} the %{object}. %{errors}" msgstr "" -#: ../../app/controllers/application_controller.rb:114 +#: ../../app/controllers/application_controller.rb:121 msgid "Successfully %{action} the %{object}." msgstr "" -#: ../../app/controllers/application_controller.rb:127 +#: ../../app/controllers/application_controller.rb:134 msgid "API client" msgstr "" -#: ../../app/controllers/application_controller.rb:128 +#: ../../app/controllers/application_controller.rb:135 msgid "plan" msgstr "" -#: ../../app/controllers/application_controller.rb:129 +#: ../../app/controllers/application_controller.rb:136 msgid "guidance group" msgstr "" -#: ../../app/controllers/application_controller.rb:130 +#: ../../app/controllers/application_controller.rb:137 msgid "comment" msgstr "" -#: ../../app/controllers/application_controller.rb:131 +#: ../../app/controllers/application_controller.rb:138 msgid "organisation" msgstr "organization" -#: ../../app/controllers/application_controller.rb:132 +#: ../../app/controllers/application_controller.rb:139 msgid "permission" msgstr "" -#: ../../app/controllers/application_controller.rb:133 +#: ../../app/controllers/application_controller.rb:140 msgid "preferences" msgstr "" -#: ../../app/controllers/application_controller.rb:134 +#: ../../app/controllers/application_controller.rb:141 msgid "profile" msgstr "" -#: ../../app/controllers/application_controller.rb:134 +#: ../../app/controllers/application_controller.rb:141 msgid "user" msgstr "" -#: ../../app/controllers/application_controller.rb:135 +#: ../../app/controllers/application_controller.rb:142 msgid "question option" msgstr "" -#: ../../app/controllers/application_controller.rb:181 +#: ../../app/controllers/application_controller.rb:188 msgid "Record Not Found" msgstr "" -#: ../../app/controllers/concerns/paginable.rb:45 +#: ../../app/controllers/concerns/paginable.rb:46 msgid "scope should be an ActiveRecord::Relation object" msgstr "" -#: ../../app/controllers/concerns/paginable.rb:47 +#: ../../app/controllers/concerns/paginable.rb:48 msgid "path_params should be a Hash object" msgstr "" -#: ../../app/controllers/concerns/paginable.rb:48 +#: ../../app/controllers/concerns/paginable.rb:49 msgid "query_params should be a Hash object" msgstr "" -#: ../../app/controllers/concerns/paginable.rb:49 +#: ../../app/controllers/concerns/paginable.rb:50 msgid "locals should be a Hash object" msgstr "" -#: ../../app/controllers/concerns/paginable.rb:70 +#: ../../app/controllers/concerns/paginable.rb:71 msgid "Restricted access to View All the records" msgstr "" -#: ../../app/controllers/concerns/paginable.rb:183 +#: ../../app/controllers/concerns/paginable.rb:184 msgid "Sort by %{sort_field}" msgstr "" @@ -244,77 +252,77 @@ msgstr "Contact email was successfully sent." msgid "Unable to submit your request" msgstr "" -#: ../../app/controllers/contributors_controller.rb:40 -#: ../../app/controllers/contributors_controller.rb:56 +#: ../../app/controllers/contributors_controller.rb:41 +#: ../../app/controllers/contributors_controller.rb:57 #: ../../app/controllers/research_outputs_controller.rb:42 msgid "add" msgstr "" -#: ../../app/controllers/contributors_controller.rb:54 +#: ../../app/controllers/contributors_controller.rb:55 #: ../../app/controllers/research_outputs_controller.rb:40 msgid "added" msgstr "" -#: ../../app/controllers/contributors_controller.rb:72 +#: ../../app/controllers/contributors_controller.rb:73 #: ../../app/controllers/guidance_groups_controller.rb:55 #: ../../app/controllers/guidances_controller.rb:75 -#: ../../app/controllers/notes_controller.rb:88 +#: ../../app/controllers/notes_controller.rb:89 #: ../../app/controllers/org_admin/departments_controller.rb:50 #: ../../app/controllers/org_admin/sections_controller.rb:103 #: ../../app/controllers/org_admin/templates_controller.rb:210 #: ../../app/controllers/orgs_controller.rb:92 -#: ../../app/controllers/plans_controller.rb:280 -#: ../../app/controllers/plans_controller.rb:283 +#: ../../app/controllers/plans_controller.rb:281 +#: ../../app/controllers/plans_controller.rb:284 #: ../../app/controllers/registrations_controller.rb:249 #: ../../app/controllers/registrations_controller.rb:253 #: ../../app/controllers/registrations_controller.rb:280 #: ../../app/controllers/registrations_controller.rb:284 #: ../../app/controllers/research_outputs_controller.rb:60 -#: ../../app/controllers/users_controller.rb:103 -#: ../../app/controllers/users_controller.rb:131 +#: ../../app/controllers/users_controller.rb:104 +#: ../../app/controllers/users_controller.rb:132 msgid "saved" msgstr "" -#: ../../app/controllers/contributors_controller.rb:74 +#: ../../app/controllers/contributors_controller.rb:75 #: ../../app/controllers/guidance_groups_controller.rb:57 #: ../../app/controllers/guidances_controller.rb:77 -#: ../../app/controllers/notes_controller.rb:106 +#: ../../app/controllers/notes_controller.rb:107 #: ../../app/controllers/org_admin/departments_controller.rb:52 #: ../../app/controllers/org_admin/sections_controller.rb:105 #: ../../app/controllers/org_admin/templates_controller.rb:215 #: ../../app/controllers/orgs_controller.rb:94 -#: ../../app/controllers/plans_controller.rb:289 -#: ../../app/controllers/plans_controller.rb:292 -#: ../../app/controllers/plans_controller.rb:296 -#: ../../app/controllers/plans_controller.rb:299 +#: ../../app/controllers/plans_controller.rb:290 +#: ../../app/controllers/plans_controller.rb:293 +#: ../../app/controllers/plans_controller.rb:297 +#: ../../app/controllers/plans_controller.rb:300 #: ../../app/controllers/registrations_controller.rb:256 #: ../../app/controllers/registrations_controller.rb:287 #: ../../app/controllers/research_outputs_controller.rb:63 msgid "save" msgstr "" -#: ../../app/controllers/contributors_controller.rb:83 -#: ../../app/controllers/notes_controller.rb:130 +#: ../../app/controllers/contributors_controller.rb:84 +#: ../../app/controllers/notes_controller.rb:131 #: ../../app/controllers/org_admin/templates_controller.rb:243 #: ../../app/controllers/research_outputs_controller.rb:74 #: ../../app/controllers/super_admin/orgs_controller.rb:94 msgid "removed" msgstr "" -#: ../../app/controllers/contributors_controller.rb:86 -#: ../../app/controllers/notes_controller.rb:148 +#: ../../app/controllers/contributors_controller.rb:87 +#: ../../app/controllers/notes_controller.rb:149 #: ../../app/controllers/org_admin/templates_controller.rb:245 #: ../../app/controllers/research_outputs_controller.rb:77 #: ../../app/controllers/super_admin/orgs_controller.rb:97 msgid "remove" msgstr "" -#: ../../app/controllers/contributors_controller.rb:160 +#: ../../app/controllers/contributors_controller.rb:161 #: ../../app/controllers/research_outputs_controller.rb:208 msgid "plan not found" msgstr "" -#: ../../app/controllers/contributors_controller.rb:168 +#: ../../app/controllers/contributors_controller.rb:169 msgid "contributor not found" msgstr "" @@ -328,7 +336,7 @@ msgstr "" #: ../../app/controllers/guidance_groups_controller.rb:31 #: ../../app/controllers/guidances_controller.rb:53 -#: ../../app/controllers/notes_controller.rb:47 +#: ../../app/controllers/notes_controller.rb:48 #: ../../app/controllers/org_admin/departments_controller.rb:26 #: ../../app/controllers/org_admin/phases_controller.rb:121 #: ../../app/controllers/org_admin/questions_controller.rb:94 @@ -344,7 +352,7 @@ msgstr "" #: ../../app/controllers/guidance_groups_controller.rb:34 #: ../../app/controllers/guidances_controller.rb:55 -#: ../../app/controllers/notes_controller.rb:66 +#: ../../app/controllers/notes_controller.rb:67 #: ../../app/controllers/org_admin/departments_controller.rb:30 #: ../../app/controllers/org_admin/phases_controller.rb:123 #: ../../app/controllers/org_admin/questions_controller.rb:96 @@ -383,7 +391,7 @@ msgstr "" #: ../../app/controllers/org_admin/question_options_controller.rb:24 #: ../../app/controllers/org_admin/questions_controller.rb:197 #: ../../app/controllers/org_admin/sections_controller.rb:128 -#: ../../app/controllers/plans_controller.rb:342 +#: ../../app/controllers/plans_controller.rb:343 #: ../../app/controllers/super_admin/api_clients_controller.rb:81 #: ../../app/controllers/super_admin/notifications_controller.rb:85 #: ../../app/controllers/super_admin/themes_controller.rb:51 @@ -397,7 +405,7 @@ msgstr "" #: ../../app/controllers/org_admin/question_options_controller.rb:26 #: ../../app/controllers/org_admin/questions_controller.rb:199 #: ../../app/controllers/org_admin/sections_controller.rb:130 -#: ../../app/controllers/plans_controller.rb:347 +#: ../../app/controllers/plans_controller.rb:348 #: ../../app/controllers/super_admin/api_clients_controller.rb:84 #: ../../app/controllers/super_admin/notifications_controller.rb:88 #: ../../app/controllers/super_admin/themes_controller.rb:54 @@ -438,19 +446,19 @@ msgstr "" #: ../../app/controllers/org_admin/phases_controller.rb:147 #: ../../app/controllers/org_admin/questions_controller.rb:166 #: ../../app/controllers/org_admin/users_controller.rb:30 -#: ../../app/controllers/plans_controller.rb:416 +#: ../../app/controllers/plans_controller.rb:417 #: ../../app/controllers/super_admin/api_clients_controller.rb:68 #: ../../app/controllers/super_admin/notifications_controller.rb:52 #: ../../app/controllers/super_admin/themes_controller.rb:39 #: ../../app/controllers/super_admin/users_controller.rb:54 -#: ../../app/controllers/users_controller.rb:108 +#: ../../app/controllers/users_controller.rb:109 msgid "updated" msgstr "" #: ../../app/controllers/org_admin/phases_controller.rb:149 #: ../../app/controllers/org_admin/questions_controller.rb:169 #: ../../app/controllers/org_admin/users_controller.rb:32 -#: ../../app/controllers/plans_controller.rb:419 +#: ../../app/controllers/plans_controller.rb:420 #: ../../app/controllers/super_admin/api_clients_controller.rb:70 #: ../../app/controllers/super_admin/notifications_controller.rb:55 #: ../../app/controllers/super_admin/themes_controller.rb:41 @@ -540,7 +548,7 @@ msgid "Unable to delete this version of the template." msgstr "" #: ../../app/controllers/org_admin/template_copies_controller.rb:20 -#: ../../app/controllers/plans_controller.rb:395 +#: ../../app/controllers/plans_controller.rb:396 msgid "copy" msgstr "" @@ -549,11 +557,11 @@ msgstr "" msgid "That template is no longer customizable." msgstr "That template is no longer customizable." -#: ../../app/controllers/org_admin/template_customizations_controller.rb:21 +#: ../../app/controllers/org_admin/template_customizations_controller.rb:22 msgid "Unable to customize that template." msgstr "Unable to customize that template." -#: ../../app/controllers/org_admin/template_customizations_controller.rb:24 +#: ../../app/controllers/org_admin/template_customizations_controller.rb:25 msgid "That template is not customizable." msgstr "That template is not customizable." @@ -643,33 +651,33 @@ msgstr "" msgid "template with customisations by the" msgstr "" -#: ../../app/controllers/plans_controller.rb:393 +#: ../../app/controllers/plans_controller.rb:394 msgid "copied" msgstr "" -#: ../../app/controllers/plans_controller.rb:424 +#: ../../app/controllers/plans_controller.rb:425 msgid "" "Unable to change the plan's status since it is needed at least %{percentage} p" "ercentage responded" msgstr "" -#: ../../app/controllers/plans_controller.rb:430 +#: ../../app/controllers/plans_controller.rb:431 msgid "Unable to find plan id %{plan_id}" msgstr "" -#: ../../app/controllers/plans_controller.rb:445 +#: ../../app/controllers/plans_controller.rb:446 msgid "Your project is now a test." msgstr "" -#: ../../app/controllers/plans_controller.rb:445 +#: ../../app/controllers/plans_controller.rb:446 msgid "Your project is no longer a test." msgstr "" -#: ../../app/controllers/plans_controller.rb:449 +#: ../../app/controllers/plans_controller.rb:450 msgid "Unable to change the plan's test status" msgstr "" -#: ../../app/controllers/plans_controller.rb:462 +#: ../../app/controllers/plans_controller.rb:463 msgid "There is no plan associated with id %{s" msgstr "" @@ -756,7 +764,7 @@ msgstr "" msgid "research output not found" msgstr "" -#: ../../app/controllers/roles_controller.rb:26 +#: ../../app/controllers/roles_controller.rb:27 msgid "" "Cannot share plan with %{email} since that email matches\n" " with the owner of the plan." @@ -921,27 +929,27 @@ msgstr "" msgid "Unable to link your account to %{scheme}." msgstr "" -#: ../../app/controllers/users_controller.rb:149 +#: ../../app/controllers/users_controller.rb:150 msgid "Successfully %{action} %{username}'s account." msgstr "" -#: ../../app/controllers/users_controller.rb:150 +#: ../../app/controllers/users_controller.rb:151 msgid "activated" msgstr "" -#: ../../app/controllers/users_controller.rb:150 +#: ../../app/controllers/users_controller.rb:151 msgid "deactivated" msgstr "" -#: ../../app/controllers/users_controller.rb:156 +#: ../../app/controllers/users_controller.rb:157 msgid "Unable to %{action} %{username}" msgstr "" -#: ../../app/controllers/users_controller.rb:157 +#: ../../app/controllers/users_controller.rb:158 msgid "activate" msgstr "" -#: ../../app/controllers/users_controller.rb:157 +#: ../../app/controllers/users_controller.rb:158 msgid "deactivate" msgstr "" @@ -1221,50 +1229,50 @@ msgstr "" msgid "Last 12 months" msgstr "" -#: ../../app/mailers/user_mailer.rb:17 +#: ../../app/mailers/user_mailer.rb:18 #: ../../app/views/devise/mailer/invitation_instructions.html.erb:5 #: ../../app/views/devise/mailer/reset_password_instructions.html.erb:5 #: ../../app/views/user_mailer/_email_signature.html.erb:2 msgid "Query or feedback related to %{tool_name}" msgstr "" -#: ../../app/mailers/user_mailer.rb:25 +#: ../../app/mailers/user_mailer.rb:26 msgid "Welcome to %{tool_name}" msgstr "" -#: ../../app/mailers/user_mailer.rb:62 +#: ../../app/mailers/user_mailer.rb:63 msgid "A Data Management Plan in %{tool_name} has been shared with you" msgstr "" -#: ../../app/mailers/user_mailer.rb:79 +#: ../../app/mailers/user_mailer.rb:80 msgid "Changed permissions on a Data Management Plan in %{tool_name}" msgstr "" -#: ../../app/mailers/user_mailer.rb:94 +#: ../../app/mailers/user_mailer.rb:95 msgid "Permissions removed on a DMP in %{tool_name}" msgstr "" -#: ../../app/mailers/user_mailer.rb:112 +#: ../../app/mailers/user_mailer.rb:113 msgid "%{user_name} has requested feedback on a %{tool_name} plan" msgstr "" -#: ../../app/mailers/user_mailer.rb:135 +#: ../../app/mailers/user_mailer.rb:136 msgid "%{tool_name}: Expert feedback has been provided for %{plan_title}" msgstr "" -#: ../../app/mailers/user_mailer.rb:153 +#: ../../app/mailers/user_mailer.rb:154 msgid "DMP Visibility Changed: %{plan_title}" msgstr "" -#: ../../app/mailers/user_mailer.rb:182 +#: ../../app/mailers/user_mailer.rb:183 msgid "%{tool_name}: A new comment was added to %{plan_title}" msgstr "" -#: ../../app/mailers/user_mailer.rb:198 +#: ../../app/mailers/user_mailer.rb:199 msgid "Administrator privileges granted in %{tool_name}" msgstr "" -#: ../../app/mailers/user_mailer.rb:216 +#: ../../app/mailers/user_mailer.rb:217 msgid "%{tool_name} API changes" msgstr "" @@ -1494,15 +1502,15 @@ msgstr "" msgid "already assigned a value" msgstr "" -#: ../../app/models/org.rb:46 +#: ../../app/models/org.rb:47 msgid "Feedback email message" msgstr "" -#: ../../app/models/org.rb:123 +#: ../../app/models/org.rb:124 msgid "must be one of the following formats: jpeg, jpg, png, gif, bmp" msgstr "" -#: ../../app/models/org.rb:128 +#: ../../app/models/org.rb:129 msgid "can't be larger than 500KB" msgstr "" @@ -1626,7 +1634,7 @@ msgstr "" msgid "Conditions in the template refer backwards" msgstr "" -#: ../../app/models/user.rb:380 +#: ../../app/models/user.rb:386 msgid "A Data Management Plan in %{application_name} has been shared with you" msgstr "" @@ -2036,7 +2044,7 @@ msgstr "" #: ../../app/views/paginable/templates/_organisational.html.erb:87 #: ../../app/views/paginable/templates/_publicly_visible.html.erb:29 #: ../../app/views/paginable/templates/_publicly_visible.html.erb:36 -#: ../../app/views/plans/_download_form.html.erb:130 +#: ../../app/views/plans/_download_form.html.erb:133 #: ../../app/views/static_pages/about_us.html.erb:22 #: ../../app/views/static_pages/about_us.html.erb:29 #: ../../app/views/static_pages/termsuse.html.erb:46 @@ -4396,7 +4404,7 @@ msgstr "" msgid "Instructions" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:6 +#: ../../app/views/plans/_download_form.html.erb:5 msgid "Format" msgstr "" @@ -4404,71 +4412,71 @@ msgstr "" msgid "Download settings" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:19 -msgid "Select phase to download" -msgstr "" - -#: ../../app/views/plans/_download_form.html.erb:26 +#: ../../app/views/plans/_download_form.html.erb:21 msgid "Optional plan components" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:30 +#: ../../app/views/plans/_download_form.html.erb:25 msgid "project details coversheet" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:36 +#: ../../app/views/plans/_download_form.html.erb:31 msgid "question text and section headings" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:42 +#: ../../app/views/plans/_download_form.html.erb:37 msgid "unanswered questions" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:49 +#: ../../app/views/plans/_download_form.html.erb:44 msgid "research outputs" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:57 +#: ../../app/views/plans/_download_form.html.erb:52 msgid "supplementary section(s) not requested by funding organisation" msgstr "supplementary section(s) not requested by funding organization" -#: ../../app/views/plans/_download_form.html.erb:65 +#: ../../app/views/plans/_download_form.html.erb:61 +msgid "Select phase to download" +msgstr "" + +#: ../../app/views/plans/_download_form.html.erb:70 msgid "PDF formatting" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:68 +#: ../../app/views/plans/_download_form.html.erb:73 msgid "Font" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:71 +#: ../../app/views/plans/_download_form.html.erb:76 msgid "Margin (mm)" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:76 +#: ../../app/views/plans/_download_form.html.erb:81 msgid "Face" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:84 +#: ../../app/views/plans/_download_form.html.erb:89 msgid "Size" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:92 +#: ../../app/views/plans/_download_form.html.erb:96 msgid "Top" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:101 +#: ../../app/views/plans/_download_form.html.erb:105 msgid "Bottom" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:110 +#: ../../app/views/plans/_download_form.html.erb:114 msgid "Left" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:119 +#: ../../app/views/plans/_download_form.html.erb:123 msgid "Right" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:130 +#: ../../app/views/plans/_download_form.html.erb:133 msgid "" "Download Plan (new window)%{open_in_new_window_text}" diff --git a/config/locale/es/LC_MESSAGES/app.mo b/config/locale/es/LC_MESSAGES/app.mo index 7199660719043a156abb24556aeda2f7639978a6..5da2fa1dff3ad50936503e8c477f6706af1ba5c2 100644 GIT binary patch delta 56 zcmdnAfOFFV&W0_FXFd1~jdYES6$~t_jE!{-%%|V>V3dN28JYscv<(c}nLQb|GkY@W GvjYIyPYzfB delta 56 zcmdnAfOFFV&W0_FXFd1~Omqzm6by~6j4X5w%%\n" "Language-Team: Spanish\n" "Language: es\n" @@ -127,87 +127,95 @@ msgstr "JSON inválido" msgid "No Plans found" msgstr "No se encontraron planes" -#: ../../app/controllers/application_controller.rb:36 +#: ../../app/controllers/api/v2/base_api_controller.rb:72 +msgid "There was a problem in the server." +msgstr "" + +#: ../../app/controllers/api/v2/base_api_controller.rb:78 +msgid "The client is not authorized to perform this action." +msgstr "" + +#: ../../app/controllers/application_controller.rb:37 msgid "You are not authorized to perform this action." msgstr "Usted no está autorizado para realizar esta acción." -#: ../../app/controllers/application_controller.rb:40 +#: ../../app/controllers/application_controller.rb:41 msgid "You need to sign in or sign up before continuing." msgstr "Necesita iniciar sesión o registrarse para continuar." -#: ../../app/controllers/application_controller.rb:108 +#: ../../app/controllers/application_controller.rb:115 msgid "Unable to %{action} the %{object}. %{errors}" msgstr "No se puede %{action} el %{object}. %{errors}" -#: ../../app/controllers/application_controller.rb:114 +#: ../../app/controllers/application_controller.rb:121 msgid "Successfully %{action} the %{object}." msgstr "Con éxito %{action} el %{object}." -#: ../../app/controllers/application_controller.rb:127 +#: ../../app/controllers/application_controller.rb:134 msgid "API client" msgstr "Cliente API" -#: ../../app/controllers/application_controller.rb:128 +#: ../../app/controllers/application_controller.rb:135 msgid "plan" msgstr "Plan" -#: ../../app/controllers/application_controller.rb:129 +#: ../../app/controllers/application_controller.rb:136 msgid "guidance group" msgstr "grupo de orientación" -#: ../../app/controllers/application_controller.rb:130 +#: ../../app/controllers/application_controller.rb:137 msgid "comment" msgstr "Comentario" -#: ../../app/controllers/application_controller.rb:131 +#: ../../app/controllers/application_controller.rb:138 msgid "organisation" msgstr "organización" -#: ../../app/controllers/application_controller.rb:132 +#: ../../app/controllers/application_controller.rb:139 msgid "permission" msgstr "permiso" -#: ../../app/controllers/application_controller.rb:133 +#: ../../app/controllers/application_controller.rb:140 msgid "preferences" msgstr "Preferencias" -#: ../../app/controllers/application_controller.rb:134 +#: ../../app/controllers/application_controller.rb:141 msgid "profile" msgstr "Perfil" -#: ../../app/controllers/application_controller.rb:134 +#: ../../app/controllers/application_controller.rb:141 msgid "user" msgstr "user" -#: ../../app/controllers/application_controller.rb:135 +#: ../../app/controllers/application_controller.rb:142 msgid "question option" msgstr "opción de pregunta" -#: ../../app/controllers/application_controller.rb:181 +#: ../../app/controllers/application_controller.rb:188 msgid "Record Not Found" msgstr "Registro no encontrado" -#: ../../app/controllers/concerns/paginable.rb:45 +#: ../../app/controllers/concerns/paginable.rb:46 msgid "scope should be an ActiveRecord::Relation object" msgstr "el alcance debe ser un objeto ActiveRecord :: Relation" -#: ../../app/controllers/concerns/paginable.rb:47 +#: ../../app/controllers/concerns/paginable.rb:48 msgid "path_params should be a Hash object" msgstr "path_params debe ser un objeto Hash" -#: ../../app/controllers/concerns/paginable.rb:48 +#: ../../app/controllers/concerns/paginable.rb:49 msgid "query_params should be a Hash object" msgstr "query_params debe ser un objeto Hash" -#: ../../app/controllers/concerns/paginable.rb:49 +#: ../../app/controllers/concerns/paginable.rb:50 msgid "locals should be a Hash object" msgstr "los locales deberían ser un objeto Hash" -#: ../../app/controllers/concerns/paginable.rb:70 +#: ../../app/controllers/concerns/paginable.rb:71 msgid "Restricted access to View All the records" msgstr "Acceso restringido a Ver todos los registros." -#: ../../app/controllers/concerns/paginable.rb:183 +#: ../../app/controllers/concerns/paginable.rb:184 msgid "Sort by %{sort_field}" msgstr "Ordenar por %{sort_field}" @@ -248,77 +256,77 @@ msgstr "El correo electrónico de contacto fue enviado con éxito." msgid "Unable to submit your request" msgstr "No se puede enviar su solicitud" -#: ../../app/controllers/contributors_controller.rb:40 -#: ../../app/controllers/contributors_controller.rb:56 +#: ../../app/controllers/contributors_controller.rb:41 +#: ../../app/controllers/contributors_controller.rb:57 #: ../../app/controllers/research_outputs_controller.rb:42 msgid "add" msgstr "Añadir" -#: ../../app/controllers/contributors_controller.rb:54 +#: ../../app/controllers/contributors_controller.rb:55 #: ../../app/controllers/research_outputs_controller.rb:40 msgid "added" msgstr "Adicional" -#: ../../app/controllers/contributors_controller.rb:72 +#: ../../app/controllers/contributors_controller.rb:73 #: ../../app/controllers/guidance_groups_controller.rb:55 #: ../../app/controllers/guidances_controller.rb:75 -#: ../../app/controllers/notes_controller.rb:88 +#: ../../app/controllers/notes_controller.rb:89 #: ../../app/controllers/org_admin/departments_controller.rb:50 #: ../../app/controllers/org_admin/sections_controller.rb:103 #: ../../app/controllers/org_admin/templates_controller.rb:210 #: ../../app/controllers/orgs_controller.rb:92 -#: ../../app/controllers/plans_controller.rb:280 -#: ../../app/controllers/plans_controller.rb:283 +#: ../../app/controllers/plans_controller.rb:281 +#: ../../app/controllers/plans_controller.rb:284 #: ../../app/controllers/registrations_controller.rb:249 #: ../../app/controllers/registrations_controller.rb:253 #: ../../app/controllers/registrations_controller.rb:280 #: ../../app/controllers/registrations_controller.rb:284 #: ../../app/controllers/research_outputs_controller.rb:60 -#: ../../app/controllers/users_controller.rb:103 -#: ../../app/controllers/users_controller.rb:131 +#: ../../app/controllers/users_controller.rb:104 +#: ../../app/controllers/users_controller.rb:132 msgid "saved" msgstr "Guardado" -#: ../../app/controllers/contributors_controller.rb:74 +#: ../../app/controllers/contributors_controller.rb:75 #: ../../app/controllers/guidance_groups_controller.rb:57 #: ../../app/controllers/guidances_controller.rb:77 -#: ../../app/controllers/notes_controller.rb:106 +#: ../../app/controllers/notes_controller.rb:107 #: ../../app/controllers/org_admin/departments_controller.rb:52 #: ../../app/controllers/org_admin/sections_controller.rb:105 #: ../../app/controllers/org_admin/templates_controller.rb:215 #: ../../app/controllers/orgs_controller.rb:94 -#: ../../app/controllers/plans_controller.rb:289 -#: ../../app/controllers/plans_controller.rb:292 -#: ../../app/controllers/plans_controller.rb:296 -#: ../../app/controllers/plans_controller.rb:299 +#: ../../app/controllers/plans_controller.rb:290 +#: ../../app/controllers/plans_controller.rb:293 +#: ../../app/controllers/plans_controller.rb:297 +#: ../../app/controllers/plans_controller.rb:300 #: ../../app/controllers/registrations_controller.rb:256 #: ../../app/controllers/registrations_controller.rb:287 #: ../../app/controllers/research_outputs_controller.rb:63 msgid "save" msgstr "Guardar" -#: ../../app/controllers/contributors_controller.rb:83 -#: ../../app/controllers/notes_controller.rb:130 +#: ../../app/controllers/contributors_controller.rb:84 +#: ../../app/controllers/notes_controller.rb:131 #: ../../app/controllers/org_admin/templates_controller.rb:243 #: ../../app/controllers/research_outputs_controller.rb:74 #: ../../app/controllers/super_admin/orgs_controller.rb:94 msgid "removed" msgstr "remoto" -#: ../../app/controllers/contributors_controller.rb:86 -#: ../../app/controllers/notes_controller.rb:148 +#: ../../app/controllers/contributors_controller.rb:87 +#: ../../app/controllers/notes_controller.rb:149 #: ../../app/controllers/org_admin/templates_controller.rb:245 #: ../../app/controllers/research_outputs_controller.rb:77 #: ../../app/controllers/super_admin/orgs_controller.rb:97 msgid "remove" msgstr "Quitar" -#: ../../app/controllers/contributors_controller.rb:160 +#: ../../app/controllers/contributors_controller.rb:161 #: ../../app/controllers/research_outputs_controller.rb:208 msgid "plan not found" msgstr "Plan no encontrado" -#: ../../app/controllers/contributors_controller.rb:168 +#: ../../app/controllers/contributors_controller.rb:169 msgid "contributor not found" msgstr "contribuyente no encontrado" @@ -332,7 +340,7 @@ msgstr "Se produjo un error al solicitar comentarios para este plan." #: ../../app/controllers/guidance_groups_controller.rb:31 #: ../../app/controllers/guidances_controller.rb:53 -#: ../../app/controllers/notes_controller.rb:47 +#: ../../app/controllers/notes_controller.rb:48 #: ../../app/controllers/org_admin/departments_controller.rb:26 #: ../../app/controllers/org_admin/phases_controller.rb:121 #: ../../app/controllers/org_admin/questions_controller.rb:94 @@ -348,7 +356,7 @@ msgstr "creado" #: ../../app/controllers/guidance_groups_controller.rb:34 #: ../../app/controllers/guidances_controller.rb:55 -#: ../../app/controllers/notes_controller.rb:66 +#: ../../app/controllers/notes_controller.rb:67 #: ../../app/controllers/org_admin/departments_controller.rb:30 #: ../../app/controllers/org_admin/phases_controller.rb:123 #: ../../app/controllers/org_admin/questions_controller.rb:96 @@ -391,7 +399,7 @@ msgstr "Despublicar" #: ../../app/controllers/org_admin/question_options_controller.rb:24 #: ../../app/controllers/org_admin/questions_controller.rb:197 #: ../../app/controllers/org_admin/sections_controller.rb:128 -#: ../../app/controllers/plans_controller.rb:342 +#: ../../app/controllers/plans_controller.rb:343 #: ../../app/controllers/super_admin/api_clients_controller.rb:81 #: ../../app/controllers/super_admin/notifications_controller.rb:85 #: ../../app/controllers/super_admin/themes_controller.rb:51 @@ -405,7 +413,7 @@ msgstr "Suprimido" #: ../../app/controllers/org_admin/question_options_controller.rb:26 #: ../../app/controllers/org_admin/questions_controller.rb:199 #: ../../app/controllers/org_admin/sections_controller.rb:130 -#: ../../app/controllers/plans_controller.rb:347 +#: ../../app/controllers/plans_controller.rb:348 #: ../../app/controllers/super_admin/api_clients_controller.rb:84 #: ../../app/controllers/super_admin/notifications_controller.rb:88 #: ../../app/controllers/super_admin/themes_controller.rb:54 @@ -446,19 +454,19 @@ msgstr "No se puede crear una nueva versión de esta plantilla.
" #: ../../app/controllers/org_admin/phases_controller.rb:147 #: ../../app/controllers/org_admin/questions_controller.rb:166 #: ../../app/controllers/org_admin/users_controller.rb:30 -#: ../../app/controllers/plans_controller.rb:416 +#: ../../app/controllers/plans_controller.rb:417 #: ../../app/controllers/super_admin/api_clients_controller.rb:68 #: ../../app/controllers/super_admin/notifications_controller.rb:52 #: ../../app/controllers/super_admin/themes_controller.rb:39 #: ../../app/controllers/super_admin/users_controller.rb:54 -#: ../../app/controllers/users_controller.rb:108 +#: ../../app/controllers/users_controller.rb:109 msgid "updated" msgstr "Actualizado" #: ../../app/controllers/org_admin/phases_controller.rb:149 #: ../../app/controllers/org_admin/questions_controller.rb:169 #: ../../app/controllers/org_admin/users_controller.rb:32 -#: ../../app/controllers/plans_controller.rb:419 +#: ../../app/controllers/plans_controller.rb:420 #: ../../app/controllers/super_admin/api_clients_controller.rb:70 #: ../../app/controllers/super_admin/notifications_controller.rb:55 #: ../../app/controllers/super_admin/themes_controller.rb:41 @@ -550,7 +558,7 @@ msgid "Unable to delete this version of the template." msgstr "No se puede eliminar esta versión de la plantilla." #: ../../app/controllers/org_admin/template_copies_controller.rb:20 -#: ../../app/controllers/plans_controller.rb:395 +#: ../../app/controllers/plans_controller.rb:396 msgid "copy" msgstr "Dupdo" @@ -559,11 +567,11 @@ msgstr "Dupdo" msgid "That template is no longer customizable." msgstr "Esa plantilla ya no es personalizable." -#: ../../app/controllers/org_admin/template_customizations_controller.rb:21 +#: ../../app/controllers/org_admin/template_customizations_controller.rb:22 msgid "Unable to customize that template." msgstr "No se puede personalizar esa plantilla." -#: ../../app/controllers/org_admin/template_customizations_controller.rb:24 +#: ../../app/controllers/org_admin/template_customizations_controller.rb:25 msgid "That template is not customizable." msgstr "Esa plantilla no es personalizable." @@ -655,11 +663,11 @@ msgstr "Este plan se basa en el" msgid "template with customisations by the" msgstr "plantilla con personalizaciones por el" -#: ../../app/controllers/plans_controller.rb:393 +#: ../../app/controllers/plans_controller.rb:394 msgid "copied" msgstr "copiado" -#: ../../app/controllers/plans_controller.rb:424 +#: ../../app/controllers/plans_controller.rb:425 msgid "" "Unable to change the plan's status since it is needed at least %{percentage} p" "ercentage responded" @@ -667,23 +675,23 @@ msgstr "" "No se puede cambiar el estado del plan ya que se necesita al menos el porcenta" "je %{percentage} respondido" -#: ../../app/controllers/plans_controller.rb:430 +#: ../../app/controllers/plans_controller.rb:431 msgid "Unable to find plan id %{plan_id}" msgstr "No se puede encontrar la identificación del plan %{plan_id}" -#: ../../app/controllers/plans_controller.rb:445 +#: ../../app/controllers/plans_controller.rb:446 msgid "Your project is now a test." msgstr "Tu proyecto es ahora una prueba." -#: ../../app/controllers/plans_controller.rb:445 +#: ../../app/controllers/plans_controller.rb:446 msgid "Your project is no longer a test." msgstr "Tu proyecto ya no es una prueba." -#: ../../app/controllers/plans_controller.rb:449 +#: ../../app/controllers/plans_controller.rb:450 msgid "Unable to change the plan's test status" msgstr "No se puede cambiar el estado de prueba del plan" -#: ../../app/controllers/plans_controller.rb:462 +#: ../../app/controllers/plans_controller.rb:463 msgid "There is no plan associated with id %{s" msgstr "No hay plan asociado con id %{ s" @@ -781,7 +789,7 @@ msgstr "La contraseña y la confirmación deben coincidir" msgid "research output not found" msgstr "resultado de la investigación no encontrado" -#: ../../app/controllers/roles_controller.rb:26 +#: ../../app/controllers/roles_controller.rb:27 msgid "" "Cannot share plan with %{email} since that email matches\n" " with the owner of the plan." @@ -960,27 +968,27 @@ msgstr "Su cuenta se ha vinculado con éxito a %{scheme}." msgid "Unable to link your account to %{scheme}." msgstr "No se puede vincular su cuenta a %{scheme}." -#: ../../app/controllers/users_controller.rb:149 +#: ../../app/controllers/users_controller.rb:150 msgid "Successfully %{action} %{username}'s account." msgstr "Con éxito la cuenta de %{action} %{username}." -#: ../../app/controllers/users_controller.rb:150 +#: ../../app/controllers/users_controller.rb:151 msgid "activated" msgstr "activado" -#: ../../app/controllers/users_controller.rb:150 +#: ../../app/controllers/users_controller.rb:151 msgid "deactivated" msgstr "Desactivado" -#: ../../app/controllers/users_controller.rb:156 +#: ../../app/controllers/users_controller.rb:157 msgid "Unable to %{action} %{username}" msgstr "No se puede %{action} %{username}" -#: ../../app/controllers/users_controller.rb:157 +#: ../../app/controllers/users_controller.rb:158 msgid "activate" msgstr "Activar" -#: ../../app/controllers/users_controller.rb:157 +#: ../../app/controllers/users_controller.rb:158 msgid "deactivate" msgstr "Desactivar" @@ -1273,50 +1281,50 @@ msgstr "Últimos 9 meses" msgid "Last 12 months" msgstr "Últimos 12 meses" -#: ../../app/mailers/user_mailer.rb:17 +#: ../../app/mailers/user_mailer.rb:18 #: ../../app/views/devise/mailer/invitation_instructions.html.erb:5 #: ../../app/views/devise/mailer/reset_password_instructions.html.erb:5 #: ../../app/views/user_mailer/_email_signature.html.erb:2 msgid "Query or feedback related to %{tool_name}" msgstr "Consulta o feedback relacionado con %{tool_name}" -#: ../../app/mailers/user_mailer.rb:25 +#: ../../app/mailers/user_mailer.rb:26 msgid "Welcome to %{tool_name}" msgstr "Bienvenido a %{tool_name}" -#: ../../app/mailers/user_mailer.rb:62 +#: ../../app/mailers/user_mailer.rb:63 msgid "A Data Management Plan in %{tool_name} has been shared with you" msgstr "Se ha compartido con usted un Plan de gestión de datos en %{tool_name}" -#: ../../app/mailers/user_mailer.rb:79 +#: ../../app/mailers/user_mailer.rb:80 msgid "Changed permissions on a Data Management Plan in %{tool_name}" msgstr "Cambios de permisos en un plan de gestión de datos en %{tool_name}" -#: ../../app/mailers/user_mailer.rb:94 +#: ../../app/mailers/user_mailer.rb:95 msgid "Permissions removed on a DMP in %{tool_name}" msgstr "Permisos eliminados en un DMP en %{tool_name}" -#: ../../app/mailers/user_mailer.rb:112 +#: ../../app/mailers/user_mailer.rb:113 msgid "%{user_name} has requested feedback on a %{tool_name} plan" msgstr "%{user_name} ha solicitado comentarios sobre un plan %{tool_name}" -#: ../../app/mailers/user_mailer.rb:135 +#: ../../app/mailers/user_mailer.rb:136 msgid "%{tool_name}: Expert feedback has been provided for %{plan_title}" msgstr "%{tool_name}: Se han proporcionado comentarios de expertos para %{plan_title}" -#: ../../app/mailers/user_mailer.rb:153 +#: ../../app/mailers/user_mailer.rb:154 msgid "DMP Visibility Changed: %{plan_title}" msgstr "Se modificó la visibilidad de DMP: %{plan_title}" -#: ../../app/mailers/user_mailer.rb:182 +#: ../../app/mailers/user_mailer.rb:183 msgid "%{tool_name}: A new comment was added to %{plan_title}" msgstr "%{tool_name}: Se agregó un nuevo comentario a %{plan_title}" -#: ../../app/mailers/user_mailer.rb:198 +#: ../../app/mailers/user_mailer.rb:199 msgid "Administrator privileges granted in %{tool_name}" msgstr "Privilegios de administrador otorgados en %{tool_name}" -#: ../../app/mailers/user_mailer.rb:216 +#: ../../app/mailers/user_mailer.rb:217 msgid "%{tool_name} API changes" msgstr "%{tool_name} Cambios de API" @@ -1556,15 +1564,15 @@ msgstr "" msgid "already assigned a value" msgstr "ya asignado un valor" -#: ../../app/models/org.rb:46 +#: ../../app/models/org.rb:47 msgid "Feedback email message" msgstr "Mensaje de correo electrónico de comentarios" -#: ../../app/models/org.rb:123 +#: ../../app/models/org.rb:124 msgid "must be one of the following formats: jpeg, jpg, png, gif, bmp" msgstr "debe ser uno de los siguientes formatos: jpeg, jpg, png, gif, bmp" -#: ../../app/models/org.rb:128 +#: ../../app/models/org.rb:129 msgid "can't be larger than 500KB" msgstr "no puede ser más grande que 500KB" @@ -1690,7 +1698,7 @@ msgstr "No se puede publicar una plantilla sin preguntas en una sección." msgid "Conditions in the template refer backwards" msgstr "Las condiciones en la plantilla se refieren al revés" -#: ../../app/models/user.rb:380 +#: ../../app/models/user.rb:386 msgid "A Data Management Plan in %{application_name} has been shared with you" msgstr "Se ha compartido un plan de gestión de datos en %{application_name} con usted" @@ -2120,7 +2128,7 @@ msgstr "" #: ../../app/views/paginable/templates/_organisational.html.erb:87 #: ../../app/views/paginable/templates/_publicly_visible.html.erb:29 #: ../../app/views/paginable/templates/_publicly_visible.html.erb:36 -#: ../../app/views/plans/_download_form.html.erb:130 +#: ../../app/views/plans/_download_form.html.erb:133 #: ../../app/views/static_pages/about_us.html.erb:22 #: ../../app/views/static_pages/about_us.html.erb:29 #: ../../app/views/static_pages/termsuse.html.erb:46 @@ -4633,7 +4641,7 @@ msgstr "Comentarios y orientación" msgid "Instructions" msgstr "Instrucciones" -#: ../../app/views/plans/_download_form.html.erb:6 +#: ../../app/views/plans/_download_form.html.erb:5 msgid "Format" msgstr "Formato" @@ -4641,71 +4649,71 @@ msgstr "Formato" msgid "Download settings" msgstr "Descargar ajustes" -#: ../../app/views/plans/_download_form.html.erb:19 -msgid "Select phase to download" -msgstr "Seleccione la fase para descargar" - -#: ../../app/views/plans/_download_form.html.erb:26 +#: ../../app/views/plans/_download_form.html.erb:21 msgid "Optional plan components" msgstr "Componentes opcionales del plan" -#: ../../app/views/plans/_download_form.html.erb:30 +#: ../../app/views/plans/_download_form.html.erb:25 msgid "project details coversheet" msgstr "detalles del proyecto portada" -#: ../../app/views/plans/_download_form.html.erb:36 +#: ../../app/views/plans/_download_form.html.erb:31 msgid "question text and section headings" msgstr "texto de la pregunta y encabezados de sección" -#: ../../app/views/plans/_download_form.html.erb:42 +#: ../../app/views/plans/_download_form.html.erb:37 msgid "unanswered questions" msgstr "preguntas sin respuesta" -#: ../../app/views/plans/_download_form.html.erb:49 +#: ../../app/views/plans/_download_form.html.erb:44 msgid "research outputs" msgstr "resultados de la investigación" -#: ../../app/views/plans/_download_form.html.erb:57 +#: ../../app/views/plans/_download_form.html.erb:52 msgid "supplementary section(s) not requested by funding organisation" msgstr "Secciones complementarias no solicitadas por la organización financiadora" -#: ../../app/views/plans/_download_form.html.erb:65 +#: ../../app/views/plans/_download_form.html.erb:61 +msgid "Select phase to download" +msgstr "Seleccione la fase para descargar" + +#: ../../app/views/plans/_download_form.html.erb:70 msgid "PDF formatting" msgstr "Formato PDF" -#: ../../app/views/plans/_download_form.html.erb:68 +#: ../../app/views/plans/_download_form.html.erb:73 msgid "Font" msgstr "Fuente" -#: ../../app/views/plans/_download_form.html.erb:71 +#: ../../app/views/plans/_download_form.html.erb:76 msgid "Margin (mm)" msgstr "Margen (mm)" -#: ../../app/views/plans/_download_form.html.erb:76 +#: ../../app/views/plans/_download_form.html.erb:81 msgid "Face" msgstr "Estilo" -#: ../../app/views/plans/_download_form.html.erb:84 +#: ../../app/views/plans/_download_form.html.erb:89 msgid "Size" msgstr "Tamaño" -#: ../../app/views/plans/_download_form.html.erb:92 +#: ../../app/views/plans/_download_form.html.erb:96 msgid "Top" msgstr "Superior" -#: ../../app/views/plans/_download_form.html.erb:101 +#: ../../app/views/plans/_download_form.html.erb:105 msgid "Bottom" msgstr "Inferior" -#: ../../app/views/plans/_download_form.html.erb:110 +#: ../../app/views/plans/_download_form.html.erb:114 msgid "Left" msgstr "Izquierdo" -#: ../../app/views/plans/_download_form.html.erb:119 +#: ../../app/views/plans/_download_form.html.erb:123 msgid "Right" msgstr "Derecho" -#: ../../app/views/plans/_download_form.html.erb:130 +#: ../../app/views/plans/_download_form.html.erb:133 msgid "" "Download Plan (new window)%{open_in_new_window_text}" diff --git a/config/locale/fi/LC_MESSAGES/app.mo b/config/locale/fi/LC_MESSAGES/app.mo index bf7f0bf1d13656e7e608d8b1025705cda9aba8b6..1e5af65c720e4ef03539b5391c23d8ee1374c8b9 100644 GIT binary patch delta 23007 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 diff --git a/config/locale/fi/app.po b/config/locale/fi/app.po index da6ecaa6c3..b2c9d08948 100644 --- a/config/locale/fi/app.po +++ b/config/locale/fi/app.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: roadmap_upstream 1.0\n" "Report-Msgid-Bugs-To: contact@translation.io\n" -"POT-Creation-Date: 2025-04-10 13:28-0600\n" -"PO-Revision-Date: 2025-04-10 21:28+0200\n" +"POT-Creation-Date: 2025-12-23 08:33-0700\n" +"PO-Revision-Date: 2025-12-23 15:33+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Finnish\n" "Language: fi\n" @@ -129,87 +129,95 @@ msgstr "Virheellinen JSON" msgid "No Plans found" msgstr "Suunnitelmia ei löytynyt" -#: ../../app/controllers/application_controller.rb:36 +#: ../../app/controllers/api/v2/base_api_controller.rb:72 +msgid "There was a problem in the server." +msgstr "Palvelimella oli ongelma." + +#: ../../app/controllers/api/v2/base_api_controller.rb:78 +msgid "The client is not authorized to perform this action." +msgstr "Asiakkaalla ei ole oikeutta suorittaa tätä toimintoa." + +#: ../../app/controllers/application_controller.rb:37 msgid "You are not authorized to perform this action." msgstr "Sinulla ei ole oikeuksia suorittaa tätä toimintoa." -#: ../../app/controllers/application_controller.rb:40 +#: ../../app/controllers/application_controller.rb:41 msgid "You need to sign in or sign up before continuing." msgstr "Kirjaudu sisään tai rekisteröidy jatkaaksesi." -#: ../../app/controllers/application_controller.rb:108 +#: ../../app/controllers/application_controller.rb:115 msgid "Unable to %{action} the %{object}. %{errors}" msgstr "Ei voida %{action} %{object}. %{errors}" -#: ../../app/controllers/application_controller.rb:114 +#: ../../app/controllers/application_controller.rb:121 msgid "Successfully %{action} the %{object}." msgstr "%{object}:n %{action} onnistui." -#: ../../app/controllers/application_controller.rb:127 +#: ../../app/controllers/application_controller.rb:134 msgid "API client" msgstr "API-asiakas" -#: ../../app/controllers/application_controller.rb:128 +#: ../../app/controllers/application_controller.rb:135 msgid "plan" msgstr "suunnitelma" -#: ../../app/controllers/application_controller.rb:129 +#: ../../app/controllers/application_controller.rb:136 msgid "guidance group" msgstr "ohjeryhmä" -#: ../../app/controllers/application_controller.rb:130 +#: ../../app/controllers/application_controller.rb:137 msgid "comment" msgstr "kommentti" -#: ../../app/controllers/application_controller.rb:131 +#: ../../app/controllers/application_controller.rb:138 msgid "organisation" msgstr "organisaatio" -#: ../../app/controllers/application_controller.rb:132 +#: ../../app/controllers/application_controller.rb:139 msgid "permission" msgstr "käyttöoikeus" -#: ../../app/controllers/application_controller.rb:133 +#: ../../app/controllers/application_controller.rb:140 msgid "preferences" msgstr "asetukset" -#: ../../app/controllers/application_controller.rb:134 +#: ../../app/controllers/application_controller.rb:141 msgid "profile" msgstr "käyttäjätiedot" -#: ../../app/controllers/application_controller.rb:134 +#: ../../app/controllers/application_controller.rb:141 msgid "user" msgstr "käyttäjä" -#: ../../app/controllers/application_controller.rb:135 +#: ../../app/controllers/application_controller.rb:142 msgid "question option" msgstr "kysymysvaihtoehto" -#: ../../app/controllers/application_controller.rb:181 +#: ../../app/controllers/application_controller.rb:188 msgid "Record Not Found" msgstr "Levyä ei löydy" -#: ../../app/controllers/concerns/paginable.rb:45 +#: ../../app/controllers/concerns/paginable.rb:46 msgid "scope should be an ActiveRecord::Relation object" msgstr "kohteen pitäisi olla ActiveRecord::Relation object" -#: ../../app/controllers/concerns/paginable.rb:47 +#: ../../app/controllers/concerns/paginable.rb:48 msgid "path_params should be a Hash object" msgstr "path_params pitäisi olla Hash object" -#: ../../app/controllers/concerns/paginable.rb:48 +#: ../../app/controllers/concerns/paginable.rb:49 msgid "query_params should be a Hash object" msgstr "query_params pitäisi olla Hash object" -#: ../../app/controllers/concerns/paginable.rb:49 +#: ../../app/controllers/concerns/paginable.rb:50 msgid "locals should be a Hash object" msgstr "paikalliset pitäisi olla Hash objekti" -#: ../../app/controllers/concerns/paginable.rb:70 +#: ../../app/controllers/concerns/paginable.rb:71 msgid "Restricted access to View All the records" msgstr "Kaikkien tietojen tarkastelu on rajoitettu" -#: ../../app/controllers/concerns/paginable.rb:183 +#: ../../app/controllers/concerns/paginable.rb:184 msgid "Sort by %{sort_field}" msgstr "Järjestä %{sort_field}" @@ -250,77 +258,77 @@ msgstr "Sähköpostin lähettäminen onnistui." msgid "Unable to submit your request" msgstr "Pyyntösi ei onnistu" -#: ../../app/controllers/contributors_controller.rb:40 -#: ../../app/controllers/contributors_controller.rb:56 +#: ../../app/controllers/contributors_controller.rb:41 +#: ../../app/controllers/contributors_controller.rb:57 #: ../../app/controllers/research_outputs_controller.rb:42 msgid "add" msgstr "lisätä" -#: ../../app/controllers/contributors_controller.rb:54 +#: ../../app/controllers/contributors_controller.rb:55 #: ../../app/controllers/research_outputs_controller.rb:40 msgid "added" msgstr "lisä-" -#: ../../app/controllers/contributors_controller.rb:72 +#: ../../app/controllers/contributors_controller.rb:73 #: ../../app/controllers/guidance_groups_controller.rb:55 #: ../../app/controllers/guidances_controller.rb:75 -#: ../../app/controllers/notes_controller.rb:88 +#: ../../app/controllers/notes_controller.rb:89 #: ../../app/controllers/org_admin/departments_controller.rb:50 #: ../../app/controllers/org_admin/sections_controller.rb:103 #: ../../app/controllers/org_admin/templates_controller.rb:210 #: ../../app/controllers/orgs_controller.rb:92 -#: ../../app/controllers/plans_controller.rb:280 -#: ../../app/controllers/plans_controller.rb:283 +#: ../../app/controllers/plans_controller.rb:281 +#: ../../app/controllers/plans_controller.rb:284 #: ../../app/controllers/registrations_controller.rb:249 #: ../../app/controllers/registrations_controller.rb:253 #: ../../app/controllers/registrations_controller.rb:280 #: ../../app/controllers/registrations_controller.rb:284 #: ../../app/controllers/research_outputs_controller.rb:60 -#: ../../app/controllers/users_controller.rb:103 -#: ../../app/controllers/users_controller.rb:131 +#: ../../app/controllers/users_controller.rb:104 +#: ../../app/controllers/users_controller.rb:132 msgid "saved" msgstr "tallennettu" -#: ../../app/controllers/contributors_controller.rb:74 +#: ../../app/controllers/contributors_controller.rb:75 #: ../../app/controllers/guidance_groups_controller.rb:57 #: ../../app/controllers/guidances_controller.rb:77 -#: ../../app/controllers/notes_controller.rb:106 +#: ../../app/controllers/notes_controller.rb:107 #: ../../app/controllers/org_admin/departments_controller.rb:52 #: ../../app/controllers/org_admin/sections_controller.rb:105 #: ../../app/controllers/org_admin/templates_controller.rb:215 #: ../../app/controllers/orgs_controller.rb:94 -#: ../../app/controllers/plans_controller.rb:289 -#: ../../app/controllers/plans_controller.rb:292 -#: ../../app/controllers/plans_controller.rb:296 -#: ../../app/controllers/plans_controller.rb:299 +#: ../../app/controllers/plans_controller.rb:290 +#: ../../app/controllers/plans_controller.rb:293 +#: ../../app/controllers/plans_controller.rb:297 +#: ../../app/controllers/plans_controller.rb:300 #: ../../app/controllers/registrations_controller.rb:256 #: ../../app/controllers/registrations_controller.rb:287 #: ../../app/controllers/research_outputs_controller.rb:63 msgid "save" msgstr "tallenna" -#: ../../app/controllers/contributors_controller.rb:83 -#: ../../app/controllers/notes_controller.rb:130 +#: ../../app/controllers/contributors_controller.rb:84 +#: ../../app/controllers/notes_controller.rb:131 #: ../../app/controllers/org_admin/templates_controller.rb:243 #: ../../app/controllers/research_outputs_controller.rb:74 #: ../../app/controllers/super_admin/orgs_controller.rb:94 msgid "removed" msgstr "poistettu" -#: ../../app/controllers/contributors_controller.rb:86 -#: ../../app/controllers/notes_controller.rb:148 +#: ../../app/controllers/contributors_controller.rb:87 +#: ../../app/controllers/notes_controller.rb:149 #: ../../app/controllers/org_admin/templates_controller.rb:245 #: ../../app/controllers/research_outputs_controller.rb:77 #: ../../app/controllers/super_admin/orgs_controller.rb:97 msgid "remove" msgstr "poista" -#: ../../app/controllers/contributors_controller.rb:160 +#: ../../app/controllers/contributors_controller.rb:161 #: ../../app/controllers/research_outputs_controller.rb:208 msgid "plan not found" msgstr "Suunnitelmaa ei löytynyt" -#: ../../app/controllers/contributors_controller.rb:168 +#: ../../app/controllers/contributors_controller.rb:169 msgid "contributor not found" msgstr "osallistujaa ei löytynyt" @@ -334,7 +342,7 @@ msgstr "Tapahtui virhe, kun pyysit palautetta tälle suunnitelmalle." #: ../../app/controllers/guidance_groups_controller.rb:31 #: ../../app/controllers/guidances_controller.rb:53 -#: ../../app/controllers/notes_controller.rb:47 +#: ../../app/controllers/notes_controller.rb:48 #: ../../app/controllers/org_admin/departments_controller.rb:26 #: ../../app/controllers/org_admin/phases_controller.rb:121 #: ../../app/controllers/org_admin/questions_controller.rb:94 @@ -350,7 +358,7 @@ msgstr "luominen" #: ../../app/controllers/guidance_groups_controller.rb:34 #: ../../app/controllers/guidances_controller.rb:55 -#: ../../app/controllers/notes_controller.rb:66 +#: ../../app/controllers/notes_controller.rb:67 #: ../../app/controllers/org_admin/departments_controller.rb:30 #: ../../app/controllers/org_admin/phases_controller.rb:123 #: ../../app/controllers/org_admin/questions_controller.rb:96 @@ -389,7 +397,7 @@ msgstr "piilota" #: ../../app/controllers/org_admin/question_options_controller.rb:24 #: ../../app/controllers/org_admin/questions_controller.rb:197 #: ../../app/controllers/org_admin/sections_controller.rb:128 -#: ../../app/controllers/plans_controller.rb:342 +#: ../../app/controllers/plans_controller.rb:343 #: ../../app/controllers/super_admin/api_clients_controller.rb:81 #: ../../app/controllers/super_admin/notifications_controller.rb:85 #: ../../app/controllers/super_admin/themes_controller.rb:51 @@ -403,7 +411,7 @@ msgstr "poistettu" #: ../../app/controllers/org_admin/question_options_controller.rb:26 #: ../../app/controllers/org_admin/questions_controller.rb:199 #: ../../app/controllers/org_admin/sections_controller.rb:130 -#: ../../app/controllers/plans_controller.rb:347 +#: ../../app/controllers/plans_controller.rb:348 #: ../../app/controllers/super_admin/api_clients_controller.rb:84 #: ../../app/controllers/super_admin/notifications_controller.rb:88 #: ../../app/controllers/super_admin/themes_controller.rb:54 @@ -446,19 +454,19 @@ msgstr "Tästä mallista ei voi luoda uutta versiota.
" #: ../../app/controllers/org_admin/phases_controller.rb:147 #: ../../app/controllers/org_admin/questions_controller.rb:166 #: ../../app/controllers/org_admin/users_controller.rb:30 -#: ../../app/controllers/plans_controller.rb:416 +#: ../../app/controllers/plans_controller.rb:417 #: ../../app/controllers/super_admin/api_clients_controller.rb:68 #: ../../app/controllers/super_admin/notifications_controller.rb:52 #: ../../app/controllers/super_admin/themes_controller.rb:39 #: ../../app/controllers/super_admin/users_controller.rb:54 -#: ../../app/controllers/users_controller.rb:108 +#: ../../app/controllers/users_controller.rb:109 msgid "updated" msgstr "päivitetty" #: ../../app/controllers/org_admin/phases_controller.rb:149 #: ../../app/controllers/org_admin/questions_controller.rb:169 #: ../../app/controllers/org_admin/users_controller.rb:32 -#: ../../app/controllers/plans_controller.rb:419 +#: ../../app/controllers/plans_controller.rb:420 #: ../../app/controllers/super_admin/api_clients_controller.rb:70 #: ../../app/controllers/super_admin/notifications_controller.rb:55 #: ../../app/controllers/super_admin/themes_controller.rb:41 @@ -548,7 +556,7 @@ msgid "Unable to delete this version of the template." msgstr "Tätä mallin versiota ei voi poistaa." #: ../../app/controllers/org_admin/template_copies_controller.rb:20 -#: ../../app/controllers/plans_controller.rb:395 +#: ../../app/controllers/plans_controller.rb:396 msgid "copy" msgstr "kopio" @@ -557,11 +565,11 @@ msgstr "kopio" msgid "That template is no longer customizable." msgstr "Suunnitelmapohjaa ei voi enää mukauttaa." -#: ../../app/controllers/org_admin/template_customizations_controller.rb:21 +#: ../../app/controllers/org_admin/template_customizations_controller.rb:22 msgid "Unable to customize that template." msgstr "Suunnitelmapohjan mukauttaminen ei onnistu." -#: ../../app/controllers/org_admin/template_customizations_controller.rb:24 +#: ../../app/controllers/org_admin/template_customizations_controller.rb:25 msgid "That template is not customizable." msgstr "Suunnitelmapohjaa ei voi mukauttaa." @@ -653,11 +661,11 @@ msgstr "Suunnitelma perustuu" msgid "template with customisations by the" msgstr "malli asiakassuhteiden mukauttamisella" -#: ../../app/controllers/plans_controller.rb:393 +#: ../../app/controllers/plans_controller.rb:394 msgid "copied" msgstr "kopionti" -#: ../../app/controllers/plans_controller.rb:424 +#: ../../app/controllers/plans_controller.rb:425 msgid "" "Unable to change the plan's status since it is needed at least %{percentage} p" "ercentage responded" @@ -665,23 +673,23 @@ msgstr "" "Suunnitelman tilan muuttaminen ei onnistunut, koska vähintään %{percentage}:a " "vastauksista pitää olla vastattuna" -#: ../../app/controllers/plans_controller.rb:430 +#: ../../app/controllers/plans_controller.rb:431 msgid "Unable to find plan id %{plan_id}" msgstr "Suunnitelman tunnistetta %{plan_id} ei löydy" -#: ../../app/controllers/plans_controller.rb:445 +#: ../../app/controllers/plans_controller.rb:446 msgid "Your project is now a test." msgstr "Projektisi on nyt testimuodossa." -#: ../../app/controllers/plans_controller.rb:445 +#: ../../app/controllers/plans_controller.rb:446 msgid "Your project is no longer a test." msgstr "Projektisi ei ole enää testimuodossa." -#: ../../app/controllers/plans_controller.rb:449 +#: ../../app/controllers/plans_controller.rb:450 msgid "Unable to change the plan's test status" msgstr "Suunnitelman testistatuksen muuttaminen ei onnistu" -#: ../../app/controllers/plans_controller.rb:462 +#: ../../app/controllers/plans_controller.rb:463 msgid "There is no plan associated with id %{s" msgstr "Tunnukseen %{ ei liity suunnitelmaa s" @@ -775,7 +783,7 @@ msgstr "Salasanan ja sen vahvistuksen on oltava samoja" msgid "research output not found" msgstr "tutkimustulosta ei löytynyt" -#: ../../app/controllers/roles_controller.rb:26 +#: ../../app/controllers/roles_controller.rb:27 msgid "" "Cannot share plan with %{email} since that email matches\n" " with the owner of the plan." @@ -950,27 +958,27 @@ msgstr "Tilisi liitettiin onnistuneesti %{scheme}:n." msgid "Unable to link your account to %{scheme}." msgstr "Tilisi liittäminen %{scheme}:hin ei onnistunut." -#: ../../app/controllers/users_controller.rb:149 +#: ../../app/controllers/users_controller.rb:150 msgid "Successfully %{action} %{username}'s account." msgstr "%{username}n tilin %{action} onnistui." -#: ../../app/controllers/users_controller.rb:150 +#: ../../app/controllers/users_controller.rb:151 msgid "activated" msgstr "aktivoitu" -#: ../../app/controllers/users_controller.rb:150 +#: ../../app/controllers/users_controller.rb:151 msgid "deactivated" msgstr "pois käytöstä" -#: ../../app/controllers/users_controller.rb:156 +#: ../../app/controllers/users_controller.rb:157 msgid "Unable to %{action} %{username}" msgstr "%{username}:n %{action} ei onnistunut" -#: ../../app/controllers/users_controller.rb:157 +#: ../../app/controllers/users_controller.rb:158 msgid "activate" msgstr "aktivoi" -#: ../../app/controllers/users_controller.rb:157 +#: ../../app/controllers/users_controller.rb:158 msgid "deactivate" msgstr "kytke pois päältä" @@ -1262,52 +1270,52 @@ msgstr "Viimeiset 9 kuukautta" msgid "Last 12 months" msgstr "Viimeiset 12 kuukautta" -#: ../../app/mailers/user_mailer.rb:17 +#: ../../app/mailers/user_mailer.rb:18 #: ../../app/views/devise/mailer/invitation_instructions.html.erb:5 #: ../../app/views/devise/mailer/reset_password_instructions.html.erb:5 #: ../../app/views/user_mailer/_email_signature.html.erb:2 msgid "Query or feedback related to %{tool_name}" msgstr "%{tool_name}:n liittyvä kysymys tai palaute" -#: ../../app/mailers/user_mailer.rb:25 +#: ../../app/mailers/user_mailer.rb:26 msgid "Welcome to %{tool_name}" msgstr "Tervetuloa %{tool_name}:n käyttäjäksi" -#: ../../app/mailers/user_mailer.rb:62 +#: ../../app/mailers/user_mailer.rb:63 msgid "A Data Management Plan in %{tool_name} has been shared with you" msgstr "Tiedonhallintasuunnitelma %{tool_name} -palvelussa on jaettu kanssasi" -#: ../../app/mailers/user_mailer.rb:79 +#: ../../app/mailers/user_mailer.rb:80 msgid "Changed permissions on a Data Management Plan in %{tool_name}" msgstr "" "%{tool_name}:ssa olevan aineistonhallintasuunnitelman käyttöoikeuksia on muute" "ttu" -#: ../../app/mailers/user_mailer.rb:94 +#: ../../app/mailers/user_mailer.rb:95 msgid "Permissions removed on a DMP in %{tool_name}" msgstr "DMP: ltä poistetut käyttöoikeudet %{tool_name}" -#: ../../app/mailers/user_mailer.rb:112 +#: ../../app/mailers/user_mailer.rb:113 msgid "%{user_name} has requested feedback on a %{tool_name} plan" msgstr "%{user_name} on pyytänyt palautetta %{tool_name} -suunnitelmasta" -#: ../../app/mailers/user_mailer.rb:135 +#: ../../app/mailers/user_mailer.rb:136 msgid "%{tool_name}: Expert feedback has been provided for %{plan_title}" msgstr "%{tool_name}: %{plan_title}: lle on annettu asiantuntijapalautetta" -#: ../../app/mailers/user_mailer.rb:153 +#: ../../app/mailers/user_mailer.rb:154 msgid "DMP Visibility Changed: %{plan_title}" msgstr "Suunnitelman näkyvyys on muuttunut: %{plan_title}" -#: ../../app/mailers/user_mailer.rb:182 +#: ../../app/mailers/user_mailer.rb:183 msgid "%{tool_name}: A new comment was added to %{plan_title}" msgstr "%{tool_name}: Uusi kommentti lisättiin suunnitelmaasi %{plan_title}" -#: ../../app/mailers/user_mailer.rb:198 +#: ../../app/mailers/user_mailer.rb:199 msgid "Administrator privileges granted in %{tool_name}" msgstr "Minulle myönnetyt ylläpito-oikeudet %{tool_name}:ssa" -#: ../../app/mailers/user_mailer.rb:216 +#: ../../app/mailers/user_mailer.rb:217 msgid "%{tool_name} API changes" msgstr "%{tool_name} API-muutokset" @@ -1543,15 +1551,15 @@ msgstr "Kysymykseen ei vastattu.\\n" msgid "already assigned a value" msgstr "jo määritetty arvo" -#: ../../app/models/org.rb:46 +#: ../../app/models/org.rb:47 msgid "Feedback email message" msgstr "Palautteen sähköpostiviesti" -#: ../../app/models/org.rb:123 +#: ../../app/models/org.rb:124 msgid "must be one of the following formats: jpeg, jpg, png, gif, bmp" msgstr "täytyy olla yksi seuraavista tiedostomuodoista: jpeg, jpg, png, gif, bmp" -#: ../../app/models/org.rb:128 +#: ../../app/models/org.rb:129 msgid "can't be larger than 500KB" msgstr "ei voi olla suurempi kuin 500KB" @@ -1675,7 +1683,7 @@ msgstr "Et voi julkaista mallipohjaa ilman kysymyksiä." msgid "Conditions in the template refer backwards" msgstr "Mallin ehdot viittaavat taaksepäin" -#: ../../app/models/user.rb:380 +#: ../../app/models/user.rb:386 msgid "A Data Management Plan in %{application_name} has been shared with you" msgstr "" "%{application_name}lla kirjoitettu aineistonhallintasuunnitelma on jaettu kans" @@ -2107,7 +2115,7 @@ msgstr "" #: ../../app/views/paginable/templates/_organisational.html.erb:87 #: ../../app/views/paginable/templates/_publicly_visible.html.erb:29 #: ../../app/views/paginable/templates/_publicly_visible.html.erb:36 -#: ../../app/views/plans/_download_form.html.erb:130 +#: ../../app/views/plans/_download_form.html.erb:133 #: ../../app/views/static_pages/about_us.html.erb:22 #: ../../app/views/static_pages/about_us.html.erb:29 #: ../../app/views/static_pages/termsuse.html.erb:46 @@ -4606,7 +4614,7 @@ msgstr "Kommentit ja ohjeet" msgid "Instructions" msgstr "Ohjeet" -#: ../../app/views/plans/_download_form.html.erb:6 +#: ../../app/views/plans/_download_form.html.erb:5 msgid "Format" msgstr "Tiedostomuoto" @@ -4614,72 +4622,72 @@ msgstr "Tiedostomuoto" msgid "Download settings" msgstr "Asetukset" -#: ../../app/views/plans/_download_form.html.erb:19 -msgid "Select phase to download" -msgstr "Valitse vaihe ladattavaksi" - -#: ../../app/views/plans/_download_form.html.erb:26 +#: ../../app/views/plans/_download_form.html.erb:21 msgid "Optional plan components" msgstr "" "Valinnaiset suunnitelman osat\n" -#: ../../app/views/plans/_download_form.html.erb:30 +#: ../../app/views/plans/_download_form.html.erb:25 msgid "project details coversheet" msgstr "Projektin tiedot" -#: ../../app/views/plans/_download_form.html.erb:36 +#: ../../app/views/plans/_download_form.html.erb:31 msgid "question text and section headings" msgstr "Kysymyksen teksti ja osioiden otsikot" -#: ../../app/views/plans/_download_form.html.erb:42 +#: ../../app/views/plans/_download_form.html.erb:37 msgid "unanswered questions" msgstr "Vastaamattomat kysymykset" -#: ../../app/views/plans/_download_form.html.erb:49 +#: ../../app/views/plans/_download_form.html.erb:44 msgid "research outputs" msgstr "tutkimustuloksista" -#: ../../app/views/plans/_download_form.html.erb:57 +#: ../../app/views/plans/_download_form.html.erb:52 msgid "supplementary section(s) not requested by funding organisation" msgstr "lisäosiot, joita rahoittajat eivät edellytä" -#: ../../app/views/plans/_download_form.html.erb:65 +#: ../../app/views/plans/_download_form.html.erb:61 +msgid "Select phase to download" +msgstr "Valitse vaihe ladattavaksi" + +#: ../../app/views/plans/_download_form.html.erb:70 msgid "PDF formatting" msgstr "PDF:n muotoilu" -#: ../../app/views/plans/_download_form.html.erb:68 +#: ../../app/views/plans/_download_form.html.erb:73 msgid "Font" msgstr "Fontti" -#: ../../app/views/plans/_download_form.html.erb:71 +#: ../../app/views/plans/_download_form.html.erb:76 msgid "Margin (mm)" msgstr "Marginaali (mm)" -#: ../../app/views/plans/_download_form.html.erb:76 +#: ../../app/views/plans/_download_form.html.erb:81 msgid "Face" msgstr "Kirjasinlaji" -#: ../../app/views/plans/_download_form.html.erb:84 +#: ../../app/views/plans/_download_form.html.erb:89 msgid "Size" msgstr "Koko" -#: ../../app/views/plans/_download_form.html.erb:92 +#: ../../app/views/plans/_download_form.html.erb:96 msgid "Top" msgstr "Yläosa" -#: ../../app/views/plans/_download_form.html.erb:101 +#: ../../app/views/plans/_download_form.html.erb:105 msgid "Bottom" msgstr "Alaosa" -#: ../../app/views/plans/_download_form.html.erb:110 +#: ../../app/views/plans/_download_form.html.erb:114 msgid "Left" msgstr "Vasen" -#: ../../app/views/plans/_download_form.html.erb:119 +#: ../../app/views/plans/_download_form.html.erb:123 msgid "Right" msgstr "Oikea" -#: ../../app/views/plans/_download_form.html.erb:130 +#: ../../app/views/plans/_download_form.html.erb:133 msgid "" "Download Plan (new window)%{open_in_new_window_text}" diff --git a/config/locale/fr_CA/LC_MESSAGES/app.mo b/config/locale/fr_CA/LC_MESSAGES/app.mo index e5da555337ecb957fd4c8021c638729d48dc1458..f31748c286ecfa07ab2c7249ad0f03105d2478ec 100644 GIT binary patch delta 52 zcmdn;j(y8J_J%Etf4TV#jdYES6$~t_jE!{-%%^knFiJti3{8Pz+6D&Ojd>UuUjqQ7 CObxF9 delta 52 zcmdn;j(y8J_J%Etf4TV#Omqzm6by~6j4X5w%%*emFiJtij0}Nd+6G43jd>UuUjqQ6 CnhmP} diff --git a/config/locale/fr_CA/app.po b/config/locale/fr_CA/app.po index dbea8d0b50..b71a5b7820 100644 --- a/config/locale/fr_CA/app.po +++ b/config/locale/fr_CA/app.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: roadmap_upstream 1.0\n" "Report-Msgid-Bugs-To: contact@translation.io\n" -"POT-Creation-Date: 2025-04-10 13:28-0600\n" -"PO-Revision-Date: 2025-04-10 21:28+0200\n" +"POT-Creation-Date: 2025-12-23 08:33-0700\n" +"PO-Revision-Date: 2025-12-23 15:33+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: French\n" "Language: fr_CA\n" @@ -127,87 +127,95 @@ msgstr "Format JSON invalide" msgid "No Plans found" msgstr "Aucun plan n’a été trouvé" -#: ../../app/controllers/application_controller.rb:36 +#: ../../app/controllers/api/v2/base_api_controller.rb:72 +msgid "There was a problem in the server." +msgstr "" + +#: ../../app/controllers/api/v2/base_api_controller.rb:78 +msgid "The client is not authorized to perform this action." +msgstr "" + +#: ../../app/controllers/application_controller.rb:37 msgid "You are not authorized to perform this action." msgstr "Vous n’êtes pas autorisé à effectuer cette action." -#: ../../app/controllers/application_controller.rb:40 +#: ../../app/controllers/application_controller.rb:41 msgid "You need to sign in or sign up before continuing." msgstr "Vous devez vous connecter ou vous inscrire pour continuer." -#: ../../app/controllers/application_controller.rb:108 +#: ../../app/controllers/application_controller.rb:115 msgid "Unable to %{action} the %{object}. %{errors}" msgstr "" -#: ../../app/controllers/application_controller.rb:114 +#: ../../app/controllers/application_controller.rb:121 msgid "Successfully %{action} the %{object}." msgstr "La mesure %{action} pour %{object} a été effectuée avec succès." -#: ../../app/controllers/application_controller.rb:127 +#: ../../app/controllers/application_controller.rb:134 msgid "API client" msgstr "Client API" -#: ../../app/controllers/application_controller.rb:128 +#: ../../app/controllers/application_controller.rb:135 msgid "plan" msgstr "plan" -#: ../../app/controllers/application_controller.rb:129 +#: ../../app/controllers/application_controller.rb:136 msgid "guidance group" msgstr "groupe de directives" -#: ../../app/controllers/application_controller.rb:130 +#: ../../app/controllers/application_controller.rb:137 msgid "comment" msgstr "laisser un commentaire" -#: ../../app/controllers/application_controller.rb:131 +#: ../../app/controllers/application_controller.rb:138 msgid "organisation" msgstr "organisme" -#: ../../app/controllers/application_controller.rb:132 +#: ../../app/controllers/application_controller.rb:139 msgid "permission" msgstr "autorisation" -#: ../../app/controllers/application_controller.rb:133 +#: ../../app/controllers/application_controller.rb:140 msgid "preferences" msgstr "préférences" -#: ../../app/controllers/application_controller.rb:134 +#: ../../app/controllers/application_controller.rb:141 msgid "profile" msgstr "profil" -#: ../../app/controllers/application_controller.rb:134 +#: ../../app/controllers/application_controller.rb:141 msgid "user" msgstr "utilisateur(trice)" -#: ../../app/controllers/application_controller.rb:135 +#: ../../app/controllers/application_controller.rb:142 msgid "question option" msgstr "choix de questions" -#: ../../app/controllers/application_controller.rb:181 +#: ../../app/controllers/application_controller.rb:188 msgid "Record Not Found" msgstr "" -#: ../../app/controllers/concerns/paginable.rb:45 +#: ../../app/controllers/concerns/paginable.rb:46 msgid "scope should be an ActiveRecord::Relation object" msgstr "la portée doit être un objet ActiveRecord::Relation" -#: ../../app/controllers/concerns/paginable.rb:47 +#: ../../app/controllers/concerns/paginable.rb:48 msgid "path_params should be a Hash object" msgstr "path_params doit être un objet Hash" -#: ../../app/controllers/concerns/paginable.rb:48 +#: ../../app/controllers/concerns/paginable.rb:49 msgid "query_params should be a Hash object" msgstr "query_params doit constituer un objet Hash" -#: ../../app/controllers/concerns/paginable.rb:49 +#: ../../app/controllers/concerns/paginable.rb:50 msgid "locals should be a Hash object" msgstr "les valeurs locales doivent être un objet Hash" -#: ../../app/controllers/concerns/paginable.rb:70 +#: ../../app/controllers/concerns/paginable.rb:71 msgid "Restricted access to View All the records" msgstr "Accès restreint à Voir Tous les enregistrements" -#: ../../app/controllers/concerns/paginable.rb:183 +#: ../../app/controllers/concerns/paginable.rb:184 msgid "Sort by %{sort_field}" msgstr "Trier par %{sort_field}" @@ -250,77 +258,77 @@ msgstr "Le courriel du contact a été envoyé avec succès." msgid "Unable to submit your request" msgstr "Il est impossible de soumettre votre demande" -#: ../../app/controllers/contributors_controller.rb:40 -#: ../../app/controllers/contributors_controller.rb:56 +#: ../../app/controllers/contributors_controller.rb:41 +#: ../../app/controllers/contributors_controller.rb:57 #: ../../app/controllers/research_outputs_controller.rb:42 msgid "add" msgstr "ajouter" -#: ../../app/controllers/contributors_controller.rb:54 +#: ../../app/controllers/contributors_controller.rb:55 #: ../../app/controllers/research_outputs_controller.rb:40 msgid "added" msgstr "ajouté" -#: ../../app/controllers/contributors_controller.rb:72 +#: ../../app/controllers/contributors_controller.rb:73 #: ../../app/controllers/guidance_groups_controller.rb:55 #: ../../app/controllers/guidances_controller.rb:75 -#: ../../app/controllers/notes_controller.rb:88 +#: ../../app/controllers/notes_controller.rb:89 #: ../../app/controllers/org_admin/departments_controller.rb:50 #: ../../app/controllers/org_admin/sections_controller.rb:103 #: ../../app/controllers/org_admin/templates_controller.rb:210 #: ../../app/controllers/orgs_controller.rb:92 -#: ../../app/controllers/plans_controller.rb:280 -#: ../../app/controllers/plans_controller.rb:283 +#: ../../app/controllers/plans_controller.rb:281 +#: ../../app/controllers/plans_controller.rb:284 #: ../../app/controllers/registrations_controller.rb:249 #: ../../app/controllers/registrations_controller.rb:253 #: ../../app/controllers/registrations_controller.rb:280 #: ../../app/controllers/registrations_controller.rb:284 #: ../../app/controllers/research_outputs_controller.rb:60 -#: ../../app/controllers/users_controller.rb:103 -#: ../../app/controllers/users_controller.rb:131 +#: ../../app/controllers/users_controller.rb:104 +#: ../../app/controllers/users_controller.rb:132 msgid "saved" msgstr "enregistré" -#: ../../app/controllers/contributors_controller.rb:74 +#: ../../app/controllers/contributors_controller.rb:75 #: ../../app/controllers/guidance_groups_controller.rb:57 #: ../../app/controllers/guidances_controller.rb:77 -#: ../../app/controllers/notes_controller.rb:106 +#: ../../app/controllers/notes_controller.rb:107 #: ../../app/controllers/org_admin/departments_controller.rb:52 #: ../../app/controllers/org_admin/sections_controller.rb:105 #: ../../app/controllers/org_admin/templates_controller.rb:215 #: ../../app/controllers/orgs_controller.rb:94 -#: ../../app/controllers/plans_controller.rb:289 -#: ../../app/controllers/plans_controller.rb:292 -#: ../../app/controllers/plans_controller.rb:296 -#: ../../app/controllers/plans_controller.rb:299 +#: ../../app/controllers/plans_controller.rb:290 +#: ../../app/controllers/plans_controller.rb:293 +#: ../../app/controllers/plans_controller.rb:297 +#: ../../app/controllers/plans_controller.rb:300 #: ../../app/controllers/registrations_controller.rb:256 #: ../../app/controllers/registrations_controller.rb:287 #: ../../app/controllers/research_outputs_controller.rb:63 msgid "save" msgstr "enregistrer" -#: ../../app/controllers/contributors_controller.rb:83 -#: ../../app/controllers/notes_controller.rb:130 +#: ../../app/controllers/contributors_controller.rb:84 +#: ../../app/controllers/notes_controller.rb:131 #: ../../app/controllers/org_admin/templates_controller.rb:243 #: ../../app/controllers/research_outputs_controller.rb:74 #: ../../app/controllers/super_admin/orgs_controller.rb:94 msgid "removed" msgstr "retiré" -#: ../../app/controllers/contributors_controller.rb:86 -#: ../../app/controllers/notes_controller.rb:148 +#: ../../app/controllers/contributors_controller.rb:87 +#: ../../app/controllers/notes_controller.rb:149 #: ../../app/controllers/org_admin/templates_controller.rb:245 #: ../../app/controllers/research_outputs_controller.rb:77 #: ../../app/controllers/super_admin/orgs_controller.rb:97 msgid "remove" msgstr "retirer" -#: ../../app/controllers/contributors_controller.rb:160 +#: ../../app/controllers/contributors_controller.rb:161 #: ../../app/controllers/research_outputs_controller.rb:208 msgid "plan not found" msgstr "plan non trouvé" -#: ../../app/controllers/contributors_controller.rb:168 +#: ../../app/controllers/contributors_controller.rb:169 msgid "contributor not found" msgstr "contributeur introuvable" @@ -334,7 +342,7 @@ msgstr "Une erreur s’est produite lors de la demande de commentaires pour ce p #: ../../app/controllers/guidance_groups_controller.rb:31 #: ../../app/controllers/guidances_controller.rb:53 -#: ../../app/controllers/notes_controller.rb:47 +#: ../../app/controllers/notes_controller.rb:48 #: ../../app/controllers/org_admin/departments_controller.rb:26 #: ../../app/controllers/org_admin/phases_controller.rb:121 #: ../../app/controllers/org_admin/questions_controller.rb:94 @@ -350,7 +358,7 @@ msgstr "créé" #: ../../app/controllers/guidance_groups_controller.rb:34 #: ../../app/controllers/guidances_controller.rb:55 -#: ../../app/controllers/notes_controller.rb:66 +#: ../../app/controllers/notes_controller.rb:67 #: ../../app/controllers/org_admin/departments_controller.rb:30 #: ../../app/controllers/org_admin/phases_controller.rb:123 #: ../../app/controllers/org_admin/questions_controller.rb:96 @@ -393,7 +401,7 @@ msgstr "annuler la publication" #: ../../app/controllers/org_admin/question_options_controller.rb:24 #: ../../app/controllers/org_admin/questions_controller.rb:197 #: ../../app/controllers/org_admin/sections_controller.rb:128 -#: ../../app/controllers/plans_controller.rb:342 +#: ../../app/controllers/plans_controller.rb:343 #: ../../app/controllers/super_admin/api_clients_controller.rb:81 #: ../../app/controllers/super_admin/notifications_controller.rb:85 #: ../../app/controllers/super_admin/themes_controller.rb:51 @@ -407,7 +415,7 @@ msgstr "supprimé" #: ../../app/controllers/org_admin/question_options_controller.rb:26 #: ../../app/controllers/org_admin/questions_controller.rb:199 #: ../../app/controllers/org_admin/sections_controller.rb:130 -#: ../../app/controllers/plans_controller.rb:347 +#: ../../app/controllers/plans_controller.rb:348 #: ../../app/controllers/super_admin/api_clients_controller.rb:84 #: ../../app/controllers/super_admin/notifications_controller.rb:88 #: ../../app/controllers/super_admin/themes_controller.rb:54 @@ -454,19 +462,19 @@ msgstr "" #: ../../app/controllers/org_admin/phases_controller.rb:147 #: ../../app/controllers/org_admin/questions_controller.rb:166 #: ../../app/controllers/org_admin/users_controller.rb:30 -#: ../../app/controllers/plans_controller.rb:416 +#: ../../app/controllers/plans_controller.rb:417 #: ../../app/controllers/super_admin/api_clients_controller.rb:68 #: ../../app/controllers/super_admin/notifications_controller.rb:52 #: ../../app/controllers/super_admin/themes_controller.rb:39 #: ../../app/controllers/super_admin/users_controller.rb:54 -#: ../../app/controllers/users_controller.rb:108 +#: ../../app/controllers/users_controller.rb:109 msgid "updated" msgstr "mis à jour" #: ../../app/controllers/org_admin/phases_controller.rb:149 #: ../../app/controllers/org_admin/questions_controller.rb:169 #: ../../app/controllers/org_admin/users_controller.rb:32 -#: ../../app/controllers/plans_controller.rb:419 +#: ../../app/controllers/plans_controller.rb:420 #: ../../app/controllers/super_admin/api_clients_controller.rb:70 #: ../../app/controllers/super_admin/notifications_controller.rb:55 #: ../../app/controllers/super_admin/themes_controller.rb:41 @@ -560,7 +568,7 @@ msgid "Unable to delete this version of the template." msgstr "" #: ../../app/controllers/org_admin/template_copies_controller.rb:20 -#: ../../app/controllers/plans_controller.rb:395 +#: ../../app/controllers/plans_controller.rb:396 msgid "copy" msgstr "copier" @@ -569,11 +577,11 @@ msgstr "copier" msgid "That template is no longer customizable." msgstr "Ce modèle n’est plus personnalisable." -#: ../../app/controllers/org_admin/template_customizations_controller.rb:21 +#: ../../app/controllers/org_admin/template_customizations_controller.rb:22 msgid "Unable to customize that template." msgstr "Il est impossible de personnaliser ce modèle." -#: ../../app/controllers/org_admin/template_customizations_controller.rb:24 +#: ../../app/controllers/org_admin/template_customizations_controller.rb:25 msgid "That template is not customizable." msgstr "Ce modèle n’est pas personnalisable." @@ -665,11 +673,11 @@ msgstr "Ce plan est fondé sur " msgid "template with customisations by the" msgstr "modèle avec des personnalisations par le" -#: ../../app/controllers/plans_controller.rb:393 +#: ../../app/controllers/plans_controller.rb:394 msgid "copied" msgstr "copié" -#: ../../app/controllers/plans_controller.rb:424 +#: ../../app/controllers/plans_controller.rb:425 msgid "" "Unable to change the plan's status since it is needed at least %{percentage} p" "ercentage responded" @@ -677,23 +685,23 @@ msgstr "" "Il est impossible de modifier l’état du plan, car il est nécessaire d’obtenir " "un taux de réponse d’au moins %{percentage}" -#: ../../app/controllers/plans_controller.rb:430 +#: ../../app/controllers/plans_controller.rb:431 msgid "Unable to find plan id %{plan_id}" msgstr "Il est impossible de trouver l’ID du plan %{plan_id}" -#: ../../app/controllers/plans_controller.rb:445 +#: ../../app/controllers/plans_controller.rb:446 msgid "Your project is now a test." msgstr "Votre projet est maintenant à l’état d’essai." -#: ../../app/controllers/plans_controller.rb:445 +#: ../../app/controllers/plans_controller.rb:446 msgid "Your project is no longer a test." msgstr "Votre projet n’est plus à l’état d’essai." -#: ../../app/controllers/plans_controller.rb:449 +#: ../../app/controllers/plans_controller.rb:450 msgid "Unable to change the plan's test status" msgstr "Il est impossible de modifier l’état d’essai du plan" -#: ../../app/controllers/plans_controller.rb:462 +#: ../../app/controllers/plans_controller.rb:463 msgid "There is no plan associated with id %{s" msgstr "" @@ -783,7 +791,7 @@ msgstr "Le mot de passe et la confirmation doivent être identiques" msgid "research output not found" msgstr "" -#: ../../app/controllers/roles_controller.rb:26 +#: ../../app/controllers/roles_controller.rb:27 msgid "" "Cannot share plan with %{email} since that email matches\n" " with the owner of the plan." @@ -956,27 +964,27 @@ msgstr "Votre compte a bien été associé à %{scheme}." msgid "Unable to link your account to %{scheme}." msgstr "Il est impossible d’associer votre compte à %{scheme}." -#: ../../app/controllers/users_controller.rb:149 +#: ../../app/controllers/users_controller.rb:150 msgid "Successfully %{action} %{username}'s account." msgstr "La mesure %{action} pour %{username} a été effectuée avec succès." -#: ../../app/controllers/users_controller.rb:150 +#: ../../app/controllers/users_controller.rb:151 msgid "activated" msgstr "activé" -#: ../../app/controllers/users_controller.rb:150 +#: ../../app/controllers/users_controller.rb:151 msgid "deactivated" msgstr "désactivé" -#: ../../app/controllers/users_controller.rb:156 +#: ../../app/controllers/users_controller.rb:157 msgid "Unable to %{action} %{username}" msgstr "Il est impossible de %{action} %{username}" -#: ../../app/controllers/users_controller.rb:157 +#: ../../app/controllers/users_controller.rb:158 msgid "activate" msgstr "activer" -#: ../../app/controllers/users_controller.rb:157 +#: ../../app/controllers/users_controller.rb:158 msgid "deactivate" msgstr "désactiver" @@ -1270,54 +1278,54 @@ msgstr "Les 9 derniers mois" msgid "Last 12 months" msgstr "Les 12 derniers mois" -#: ../../app/mailers/user_mailer.rb:17 +#: ../../app/mailers/user_mailer.rb:18 #: ../../app/views/devise/mailer/invitation_instructions.html.erb:5 #: ../../app/views/devise/mailer/reset_password_instructions.html.erb:5 #: ../../app/views/user_mailer/_email_signature.html.erb:2 msgid "Query or feedback related to %{tool_name}" msgstr "Requête ou commentaire associé à %{tool_name}" -#: ../../app/mailers/user_mailer.rb:25 +#: ../../app/mailers/user_mailer.rb:26 msgid "Welcome to %{tool_name}" msgstr "Bienvenue à %{tool_name}" -#: ../../app/mailers/user_mailer.rb:62 +#: ../../app/mailers/user_mailer.rb:63 msgid "A Data Management Plan in %{tool_name} has been shared with you" msgstr "Un plan de gestion des données dans %{tool_name} a été partagé avec vous" -#: ../../app/mailers/user_mailer.rb:79 +#: ../../app/mailers/user_mailer.rb:80 msgid "Changed permissions on a Data Management Plan in %{tool_name}" msgstr "" "Les autorisations pour un plan de gestion des données dans %{tool_name} sont m" "odifiées" -#: ../../app/mailers/user_mailer.rb:94 +#: ../../app/mailers/user_mailer.rb:95 msgid "Permissions removed on a DMP in %{tool_name}" msgstr "Autorisations relatives à PGD retirées dans %{tool_name}" -#: ../../app/mailers/user_mailer.rb:112 +#: ../../app/mailers/user_mailer.rb:113 msgid "%{user_name} has requested feedback on a %{tool_name} plan" msgstr "" -#: ../../app/mailers/user_mailer.rb:135 +#: ../../app/mailers/user_mailer.rb:136 msgid "%{tool_name}: Expert feedback has been provided for %{plan_title}" msgstr "" "%{tool_name}: Les commentaires d’un spécialiste ont été fournis pour %{plan_ti" "tle}" -#: ../../app/mailers/user_mailer.rb:153 +#: ../../app/mailers/user_mailer.rb:154 msgid "DMP Visibility Changed: %{plan_title}" msgstr "Visibilité du PGD modifiée : %{plan_title}" -#: ../../app/mailers/user_mailer.rb:182 +#: ../../app/mailers/user_mailer.rb:183 msgid "%{tool_name}: A new comment was added to %{plan_title}" msgstr "%{tool_name}: un nouveau commentaire a été ajouté à %{plan_title}" -#: ../../app/mailers/user_mailer.rb:198 +#: ../../app/mailers/user_mailer.rb:199 msgid "Administrator privileges granted in %{tool_name}" msgstr "Privilèges d’administrateur accordés dans %{tool_name}" -#: ../../app/mailers/user_mailer.rb:216 +#: ../../app/mailers/user_mailer.rb:217 msgid "%{tool_name} API changes" msgstr "Modifications de l'API pour %{tool_name}" @@ -1553,15 +1561,15 @@ msgstr "" msgid "already assigned a value" msgstr "une valeur a déjà été attribuée" -#: ../../app/models/org.rb:46 +#: ../../app/models/org.rb:47 msgid "Feedback email message" msgstr "Courriel de rétroaction" -#: ../../app/models/org.rb:123 +#: ../../app/models/org.rb:124 msgid "must be one of the following formats: jpeg, jpg, png, gif, bmp" msgstr "doit être dans l’un des formats suivants: jpeg, jpg, png, gif, bmp" -#: ../../app/models/org.rb:128 +#: ../../app/models/org.rb:129 msgid "can't be larger than 500KB" msgstr "ne peut pas dépasser 500 Ko" @@ -1691,7 +1699,7 @@ msgstr "" msgid "Conditions in the template refer backwards" msgstr "Les conditions du modèle sont associées à une référence antérieure" -#: ../../app/models/user.rb:380 +#: ../../app/models/user.rb:386 msgid "A Data Management Plan in %{application_name} has been shared with you" msgstr "" "Un plan de gestion des données dans %{application_name} a été partagé avec vou" @@ -2122,7 +2130,7 @@ msgstr "" #: ../../app/views/paginable/templates/_organisational.html.erb:87 #: ../../app/views/paginable/templates/_publicly_visible.html.erb:29 #: ../../app/views/paginable/templates/_publicly_visible.html.erb:36 -#: ../../app/views/plans/_download_form.html.erb:130 +#: ../../app/views/plans/_download_form.html.erb:133 #: ../../app/views/static_pages/about_us.html.erb:22 #: ../../app/views/static_pages/about_us.html.erb:29 #: ../../app/views/static_pages/termsuse.html.erb:46 @@ -4652,7 +4660,7 @@ msgstr "" msgid "Instructions" msgstr "Consignes" -#: ../../app/views/plans/_download_form.html.erb:6 +#: ../../app/views/plans/_download_form.html.erb:5 msgid "Format" msgstr "Format" @@ -4660,71 +4668,71 @@ msgstr "Format" msgid "Download settings" msgstr "Télécharger les paramètres" -#: ../../app/views/plans/_download_form.html.erb:19 -msgid "Select phase to download" -msgstr "Sélectionner la phase à télécharger" - -#: ../../app/views/plans/_download_form.html.erb:26 +#: ../../app/views/plans/_download_form.html.erb:21 msgid "Optional plan components" msgstr "Composants de plan facultatifs" -#: ../../app/views/plans/_download_form.html.erb:30 +#: ../../app/views/plans/_download_form.html.erb:25 msgid "project details coversheet" msgstr "page de couverture des détails du projet" -#: ../../app/views/plans/_download_form.html.erb:36 +#: ../../app/views/plans/_download_form.html.erb:31 msgid "question text and section headings" msgstr "texte des questions et en-têtes des sections" -#: ../../app/views/plans/_download_form.html.erb:42 +#: ../../app/views/plans/_download_form.html.erb:37 msgid "unanswered questions" msgstr "questions sans réponse" -#: ../../app/views/plans/_download_form.html.erb:49 +#: ../../app/views/plans/_download_form.html.erb:44 msgid "research outputs" msgstr "" -#: ../../app/views/plans/_download_form.html.erb:57 +#: ../../app/views/plans/_download_form.html.erb:52 msgid "supplementary section(s) not requested by funding organisation" msgstr "sections supplémentaires non demandées par l’organisme de financement" -#: ../../app/views/plans/_download_form.html.erb:65 +#: ../../app/views/plans/_download_form.html.erb:61 +msgid "Select phase to download" +msgstr "Sélectionner la phase à télécharger" + +#: ../../app/views/plans/_download_form.html.erb:70 msgid "PDF formatting" msgstr "Format PDF" -#: ../../app/views/plans/_download_form.html.erb:68 +#: ../../app/views/plans/_download_form.html.erb:73 msgid "Font" msgstr "Police de caractère" -#: ../../app/views/plans/_download_form.html.erb:71 +#: ../../app/views/plans/_download_form.html.erb:76 msgid "Margin (mm)" msgstr "Marge (mm)" -#: ../../app/views/plans/_download_form.html.erb:76 +#: ../../app/views/plans/_download_form.html.erb:81 msgid "Face" msgstr "Police de caractère" -#: ../../app/views/plans/_download_form.html.erb:84 +#: ../../app/views/plans/_download_form.html.erb:89 msgid "Size" msgstr "Taille" -#: ../../app/views/plans/_download_form.html.erb:92 +#: ../../app/views/plans/_download_form.html.erb:96 msgid "Top" msgstr "Haut" -#: ../../app/views/plans/_download_form.html.erb:101 +#: ../../app/views/plans/_download_form.html.erb:105 msgid "Bottom" msgstr "Bas" -#: ../../app/views/plans/_download_form.html.erb:110 +#: ../../app/views/plans/_download_form.html.erb:114 msgid "Left" msgstr "Gauche" -#: ../../app/views/plans/_download_form.html.erb:119 +#: ../../app/views/plans/_download_form.html.erb:123 msgid "Right" msgstr "Droite" -#: ../../app/views/plans/_download_form.html.erb:130 +#: ../../app/views/plans/_download_form.html.erb:133 msgid "" "Download Plan (new window)%{open_in_new_window_text}" diff --git a/config/locale/fr_FR/LC_MESSAGES/app.mo b/config/locale/fr_FR/LC_MESSAGES/app.mo index 281700601f5b4bb07167bfbd7aba5685e838bbc7..17404fb0edeb0ed073874b7ed3ead5db63658f17 100644 GIT binary patch delta 56 zcmeC(%h|h^vtbM4A}>BeBV8k71p^B!V`E(d^XVJB7^R?MhNeIAz6J0|C1w&&iBMV&vv*{bW7^R?MMutE!Z3CnB8(xgtZ+J0n G6$Sv-g%B_R diff --git a/config/locale/fr_FR/app.po b/config/locale/fr_FR/app.po index 739c9150b6..a212b381ce 100644 --- a/config/locale/fr_FR/app.po +++ b/config/locale/fr_FR/app.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: roadmap_upstream 1.0\n" "Report-Msgid-Bugs-To: contact@translation.io\n" -"POT-Creation-Date: 2025-04-10 13:28-0600\n" -"PO-Revision-Date: 2025-04-10 21:28+0200\n" +"POT-Creation-Date: 2025-12-23 08:33-0700\n" +"PO-Revision-Date: 2025-12-23 15:33+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: French\n" "Language: fr_FR\n" @@ -130,87 +130,95 @@ msgstr "JSON non valide" msgid "No Plans found" msgstr "Aucun plan trouvé" -#: ../../app/controllers/application_controller.rb:36 +#: ../../app/controllers/api/v2/base_api_controller.rb:72 +msgid "There was a problem in the server." +msgstr "" + +#: ../../app/controllers/api/v2/base_api_controller.rb:78 +msgid "The client is not authorized to perform this action." +msgstr "" + +#: ../../app/controllers/application_controller.rb:37 msgid "You are not authorized to perform this action." msgstr "Vous n'êtes pas autorisé à effectuer cette opération." -#: ../../app/controllers/application_controller.rb:40 +#: ../../app/controllers/application_controller.rb:41 msgid "You need to sign in or sign up before continuing." msgstr "Vous devez vous connecter ou vous enregistrer afin de continuer." -#: ../../app/controllers/application_controller.rb:108 +#: ../../app/controllers/application_controller.rb:115 msgid "Unable to %{action} the %{object}. %{errors}" msgstr "Impossible de %{action} le %{object}. %{errors}" -#: ../../app/controllers/application_controller.rb:114 +#: ../../app/controllers/application_controller.rb:121 msgid "Successfully %{action} the %{object}." msgstr "%{object} %{action} avec succès." -#: ../../app/controllers/application_controller.rb:127 +#: ../../app/controllers/application_controller.rb:134 msgid "API client" msgstr "Client API" -#: ../../app/controllers/application_controller.rb:128 +#: ../../app/controllers/application_controller.rb:135 msgid "plan" msgstr "plan" -#: ../../app/controllers/application_controller.rb:129 +#: ../../app/controllers/application_controller.rb:136 msgid "guidance group" msgstr "Groupe de recommandations" -#: ../../app/controllers/application_controller.rb:130 +#: ../../app/controllers/application_controller.rb:137 msgid "comment" msgstr "Commentaire" -#: ../../app/controllers/application_controller.rb:131 +#: ../../app/controllers/application_controller.rb:138 msgid "organisation" msgstr "organisme" -#: ../../app/controllers/application_controller.rb:132 +#: ../../app/controllers/application_controller.rb:139 msgid "permission" msgstr "autorisation" -#: ../../app/controllers/application_controller.rb:133 +#: ../../app/controllers/application_controller.rb:140 msgid "preferences" msgstr "préférences" -#: ../../app/controllers/application_controller.rb:134 +#: ../../app/controllers/application_controller.rb:141 msgid "profile" msgstr "profil" -#: ../../app/controllers/application_controller.rb:134 +#: ../../app/controllers/application_controller.rb:141 msgid "user" msgstr "utilisateur" -#: ../../app/controllers/application_controller.rb:135 +#: ../../app/controllers/application_controller.rb:142 msgid "question option" msgstr "option de question" -#: ../../app/controllers/application_controller.rb:181 +#: ../../app/controllers/application_controller.rb:188 msgid "Record Not Found" msgstr "Enregistrement non trouvé" -#: ../../app/controllers/concerns/paginable.rb:45 +#: ../../app/controllers/concerns/paginable.rb:46 msgid "scope should be an ActiveRecord::Relation object" msgstr "scope doit être un objet de type ActiveRecord::Relation" -#: ../../app/controllers/concerns/paginable.rb:47 +#: ../../app/controllers/concerns/paginable.rb:48 msgid "path_params should be a Hash object" msgstr "path_params doit être un objet de type Hash" -#: ../../app/controllers/concerns/paginable.rb:48 +#: ../../app/controllers/concerns/paginable.rb:49 msgid "query_params should be a Hash object" msgstr "query_params doit être un objet de type Hash" -#: ../../app/controllers/concerns/paginable.rb:49 +#: ../../app/controllers/concerns/paginable.rb:50 msgid "locals should be a Hash object" msgstr "locals doit être un objet de type Hash" -#: ../../app/controllers/concerns/paginable.rb:70 +#: ../../app/controllers/concerns/paginable.rb:71 msgid "Restricted access to View All the records" msgstr "Accès restreint à Voir tous les enregistrements" -#: ../../app/controllers/concerns/paginable.rb:183 +#: ../../app/controllers/concerns/paginable.rb:184 msgid "Sort by %{sort_field}" msgstr "Trier par %{sort_field}" @@ -251,77 +259,77 @@ msgstr "Mail de contact envoyé avec succès." msgid "Unable to submit your request" msgstr "Impossible de soumettre votre demande" -#: ../../app/controllers/contributors_controller.rb:40 -#: ../../app/controllers/contributors_controller.rb:56 +#: ../../app/controllers/contributors_controller.rb:41 +#: ../../app/controllers/contributors_controller.rb:57 #: ../../app/controllers/research_outputs_controller.rb:42 msgid "add" msgstr "ajouter" -#: ../../app/controllers/contributors_controller.rb:54 +#: ../../app/controllers/contributors_controller.rb:55 #: ../../app/controllers/research_outputs_controller.rb:40 msgid "added" msgstr "ajouté" -#: ../../app/controllers/contributors_controller.rb:72 +#: ../../app/controllers/contributors_controller.rb:73 #: ../../app/controllers/guidance_groups_controller.rb:55 #: ../../app/controllers/guidances_controller.rb:75 -#: ../../app/controllers/notes_controller.rb:88 +#: ../../app/controllers/notes_controller.rb:89 #: ../../app/controllers/org_admin/departments_controller.rb:50 #: ../../app/controllers/org_admin/sections_controller.rb:103 #: ../../app/controllers/org_admin/templates_controller.rb:210 #: ../../app/controllers/orgs_controller.rb:92 -#: ../../app/controllers/plans_controller.rb:280 -#: ../../app/controllers/plans_controller.rb:283 +#: ../../app/controllers/plans_controller.rb:281 +#: ../../app/controllers/plans_controller.rb:284 #: ../../app/controllers/registrations_controller.rb:249 #: ../../app/controllers/registrations_controller.rb:253 #: ../../app/controllers/registrations_controller.rb:280 #: ../../app/controllers/registrations_controller.rb:284 #: ../../app/controllers/research_outputs_controller.rb:60 -#: ../../app/controllers/users_controller.rb:103 -#: ../../app/controllers/users_controller.rb:131 +#: ../../app/controllers/users_controller.rb:104 +#: ../../app/controllers/users_controller.rb:132 msgid "saved" msgstr "enregistré" -#: ../../app/controllers/contributors_controller.rb:74 +#: ../../app/controllers/contributors_controller.rb:75 #: ../../app/controllers/guidance_groups_controller.rb:57 #: ../../app/controllers/guidances_controller.rb:77 -#: ../../app/controllers/notes_controller.rb:106 +#: ../../app/controllers/notes_controller.rb:107 #: ../../app/controllers/org_admin/departments_controller.rb:52 #: ../../app/controllers/org_admin/sections_controller.rb:105 #: ../../app/controllers/org_admin/templates_controller.rb:215 #: ../../app/controllers/orgs_controller.rb:94 -#: ../../app/controllers/plans_controller.rb:289 -#: ../../app/controllers/plans_controller.rb:292 -#: ../../app/controllers/plans_controller.rb:296 -#: ../../app/controllers/plans_controller.rb:299 +#: ../../app/controllers/plans_controller.rb:290 +#: ../../app/controllers/plans_controller.rb:293 +#: ../../app/controllers/plans_controller.rb:297 +#: ../../app/controllers/plans_controller.rb:300 #: ../../app/controllers/registrations_controller.rb:256 #: ../../app/controllers/registrations_controller.rb:287 #: ../../app/controllers/research_outputs_controller.rb:63 msgid "save" msgstr "enregistrer" -#: ../../app/controllers/contributors_controller.rb:83 -#: ../../app/controllers/notes_controller.rb:130 +#: ../../app/controllers/contributors_controller.rb:84 +#: ../../app/controllers/notes_controller.rb:131 #: ../../app/controllers/org_admin/templates_controller.rb:243 #: ../../app/controllers/research_outputs_controller.rb:74 #: ../../app/controllers/super_admin/orgs_controller.rb:94 msgid "removed" msgstr "supprimé(e)" -#: ../../app/controllers/contributors_controller.rb:86 -#: ../../app/controllers/notes_controller.rb:148 +#: ../../app/controllers/contributors_controller.rb:87 +#: ../../app/controllers/notes_controller.rb:149 #: ../../app/controllers/org_admin/templates_controller.rb:245 #: ../../app/controllers/research_outputs_controller.rb:77 #: ../../app/controllers/super_admin/orgs_controller.rb:97 msgid "remove" msgstr "supprimer" -#: ../../app/controllers/contributors_controller.rb:160 +#: ../../app/controllers/contributors_controller.rb:161 #: ../../app/controllers/research_outputs_controller.rb:208 msgid "plan not found" msgstr "Plan non trouvé" -#: ../../app/controllers/contributors_controller.rb:168 +#: ../../app/controllers/contributors_controller.rb:169 msgid "contributor not found" msgstr "contributeur non trouvé" @@ -335,7 +343,7 @@ msgstr "Une erreur s'est produite lors de la demande de commentaires sur ce plan #: ../../app/controllers/guidance_groups_controller.rb:31 #: ../../app/controllers/guidances_controller.rb:53 -#: ../../app/controllers/notes_controller.rb:47 +#: ../../app/controllers/notes_controller.rb:48 #: ../../app/controllers/org_admin/departments_controller.rb:26 #: ../../app/controllers/org_admin/phases_controller.rb:121 #: ../../app/controllers/org_admin/questions_controller.rb:94 @@ -351,7 +359,7 @@ msgstr "créé" #: ../../app/controllers/guidance_groups_controller.rb:34 #: ../../app/controllers/guidances_controller.rb:55 -#: ../../app/controllers/notes_controller.rb:66 +#: ../../app/controllers/notes_controller.rb:67 #: ../../app/controllers/org_admin/departments_controller.rb:30 #: ../../app/controllers/org_admin/phases_controller.rb:123 #: ../../app/controllers/org_admin/questions_controller.rb:96 @@ -394,7 +402,7 @@ msgstr "dépublier" #: ../../app/controllers/org_admin/question_options_controller.rb:24 #: ../../app/controllers/org_admin/questions_controller.rb:197 #: ../../app/controllers/org_admin/sections_controller.rb:128 -#: ../../app/controllers/plans_controller.rb:342 +#: ../../app/controllers/plans_controller.rb:343 #: ../../app/controllers/super_admin/api_clients_controller.rb:81 #: ../../app/controllers/super_admin/notifications_controller.rb:85 #: ../../app/controllers/super_admin/themes_controller.rb:51 @@ -408,7 +416,7 @@ msgstr "supprimé" #: ../../app/controllers/org_admin/question_options_controller.rb:26 #: ../../app/controllers/org_admin/questions_controller.rb:199 #: ../../app/controllers/org_admin/sections_controller.rb:130 -#: ../../app/controllers/plans_controller.rb:347 +#: ../../app/controllers/plans_controller.rb:348 #: ../../app/controllers/super_admin/api_clients_controller.rb:84 #: ../../app/controllers/super_admin/notifications_controller.rb:88 #: ../../app/controllers/super_admin/themes_controller.rb:54 @@ -453,19 +461,19 @@ msgstr "Impossible de créer une nouvelle version de ce modèle.
" #: ../../app/controllers/org_admin/phases_controller.rb:147 #: ../../app/controllers/org_admin/questions_controller.rb:166 #: ../../app/controllers/org_admin/users_controller.rb:30 -#: ../../app/controllers/plans_controller.rb:416 +#: ../../app/controllers/plans_controller.rb:417 #: ../../app/controllers/super_admin/api_clients_controller.rb:68 #: ../../app/controllers/super_admin/notifications_controller.rb:52 #: ../../app/controllers/super_admin/themes_controller.rb:39 #: ../../app/controllers/super_admin/users_controller.rb:54 -#: ../../app/controllers/users_controller.rb:108 +#: ../../app/controllers/users_controller.rb:109 msgid "updated" msgstr "mis à jour" #: ../../app/controllers/org_admin/phases_controller.rb:149 #: ../../app/controllers/org_admin/questions_controller.rb:169 #: ../../app/controllers/org_admin/users_controller.rb:32 -#: ../../app/controllers/plans_controller.rb:419 +#: ../../app/controllers/plans_controller.rb:420 #: ../../app/controllers/super_admin/api_clients_controller.rb:70 #: ../../app/controllers/super_admin/notifications_controller.rb:55 #: ../../app/controllers/super_admin/themes_controller.rb:41 @@ -559,7 +567,7 @@ msgid "Unable to delete this version of the template." msgstr "Impossible de supprimer cette version du modèle." #: ../../app/controllers/org_admin/template_copies_controller.rb:20 -#: ../../app/controllers/plans_controller.rb:395 +#: ../../app/controllers/plans_controller.rb:396 msgid "copy" msgstr "copier" @@ -568,11 +576,11 @@ msgstr "copier" msgid "That template is no longer customizable." msgstr "Ce template n'est plus personnalisable." -#: ../../app/controllers/org_admin/template_customizations_controller.rb:21 +#: ../../app/controllers/org_admin/template_customizations_controller.rb:22 msgid "Unable to customize that template." msgstr "Impossible de personnaliser ce modèle." -#: ../../app/controllers/org_admin/template_customizations_controller.rb:24 +#: ../../app/controllers/org_admin/template_customizations_controller.rb:25 msgid "That template is not customizable." msgstr "Ce modèle n'est pas personnalisable." @@ -662,11 +670,11 @@ msgstr "Ce plan est basé sur le" msgid "template with customisations by the" msgstr "modèle personnalisé par" -#: ../../app/controllers/plans_controller.rb:393 +#: ../../app/controllers/plans_controller.rb:394 msgid "copied" msgstr "copié" -#: ../../app/controllers/plans_controller.rb:424 +#: ../../app/controllers/plans_controller.rb:425 msgid "" "Unable to change the plan's status since it is needed at least %{percentage} p" "ercentage responded" @@ -674,23 +682,23 @@ msgstr "" "Impossible de changer le statut du plan, au moins %{percentage} % de questions" " répondues sont nécessaires" -#: ../../app/controllers/plans_controller.rb:430 +#: ../../app/controllers/plans_controller.rb:431 msgid "Unable to find plan id %{plan_id}" msgstr "Impossible de trouver le plan avec l'identifiant %{plan_id}" -#: ../../app/controllers/plans_controller.rb:445 +#: ../../app/controllers/plans_controller.rb:446 msgid "Your project is now a test." msgstr "Votre projet est maintenant un test." -#: ../../app/controllers/plans_controller.rb:445 +#: ../../app/controllers/plans_controller.rb:446 msgid "Your project is no longer a test." msgstr "Votre projet n'est plus un test." -#: ../../app/controllers/plans_controller.rb:449 +#: ../../app/controllers/plans_controller.rb:450 msgid "Unable to change the plan's test status" msgstr "Impossible de changer le statut du plan" -#: ../../app/controllers/plans_controller.rb:462 +#: ../../app/controllers/plans_controller.rb:463 msgid "There is no plan associated with id %{s" msgstr "Il n'y a pas de forfait associé à l'identifiant %{ s" @@ -788,7 +796,7 @@ msgstr "Le mot de passe et sa confirmation doivent correspondre" msgid "research output not found" msgstr "produit de recherche introuvable" -#: ../../app/controllers/roles_controller.rb:26 +#: ../../app/controllers/roles_controller.rb:27 msgid "" "Cannot share plan with %{email} since that email matches\n" " with the owner of the plan." @@ -967,27 +975,27 @@ msgstr "Votre compte a été lié à %{scheme} avec succès." msgid "Unable to link your account to %{scheme}." msgstr "Impossible de lier votre compte avec %{scheme}." -#: ../../app/controllers/users_controller.rb:149 +#: ../../app/controllers/users_controller.rb:150 msgid "Successfully %{action} %{username}'s account." msgstr "Compte de %{username} %{action} avec succès." -#: ../../app/controllers/users_controller.rb:150 +#: ../../app/controllers/users_controller.rb:151 msgid "activated" msgstr "activé" -#: ../../app/controllers/users_controller.rb:150 +#: ../../app/controllers/users_controller.rb:151 msgid "deactivated" msgstr "désactivé" -#: ../../app/controllers/users_controller.rb:156 +#: ../../app/controllers/users_controller.rb:157 msgid "Unable to %{action} %{username}" msgstr "Impossible de %{action} %{username}" -#: ../../app/controllers/users_controller.rb:157 +#: ../../app/controllers/users_controller.rb:158 msgid "activate" msgstr "activer" -#: ../../app/controllers/users_controller.rb:157 +#: ../../app/controllers/users_controller.rb:158 msgid "deactivate" msgstr "désactiver" @@ -1280,50 +1288,50 @@ msgstr "9 derniers mois" msgid "Last 12 months" msgstr "12 derniers mois" -#: ../../app/mailers/user_mailer.rb:17 +#: ../../app/mailers/user_mailer.rb:18 #: ../../app/views/devise/mailer/invitation_instructions.html.erb:5 #: ../../app/views/devise/mailer/reset_password_instructions.html.erb:5 #: ../../app/views/user_mailer/_email_signature.html.erb:2 msgid "Query or feedback related to %{tool_name}" msgstr "Requête ou suggestion liée à %{tool_name}" -#: ../../app/mailers/user_mailer.rb:25 +#: ../../app/mailers/user_mailer.rb:26 msgid "Welcome to %{tool_name}" msgstr "Bienvenue sur %{tool_name}" -#: ../../app/mailers/user_mailer.rb:62 +#: ../../app/mailers/user_mailer.rb:63 msgid "A Data Management Plan in %{tool_name} has been shared with you" msgstr "Un plan de gestion de données a été partagé avec vous sur %{tool_name}" -#: ../../app/mailers/user_mailer.rb:79 +#: ../../app/mailers/user_mailer.rb:80 msgid "Changed permissions on a Data Management Plan in %{tool_name}" msgstr "Modification des autorisations sur un plan de %{tool_name}" -#: ../../app/mailers/user_mailer.rb:94 +#: ../../app/mailers/user_mailer.rb:95 msgid "Permissions removed on a DMP in %{tool_name}" msgstr "Autorisations retirées d'un plan de %{tool_name}" -#: ../../app/mailers/user_mailer.rb:112 +#: ../../app/mailers/user_mailer.rb:113 msgid "%{user_name} has requested feedback on a %{tool_name} plan" msgstr "%{user_name} a demandé une assistance conseil pour un plan %{tool_name}" -#: ../../app/mailers/user_mailer.rb:135 +#: ../../app/mailers/user_mailer.rb:136 msgid "%{tool_name}: Expert feedback has been provided for %{plan_title}" msgstr "%{tool_name} : Une assistance conseil a été fournie pour %{plan_title}" -#: ../../app/mailers/user_mailer.rb:153 +#: ../../app/mailers/user_mailer.rb:154 msgid "DMP Visibility Changed: %{plan_title}" msgstr "Changement de visibilité d'un plan : %{plan_title}" -#: ../../app/mailers/user_mailer.rb:182 +#: ../../app/mailers/user_mailer.rb:183 msgid "%{tool_name}: A new comment was added to %{plan_title}" msgstr "%{tool_name}: Un nouveau commentaire a été ajouté à %{plan_title}" -#: ../../app/mailers/user_mailer.rb:198 +#: ../../app/mailers/user_mailer.rb:199 msgid "Administrator privileges granted in %{tool_name}" msgstr "Droits administrateur attribués dans %{tool_name}" -#: ../../app/mailers/user_mailer.rb:216 +#: ../../app/mailers/user_mailer.rb:217 msgid "%{tool_name} API changes" msgstr "Modifications de l'API %{tool_name}" @@ -1564,15 +1572,15 @@ msgstr "" msgid "already assigned a value" msgstr "a déjà une valeur attribuée" -#: ../../app/models/org.rb:46 +#: ../../app/models/org.rb:47 msgid "Feedback email message" msgstr "Message du mail de l'assistance conseil" -#: ../../app/models/org.rb:123 +#: ../../app/models/org.rb:124 msgid "must be one of the following formats: jpeg, jpg, png, gif, bmp" msgstr "doit être dans l'un des formats suivants : jpeg, jpg, png, gif, bmp" -#: ../../app/models/org.rb:128 +#: ../../app/models/org.rb:129 msgid "can't be larger than 500KB" msgstr "ne peut peser plus de 500ko" @@ -1700,7 +1708,7 @@ msgstr "" "Les conditions du modèle s'appliquent à une question positionnée avant celle-c" "i" -#: ../../app/models/user.rb:380 +#: ../../app/models/user.rb:386 msgid "A Data Management Plan in %{application_name} has been shared with you" msgstr "Un plan de gestion de données a été partagé avec vous sur %{application_name}" @@ -2128,7 +2136,7 @@ msgstr "" #: ../../app/views/paginable/templates/_organisational.html.erb:87 #: ../../app/views/paginable/templates/_publicly_visible.html.erb:29 #: ../../app/views/paginable/templates/_publicly_visible.html.erb:36 -#: ../../app/views/plans/_download_form.html.erb:130 +#: ../../app/views/plans/_download_form.html.erb:133 #: ../../app/views/static_pages/about_us.html.erb:22 #: ../../app/views/static_pages/about_us.html.erb:29 #: ../../app/views/static_pages/termsuse.html.erb:46 @@ -4654,7 +4662,7 @@ msgstr "Commentaires & Recommandations" msgid "Instructions" msgstr "Instructions" -#: ../../app/views/plans/_download_form.html.erb:6 +#: ../../app/views/plans/_download_form.html.erb:5 msgid "Format" msgstr "Format" @@ -4662,71 +4670,71 @@ msgstr "Format" msgid "Download settings" msgstr "Paramètres de téléchargement" -#: ../../app/views/plans/_download_form.html.erb:19 -msgid "Select phase to download" -msgstr "Sélectionner la phase à télécharger" - -#: ../../app/views/plans/_download_form.html.erb:26 +#: ../../app/views/plans/_download_form.html.erb:21 msgid "Optional plan components" msgstr "Eléments optionnels du plan" -#: ../../app/views/plans/_download_form.html.erb:30 +#: ../../app/views/plans/_download_form.html.erb:25 msgid "project details coversheet" msgstr "page de renseignements sur le projet" -#: ../../app/views/plans/_download_form.html.erb:36 +#: ../../app/views/plans/_download_form.html.erb:31 msgid "question text and section headings" msgstr "texte de la question et entête de la section" -#: ../../app/views/plans/_download_form.html.erb:42 +#: ../../app/views/plans/_download_form.html.erb:37 msgid "unanswered questions" msgstr "questions non répondues" -#: ../../app/views/plans/_download_form.html.erb:49 +#: ../../app/views/plans/_download_form.html.erb:44 msgid "research outputs" msgstr "produits de recherche" -#: ../../app/views/plans/_download_form.html.erb:57 +#: ../../app/views/plans/_download_form.html.erb:52 msgid "supplementary section(s) not requested by funding organisation" msgstr "section(s) supplémentaire(s) non requise(s) par l'organisme financeur" -#: ../../app/views/plans/_download_form.html.erb:65 +#: ../../app/views/plans/_download_form.html.erb:61 +msgid "Select phase to download" +msgstr "Sélectionner la phase à télécharger" + +#: ../../app/views/plans/_download_form.html.erb:70 msgid "PDF formatting" msgstr "Mise en forme du PDF" -#: ../../app/views/plans/_download_form.html.erb:68 +#: ../../app/views/plans/_download_form.html.erb:73 msgid "Font" msgstr "Police de caractères" -#: ../../app/views/plans/_download_form.html.erb:71 +#: ../../app/views/plans/_download_form.html.erb:76 msgid "Margin (mm)" msgstr "Marge (mm)" -#: ../../app/views/plans/_download_form.html.erb:76 +#: ../../app/views/plans/_download_form.html.erb:81 msgid "Face" msgstr "Police" -#: ../../app/views/plans/_download_form.html.erb:84 +#: ../../app/views/plans/_download_form.html.erb:89 msgid "Size" msgstr "Taille" -#: ../../app/views/plans/_download_form.html.erb:92 +#: ../../app/views/plans/_download_form.html.erb:96 msgid "Top" msgstr "Haut" -#: ../../app/views/plans/_download_form.html.erb:101 +#: ../../app/views/plans/_download_form.html.erb:105 msgid "Bottom" msgstr "Bas" -#: ../../app/views/plans/_download_form.html.erb:110 +#: ../../app/views/plans/_download_form.html.erb:114 msgid "Left" msgstr "Gauche" -#: ../../app/views/plans/_download_form.html.erb:119 +#: ../../app/views/plans/_download_form.html.erb:123 msgid "Right" msgstr "Droite" -#: ../../app/views/plans/_download_form.html.erb:130 +#: ../../app/views/plans/_download_form.html.erb:133 msgid "" "Download Plan (new window)%{open_in_new_window_text}" diff --git a/config/locale/pt_BR/LC_MESSAGES/app.mo b/config/locale/pt_BR/LC_MESSAGES/app.mo index 48f01f060c9880671d225fcd48fead45b25ad958..6695cbe96a17fd533d0ea71792229f2869bb0df6 100644 GIT binary patch delta 76 zcmcaSlk@US&W0_F9bRUJM!H7E3I-Nd#>Tn^<^~2_0sgu{sb!hPnfZCTE{P?nRtiQ2 bMy9$Db%v%ub=n37?fbkKx9{^}5@iAaY-$x} delta 76 zcmcaSlk@US&W0_F9bRSzCc1_O3Wmm3Mi#mTW(Eda0sgu{sb!hPnfZCTE{P?nRtiQ2 bMy9$Dbw-9jb=n3-?fbkKx9{^}5@iAaYgiRy diff --git a/config/locale/pt_BR/app.po b/config/locale/pt_BR/app.po index 44e4aeb102..a401ad5aad 100644 --- a/config/locale/pt_BR/app.po +++ b/config/locale/pt_BR/app.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: roadmap_upstream 1.0\n" "Report-Msgid-Bugs-To: contact@translation.io\n" -"POT-Creation-Date: 2025-04-10 13:28-0600\n" -"PO-Revision-Date: 2025-04-10 21:28+0200\n" +"POT-Creation-Date: 2025-12-23 08:33-0700\n" +"PO-Revision-Date: 2025-12-23 15:33+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Portuguese\n" "Language: pt_BR\n" @@ -127,87 +127,95 @@ msgstr "JSON inválido" msgid "No Plans found" msgstr "Nenhum plano encontrado" -#: ../../app/controllers/application_controller.rb:36 +#: ../../app/controllers/api/v2/base_api_controller.rb:72 +msgid "There was a problem in the server." +msgstr "" + +#: ../../app/controllers/api/v2/base_api_controller.rb:78 +msgid "The client is not authorized to perform this action." +msgstr "" + +#: ../../app/controllers/application_controller.rb:37 msgid "You are not authorized to perform this action." msgstr "Você não tem permissão para realizar essa ação." -#: ../../app/controllers/application_controller.rb:40 +#: ../../app/controllers/application_controller.rb:41 msgid "You need to sign in or sign up before continuing." msgstr "Você precisa entrar ou registrar-se antes de continuar." -#: ../../app/controllers/application_controller.rb:108 +#: ../../app/controllers/application_controller.rb:115 msgid "Unable to %{action} the %{object}. %{errors}" msgstr "Não é possível %{action} o %{object}. %{errors}" -#: ../../app/controllers/application_controller.rb:114 +#: ../../app/controllers/application_controller.rb:121 msgid "Successfully %{action} the %{object}." msgstr "Com sucesso %{action} o %{object}." -#: ../../app/controllers/application_controller.rb:127 +#: ../../app/controllers/application_controller.rb:134 msgid "API client" msgstr "Cliente da API" -#: ../../app/controllers/application_controller.rb:128 +#: ../../app/controllers/application_controller.rb:135 msgid "plan" msgstr "plano" -#: ../../app/controllers/application_controller.rb:129 +#: ../../app/controllers/application_controller.rb:136 msgid "guidance group" msgstr "grupo de instruções" -#: ../../app/controllers/application_controller.rb:130 +#: ../../app/controllers/application_controller.rb:137 msgid "comment" msgstr "commentário" -#: ../../app/controllers/application_controller.rb:131 +#: ../../app/controllers/application_controller.rb:138 msgid "organisation" msgstr "organização" -#: ../../app/controllers/application_controller.rb:132 +#: ../../app/controllers/application_controller.rb:139 msgid "permission" msgstr "permissão" -#: ../../app/controllers/application_controller.rb:133 +#: ../../app/controllers/application_controller.rb:140 msgid "preferences" msgstr "preferências" -#: ../../app/controllers/application_controller.rb:134 +#: ../../app/controllers/application_controller.rb:141 msgid "profile" msgstr "perfil" -#: ../../app/controllers/application_controller.rb:134 +#: ../../app/controllers/application_controller.rb:141 msgid "user" msgstr "usuário" -#: ../../app/controllers/application_controller.rb:135 +#: ../../app/controllers/application_controller.rb:142 msgid "question option" msgstr "opção de pergunta" -#: ../../app/controllers/application_controller.rb:181 +#: ../../app/controllers/application_controller.rb:188 msgid "Record Not Found" msgstr "Registro não encontrado" -#: ../../app/controllers/concerns/paginable.rb:45 +#: ../../app/controllers/concerns/paginable.rb:46 msgid "scope should be an ActiveRecord::Relation object" msgstr "escopo deve ser um objeto ActiveRecord::Relation" -#: ../../app/controllers/concerns/paginable.rb:47 +#: ../../app/controllers/concerns/paginable.rb:48 msgid "path_params should be a Hash object" msgstr "path_params deve ser um objeto hash" -#: ../../app/controllers/concerns/paginable.rb:48 +#: ../../app/controllers/concerns/paginable.rb:49 msgid "query_params should be a Hash object" msgstr "query_params deve ser um objeto hash" -#: ../../app/controllers/concerns/paginable.rb:49 +#: ../../app/controllers/concerns/paginable.rb:50 msgid "locals should be a Hash object" msgstr "locals deve ser um objeto Hash" -#: ../../app/controllers/concerns/paginable.rb:70 +#: ../../app/controllers/concerns/paginable.rb:71 msgid "Restricted access to View All the records" msgstr "Acesso restrito para visualizar todos os registros" -#: ../../app/controllers/concerns/paginable.rb:183 +#: ../../app/controllers/concerns/paginable.rb:184 msgid "Sort by %{sort_field}" msgstr "Classificar por %{sort_field}" @@ -248,77 +256,77 @@ msgstr "Email de contato foi enviado com sucesso." msgid "Unable to submit your request" msgstr "Não é possível enviar sua solicitação" -#: ../../app/controllers/contributors_controller.rb:40 -#: ../../app/controllers/contributors_controller.rb:56 +#: ../../app/controllers/contributors_controller.rb:41 +#: ../../app/controllers/contributors_controller.rb:57 #: ../../app/controllers/research_outputs_controller.rb:42 msgid "add" msgstr "Adicionar" -#: ../../app/controllers/contributors_controller.rb:54 +#: ../../app/controllers/contributors_controller.rb:55 #: ../../app/controllers/research_outputs_controller.rb:40 msgid "added" msgstr "adicionado" -#: ../../app/controllers/contributors_controller.rb:72 +#: ../../app/controllers/contributors_controller.rb:73 #: ../../app/controllers/guidance_groups_controller.rb:55 #: ../../app/controllers/guidances_controller.rb:75 -#: ../../app/controllers/notes_controller.rb:88 +#: ../../app/controllers/notes_controller.rb:89 #: ../../app/controllers/org_admin/departments_controller.rb:50 #: ../../app/controllers/org_admin/sections_controller.rb:103 #: ../../app/controllers/org_admin/templates_controller.rb:210 #: ../../app/controllers/orgs_controller.rb:92 -#: ../../app/controllers/plans_controller.rb:280 -#: ../../app/controllers/plans_controller.rb:283 +#: ../../app/controllers/plans_controller.rb:281 +#: ../../app/controllers/plans_controller.rb:284 #: ../../app/controllers/registrations_controller.rb:249 #: ../../app/controllers/registrations_controller.rb:253 #: ../../app/controllers/registrations_controller.rb:280 #: ../../app/controllers/registrations_controller.rb:284 #: ../../app/controllers/research_outputs_controller.rb:60 -#: ../../app/controllers/users_controller.rb:103 -#: ../../app/controllers/users_controller.rb:131 +#: ../../app/controllers/users_controller.rb:104 +#: ../../app/controllers/users_controller.rb:132 msgid "saved" msgstr "salvo" -#: ../../app/controllers/contributors_controller.rb:74 +#: ../../app/controllers/contributors_controller.rb:75 #: ../../app/controllers/guidance_groups_controller.rb:57 #: ../../app/controllers/guidances_controller.rb:77 -#: ../../app/controllers/notes_controller.rb:106 +#: ../../app/controllers/notes_controller.rb:107 #: ../../app/controllers/org_admin/departments_controller.rb:52 #: ../../app/controllers/org_admin/sections_controller.rb:105 #: ../../app/controllers/org_admin/templates_controller.rb:215 #: ../../app/controllers/orgs_controller.rb:94 -#: ../../app/controllers/plans_controller.rb:289 -#: ../../app/controllers/plans_controller.rb:292 -#: ../../app/controllers/plans_controller.rb:296 -#: ../../app/controllers/plans_controller.rb:299 +#: ../../app/controllers/plans_controller.rb:290 +#: ../../app/controllers/plans_controller.rb:293 +#: ../../app/controllers/plans_controller.rb:297 +#: ../../app/controllers/plans_controller.rb:300 #: ../../app/controllers/registrations_controller.rb:256 #: ../../app/controllers/registrations_controller.rb:287 #: ../../app/controllers/research_outputs_controller.rb:63 msgid "save" msgstr "Salvar" -#: ../../app/controllers/contributors_controller.rb:83 -#: ../../app/controllers/notes_controller.rb:130 +#: ../../app/controllers/contributors_controller.rb:84 +#: ../../app/controllers/notes_controller.rb:131 #: ../../app/controllers/org_admin/templates_controller.rb:243 #: ../../app/controllers/research_outputs_controller.rb:74 #: ../../app/controllers/super_admin/orgs_controller.rb:94 msgid "removed" msgstr "removido" -#: ../../app/controllers/contributors_controller.rb:86 -#: ../../app/controllers/notes_controller.rb:148 +#: ../../app/controllers/contributors_controller.rb:87 +#: ../../app/controllers/notes_controller.rb:149 #: ../../app/controllers/org_admin/templates_controller.rb:245 #: ../../app/controllers/research_outputs_controller.rb:77 #: ../../app/controllers/super_admin/orgs_controller.rb:97 msgid "remove" msgstr "Remover" -#: ../../app/controllers/contributors_controller.rb:160 +#: ../../app/controllers/contributors_controller.rb:161 #: ../../app/controllers/research_outputs_controller.rb:208 msgid "plan not found" msgstr "plano não encontrado" -#: ../../app/controllers/contributors_controller.rb:168 +#: ../../app/controllers/contributors_controller.rb:169 msgid "contributor not found" msgstr "colaborador não encontrado" @@ -332,7 +340,7 @@ msgstr "Ocorreu um erro ao solicitar feedback para este plano." #: ../../app/controllers/guidance_groups_controller.rb:31 #: ../../app/controllers/guidances_controller.rb:53 -#: ../../app/controllers/notes_controller.rb:47 +#: ../../app/controllers/notes_controller.rb:48 #: ../../app/controllers/org_admin/departments_controller.rb:26 #: ../../app/controllers/org_admin/phases_controller.rb:121 #: ../../app/controllers/org_admin/questions_controller.rb:94 @@ -348,7 +356,7 @@ msgstr "criado" #: ../../app/controllers/guidance_groups_controller.rb:34 #: ../../app/controllers/guidances_controller.rb:55 -#: ../../app/controllers/notes_controller.rb:66 +#: ../../app/controllers/notes_controller.rb:67 #: ../../app/controllers/org_admin/departments_controller.rb:30 #: ../../app/controllers/org_admin/phases_controller.rb:123 #: ../../app/controllers/org_admin/questions_controller.rb:96 @@ -391,7 +399,7 @@ msgstr "cancelar publicação" #: ../../app/controllers/org_admin/question_options_controller.rb:24 #: ../../app/controllers/org_admin/questions_controller.rb:197 #: ../../app/controllers/org_admin/sections_controller.rb:128 -#: ../../app/controllers/plans_controller.rb:342 +#: ../../app/controllers/plans_controller.rb:343 #: ../../app/controllers/super_admin/api_clients_controller.rb:81 #: ../../app/controllers/super_admin/notifications_controller.rb:85 #: ../../app/controllers/super_admin/themes_controller.rb:51 @@ -405,7 +413,7 @@ msgstr "apagado" #: ../../app/controllers/org_admin/question_options_controller.rb:26 #: ../../app/controllers/org_admin/questions_controller.rb:199 #: ../../app/controllers/org_admin/sections_controller.rb:130 -#: ../../app/controllers/plans_controller.rb:347 +#: ../../app/controllers/plans_controller.rb:348 #: ../../app/controllers/super_admin/api_clients_controller.rb:84 #: ../../app/controllers/super_admin/notifications_controller.rb:88 #: ../../app/controllers/super_admin/themes_controller.rb:54 @@ -450,19 +458,19 @@ msgstr "Não foi possível criar uma nova versão deste modelo.
" #: ../../app/controllers/org_admin/phases_controller.rb:147 #: ../../app/controllers/org_admin/questions_controller.rb:166 #: ../../app/controllers/org_admin/users_controller.rb:30 -#: ../../app/controllers/plans_controller.rb:416 +#: ../../app/controllers/plans_controller.rb:417 #: ../../app/controllers/super_admin/api_clients_controller.rb:68 #: ../../app/controllers/super_admin/notifications_controller.rb:52 #: ../../app/controllers/super_admin/themes_controller.rb:39 #: ../../app/controllers/super_admin/users_controller.rb:54 -#: ../../app/controllers/users_controller.rb:108 +#: ../../app/controllers/users_controller.rb:109 msgid "updated" msgstr "Atualizado" #: ../../app/controllers/org_admin/phases_controller.rb:149 #: ../../app/controllers/org_admin/questions_controller.rb:169 #: ../../app/controllers/org_admin/users_controller.rb:32 -#: ../../app/controllers/plans_controller.rb:419 +#: ../../app/controllers/plans_controller.rb:420 #: ../../app/controllers/super_admin/api_clients_controller.rb:70 #: ../../app/controllers/super_admin/notifications_controller.rb:55 #: ../../app/controllers/super_admin/themes_controller.rb:41 @@ -552,7 +560,7 @@ msgid "Unable to delete this version of the template." msgstr "Não foi possível excluir esta versão do modelo." #: ../../app/controllers/org_admin/template_copies_controller.rb:20 -#: ../../app/controllers/plans_controller.rb:395 +#: ../../app/controllers/plans_controller.rb:396 msgid "copy" msgstr "cópia" @@ -561,11 +569,11 @@ msgstr "cópia" msgid "That template is no longer customizable." msgstr "Esse modelo não é mais customizáveis." -#: ../../app/controllers/org_admin/template_customizations_controller.rb:21 +#: ../../app/controllers/org_admin/template_customizations_controller.rb:22 msgid "Unable to customize that template." msgstr "Não customização esse modelo." -#: ../../app/controllers/org_admin/template_customizations_controller.rb:24 +#: ../../app/controllers/org_admin/template_customizations_controller.rb:25 msgid "That template is not customizable." msgstr "Esse modelo não é customizáveis." @@ -655,11 +663,11 @@ msgstr "Este plano é baseado no" msgid "template with customisations by the" msgstr "modelo com personalizações pelo" -#: ../../app/controllers/plans_controller.rb:393 +#: ../../app/controllers/plans_controller.rb:394 msgid "copied" msgstr "copieado" -#: ../../app/controllers/plans_controller.rb:424 +#: ../../app/controllers/plans_controller.rb:425 msgid "" "Unable to change the plan's status since it is needed at least %{percentage} p" "ercentage responded" @@ -667,23 +675,23 @@ msgstr "" "Não conseguimos mudar o status do plano. É preciso pelo menos %{percentage} de" " respostas." -#: ../../app/controllers/plans_controller.rb:430 +#: ../../app/controllers/plans_controller.rb:431 msgid "Unable to find plan id %{plan_id}" msgstr "Não conseguimos encontrar o plano com id %{plan_id}" -#: ../../app/controllers/plans_controller.rb:445 +#: ../../app/controllers/plans_controller.rb:446 msgid "Your project is now a test." msgstr "Seu projeto agora é um teste." -#: ../../app/controllers/plans_controller.rb:445 +#: ../../app/controllers/plans_controller.rb:446 msgid "Your project is no longer a test." msgstr "Seu projeto não é mais um teste." -#: ../../app/controllers/plans_controller.rb:449 +#: ../../app/controllers/plans_controller.rb:450 msgid "Unable to change the plan's test status" msgstr "Não conseguimos mudar o status de teste do plano" -#: ../../app/controllers/plans_controller.rb:462 +#: ../../app/controllers/plans_controller.rb:463 msgid "There is no plan associated with id %{s" msgstr "Não há plano associado ao id %{ s" @@ -779,7 +787,7 @@ msgstr "A senha e a confirmação devem ser iguais" msgid "research output not found" msgstr "resultado da pesquisa não encontrado" -#: ../../app/controllers/roles_controller.rb:26 +#: ../../app/controllers/roles_controller.rb:27 msgid "" "Cannot share plan with %{email} since that email matches\n" " with the owner of the plan." @@ -956,27 +964,27 @@ msgstr "Sua conta foi vinculada a %{scheme}." msgid "Unable to link your account to %{scheme}." msgstr "Não é possível vincular sua conta a% {scheme}." -#: ../../app/controllers/users_controller.rb:149 +#: ../../app/controllers/users_controller.rb:150 msgid "Successfully %{action} %{username}'s account." msgstr "Successo ao %{action} conta do %{username}" -#: ../../app/controllers/users_controller.rb:150 +#: ../../app/controllers/users_controller.rb:151 msgid "activated" msgstr "ativado" -#: ../../app/controllers/users_controller.rb:150 +#: ../../app/controllers/users_controller.rb:151 msgid "deactivated" msgstr "desativado" -#: ../../app/controllers/users_controller.rb:156 +#: ../../app/controllers/users_controller.rb:157 msgid "Unable to %{action} %{username}" msgstr "Incapaz de %{action} %{username}" -#: ../../app/controllers/users_controller.rb:157 +#: ../../app/controllers/users_controller.rb:158 msgid "activate" msgstr "Ativo" -#: ../../app/controllers/users_controller.rb:157 +#: ../../app/controllers/users_controller.rb:158 msgid "deactivate" msgstr "desativar" @@ -1268,50 +1276,50 @@ msgstr "Últimos 9 meses" msgid "Last 12 months" msgstr "Últimos 12 meses" -#: ../../app/mailers/user_mailer.rb:17 +#: ../../app/mailers/user_mailer.rb:18 #: ../../app/views/devise/mailer/invitation_instructions.html.erb:5 #: ../../app/views/devise/mailer/reset_password_instructions.html.erb:5 #: ../../app/views/user_mailer/_email_signature.html.erb:2 msgid "Query or feedback related to %{tool_name}" msgstr "Pergunta ou feedback relacionado a %{tool_name}" -#: ../../app/mailers/user_mailer.rb:25 +#: ../../app/mailers/user_mailer.rb:26 msgid "Welcome to %{tool_name}" msgstr "Bem-vindo a %{tool_name}" -#: ../../app/mailers/user_mailer.rb:62 +#: ../../app/mailers/user_mailer.rb:63 msgid "A Data Management Plan in %{tool_name} has been shared with you" msgstr "Um plano de gerenciamento de dados em %{tool_name} foi compartilhado com você" -#: ../../app/mailers/user_mailer.rb:79 +#: ../../app/mailers/user_mailer.rb:80 msgid "Changed permissions on a Data Management Plan in %{tool_name}" msgstr "Permissões modificadas em um Plano de Gestão de Dados em %{tool_name}" -#: ../../app/mailers/user_mailer.rb:94 +#: ../../app/mailers/user_mailer.rb:95 msgid "Permissions removed on a DMP in %{tool_name}" msgstr "Permissões removidas em um PGD em %{tool_name}" -#: ../../app/mailers/user_mailer.rb:112 +#: ../../app/mailers/user_mailer.rb:113 msgid "%{user_name} has requested feedback on a %{tool_name} plan" msgstr "%{user_name} solicitou feedback sobre um plano %{tool_name}" -#: ../../app/mailers/user_mailer.rb:135 +#: ../../app/mailers/user_mailer.rb:136 msgid "%{tool_name}: Expert feedback has been provided for %{plan_title}" msgstr "%{tool_name}: O feedback de especialistas foi fornecido para %{plan_title}" -#: ../../app/mailers/user_mailer.rb:153 +#: ../../app/mailers/user_mailer.rb:154 msgid "DMP Visibility Changed: %{plan_title}" msgstr "Visibilidade do PGD Modificada: %{plan_title}" -#: ../../app/mailers/user_mailer.rb:182 +#: ../../app/mailers/user_mailer.rb:183 msgid "%{tool_name}: A new comment was added to %{plan_title}" msgstr "%{tool_name}: Um novo comentário foi adicionado a %{plan_title}" -#: ../../app/mailers/user_mailer.rb:198 +#: ../../app/mailers/user_mailer.rb:199 msgid "Administrator privileges granted in %{tool_name}" msgstr "Privilégios de administrador atribuídos em %{tool_name}" -#: ../../app/mailers/user_mailer.rb:216 +#: ../../app/mailers/user_mailer.rb:217 msgid "%{tool_name} API changes" msgstr "Alterações na API %{tool_name}" @@ -1551,15 +1559,15 @@ msgstr "" msgid "already assigned a value" msgstr "já atribuiu um valor" -#: ../../app/models/org.rb:46 +#: ../../app/models/org.rb:47 msgid "Feedback email message" msgstr "Mensagem de email de feedback" -#: ../../app/models/org.rb:123 +#: ../../app/models/org.rb:124 msgid "must be one of the following formats: jpeg, jpg, png, gif, bmp" msgstr "deve ser um dos seguintes formatos: jpeg, jpg, png, gif, bmp" -#: ../../app/models/org.rb:128 +#: ../../app/models/org.rb:129 msgid "can't be larger than 500KB" msgstr "não pode ser maior que 500KB" @@ -1685,7 +1693,7 @@ msgstr "Você não pode publicar um modelo sem perguntas em uma seção." msgid "Conditions in the template refer backwards" msgstr "As condições no modelo se referem ao contrário" -#: ../../app/models/user.rb:380 +#: ../../app/models/user.rb:386 msgid "A Data Management Plan in %{application_name} has been shared with you" msgstr "Um Plano de Gestão de Dados em %{application_name} foi compartilhado com você" @@ -2112,7 +2120,7 @@ msgstr "" #: ../../app/views/paginable/templates/_organisational.html.erb:87 #: ../../app/views/paginable/templates/_publicly_visible.html.erb:29 #: ../../app/views/paginable/templates/_publicly_visible.html.erb:36 -#: ../../app/views/plans/_download_form.html.erb:130 +#: ../../app/views/plans/_download_form.html.erb:133 #: ../../app/views/static_pages/about_us.html.erb:22 #: ../../app/views/static_pages/about_us.html.erb:29 #: ../../app/views/static_pages/termsuse.html.erb:46 @@ -4621,7 +4629,7 @@ msgstr "Comentários e orientações" msgid "Instructions" msgstr "Instruções" -#: ../../app/views/plans/_download_form.html.erb:6 +#: ../../app/views/plans/_download_form.html.erb:5 msgid "Format" msgstr "Formato" @@ -4629,71 +4637,71 @@ msgstr "Formato" msgid "Download settings" msgstr "Baixar parâmetros" -#: ../../app/views/plans/_download_form.html.erb:19 -msgid "Select phase to download" -msgstr "Selecione a fase a ser baixada" - -#: ../../app/views/plans/_download_form.html.erb:26 +#: ../../app/views/plans/_download_form.html.erb:21 msgid "Optional plan components" msgstr "Componentes opcionais do plano" -#: ../../app/views/plans/_download_form.html.erb:30 +#: ../../app/views/plans/_download_form.html.erb:25 msgid "project details coversheet" msgstr "capa com detalhes do projeto" -#: ../../app/views/plans/_download_form.html.erb:36 +#: ../../app/views/plans/_download_form.html.erb:31 msgid "question text and section headings" msgstr "texto das questões e cabeçalhos das seções" -#: ../../app/views/plans/_download_form.html.erb:42 +#: ../../app/views/plans/_download_form.html.erb:37 msgid "unanswered questions" msgstr "questões não respondida" -#: ../../app/views/plans/_download_form.html.erb:49 +#: ../../app/views/plans/_download_form.html.erb:44 msgid "research outputs" msgstr "resultados de pesquisa" -#: ../../app/views/plans/_download_form.html.erb:57 +#: ../../app/views/plans/_download_form.html.erb:52 msgid "supplementary section(s) not requested by funding organisation" msgstr "seção(ões) suplementar(es) não solicitada(s) pela organização financiadora" -#: ../../app/views/plans/_download_form.html.erb:65 +#: ../../app/views/plans/_download_form.html.erb:61 +msgid "Select phase to download" +msgstr "Selecione a fase a ser baixada" + +#: ../../app/views/plans/_download_form.html.erb:70 msgid "PDF formatting" msgstr "Formatação de PDF" -#: ../../app/views/plans/_download_form.html.erb:68 +#: ../../app/views/plans/_download_form.html.erb:73 msgid "Font" msgstr "Fonte" -#: ../../app/views/plans/_download_form.html.erb:71 +#: ../../app/views/plans/_download_form.html.erb:76 msgid "Margin (mm)" msgstr "Margem (mm)" -#: ../../app/views/plans/_download_form.html.erb:76 +#: ../../app/views/plans/_download_form.html.erb:81 msgid "Face" msgstr "Face" -#: ../../app/views/plans/_download_form.html.erb:84 +#: ../../app/views/plans/_download_form.html.erb:89 msgid "Size" msgstr "Tamanho" -#: ../../app/views/plans/_download_form.html.erb:92 +#: ../../app/views/plans/_download_form.html.erb:96 msgid "Top" msgstr "Alto" -#: ../../app/views/plans/_download_form.html.erb:101 +#: ../../app/views/plans/_download_form.html.erb:105 msgid "Bottom" msgstr "Fim da página" -#: ../../app/views/plans/_download_form.html.erb:110 +#: ../../app/views/plans/_download_form.html.erb:114 msgid "Left" msgstr "Esquerda" -#: ../../app/views/plans/_download_form.html.erb:119 +#: ../../app/views/plans/_download_form.html.erb:123 msgid "Right" msgstr "Direito" -#: ../../app/views/plans/_download_form.html.erb:130 +#: ../../app/views/plans/_download_form.html.erb:133 msgid "" "Download Plan (new window)%{open_in_new_window_text}" diff --git a/config/locale/sv_FI/LC_MESSAGES/app.mo b/config/locale/sv_FI/LC_MESSAGES/app.mo index 87905cb49b97a0c50ccdf2c565c840c4cca75717..90d0abe8ae531c1a581ad504f7a210da586a65fd 100644 GIT binary patch delta 52 zcmcclh2!QIj)pCaXFd1~jdYES6$~t_jE!{-%%|V>V3dN28JYscv<(clGkY?IeFOl~ CE)R$R delta 52 zcmcclh2!QIj)pCaXFd1~Omqzm6by~6j4X5w%%G diff --git a/config/locale/sv_FI/app.po b/config/locale/sv_FI/app.po index 93e28ad899..c464b0683b 100644 --- a/config/locale/sv_FI/app.po +++ b/config/locale/sv_FI/app.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: roadmap_upstream 1.0\n" "Report-Msgid-Bugs-To: contact@translation.io\n" -"POT-Creation-Date: 2025-04-10 13:28-0600\n" -"PO-Revision-Date: 2025-04-10 21:28+0200\n" +"POT-Creation-Date: 2025-12-23 08:33-0700\n" +"PO-Revision-Date: 2025-12-23 15:33+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Swedish\n" "Language: sv_FI\n" @@ -127,87 +127,95 @@ msgstr "Ogiltig JSON" msgid "No Plans found" msgstr "Inga planer hittades" -#: ../../app/controllers/application_controller.rb:36 +#: ../../app/controllers/api/v2/base_api_controller.rb:72 +msgid "There was a problem in the server." +msgstr "" + +#: ../../app/controllers/api/v2/base_api_controller.rb:78 +msgid "The client is not authorized to perform this action." +msgstr "" + +#: ../../app/controllers/application_controller.rb:37 msgid "You are not authorized to perform this action." msgstr "Du har inte behörighet att utföra denna åtgärd." -#: ../../app/controllers/application_controller.rb:40 +#: ../../app/controllers/application_controller.rb:41 msgid "You need to sign in or sign up before continuing." msgstr "Du behöver logga in eller registrera dig innan du kan fortsätta." -#: ../../app/controllers/application_controller.rb:108 +#: ../../app/controllers/application_controller.rb:115 msgid "Unable to %{action} the %{object}. %{errors}" msgstr "Det går inte att %{action} %{object}. %{errors}" -#: ../../app/controllers/application_controller.rb:114 +#: ../../app/controllers/application_controller.rb:121 msgid "Successfully %{action} the %{object}." msgstr "Framgångsrikt %{action} %{object}." -#: ../../app/controllers/application_controller.rb:127 +#: ../../app/controllers/application_controller.rb:134 msgid "API client" msgstr "API-klient" -#: ../../app/controllers/application_controller.rb:128 +#: ../../app/controllers/application_controller.rb:135 msgid "plan" msgstr "planen" -#: ../../app/controllers/application_controller.rb:129 +#: ../../app/controllers/application_controller.rb:136 msgid "guidance group" msgstr "Guidningsgrupp" -#: ../../app/controllers/application_controller.rb:130 +#: ../../app/controllers/application_controller.rb:137 msgid "comment" msgstr "Kommentar" -#: ../../app/controllers/application_controller.rb:131 +#: ../../app/controllers/application_controller.rb:138 msgid "organisation" msgstr "organisation" -#: ../../app/controllers/application_controller.rb:132 +#: ../../app/controllers/application_controller.rb:139 msgid "permission" msgstr "lov" -#: ../../app/controllers/application_controller.rb:133 +#: ../../app/controllers/application_controller.rb:140 msgid "preferences" msgstr "preferenser" -#: ../../app/controllers/application_controller.rb:134 +#: ../../app/controllers/application_controller.rb:141 msgid "profile" msgstr "profil" -#: ../../app/controllers/application_controller.rb:134 +#: ../../app/controllers/application_controller.rb:141 msgid "user" msgstr "användare" -#: ../../app/controllers/application_controller.rb:135 +#: ../../app/controllers/application_controller.rb:142 msgid "question option" msgstr "fråga alternativ" -#: ../../app/controllers/application_controller.rb:181 +#: ../../app/controllers/application_controller.rb:188 msgid "Record Not Found" msgstr "Posten hittades inte" -#: ../../app/controllers/concerns/paginable.rb:45 +#: ../../app/controllers/concerns/paginable.rb:46 msgid "scope should be an ActiveRecord::Relation object" msgstr "Räckvidd bör vara ett ActiveRecord :: Relation-objekt" -#: ../../app/controllers/concerns/paginable.rb:47 +#: ../../app/controllers/concerns/paginable.rb:48 msgid "path_params should be a Hash object" msgstr "path_params ska vara ett Hash-objekt" -#: ../../app/controllers/concerns/paginable.rb:48 +#: ../../app/controllers/concerns/paginable.rb:49 msgid "query_params should be a Hash object" msgstr "query_params ska vara ett Hash-objekt" -#: ../../app/controllers/concerns/paginable.rb:49 +#: ../../app/controllers/concerns/paginable.rb:50 msgid "locals should be a Hash object" msgstr "lokalbefolkningen borde vara ett Hash-objekt" -#: ../../app/controllers/concerns/paginable.rb:70 +#: ../../app/controllers/concerns/paginable.rb:71 msgid "Restricted access to View All the records" msgstr "Begränsad åtkomst till Visa alla poster" -#: ../../app/controllers/concerns/paginable.rb:183 +#: ../../app/controllers/concerns/paginable.rb:184 msgid "Sort by %{sort_field}" msgstr "Sortera efter %{sort_field}" @@ -248,77 +256,77 @@ msgstr "Kontaktadressen skickades med framgång." msgid "Unable to submit your request" msgstr "Det gick inte att skicka din förfrågan" -#: ../../app/controllers/contributors_controller.rb:40 -#: ../../app/controllers/contributors_controller.rb:56 +#: ../../app/controllers/contributors_controller.rb:41 +#: ../../app/controllers/contributors_controller.rb:57 #: ../../app/controllers/research_outputs_controller.rb:42 msgid "add" msgstr "Lägg till" -#: ../../app/controllers/contributors_controller.rb:54 +#: ../../app/controllers/contributors_controller.rb:55 #: ../../app/controllers/research_outputs_controller.rb:40 msgid "added" msgstr "Lagt till" -#: ../../app/controllers/contributors_controller.rb:72 +#: ../../app/controllers/contributors_controller.rb:73 #: ../../app/controllers/guidance_groups_controller.rb:55 #: ../../app/controllers/guidances_controller.rb:75 -#: ../../app/controllers/notes_controller.rb:88 +#: ../../app/controllers/notes_controller.rb:89 #: ../../app/controllers/org_admin/departments_controller.rb:50 #: ../../app/controllers/org_admin/sections_controller.rb:103 #: ../../app/controllers/org_admin/templates_controller.rb:210 #: ../../app/controllers/orgs_controller.rb:92 -#: ../../app/controllers/plans_controller.rb:280 -#: ../../app/controllers/plans_controller.rb:283 +#: ../../app/controllers/plans_controller.rb:281 +#: ../../app/controllers/plans_controller.rb:284 #: ../../app/controllers/registrations_controller.rb:249 #: ../../app/controllers/registrations_controller.rb:253 #: ../../app/controllers/registrations_controller.rb:280 #: ../../app/controllers/registrations_controller.rb:284 #: ../../app/controllers/research_outputs_controller.rb:60 -#: ../../app/controllers/users_controller.rb:103 -#: ../../app/controllers/users_controller.rb:131 +#: ../../app/controllers/users_controller.rb:104 +#: ../../app/controllers/users_controller.rb:132 msgid "saved" msgstr "sparade" -#: ../../app/controllers/contributors_controller.rb:74 +#: ../../app/controllers/contributors_controller.rb:75 #: ../../app/controllers/guidance_groups_controller.rb:57 #: ../../app/controllers/guidances_controller.rb:77 -#: ../../app/controllers/notes_controller.rb:106 +#: ../../app/controllers/notes_controller.rb:107 #: ../../app/controllers/org_admin/departments_controller.rb:52 #: ../../app/controllers/org_admin/sections_controller.rb:105 #: ../../app/controllers/org_admin/templates_controller.rb:215 #: ../../app/controllers/orgs_controller.rb:94 -#: ../../app/controllers/plans_controller.rb:289 -#: ../../app/controllers/plans_controller.rb:292 -#: ../../app/controllers/plans_controller.rb:296 -#: ../../app/controllers/plans_controller.rb:299 +#: ../../app/controllers/plans_controller.rb:290 +#: ../../app/controllers/plans_controller.rb:293 +#: ../../app/controllers/plans_controller.rb:297 +#: ../../app/controllers/plans_controller.rb:300 #: ../../app/controllers/registrations_controller.rb:256 #: ../../app/controllers/registrations_controller.rb:287 #: ../../app/controllers/research_outputs_controller.rb:63 msgid "save" msgstr "spara" -#: ../../app/controllers/contributors_controller.rb:83 -#: ../../app/controllers/notes_controller.rb:130 +#: ../../app/controllers/contributors_controller.rb:84 +#: ../../app/controllers/notes_controller.rb:131 #: ../../app/controllers/org_admin/templates_controller.rb:243 #: ../../app/controllers/research_outputs_controller.rb:74 #: ../../app/controllers/super_admin/orgs_controller.rb:94 msgid "removed" msgstr "tog bort" -#: ../../app/controllers/contributors_controller.rb:86 -#: ../../app/controllers/notes_controller.rb:148 +#: ../../app/controllers/contributors_controller.rb:87 +#: ../../app/controllers/notes_controller.rb:149 #: ../../app/controllers/org_admin/templates_controller.rb:245 #: ../../app/controllers/research_outputs_controller.rb:77 #: ../../app/controllers/super_admin/orgs_controller.rb:97 msgid "remove" msgstr "ta bort" -#: ../../app/controllers/contributors_controller.rb:160 +#: ../../app/controllers/contributors_controller.rb:161 #: ../../app/controllers/research_outputs_controller.rb:208 msgid "plan not found" msgstr "Planen hittades inte" -#: ../../app/controllers/contributors_controller.rb:168 +#: ../../app/controllers/contributors_controller.rb:169 msgid "contributor not found" msgstr "bidragsgivare hittades inte" @@ -332,7 +340,7 @@ msgstr "Ett fel uppstod när du begärde feedback för den här planen." #: ../../app/controllers/guidance_groups_controller.rb:31 #: ../../app/controllers/guidances_controller.rb:53 -#: ../../app/controllers/notes_controller.rb:47 +#: ../../app/controllers/notes_controller.rb:48 #: ../../app/controllers/org_admin/departments_controller.rb:26 #: ../../app/controllers/org_admin/phases_controller.rb:121 #: ../../app/controllers/org_admin/questions_controller.rb:94 @@ -348,7 +356,7 @@ msgstr "skapad" #: ../../app/controllers/guidance_groups_controller.rb:34 #: ../../app/controllers/guidances_controller.rb:55 -#: ../../app/controllers/notes_controller.rb:66 +#: ../../app/controllers/notes_controller.rb:67 #: ../../app/controllers/org_admin/departments_controller.rb:30 #: ../../app/controllers/org_admin/phases_controller.rb:123 #: ../../app/controllers/org_admin/questions_controller.rb:96 @@ -389,7 +397,7 @@ msgstr "Avpublicera" #: ../../app/controllers/org_admin/question_options_controller.rb:24 #: ../../app/controllers/org_admin/questions_controller.rb:197 #: ../../app/controllers/org_admin/sections_controller.rb:128 -#: ../../app/controllers/plans_controller.rb:342 +#: ../../app/controllers/plans_controller.rb:343 #: ../../app/controllers/super_admin/api_clients_controller.rb:81 #: ../../app/controllers/super_admin/notifications_controller.rb:85 #: ../../app/controllers/super_admin/themes_controller.rb:51 @@ -403,7 +411,7 @@ msgstr "raderade" #: ../../app/controllers/org_admin/question_options_controller.rb:26 #: ../../app/controllers/org_admin/questions_controller.rb:199 #: ../../app/controllers/org_admin/sections_controller.rb:130 -#: ../../app/controllers/plans_controller.rb:347 +#: ../../app/controllers/plans_controller.rb:348 #: ../../app/controllers/super_admin/api_clients_controller.rb:84 #: ../../app/controllers/super_admin/notifications_controller.rb:88 #: ../../app/controllers/super_admin/themes_controller.rb:54 @@ -448,19 +456,19 @@ msgstr "Det gick inte att skapa en ny version av den här mallen.
" #: ../../app/controllers/org_admin/phases_controller.rb:147 #: ../../app/controllers/org_admin/questions_controller.rb:166 #: ../../app/controllers/org_admin/users_controller.rb:30 -#: ../../app/controllers/plans_controller.rb:416 +#: ../../app/controllers/plans_controller.rb:417 #: ../../app/controllers/super_admin/api_clients_controller.rb:68 #: ../../app/controllers/super_admin/notifications_controller.rb:52 #: ../../app/controllers/super_admin/themes_controller.rb:39 #: ../../app/controllers/super_admin/users_controller.rb:54 -#: ../../app/controllers/users_controller.rb:108 +#: ../../app/controllers/users_controller.rb:109 msgid "updated" msgstr "Uppdaterad" #: ../../app/controllers/org_admin/phases_controller.rb:149 #: ../../app/controllers/org_admin/questions_controller.rb:169 #: ../../app/controllers/org_admin/users_controller.rb:32 -#: ../../app/controllers/plans_controller.rb:419 +#: ../../app/controllers/plans_controller.rb:420 #: ../../app/controllers/super_admin/api_clients_controller.rb:70 #: ../../app/controllers/super_admin/notifications_controller.rb:55 #: ../../app/controllers/super_admin/themes_controller.rb:41 @@ -550,7 +558,7 @@ msgid "Unable to delete this version of the template." msgstr "Det gick inte att ta bort den här versionen av mallen." #: ../../app/controllers/org_admin/template_copies_controller.rb:20 -#: ../../app/controllers/plans_controller.rb:395 +#: ../../app/controllers/plans_controller.rb:396 msgid "copy" msgstr "kopia" @@ -559,11 +567,11 @@ msgstr "kopia" msgid "That template is no longer customizable." msgstr "Den mallen är inte längre anpassningsbar." -#: ../../app/controllers/org_admin/template_customizations_controller.rb:21 +#: ../../app/controllers/org_admin/template_customizations_controller.rb:22 msgid "Unable to customize that template." msgstr "Det gick inte att anpassa den mallen." -#: ../../app/controllers/org_admin/template_customizations_controller.rb:24 +#: ../../app/controllers/org_admin/template_customizations_controller.rb:25 msgid "That template is not customizable." msgstr "Den mallen är inte anpassningsbar." @@ -653,11 +661,11 @@ msgstr "Denna plan är baserad på" msgid "template with customisations by the" msgstr "mall med anpassningar av" -#: ../../app/controllers/plans_controller.rb:393 +#: ../../app/controllers/plans_controller.rb:394 msgid "copied" msgstr "kopieras" -#: ../../app/controllers/plans_controller.rb:424 +#: ../../app/controllers/plans_controller.rb:425 msgid "" "Unable to change the plan's status since it is needed at least %{percentage} p" "ercentage responded" @@ -665,23 +673,23 @@ msgstr "" "Det går inte att ändra planens status eftersom det behövs minst %{percentage} " "procent svarat" -#: ../../app/controllers/plans_controller.rb:430 +#: ../../app/controllers/plans_controller.rb:431 msgid "Unable to find plan id %{plan_id}" msgstr "Det gick inte att hitta plan id %{plan_id}" -#: ../../app/controllers/plans_controller.rb:445 +#: ../../app/controllers/plans_controller.rb:446 msgid "Your project is now a test." msgstr "Ditt projekt är nu ett test." -#: ../../app/controllers/plans_controller.rb:445 +#: ../../app/controllers/plans_controller.rb:446 msgid "Your project is no longer a test." msgstr "Ditt projekt är inte längre ett test." -#: ../../app/controllers/plans_controller.rb:449 +#: ../../app/controllers/plans_controller.rb:450 msgid "Unable to change the plan's test status" msgstr "Kan inte ändra planens teststatus" -#: ../../app/controllers/plans_controller.rb:462 +#: ../../app/controllers/plans_controller.rb:463 msgid "There is no plan associated with id %{s" msgstr "Det finns ingen plan kopplad till id %{ s" @@ -775,7 +783,7 @@ msgstr "Lösenord och bekräftelse måste matcha" msgid "research output not found" msgstr "forskningsresultat hittades inte" -#: ../../app/controllers/roles_controller.rb:26 +#: ../../app/controllers/roles_controller.rb:27 msgid "" "Cannot share plan with %{email} since that email matches\n" " with the owner of the plan." @@ -948,27 +956,27 @@ msgstr "Ditt konto har länkats till %{scheme}." msgid "Unable to link your account to %{scheme}." msgstr "Det gick inte att länka ditt konto till %{scheme}." -#: ../../app/controllers/users_controller.rb:149 +#: ../../app/controllers/users_controller.rb:150 msgid "Successfully %{action} %{username}'s account." msgstr "Framgångsrikt %{action} %{username} s konto." -#: ../../app/controllers/users_controller.rb:150 +#: ../../app/controllers/users_controller.rb:151 msgid "activated" msgstr "aktiverad" -#: ../../app/controllers/users_controller.rb:150 +#: ../../app/controllers/users_controller.rb:151 msgid "deactivated" msgstr "deaktiveras" -#: ../../app/controllers/users_controller.rb:156 +#: ../../app/controllers/users_controller.rb:157 msgid "Unable to %{action} %{username}" msgstr "Kan inte %{action} %{username}" -#: ../../app/controllers/users_controller.rb:157 +#: ../../app/controllers/users_controller.rb:158 msgid "activate" msgstr "Aktivera" -#: ../../app/controllers/users_controller.rb:157 +#: ../../app/controllers/users_controller.rb:158 msgid "deactivate" msgstr "avaktivera" @@ -1259,50 +1267,50 @@ msgstr "Senaste 9 månaderna" msgid "Last 12 months" msgstr "Senaste 12 månaderna" -#: ../../app/mailers/user_mailer.rb:17 +#: ../../app/mailers/user_mailer.rb:18 #: ../../app/views/devise/mailer/invitation_instructions.html.erb:5 #: ../../app/views/devise/mailer/reset_password_instructions.html.erb:5 #: ../../app/views/user_mailer/_email_signature.html.erb:2 msgid "Query or feedback related to %{tool_name}" msgstr "Fråga eller feedback relaterad till %{tool_name}" -#: ../../app/mailers/user_mailer.rb:25 +#: ../../app/mailers/user_mailer.rb:26 msgid "Welcome to %{tool_name}" msgstr "Välkommen till %{tool_name}" -#: ../../app/mailers/user_mailer.rb:62 +#: ../../app/mailers/user_mailer.rb:63 msgid "A Data Management Plan in %{tool_name} has been shared with you" msgstr "En datahanteringsplan i %{tool_name} har delats med dig" -#: ../../app/mailers/user_mailer.rb:79 +#: ../../app/mailers/user_mailer.rb:80 msgid "Changed permissions on a Data Management Plan in %{tool_name}" msgstr "Ändrade behörigheter på en datahanteringsplan i %{tool_name}" -#: ../../app/mailers/user_mailer.rb:94 +#: ../../app/mailers/user_mailer.rb:95 msgid "Permissions removed on a DMP in %{tool_name}" msgstr "Behörigheter tas bort på en DMP i %{tool_name}" -#: ../../app/mailers/user_mailer.rb:112 +#: ../../app/mailers/user_mailer.rb:113 msgid "%{user_name} has requested feedback on a %{tool_name} plan" msgstr "%{user_name} har begärt feedback på en %{tool_name} plan" -#: ../../app/mailers/user_mailer.rb:135 +#: ../../app/mailers/user_mailer.rb:136 msgid "%{tool_name}: Expert feedback has been provided for %{plan_title}" msgstr "%{tool_name}: Feedback från experter har lämnats för %{plan_title}" -#: ../../app/mailers/user_mailer.rb:153 +#: ../../app/mailers/user_mailer.rb:154 msgid "DMP Visibility Changed: %{plan_title}" msgstr "DMP-synlighet ändrad: %{plan_title}" -#: ../../app/mailers/user_mailer.rb:182 +#: ../../app/mailers/user_mailer.rb:183 msgid "%{tool_name}: A new comment was added to %{plan_title}" msgstr "%{tool_name}: En ny kommentar läggs till i %{plan_title}" -#: ../../app/mailers/user_mailer.rb:198 +#: ../../app/mailers/user_mailer.rb:199 msgid "Administrator privileges granted in %{tool_name}" msgstr "Administratörsbehörighet beviljas i %{tool_name}" -#: ../../app/mailers/user_mailer.rb:216 +#: ../../app/mailers/user_mailer.rb:217 msgid "%{tool_name} API changes" msgstr "%{tool_name} API-ändringar" @@ -1542,15 +1550,15 @@ msgstr "" msgid "already assigned a value" msgstr "redan tilldelat ett värde" -#: ../../app/models/org.rb:46 +#: ../../app/models/org.rb:47 msgid "Feedback email message" msgstr "Feedback e-postmeddelande" -#: ../../app/models/org.rb:123 +#: ../../app/models/org.rb:124 msgid "must be one of the following formats: jpeg, jpg, png, gif, bmp" msgstr "måste vara ett av följande format: jpeg, jpg, png, gif, bmp" -#: ../../app/models/org.rb:128 +#: ../../app/models/org.rb:129 msgid "can't be larger than 500KB" msgstr "kan inte vara större än 500 kB" @@ -1674,7 +1682,7 @@ msgstr "Du kan inte publicera en mall utan frågor i en sektion." msgid "Conditions in the template refer backwards" msgstr "Förhållandena i mallen hänvisar bakåt" -#: ../../app/models/user.rb:380 +#: ../../app/models/user.rb:386 msgid "A Data Management Plan in %{application_name} has been shared with you" msgstr "En datahanteringsplan i %{application_name} har delats med dig" @@ -2101,7 +2109,7 @@ msgstr "" #: ../../app/views/paginable/templates/_organisational.html.erb:87 #: ../../app/views/paginable/templates/_publicly_visible.html.erb:29 #: ../../app/views/paginable/templates/_publicly_visible.html.erb:36 -#: ../../app/views/plans/_download_form.html.erb:130 +#: ../../app/views/plans/_download_form.html.erb:133 #: ../../app/views/static_pages/about_us.html.erb:22 #: ../../app/views/static_pages/about_us.html.erb:29 #: ../../app/views/static_pages/termsuse.html.erb:46 @@ -4595,7 +4603,7 @@ msgstr "Kommentarer & vägledning" msgid "Instructions" msgstr "Instruktioner" -#: ../../app/views/plans/_download_form.html.erb:6 +#: ../../app/views/plans/_download_form.html.erb:5 msgid "Format" msgstr "Formatera" @@ -4603,71 +4611,71 @@ msgstr "Formatera" msgid "Download settings" msgstr "Hämta inställningar" -#: ../../app/views/plans/_download_form.html.erb:19 -msgid "Select phase to download" -msgstr "Välj fas att hämta" - -#: ../../app/views/plans/_download_form.html.erb:26 +#: ../../app/views/plans/_download_form.html.erb:21 msgid "Optional plan components" msgstr "Valfria plankomponenter" -#: ../../app/views/plans/_download_form.html.erb:30 +#: ../../app/views/plans/_download_form.html.erb:25 msgid "project details coversheet" msgstr "projekt detaljer täckplåt" -#: ../../app/views/plans/_download_form.html.erb:36 +#: ../../app/views/plans/_download_form.html.erb:31 msgid "question text and section headings" msgstr "Frågeformulär och rubrikrubriker" -#: ../../app/views/plans/_download_form.html.erb:42 +#: ../../app/views/plans/_download_form.html.erb:37 msgid "unanswered questions" msgstr "obesvarade frågor" -#: ../../app/views/plans/_download_form.html.erb:49 +#: ../../app/views/plans/_download_form.html.erb:44 msgid "research outputs" msgstr "forskningsresultat" -#: ../../app/views/plans/_download_form.html.erb:57 +#: ../../app/views/plans/_download_form.html.erb:52 msgid "supplementary section(s) not requested by funding organisation" msgstr "kompletterande sektion (er) som inte begärs av finansieringsorganisationen" -#: ../../app/views/plans/_download_form.html.erb:65 +#: ../../app/views/plans/_download_form.html.erb:61 +msgid "Select phase to download" +msgstr "Välj fas att hämta" + +#: ../../app/views/plans/_download_form.html.erb:70 msgid "PDF formatting" msgstr "PDF-formatering" -#: ../../app/views/plans/_download_form.html.erb:68 +#: ../../app/views/plans/_download_form.html.erb:73 msgid "Font" msgstr "Font" -#: ../../app/views/plans/_download_form.html.erb:71 +#: ../../app/views/plans/_download_form.html.erb:76 msgid "Margin (mm)" msgstr "Marginal (mm)" -#: ../../app/views/plans/_download_form.html.erb:76 +#: ../../app/views/plans/_download_form.html.erb:81 msgid "Face" msgstr "Ansikte" -#: ../../app/views/plans/_download_form.html.erb:84 +#: ../../app/views/plans/_download_form.html.erb:89 msgid "Size" msgstr "Storlek" -#: ../../app/views/plans/_download_form.html.erb:92 +#: ../../app/views/plans/_download_form.html.erb:96 msgid "Top" msgstr "Topp" -#: ../../app/views/plans/_download_form.html.erb:101 +#: ../../app/views/plans/_download_form.html.erb:105 msgid "Bottom" msgstr "Botten" -#: ../../app/views/plans/_download_form.html.erb:110 +#: ../../app/views/plans/_download_form.html.erb:114 msgid "Left" msgstr "Vänster" -#: ../../app/views/plans/_download_form.html.erb:119 +#: ../../app/views/plans/_download_form.html.erb:123 msgid "Right" msgstr "Höger" -#: ../../app/views/plans/_download_form.html.erb:130 +#: ../../app/views/plans/_download_form.html.erb:133 msgid "" "Download Plan (new window)%{open_in_new_window_text}" diff --git a/config/locale/tr_TR/LC_MESSAGES/app.mo b/config/locale/tr_TR/LC_MESSAGES/app.mo index 771cc90b3d17915004f05195d24336387e4b7da5..147db984325b8219ccdb76b789206018e870dd57 100644 GIT binary patch delta 56 zcmcbykn_eu&W0_FXFd1~jdYES6$~t_jE!{-%%|V>V3dN28JYscv<(c}nLQb|GkY>! GWd{K4G!IMw delta 56 zcmcbykn_eu&W0_FXFd1~Omqzm6by~6j4X5w%%! GWd{K3at}xV diff --git a/config/locale/tr_TR/app.po b/config/locale/tr_TR/app.po index 184aef913c..439e806db9 100644 --- a/config/locale/tr_TR/app.po +++ b/config/locale/tr_TR/app.po @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: roadmap_upstream 1.0\n" "Report-Msgid-Bugs-To: contact@translation.io\n" -"POT-Creation-Date: 2025-04-10 13:28-0600\n" -"PO-Revision-Date: 2025-04-10 21:28+0200\n" +"POT-Creation-Date: 2025-12-23 08:33-0700\n" +"PO-Revision-Date: 2025-12-23 15:33+0000\n" "Last-Translator: FULL NAME \n" "Language-Team: Turkish\n" "Language: tr_TR\n" @@ -125,87 +125,95 @@ msgstr "Geçersiz JSON" msgid "No Plans found" msgstr "Hiç Plan bulunamadı" -#: ../../app/controllers/application_controller.rb:36 +#: ../../app/controllers/api/v2/base_api_controller.rb:72 +msgid "There was a problem in the server." +msgstr "" + +#: ../../app/controllers/api/v2/base_api_controller.rb:78 +msgid "The client is not authorized to perform this action." +msgstr "" + +#: ../../app/controllers/application_controller.rb:37 msgid "You are not authorized to perform this action." msgstr "Bu eylemi gerçekleştirme yetkiniz yok." -#: ../../app/controllers/application_controller.rb:40 +#: ../../app/controllers/application_controller.rb:41 msgid "You need to sign in or sign up before continuing." msgstr "Devam etmeden önce oturum açmanız veya kaydolmanız gerekir." -#: ../../app/controllers/application_controller.rb:108 +#: ../../app/controllers/application_controller.rb:115 msgid "Unable to %{action} the %{object}. %{errors}" msgstr "%{action} %{object} yapılamıyor. %{errors}" -#: ../../app/controllers/application_controller.rb:114 +#: ../../app/controllers/application_controller.rb:121 msgid "Successfully %{action} the %{object}." msgstr "%{object} başarıyla %{action}." -#: ../../app/controllers/application_controller.rb:127 +#: ../../app/controllers/application_controller.rb:134 msgid "API client" msgstr "API istemcisi" -#: ../../app/controllers/application_controller.rb:128 +#: ../../app/controllers/application_controller.rb:135 msgid "plan" msgstr "plan" -#: ../../app/controllers/application_controller.rb:129 +#: ../../app/controllers/application_controller.rb:136 msgid "guidance group" msgstr "rehberlik grubu" -#: ../../app/controllers/application_controller.rb:130 +#: ../../app/controllers/application_controller.rb:137 msgid "comment" msgstr "yorum yap" -#: ../../app/controllers/application_controller.rb:131 +#: ../../app/controllers/application_controller.rb:138 msgid "organisation" msgstr "kuruluş" -#: ../../app/controllers/application_controller.rb:132 +#: ../../app/controllers/application_controller.rb:139 msgid "permission" msgstr "izin" -#: ../../app/controllers/application_controller.rb:133 +#: ../../app/controllers/application_controller.rb:140 msgid "preferences" msgstr "tercihler" -#: ../../app/controllers/application_controller.rb:134 +#: ../../app/controllers/application_controller.rb:141 msgid "profile" msgstr "profil" -#: ../../app/controllers/application_controller.rb:134 +#: ../../app/controllers/application_controller.rb:141 msgid "user" msgstr "kullanıcı" -#: ../../app/controllers/application_controller.rb:135 +#: ../../app/controllers/application_controller.rb:142 msgid "question option" msgstr "soru seçeneği" -#: ../../app/controllers/application_controller.rb:181 +#: ../../app/controllers/application_controller.rb:188 msgid "Record Not Found" msgstr "Kayıt bulunamadı" -#: ../../app/controllers/concerns/paginable.rb:45 +#: ../../app/controllers/concerns/paginable.rb:46 msgid "scope should be an ActiveRecord::Relation object" msgstr "kapsam bir ActiveRecord::Relation nesnesi olmalıdır" -#: ../../app/controllers/concerns/paginable.rb:47 +#: ../../app/controllers/concerns/paginable.rb:48 msgid "path_params should be a Hash object" msgstr "path_params bir Hash nesnesi olmalıdır" -#: ../../app/controllers/concerns/paginable.rb:48 +#: ../../app/controllers/concerns/paginable.rb:49 msgid "query_params should be a Hash object" msgstr "query_params bir Hash nesnesi olmalıdır" -#: ../../app/controllers/concerns/paginable.rb:49 +#: ../../app/controllers/concerns/paginable.rb:50 msgid "locals should be a Hash object" msgstr "locals bir Hash nesnesi olmalıdır" -#: ../../app/controllers/concerns/paginable.rb:70 +#: ../../app/controllers/concerns/paginable.rb:71 msgid "Restricted access to View All the records" msgstr "Tüm kayıtları görüntülemek için kısıtlı erişim" -#: ../../app/controllers/concerns/paginable.rb:183 +#: ../../app/controllers/concerns/paginable.rb:184 msgid "Sort by %{sort_field}" msgstr "%{sort_field} alanına göre sırala" @@ -246,77 +254,77 @@ msgstr "İletişim e-postası başarıyla gönderildi." msgid "Unable to submit your request" msgstr "İsteğiniz gönderilemedi" -#: ../../app/controllers/contributors_controller.rb:40 -#: ../../app/controllers/contributors_controller.rb:56 +#: ../../app/controllers/contributors_controller.rb:41 +#: ../../app/controllers/contributors_controller.rb:57 #: ../../app/controllers/research_outputs_controller.rb:42 msgid "add" msgstr "ekle" -#: ../../app/controllers/contributors_controller.rb:54 +#: ../../app/controllers/contributors_controller.rb:55 #: ../../app/controllers/research_outputs_controller.rb:40 msgid "added" msgstr "eklendi" -#: ../../app/controllers/contributors_controller.rb:72 +#: ../../app/controllers/contributors_controller.rb:73 #: ../../app/controllers/guidance_groups_controller.rb:55 #: ../../app/controllers/guidances_controller.rb:75 -#: ../../app/controllers/notes_controller.rb:88 +#: ../../app/controllers/notes_controller.rb:89 #: ../../app/controllers/org_admin/departments_controller.rb:50 #: ../../app/controllers/org_admin/sections_controller.rb:103 #: ../../app/controllers/org_admin/templates_controller.rb:210 #: ../../app/controllers/orgs_controller.rb:92 -#: ../../app/controllers/plans_controller.rb:280 -#: ../../app/controllers/plans_controller.rb:283 +#: ../../app/controllers/plans_controller.rb:281 +#: ../../app/controllers/plans_controller.rb:284 #: ../../app/controllers/registrations_controller.rb:249 #: ../../app/controllers/registrations_controller.rb:253 #: ../../app/controllers/registrations_controller.rb:280 #: ../../app/controllers/registrations_controller.rb:284 #: ../../app/controllers/research_outputs_controller.rb:60 -#: ../../app/controllers/users_controller.rb:103 -#: ../../app/controllers/users_controller.rb:131 +#: ../../app/controllers/users_controller.rb:104 +#: ../../app/controllers/users_controller.rb:132 msgid "saved" msgstr "kaydedildi" -#: ../../app/controllers/contributors_controller.rb:74 +#: ../../app/controllers/contributors_controller.rb:75 #: ../../app/controllers/guidance_groups_controller.rb:57 #: ../../app/controllers/guidances_controller.rb:77 -#: ../../app/controllers/notes_controller.rb:106 +#: ../../app/controllers/notes_controller.rb:107 #: ../../app/controllers/org_admin/departments_controller.rb:52 #: ../../app/controllers/org_admin/sections_controller.rb:105 #: ../../app/controllers/org_admin/templates_controller.rb:215 #: ../../app/controllers/orgs_controller.rb:94 -#: ../../app/controllers/plans_controller.rb:289 -#: ../../app/controllers/plans_controller.rb:292 -#: ../../app/controllers/plans_controller.rb:296 -#: ../../app/controllers/plans_controller.rb:299 +#: ../../app/controllers/plans_controller.rb:290 +#: ../../app/controllers/plans_controller.rb:293 +#: ../../app/controllers/plans_controller.rb:297 +#: ../../app/controllers/plans_controller.rb:300 #: ../../app/controllers/registrations_controller.rb:256 #: ../../app/controllers/registrations_controller.rb:287 #: ../../app/controllers/research_outputs_controller.rb:63 msgid "save" msgstr "kaydet" -#: ../../app/controllers/contributors_controller.rb:83 -#: ../../app/controllers/notes_controller.rb:130 +#: ../../app/controllers/contributors_controller.rb:84 +#: ../../app/controllers/notes_controller.rb:131 #: ../../app/controllers/org_admin/templates_controller.rb:243 #: ../../app/controllers/research_outputs_controller.rb:74 #: ../../app/controllers/super_admin/orgs_controller.rb:94 msgid "removed" msgstr "kaldırıldı" -#: ../../app/controllers/contributors_controller.rb:86 -#: ../../app/controllers/notes_controller.rb:148 +#: ../../app/controllers/contributors_controller.rb:87 +#: ../../app/controllers/notes_controller.rb:149 #: ../../app/controllers/org_admin/templates_controller.rb:245 #: ../../app/controllers/research_outputs_controller.rb:77 #: ../../app/controllers/super_admin/orgs_controller.rb:97 msgid "remove" msgstr "kaldır" -#: ../../app/controllers/contributors_controller.rb:160 +#: ../../app/controllers/contributors_controller.rb:161 #: ../../app/controllers/research_outputs_controller.rb:208 msgid "plan not found" msgstr "plan bulunamadı" -#: ../../app/controllers/contributors_controller.rb:168 +#: ../../app/controllers/contributors_controller.rb:169 msgid "contributor not found" msgstr "katkı sağlayan kişi bulunamadı" @@ -330,7 +338,7 @@ msgstr "Bu plan için geri bildirim istenirken bir hata oluştu." #: ../../app/controllers/guidance_groups_controller.rb:31 #: ../../app/controllers/guidances_controller.rb:53 -#: ../../app/controllers/notes_controller.rb:47 +#: ../../app/controllers/notes_controller.rb:48 #: ../../app/controllers/org_admin/departments_controller.rb:26 #: ../../app/controllers/org_admin/phases_controller.rb:121 #: ../../app/controllers/org_admin/questions_controller.rb:94 @@ -346,7 +354,7 @@ msgstr "oluşturuldu" #: ../../app/controllers/guidance_groups_controller.rb:34 #: ../../app/controllers/guidances_controller.rb:55 -#: ../../app/controllers/notes_controller.rb:66 +#: ../../app/controllers/notes_controller.rb:67 #: ../../app/controllers/org_admin/departments_controller.rb:30 #: ../../app/controllers/org_admin/phases_controller.rb:123 #: ../../app/controllers/org_admin/questions_controller.rb:96 @@ -385,7 +393,7 @@ msgstr "yayından kaldır" #: ../../app/controllers/org_admin/question_options_controller.rb:24 #: ../../app/controllers/org_admin/questions_controller.rb:197 #: ../../app/controllers/org_admin/sections_controller.rb:128 -#: ../../app/controllers/plans_controller.rb:342 +#: ../../app/controllers/plans_controller.rb:343 #: ../../app/controllers/super_admin/api_clients_controller.rb:81 #: ../../app/controllers/super_admin/notifications_controller.rb:85 #: ../../app/controllers/super_admin/themes_controller.rb:51 @@ -399,7 +407,7 @@ msgstr "silindi" #: ../../app/controllers/org_admin/question_options_controller.rb:26 #: ../../app/controllers/org_admin/questions_controller.rb:199 #: ../../app/controllers/org_admin/sections_controller.rb:130 -#: ../../app/controllers/plans_controller.rb:347 +#: ../../app/controllers/plans_controller.rb:348 #: ../../app/controllers/super_admin/api_clients_controller.rb:84 #: ../../app/controllers/super_admin/notifications_controller.rb:88 #: ../../app/controllers/super_admin/themes_controller.rb:54 @@ -442,19 +450,19 @@ msgstr "Bu şablonun yeni bir sürümü oluşturulamıyor.
" #: ../../app/controllers/org_admin/phases_controller.rb:147 #: ../../app/controllers/org_admin/questions_controller.rb:166 #: ../../app/controllers/org_admin/users_controller.rb:30 -#: ../../app/controllers/plans_controller.rb:416 +#: ../../app/controllers/plans_controller.rb:417 #: ../../app/controllers/super_admin/api_clients_controller.rb:68 #: ../../app/controllers/super_admin/notifications_controller.rb:52 #: ../../app/controllers/super_admin/themes_controller.rb:39 #: ../../app/controllers/super_admin/users_controller.rb:54 -#: ../../app/controllers/users_controller.rb:108 +#: ../../app/controllers/users_controller.rb:109 msgid "updated" msgstr "güncellendi" #: ../../app/controllers/org_admin/phases_controller.rb:149 #: ../../app/controllers/org_admin/questions_controller.rb:169 #: ../../app/controllers/org_admin/users_controller.rb:32 -#: ../../app/controllers/plans_controller.rb:419 +#: ../../app/controllers/plans_controller.rb:420 #: ../../app/controllers/super_admin/api_clients_controller.rb:70 #: ../../app/controllers/super_admin/notifications_controller.rb:55 #: ../../app/controllers/super_admin/themes_controller.rb:41 @@ -544,7 +552,7 @@ msgid "Unable to delete this version of the template." msgstr "Şablonun bu sürümü silinemiyor." #: ../../app/controllers/org_admin/template_copies_controller.rb:20 -#: ../../app/controllers/plans_controller.rb:395 +#: ../../app/controllers/plans_controller.rb:396 msgid "copy" msgstr "kopyala" @@ -553,11 +561,11 @@ msgstr "kopyala" msgid "That template is no longer customizable." msgstr "Bu şablon artık özelleştirilemez." -#: ../../app/controllers/org_admin/template_customizations_controller.rb:21 +#: ../../app/controllers/org_admin/template_customizations_controller.rb:22 msgid "Unable to customize that template." msgstr "Bu şablon özelleştirilemiyor." -#: ../../app/controllers/org_admin/template_customizations_controller.rb:24 +#: ../../app/controllers/org_admin/template_customizations_controller.rb:25 msgid "That template is not customizable." msgstr "Bu şablon özelleştirilemez." @@ -649,11 +657,11 @@ msgstr "Bu plan şunlara dayanmaktadır:" msgid "template with customisations by the" msgstr "şu kişi tarafından özelleştirmeler içeren şablon:" -#: ../../app/controllers/plans_controller.rb:393 +#: ../../app/controllers/plans_controller.rb:394 msgid "copied" msgstr "kopyalandı" -#: ../../app/controllers/plans_controller.rb:424 +#: ../../app/controllers/plans_controller.rb:425 msgid "" "Unable to change the plan's status since it is needed at least %{percentage} p" "ercentage responded" @@ -661,23 +669,23 @@ msgstr "" "En az yüzde %{percentage} yanıt verilmesi gerektiğinden planın durumu değiştir" "ilemiyor" -#: ../../app/controllers/plans_controller.rb:430 +#: ../../app/controllers/plans_controller.rb:431 msgid "Unable to find plan id %{plan_id}" msgstr "%{plan_id} no.'lu plan bulunamadı" -#: ../../app/controllers/plans_controller.rb:445 +#: ../../app/controllers/plans_controller.rb:446 msgid "Your project is now a test." msgstr "Projeniz şu an bir test." -#: ../../app/controllers/plans_controller.rb:445 +#: ../../app/controllers/plans_controller.rb:446 msgid "Your project is no longer a test." msgstr "Projeniz artık bir test değil." -#: ../../app/controllers/plans_controller.rb:449 +#: ../../app/controllers/plans_controller.rb:450 msgid "Unable to change the plan's test status" msgstr "Planın test durumu değiştirilemiyor" -#: ../../app/controllers/plans_controller.rb:462 +#: ../../app/controllers/plans_controller.rb:463 msgid "There is no plan associated with id %{s" msgstr "%{ kimliğiyle ilişkilendirilmiş bir plan yok s" @@ -770,7 +778,7 @@ msgstr "Şifre ve onay eşleşmelidir" msgid "research output not found" msgstr "araştırma çıktısı bulunamadı" -#: ../../app/controllers/roles_controller.rb:26 +#: ../../app/controllers/roles_controller.rb:27 msgid "" "Cannot share plan with %{email} since that email matches\n" " with the owner of the plan." @@ -943,27 +951,27 @@ msgstr "Hesabınız başarıyla %{scheme} şemasına bağlandı." msgid "Unable to link your account to %{scheme}." msgstr "Hesabınız %{scheme} şemasına bağlanamadı." -#: ../../app/controllers/users_controller.rb:149 +#: ../../app/controllers/users_controller.rb:150 msgid "Successfully %{action} %{username}'s account." msgstr "%{username} adlı kullanıcının hesabı başarıyla %{action}." -#: ../../app/controllers/users_controller.rb:150 +#: ../../app/controllers/users_controller.rb:151 msgid "activated" msgstr "etkinleştirildi" -#: ../../app/controllers/users_controller.rb:150 +#: ../../app/controllers/users_controller.rb:151 msgid "deactivated" msgstr "devre dışı bırakıldı" -#: ../../app/controllers/users_controller.rb:156 +#: ../../app/controllers/users_controller.rb:157 msgid "Unable to %{action} %{username}" msgstr " %{username} %{action} yapılamıyor" -#: ../../app/controllers/users_controller.rb:157 +#: ../../app/controllers/users_controller.rb:158 msgid "activate" msgstr "etkinleştir" -#: ../../app/controllers/users_controller.rb:157 +#: ../../app/controllers/users_controller.rb:158 msgid "deactivate" msgstr "devre dışı bırak" @@ -1255,50 +1263,50 @@ msgstr "Son 9 ay" msgid "Last 12 months" msgstr "Son 12 ay" -#: ../../app/mailers/user_mailer.rb:17 +#: ../../app/mailers/user_mailer.rb:18 #: ../../app/views/devise/mailer/invitation_instructions.html.erb:5 #: ../../app/views/devise/mailer/reset_password_instructions.html.erb:5 #: ../../app/views/user_mailer/_email_signature.html.erb:2 msgid "Query or feedback related to %{tool_name}" msgstr "%{tool_name} ile ilgili sorgu veya geri bildirim" -#: ../../app/mailers/user_mailer.rb:25 +#: ../../app/mailers/user_mailer.rb:26 msgid "Welcome to %{tool_name}" msgstr "%{tool_name} aracına hoş geldiniz" -#: ../../app/mailers/user_mailer.rb:62 +#: ../../app/mailers/user_mailer.rb:63 msgid "A Data Management Plan in %{tool_name} has been shared with you" msgstr "%{tool_name} içinde bir Veri Yönetim Planı sizinle paylaşıldı" -#: ../../app/mailers/user_mailer.rb:79 +#: ../../app/mailers/user_mailer.rb:80 msgid "Changed permissions on a Data Management Plan in %{tool_name}" msgstr "%{tool_name} aracındaki bir Veri Yönetim Planına ilişkin değiştirilen izinler" -#: ../../app/mailers/user_mailer.rb:94 +#: ../../app/mailers/user_mailer.rb:95 msgid "Permissions removed on a DMP in %{tool_name}" msgstr "%{tool_name} içindeki bir VYP'de izinler kaldırıldı" -#: ../../app/mailers/user_mailer.rb:112 +#: ../../app/mailers/user_mailer.rb:113 msgid "%{user_name} has requested feedback on a %{tool_name} plan" msgstr "%{user_name}, bir %{tool_name} planı hakkında geri bildirim istedi" -#: ../../app/mailers/user_mailer.rb:135 +#: ../../app/mailers/user_mailer.rb:136 msgid "%{tool_name}: Expert feedback has been provided for %{plan_title}" msgstr "%{tool_name}: %{plan_title} için uzman geri bildirimi sağlandı" -#: ../../app/mailers/user_mailer.rb:153 +#: ../../app/mailers/user_mailer.rb:154 msgid "DMP Visibility Changed: %{plan_title}" msgstr "VYP Görünürlüğü Değiştirildi: %{plan_title}" -#: ../../app/mailers/user_mailer.rb:182 +#: ../../app/mailers/user_mailer.rb:183 msgid "%{tool_name}: A new comment was added to %{plan_title}" msgstr "%{tool_name}: %{plan_title} adlı plana yeni bir yorum eklendi" -#: ../../app/mailers/user_mailer.rb:198 +#: ../../app/mailers/user_mailer.rb:199 msgid "Administrator privileges granted in %{tool_name}" msgstr "%{tool_name} içinde verilen yönetici ayrıcalıkları" -#: ../../app/mailers/user_mailer.rb:216 +#: ../../app/mailers/user_mailer.rb:217 msgid "%{tool_name} API changes" msgstr "%{tool_name} API değişiklikleri" @@ -1534,15 +1542,15 @@ msgstr "" msgid "already assigned a value" msgstr "zaten bir değer atanmış" -#: ../../app/models/org.rb:46 +#: ../../app/models/org.rb:47 msgid "Feedback email message" msgstr "Geri bildirim e-posta iletisi" -#: ../../app/models/org.rb:123 +#: ../../app/models/org.rb:124 msgid "must be one of the following formats: jpeg, jpg, png, gif, bmp" msgstr "şu biçimlerden biri olmalıdır: jpeg, jpg, png, gif, bmp" -#: ../../app/models/org.rb:128 +#: ../../app/models/org.rb:129 msgid "can't be larger than 500KB" msgstr "500KB'den büyük olamaz" @@ -1666,7 +1674,7 @@ msgstr "Bir bölümünde soru bulunmayan bir şablonu yayınlayamazsınız." msgid "Conditions in the template refer backwards" msgstr "Şablondaki koşullar geriye dönük" -#: ../../app/models/user.rb:380 +#: ../../app/models/user.rb:386 msgid "A Data Management Plan in %{application_name} has been shared with you" msgstr "%{application_name} içinde bir Veri Yönetim Planı sizinle paylaşıldı" @@ -2094,7 +2102,7 @@ msgstr "" #: ../../app/views/paginable/templates/_organisational.html.erb:87 #: ../../app/views/paginable/templates/_publicly_visible.html.erb:29 #: ../../app/views/paginable/templates/_publicly_visible.html.erb:36 -#: ../../app/views/plans/_download_form.html.erb:130 +#: ../../app/views/plans/_download_form.html.erb:133 #: ../../app/views/static_pages/about_us.html.erb:22 #: ../../app/views/static_pages/about_us.html.erb:29 #: ../../app/views/static_pages/termsuse.html.erb:46 @@ -4595,7 +4603,7 @@ msgstr "Yorumlar ve Rehberlik" msgid "Instructions" msgstr "Talimatlar" -#: ../../app/views/plans/_download_form.html.erb:6 +#: ../../app/views/plans/_download_form.html.erb:5 msgid "Format" msgstr "Biçim" @@ -4603,71 +4611,71 @@ msgstr "Biçim" msgid "Download settings" msgstr "İndirme ayarları" -#: ../../app/views/plans/_download_form.html.erb:19 -msgid "Select phase to download" -msgstr "İndirilecek aşamayı seçin" - -#: ../../app/views/plans/_download_form.html.erb:26 +#: ../../app/views/plans/_download_form.html.erb:21 msgid "Optional plan components" msgstr "İsteğe bağlı plan bileşenleri" -#: ../../app/views/plans/_download_form.html.erb:30 +#: ../../app/views/plans/_download_form.html.erb:25 msgid "project details coversheet" msgstr "proje detayları kapak sayfası" -#: ../../app/views/plans/_download_form.html.erb:36 +#: ../../app/views/plans/_download_form.html.erb:31 msgid "question text and section headings" msgstr "soru metni ve bölüm başlıkları" -#: ../../app/views/plans/_download_form.html.erb:42 +#: ../../app/views/plans/_download_form.html.erb:37 msgid "unanswered questions" msgstr "cevaplanmamış sorular" -#: ../../app/views/plans/_download_form.html.erb:49 +#: ../../app/views/plans/_download_form.html.erb:44 msgid "research outputs" msgstr "araştırma çıktıları" -#: ../../app/views/plans/_download_form.html.erb:57 +#: ../../app/views/plans/_download_form.html.erb:52 msgid "supplementary section(s) not requested by funding organisation" msgstr "Fon sağlayıcı kurum tarafından talep edilmeyen ek bölüm(ler)" -#: ../../app/views/plans/_download_form.html.erb:65 +#: ../../app/views/plans/_download_form.html.erb:61 +msgid "Select phase to download" +msgstr "İndirilecek aşamayı seçin" + +#: ../../app/views/plans/_download_form.html.erb:70 msgid "PDF formatting" msgstr "PDF biçimlendirme" -#: ../../app/views/plans/_download_form.html.erb:68 +#: ../../app/views/plans/_download_form.html.erb:73 msgid "Font" msgstr "Yazı tipi" -#: ../../app/views/plans/_download_form.html.erb:71 +#: ../../app/views/plans/_download_form.html.erb:76 msgid "Margin (mm)" msgstr "Kenar boşluğu (mm)" -#: ../../app/views/plans/_download_form.html.erb:76 +#: ../../app/views/plans/_download_form.html.erb:81 msgid "Face" msgstr "Yüz" -#: ../../app/views/plans/_download_form.html.erb:84 +#: ../../app/views/plans/_download_form.html.erb:89 msgid "Size" msgstr "Boyut" -#: ../../app/views/plans/_download_form.html.erb:92 +#: ../../app/views/plans/_download_form.html.erb:96 msgid "Top" msgstr "Üst" -#: ../../app/views/plans/_download_form.html.erb:101 +#: ../../app/views/plans/_download_form.html.erb:105 msgid "Bottom" msgstr "Alt" -#: ../../app/views/plans/_download_form.html.erb:110 +#: ../../app/views/plans/_download_form.html.erb:114 msgid "Left" msgstr "Kalan" -#: ../../app/views/plans/_download_form.html.erb:119 +#: ../../app/views/plans/_download_form.html.erb:123 msgid "Right" msgstr "Yetki" -#: ../../app/views/plans/_download_form.html.erb:130 +#: ../../app/views/plans/_download_form.html.erb:133 msgid "" "Download Plan (new window)%{open_in_new_window_text}" diff --git a/config/locales/.translation_io b/config/locales/.translation_io index 41850daef0..934fc62ef3 100644 --- a/config/locales/.translation_io +++ b/config/locales/.translation_io @@ -5,4 +5,4 @@ # ignore the conflicts and "sync" again, it will fix this file for you. --- -timestamp: 1744313316 +timestamp: 1766503989 diff --git a/config/locales/translation.de.yml b/config/locales/translation.de.yml index f0e01bc673..bdf11acbeb 100644 --- a/config/locales/translation.de.yml +++ b/config/locales/translation.de.yml @@ -143,6 +143,23 @@ de: has_one: Datensatz kann nicht gelöscht werden, da ein abhängiger %{record} existiert. has_many: Datensatz kann nicht gelöscht werden, da abhängige %{record} existieren. + models: + doorkeeper/application: + attributes: + redirect_uri: + fragment_present: darf kein Fragment enthalten. + invalid_uri: muss ein valider URI (Identifier) sein. + unspecified_scheme: muss ein Schema angeben. + relative_uri: muss ein absoluter URI (Identifier) sein. + secured_uri: muss ein HTTPS/SSL URI (Identifier) sein. + forbidden_uri: ist vom server verboten. + scopes: + not_match_configured: stimmen nicht mit denen am server hinterlegten + überein. + attributes: + doorkeeper/application: + name: Name + redirect_uri: Redirect URI datetime: distance_in_words: half_a_minute: einer halben Minute @@ -361,3 +378,146 @@ de: Sie es erneut. recaptcha_unreachable: Ups, wir konnten Ihre reCAPTCHA-Antwort nicht validieren. Bitte versuche es erneut. + doorkeeper: + applications: + confirmations: + destroy: Bist du sicher? + buttons: + edit: Bearbeiten + destroy: Löschen + submit: Übertragen + cancel: Abbrechen + authorize: Autorisieren + form: + error: Whoops! Bitte überprüfe das Formular auf Fehler! + help: + confidential: Application will be used where the client secret can be kept + confidential. Native mobile apps and Single Page Apps are considered non-confidential. + redirect_uri: Bitte benutze eine Zeile pro URI + blank_redirect_uri: Leave it blank if you configured your provider to use + Client Credentials, Resource Owner Password Credentials or any other grant + type that doesn't require redirect URI. + scopes: Bitte die "Scopes" mit Leerzeichen trennen. Bitte frei lassen für + die Verwendung der Default-Werte. + edit: + title: Applikation bearbeiten + index: + title: Deine Applikationen + new: Neue Applikation + name: Name + callback_url: Callback URL + confidential: Vertraulich? + actions: Aktionen + confidentiality: + 'yes': Ja + 'no': Nein + new: + title: Neue Applikation + show: + title: 'Applikation: %{name}' + application_id: Applikations-ID + secret: Secret + secret_hashed: + scopes: Scopes + confidential: Vertraulich + callback_urls: Callback URLs + actions: Aktionen + not_defined: + authorizations: + buttons: + authorize: Autorisieren + deny: Verweigern + error: + title: Ein Fehler ist aufgetreten + new: + title: Autorisierung erforderlich + prompt: Soll %{client_name} für die Benutzung dieses Accounts autorisiert + werden? + able_to: Diese Anwendung wird folgende Rechte haben + show: + title: Autorisierungscode + form_post: + title: + authorized_applications: + confirmations: + revoke: Bist du sicher? + buttons: + revoke: Ungültig machen + index: + title: Deine autorisierten Applikationen + application: Applikation + created_at: erstellt am + date_format: "%Y-%m-%d %H:%M:%S" + pre_authorization: + status: Pre-authorization + errors: + messages: + invalid_request: + unknown: Die Anfrage enthält einen nicht-unterstützten Parameter, ein Parameter + fehlt oder sie ist anderweitig fehlerhaft. + missing_param: 'Missing required parameter: %{value}.' + request_not_authorized: Request need to be authorized. Required parameter + for authorizing request is missing or invalid. + invalid_code_challenge: + invalid_redirect_uri: Der Redirect-URI in der Anfrage ist ungültig. + unauthorized_client: Der Client ist nicht autorisiert, diese Anfrage mit dieser + Methode auszuführen. + access_denied: Der Resource Owner oder der Autorisierungs-Server hat die Anfrage + verweigert. + invalid_scope: Der angeforderte Scope ist inkorrekt, unbekannt oder fehlerhaft. + invalid_code_challenge_method: + zero: + one: + other: + server_error: Der Autorisierungs-Server hat ein unerwartetes Problem festgestellt + und konnte die Anfrage nicht beenden. + temporarily_unavailable: Der Autorisierungs-Server ist derzeit auf Grund von + temporärer Überlastung oder Wartungsarbeiten am Server nicht in der Lage, + die Anfrage zu bearbeiten . + credential_flow_not_configured: 'Die Prozedur "Resource Owner Password Credentials" + ist fehlgeschlagen: Doorkeeper.configure.resource_owner_from_credentials + ist nicht konfiguriert.' + resource_owner_authenticator_not_configured: 'Die Prozedur "Resource Owner + find" ist fehlgeschlagen: Doorkeeper.configure.resource_owner_authenticator + ist nicht konfiguriert.' + admin_authenticator_not_configured: Access to admin panel is forbidden due + to Doorkeeper.configure.admin_authenticator being unconfigured. + unsupported_response_type: Der Autorisierungs-Server unterstützt diesen Antwort-Typ + nicht. + unsupported_response_mode: + invalid_client: 'Client-Autorisierung MKIM ist fehlgeschlagen: Unbekannter + Client, keine Autorisierung mitgeliefert oder Autorisierungsmethode nicht + unterstützt.' + invalid_grant: Die bereitgestellte Autorisierung ist inkorrekt, abgelaufen, + widerrufen, ist mit einem anderen Client verknüpft oder der Redirection + URI stimmt nicht mit der Autorisierungs-Anfrage überein. + unsupported_grant_type: Der Autorisierungs-Typ wird nicht vom Autorisierungs-Server + unterstützt. + invalid_token: + revoked: Der Access Token wurde annuliert + expired: Der Access Token ist abgelaufen + unknown: Der Access Token ist nicht gültig/korrekt + revoke: + unauthorized: Sie sind nicht berechtigt, dieses Token zu widerrufen + forbidden_token: + missing_scope: + flash: + applications: + create: + notice: Applikation erstellt. + destroy: + notice: Applikation gelöscht. + update: + notice: Applikation geupdated. + authorized_applications: + destroy: + notice: Applikation widerrufen. + layouts: + admin: + title: Doorkeeper + nav: + oauth2_provider: OAuth2 Provider + applications: Applikationen + home: Home + application: + title: OAuth Autorisierung erforderlich diff --git a/config/locales/translation.en-CA.yml b/config/locales/translation.en-CA.yml index 9e5ed6e7c8..be1ccaed77 100644 --- a/config/locales/translation.en-CA.yml +++ b/config/locales/translation.en-CA.yml @@ -134,6 +134,22 @@ en-CA: restrict_dependent_destroy: has_one: Cannot delete record because a dependent %{record} exists has_many: Cannot delete record because dependent %{record} exist + models: + doorkeeper/application: + attributes: + redirect_uri: + fragment_present: cannot contain a fragment. + invalid_uri: must be a valid URI. + unspecified_scheme: must specify a scheme. + relative_uri: must be an absolute URI. + secured_uri: must be an HTTPS/SSL URI. + forbidden_uri: is forbidden by the server. + scopes: + not_match_configured: doesn't match configured on the server. + attributes: + doorkeeper/application: + name: Name + redirect_uri: Redirect URI datetime: distance_in_words: half_a_minute: half a minute @@ -230,7 +246,8 @@ en-CA: not_found_in_database: Invalid %{authentication_keys} or password. timeout: Your session expired. Please sign in again to continue. unauthenticated: You need to sign in or sign up before continuing. - unconfirmed: You have to confirm your email address before continuing. + unconfirmed: You need to confirm your account before continuing. (Click to request a new confirmation email) invited: mailer: confirmation_instructions: @@ -340,3 +357,140 @@ en-CA: previous: "‹ Prev" next: Next › truncate: "…" + doorkeeper: + applications: + confirmations: + destroy: Are you sure? + buttons: + edit: Edit + destroy: Destroy + submit: Submit + cancel: Cancel + authorize: Authorize + form: + error: Whoops! Check your form for possible errors + help: + confidential: Application will be used where the client secret can be kept + confidential. Native mobile apps and Single Page Apps are considered non-confidential. + redirect_uri: Use one line per URI + blank_redirect_uri: Leave it blank if you configured your provider to use + Client Credentials, Resource Owner Password Credentials or any other grant + type that doesn't require redirect URI. + scopes: Separate scopes with spaces. Leave blank to use the default scopes. + edit: + title: Edit application + index: + title: Your applications + new: New Application + name: Name + callback_url: Callback URL + confidential: Confidential? + actions: Actions + confidentiality: + 'yes': 'Yes' + 'no': 'No' + new: + title: New Application + show: + title: 'Application: %{name}' + application_id: Application UID + secret: Secret + secret_hashed: + scopes: Scopes + confidential: Confidential + callback_urls: Callback urls + actions: Actions + not_defined: + authorizations: + buttons: + authorize: Authorize + deny: Deny + error: + title: An error has occurred + new: + title: Authorization required + prompt: Authorize %{client_name} to use your account? + able_to: This application will be able to + show: + title: Authorization code + form_post: + title: + authorized_applications: + confirmations: + revoke: Are you sure? + buttons: + revoke: Revoke + index: + title: Your authorized applications + application: Application + created_at: Created At + date_format: "%Y-%m-%d %H:%M:%S" + pre_authorization: + status: Pre-authorization + errors: + messages: + invalid_request: + unknown: The request is missing a required parameter, includes an unsupported + parameter value, or is otherwise malformed. + missing_param: 'Missing required parameter: %{value}.' + request_not_authorized: Request need to be authorized. Required parameter + for authorizing request is missing or invalid. + invalid_code_challenge: + invalid_redirect_uri: The requested redirect uri is malformed or doesn't match + client redirect URI. + unauthorized_client: The client is not authorized to perform this request + using this method. + access_denied: The resource owner or authorization server denied the request. + invalid_scope: The requested scope is invalid, unknown, or malformed. + invalid_code_challenge_method: + zero: + one: + other: + server_error: The authorization server encountered an unexpected condition + which prevented it from fulfilling the request. + temporarily_unavailable: The authorization server is currently unable to handle + the request due to a temporary overloading or maintenance of the server. + credential_flow_not_configured: Resource Owner Password Credentials flow failed + due to Doorkeeper.configure.resource_owner_from_credentials being unconfigured. + resource_owner_authenticator_not_configured: Resource Owner find failed due + to Doorkeeper.configure.resource_owner_authenticator being unconfigured. + admin_authenticator_not_configured: Access to admin panel is forbidden due + to Doorkeeper.configure.admin_authenticator being unconfigured. + unsupported_response_type: The authorization server does not support this + response type. + unsupported_response_mode: + invalid_client: Client authentication failed due to unknown client, no client + authentication included, or unsupported authentication method. + invalid_grant: The provided authorization grant is invalid, expired, revoked, + does not match the redirection URI used in the authorization request, or + was issued to another client. + unsupported_grant_type: The authorization grant type is not supported by the + authorization server. + invalid_token: + revoked: The access token was revoked + expired: The access token expired + unknown: The access token is invalid + revoke: + unauthorized: You are not authorized to revoke this token + forbidden_token: + missing_scope: + flash: + applications: + create: + notice: Application created. + destroy: + notice: Application deleted. + update: + notice: Application updated. + authorized_applications: + destroy: + notice: Application revoked. + layouts: + admin: + title: Doorkeeper + nav: + oauth2_provider: OAuth2 Provider + applications: Applications + home: Home + application: + title: OAuth authorization required diff --git a/config/locales/translation.en-GB.yml b/config/locales/translation.en-GB.yml index 91014ac51c..c5dfbe313f 100644 --- a/config/locales/translation.en-GB.yml +++ b/config/locales/translation.en-GB.yml @@ -134,6 +134,22 @@ en-GB: restrict_dependent_destroy: has_one: Cannot delete record because a dependent %{record} exists has_many: Cannot delete record because dependent %{record} exist + models: + doorkeeper/application: + attributes: + redirect_uri: + fragment_present: cannot contain a fragment. + invalid_uri: must be a valid URI. + unspecified_scheme: must specify a scheme. + relative_uri: must be an absolute URI. + secured_uri: must be an HTTPS/SSL URI. + forbidden_uri: is forbidden by the server. + scopes: + not_match_configured: doesn't match configured on the server. + attributes: + doorkeeper/application: + name: Name + redirect_uri: Redirect URI datetime: distance_in_words: half_a_minute: half a minute @@ -227,7 +243,8 @@ en-GB: not_found_in_database: Invalid email or password. timeout: Your session expired, please sign in again to continue. unauthenticated: You need to sign in or sign up before continuing. - unconfirmed: You have to confirm your account before continuing. + unconfirmed: You need to confirm your account before continuing. (Click to request a new confirmation email) invited: You have a pending invitation, accept it to finish creating your account. mailer: confirmation_instructions: @@ -341,3 +358,140 @@ en-GB: errors: verification_failed: recaptcha_unreachable: + doorkeeper: + applications: + confirmations: + destroy: Are you sure? + buttons: + edit: Edit + destroy: Destroy + submit: Submit + cancel: Cancel + authorize: Authorize + form: + error: Whoops! Check your form for possible errors + help: + confidential: Application will be used where the client secret can be kept + confidential. Native mobile apps and Single Page Apps are considered non-confidential. + redirect_uri: Use one line per URI + blank_redirect_uri: Leave it blank if you configured your provider to use + Client Credentials, Resource Owner Password Credentials or any other grant + type that doesn't require redirect URI. + scopes: Separate scopes with spaces. Leave blank to use the default scopes. + edit: + title: Edit application + index: + title: Your applications + new: New Application + name: Name + callback_url: Callback URL + confidential: Confidential? + actions: Actions + confidentiality: + 'yes': 'Yes' + 'no': 'No' + new: + title: New Application + show: + title: 'Application: %{name}' + application_id: Application UID + secret: Secret + secret_hashed: + scopes: Scopes + confidential: Confidential + callback_urls: Callback urls + actions: Actions + not_defined: + authorizations: + buttons: + authorize: Authorize + deny: Deny + error: + title: An error has occurred + new: + title: Authorization required + prompt: Authorize %{client_name} to use your account? + able_to: This application will be able to + show: + title: Authorization code + form_post: + title: + authorized_applications: + confirmations: + revoke: Are you sure? + buttons: + revoke: Revoke + index: + title: Your authorized applications + application: Application + created_at: Created At + date_format: "%Y-%m-%d %H:%M:%S" + pre_authorization: + status: Pre-authorization + errors: + messages: + invalid_request: + unknown: The request is missing a required parameter, includes an unsupported + parameter value, or is otherwise malformed. + missing_param: 'Missing required parameter: %{value}.' + request_not_authorized: Request need to be authorized. Required parameter + for authorizing request is missing or invalid. + invalid_code_challenge: + invalid_redirect_uri: The requested redirect uri is malformed or doesn't match + client redirect URI. + unauthorized_client: The client is not authorized to perform this request + using this method. + access_denied: The resource owner or authorization server denied the request. + invalid_scope: The requested scope is invalid, unknown, or malformed. + invalid_code_challenge_method: + zero: + one: + other: + server_error: The authorization server encountered an unexpected condition + which prevented it from fulfilling the request. + temporarily_unavailable: The authorization server is currently unable to handle + the request due to a temporary overloading or maintenance of the server. + credential_flow_not_configured: Resource Owner Password Credentials flow failed + due to Doorkeeper.configure.resource_owner_from_credentials being unconfigured. + resource_owner_authenticator_not_configured: Resource Owner find failed due + to Doorkeeper.configure.resource_owner_authenticator being unconfigured. + admin_authenticator_not_configured: Access to admin panel is forbidden due + to Doorkeeper.configure.admin_authenticator being unconfigured. + unsupported_response_type: The authorization server does not support this + response type. + unsupported_response_mode: + invalid_client: Client authentication failed due to unknown client, no client + authentication included, or unsupported authentication method. + invalid_grant: The provided authorization grant is invalid, expired, revoked, + does not match the redirection URI used in the authorization request, or + was issued to another client. + unsupported_grant_type: The authorization grant type is not supported by the + authorization server. + invalid_token: + revoked: The access token was revoked + expired: The access token expired + unknown: The access token is invalid + revoke: + unauthorized: You are not authorized to revoke this token + forbidden_token: + missing_scope: + flash: + applications: + create: + notice: Application created. + destroy: + notice: Application deleted. + update: + notice: Application updated. + authorized_applications: + destroy: + notice: Application revoked. + layouts: + admin: + title: Doorkeeper + nav: + oauth2_provider: OAuth2 Provider + applications: Applications + home: Home + application: + title: OAuth authorization required diff --git a/config/locales/translation.en-US.yml b/config/locales/translation.en-US.yml index 04f0271b43..7c56f76d0a 100644 --- a/config/locales/translation.en-US.yml +++ b/config/locales/translation.en-US.yml @@ -134,6 +134,22 @@ en-US: restrict_dependent_destroy: has_one: Cannot delete record because a dependent %{record} exists has_many: Cannot delete record because dependent %{record} exist + models: + doorkeeper/application: + attributes: + redirect_uri: + fragment_present: cannot contain a fragment. + invalid_uri: must be a valid URI. + unspecified_scheme: must specify a scheme. + relative_uri: must be an absolute URI. + secured_uri: must be an HTTPS/SSL URI. + forbidden_uri: is forbidden by the server. + scopes: + not_match_configured: doesn't match configured on the server. + attributes: + doorkeeper/application: + name: Name + redirect_uri: Redirect URI datetime: distance_in_words: half_a_minute: half a minute @@ -343,3 +359,140 @@ en-US: errors: verification_failed: recaptcha_unreachable: + doorkeeper: + applications: + confirmations: + destroy: Are you sure? + buttons: + edit: Edit + destroy: Destroy + submit: Submit + cancel: Cancel + authorize: Authorize + form: + error: Whoops! Check your form for possible errors + help: + confidential: Application will be used where the client secret can be kept + confidential. Native mobile apps and Single Page Apps are considered non-confidential. + redirect_uri: Use one line per URI + blank_redirect_uri: Leave it blank if you configured your provider to use + Client Credentials, Resource Owner Password Credentials or any other grant + type that doesn't require redirect URI. + scopes: Separate scopes with spaces. Leave blank to use the default scopes. + edit: + title: Edit application + index: + title: Your applications + new: New Application + name: Name + callback_url: Callback URL + confidential: Confidential? + actions: Actions + confidentiality: + 'yes': 'Yes' + 'no': 'No' + new: + title: New Application + show: + title: 'Application: %{name}' + application_id: Application UID + secret: Secret + secret_hashed: + scopes: Scopes + confidential: Confidential + callback_urls: Callback urls + actions: Actions + not_defined: + authorizations: + buttons: + authorize: Authorize + deny: Deny + error: + title: An error has occurred + new: + title: Authorization required + prompt: Authorize %{client_name} to use your account? + able_to: This application will be able to + show: + title: Authorization code + form_post: + title: + authorized_applications: + confirmations: + revoke: Are you sure? + buttons: + revoke: Revoke + index: + title: Your authorized applications + application: Application + created_at: Created At + date_format: "%Y-%m-%d %H:%M:%S" + pre_authorization: + status: Pre-authorization + errors: + messages: + invalid_request: + unknown: The request is missing a required parameter, includes an unsupported + parameter value, or is otherwise malformed. + missing_param: 'Missing required parameter: %{value}.' + request_not_authorized: Request need to be authorized. Required parameter + for authorizing request is missing or invalid. + invalid_code_challenge: + invalid_redirect_uri: The requested redirect uri is malformed or doesn't match + client redirect URI. + unauthorized_client: The client is not authorized to perform this request + using this method. + access_denied: The resource owner or authorization server denied the request. + invalid_scope: The requested scope is invalid, unknown, or malformed. + invalid_code_challenge_method: + zero: + one: + other: + server_error: The authorization server encountered an unexpected condition + which prevented it from fulfilling the request. + temporarily_unavailable: The authorization server is currently unable to handle + the request due to a temporary overloading or maintenance of the server. + credential_flow_not_configured: Resource Owner Password Credentials flow failed + due to Doorkeeper.configure.resource_owner_from_credentials being unconfigured. + resource_owner_authenticator_not_configured: Resource Owner find failed due + to Doorkeeper.configure.resource_owner_authenticator being unconfigured. + admin_authenticator_not_configured: Access to admin panel is forbidden due + to Doorkeeper.configure.admin_authenticator being unconfigured. + unsupported_response_type: The authorization server does not support this + response type. + unsupported_response_mode: + invalid_client: Client authentication failed due to unknown client, no client + authentication included, or unsupported authentication method. + invalid_grant: The provided authorization grant is invalid, expired, revoked, + does not match the redirection URI used in the authorization request, or + was issued to another client. + unsupported_grant_type: The authorization grant type is not supported by the + authorization server. + invalid_token: + revoked: The access token was revoked + expired: The access token expired + unknown: The access token is invalid + revoke: + unauthorized: You are not authorized to revoke this token + forbidden_token: + missing_scope: + flash: + applications: + create: + notice: Application created. + destroy: + notice: Application deleted. + update: + notice: Application updated. + authorized_applications: + destroy: + notice: Application revoked. + layouts: + admin: + title: Doorkeeper + nav: + oauth2_provider: OAuth2 Provider + applications: Applications + home: Home + application: + title: OAuth authorization required diff --git a/config/locales/translation.es.yml b/config/locales/translation.es.yml index 7491ded07f..ba5ef434ce 100644 --- a/config/locales/translation.es.yml +++ b/config/locales/translation.es.yml @@ -141,6 +141,22 @@ es: restrict_dependent_destroy: has_one: No se puede eliminar el registro porque existe un %{record} dependiente has_many: No se puede eliminar el registro porque existen %{record} dependientes + models: + doorkeeper/application: + attributes: + redirect_uri: + fragment_present: no puede contener un fragmento. + invalid_uri: debe ser una URI válida. + unspecified_scheme: debe especificar un esquema. + relative_uri: debe ser una URI absoluta. + secured_uri: debe ser una URI HTTPS/SSL. + forbidden_uri: está prohibido por el servidor. + scopes: + not_match_configured: doesn't match configured on the server. + attributes: + doorkeeper/application: + name: Nombre + redirect_uri: URI de redirección datetime: distance_in_words: half_a_minute: medio minuto @@ -353,3 +369,144 @@ es: verification_failed: La verificación reCAPTCHA falló, por favor intente nuevamente. recaptcha_unreachable: Vaya, no hemos podido validar su respuesta reCAPTCHA. Inténtalo de nuevo. + doorkeeper: + applications: + confirmations: + destroy: "¿Estás seguro?" + buttons: + edit: Editar + destroy: Eliminar + submit: Enviar + cancel: Cancelar + authorize: Autorizar + form: + error: Ups! Verifica tu formulario por posibles errores + help: + confidential: Application will be used where the client secret can be kept + confidential. Native mobile apps and Single Page Apps are considered non-confidential. + redirect_uri: Usa una linea por URI + blank_redirect_uri: Leave it blank if you configured your provider to use + Client Credentials, Resource Owner Password Credentials or any other grant + type that doesn't require redirect URI. + scopes: Separa los ámbitos con espacios. Deja en blanco para usar los ámbitos + predeterminados. + edit: + title: Editar aplicación + index: + title: Tus aplicaciones + new: Nueva aplicación + name: Nombre + callback_url: Callback URL + confidential: Confidential? + actions: Actions + confidentiality: + 'yes': Sí + 'no': 'No' + new: + title: Nueva aplicación + show: + title: 'Aplicación: %{name}' + application_id: Identificador de aplicación + secret: Secret + secret_hashed: + scopes: Ámbitos + confidential: Confidential + callback_urls: Callback urls + actions: Acciones + not_defined: + authorizations: + buttons: + authorize: Autorizar + deny: Denegar + error: + title: Ha ocurrido un error + new: + title: Autorización requerida + prompt: "¿Autorizas a %{client_name} para usar tu cuenta?" + able_to: Está aplicación tendrá permisos para + show: + title: Código de autorización + form_post: + title: + authorized_applications: + confirmations: + revoke: "¿Estás seguro?" + buttons: + revoke: Revocar + index: + title: Tus aplicaciones autorizadas + application: Aplicación + created_at: Creada el + date_format: "%d/%m/%Y %H:%M:%S" + pre_authorization: + status: Pre-authorization + errors: + messages: + invalid_request: + unknown: La petición no tiene un parámetro obligatorio, incluye un valor + de parámetro incompatible, o tiene un formato incorrecto. + missing_param: 'Missing required parameter: %{value}.' + request_not_authorized: Request need to be authorized. Required parameter + for authorizing request is missing or invalid. + invalid_code_challenge: + invalid_redirect_uri: La uri de redirección no es valida. + unauthorized_client: El cliente no tiene autorización para realizar esta petición + utilizando este método. + access_denied: El propietario del recurso o el servidor de autorización han + denegado la petición. + invalid_scope: El scope solicitado no es válido, es desconocido, o tiene un + formato incorrecto. + invalid_code_challenge_method: + zero: + one: + other: + server_error: El servidor de autorización ha encontrado una condición inesperada + que le ha impedido completar la petición. + temporarily_unavailable: El servidor de autorización no ha podido manejar + la petición por una sobrecarga temporal o por mantenimiento del servidor. + credential_flow_not_configured: El flujo de credenciales del propietario del + recurso ha fallado porque Doorkeeper.configure.resource_owner_from_credentials + no está configurado. + resource_owner_authenticator_not_configured: La búsqueda del propietario del + recurso ha fallado porque Doorkeeper.configure.resource_owner_authenticator + no está configurado. + admin_authenticator_not_configured: Access to admin panel is forbidden due + to Doorkeeper.configure.admin_authenticator being unconfigured. + unsupported_response_type: El servidor de autorización no soporta este tipo + de respuesta. + unsupported_response_mode: + invalid_client: La autenticación del cliente ha fallado por cliente desconocido, + cliente no autenticado, o método de autenticación incompatible. + invalid_grant: La autorización proporcionada no es válida, ha expirado, se + ha revocado, no coincide con la URI de redirección utilizada en la petición + de autorización, o ha sido solicitada por otro cliente. + unsupported_grant_type: El tipo de autorización no está soportada por el servidor + de autorización. + invalid_token: + revoked: El token de acceso ha sido revocado + expired: El token de acceso ha expirado + unknown: El token de acceso es inválido + revoke: + unauthorized: No tiene autorización para revocar este token + forbidden_token: + missing_scope: + flash: + applications: + create: + notice: Aplicación creada. + destroy: + notice: Aplicación eliminada. + update: + notice: Aplicación actualizada. + authorized_applications: + destroy: + notice: Aplicación revocada. + layouts: + admin: + title: Doorkeeper + nav: + oauth2_provider: Proveedor OAuth2 + applications: Aplicaciones + home: Home + application: + title: Autorización OAuth requerida diff --git a/config/locales/translation.fi.yml b/config/locales/translation.fi.yml index 7b6eda4977..287ae72e94 100644 --- a/config/locales/translation.fi.yml +++ b/config/locales/translation.fi.yml @@ -138,6 +138,22 @@ fi: restrict_dependent_destroy: has_one: Ei voida poistaa mallia koska tästä riippuvainen %{record} löytyy has_many: Ei voida poistaa mallia koska tästä riippuvaisia %{record} löytyy + models: + doorkeeper/application: + attributes: + redirect_uri: + fragment_present: ei voi sisältää URI fragmenttia. + invalid_uri: täytyy olla validi URI. + unspecified_scheme: täytyy määrittää järjestelmä. + relative_uri: täytyy olla absoluuttinen URI. + secured_uri: täytyy olla HTTPS/SSL URI. + forbidden_uri: on kielletty palvelimella. + scopes: + not_match_configured: doesn't match configured on the server. + attributes: + doorkeeper/application: + name: Nimi + redirect_uri: Uudelleenohjauksen URI datetime: distance_in_words: half_a_minute: puoli minuuttia @@ -346,3 +362,143 @@ fi: verification_failed: reCAPTCHA-vahvistus epäonnistui, yritä uudelleen. recaptcha_unreachable: Hups, emme vahvistaneet reCAPTCHA-vastaustasi. Yritä uudelleen. + doorkeeper: + applications: + confirmations: + destroy: Oletko varma? + buttons: + edit: Muokkaa + destroy: Poista + submit: Lähetä + cancel: Peruuta + authorize: Valtuuta + form: + error: Hups! Tarkasta lomakkeesi mahdollisten virheiden varalta. + help: + confidential: Application will be used where the client secret can be kept + confidential. Native mobile apps and Single Page Apps are considered non-confidential. + redirect_uri: Yksi URI riviä kohden + blank_redirect_uri: Leave it blank if you configured your provider to use + Client Credentials, Resource Owner Password Credentials or any other grant + type that doesn't require redirect URI. + scopes: Erottele näkyvyysalueet välilyönnein. Jätä tyhjäksi, mikäli haluat + käyttää oletusnäkyvyysalueita. + edit: + title: Muokkaa sovellusta + index: + title: Omat sovellukset + new: Uusi sovellus + name: Nimi + callback_url: Callback URL + confidential: Confidential? + actions: Actions + confidentiality: + 'yes': Joo + 'no': Ei + new: + title: Uusi sovellus + show: + title: 'Sovellus: %{name}' + application_id: Sovelluksen UID + secret: Salainen avain + secret_hashed: Salainen tiivistetty + scopes: Näkyvyysalueet + confidential: Confidential + callback_urls: Callback URL:t + actions: Toiminnot + not_defined: Ei määritelty + authorizations: + buttons: + authorize: Valtuuta + deny: Kiellä + error: + title: Virhe + new: + title: Valtuutus vaadittu + prompt: Valtuuta %{client_name} käyttämään tiliäsi? + able_to: Tämä sovellus pystyy + show: + title: Valtuutuskoodi + form_post: + title: Lähetä tämä lomake + authorized_applications: + confirmations: + revoke: Oletko varma? + buttons: + revoke: Evää + index: + title: Valtuuttamasi sovellukset + application: Sovellukset + created_at: Valtuutettu + date_format: "%d. %m. %Y klo %H:%M:%S" + pre_authorization: + status: Pre-authorization + errors: + messages: + invalid_request: + unknown: Pyynnöstä puuttuu vaadittu parametri, se sisältää virheellisen + parametrin arvon tai on muutoin väärin muodostettu. + missing_param: 'Missing required parameter: %{value}.' + request_not_authorized: Request need to be authorized. Required parameter + for authorizing request is missing or invalid. + invalid_code_challenge: + invalid_redirect_uri: Uudelleenohjauksen URI ei ole validi. + unauthorized_client: Asiakasohjelmaa ei ole valtuutettu suorittamaan haluttua + pyyntöä käyttäen tätä metodia. + access_denied: Resurssin omistaja tai valtuutuspalvelin kieltäytyi suorittamasta + pyyntöä. + invalid_scope: Pyynnön näkyvyysalue on virheellinen, tuntematon tai väärin + muodostettu. + invalid_code_challenge_method: + zero: Valtuutuspalvelin ei tue PKCE:tä, koska hyväksyttyjä code_challenge_method-arvoja + ei ole. + one: Koodihaastemetodin on oltava muotoa %{challenge_methods}. + other: 'Koodihaastemetodin on oltava jokin seuraavista: %{challenge_methods}.' + server_error: Valtuutuspalvelin kohtasi odottamattoman tilan, jonka seurauksena + se ei pystynyt suorittamaan pyyntöä. + temporarily_unavailable: Valtuutuspalvelin ei tällä hetkellä pysty suorittamaan + pyyntöä väliaikaisen ylikuormituksen tai palvelinhuollon takia. + credential_flow_not_configured: '"Resource Owner Password Credentials flow" + - proseduuri epäonnistui, koska Doorkeeper.configure.resource_owner_from_credentials + -asetusta ei ole konfiguroitu.' + resource_owner_authenticator_not_configured: '"Resource Owner find" - proseduuri + epäonnistui, koska Doorkeeper.configure.resource_owner_authenticator -asetusta + ei ole konfiguroitu.' + admin_authenticator_not_configured: Access to admin panel is forbidden due + to Doorkeeper.configure.admin_authenticator being unconfigured. + unsupported_response_type: Valtuutuspalvelin ei tue tämän tyyppisiä vastauksia. + unsupported_response_mode: Valtuutuspalvelin ei tue tätä vastaustilaa. + invalid_client: Asiakasohjelman valtuutus epäonnistui tuntemattoman asiakasohjelman, + virheellisen valtuutuksen tai tukemattoman valtuutusmetodin takia. + invalid_grant: Toimitettu valtuutus on virheellinen, vanhentunut, evätty, + se ei vastaa valtuutuspyynnön uudelleenohjauksen URI:a tai sen on myöntänyt + toinen asiakasohjelma. + unsupported_grant_type: Valtuutuspalvelin ei tue tämän tyyppisiä valtuutuksia. + invalid_token: + revoked: Pääsyoikeus evätty + expired: Pääsyoikeus vanhentunut + unknown: Pääsyoikeus virheellinen + revoke: + unauthorized: You are not authorized to revoke this token + forbidden_token: + missing_scope: Tämän resurssin käyttö edellyttää laajuutta "%{oauth_scopes}". + flash: + applications: + create: + notice: Sovellus luotu. + destroy: + notice: Sovellus poistettu. + update: + notice: Sovellus päivitetty. + authorized_applications: + destroy: + notice: Sovellus evätty. + layouts: + admin: + title: Doorkeeper + nav: + oauth2_provider: OAuth2 tarjoaja + applications: Sovellukset + home: Etusivu + application: + title: OAuth valtuutus vaadittu. diff --git a/config/locales/translation.fr-CA.yml b/config/locales/translation.fr-CA.yml index 8f23004765..10db3d80b6 100644 --- a/config/locales/translation.fr-CA.yml +++ b/config/locales/translation.fr-CA.yml @@ -144,6 +144,22 @@ fr-CA: la) %{record} dépendant(e) has_many: Vous ne pouvez pas supprimer l’enregistrement en raison du (de la) %{record} dépendant(e) + models: + doorkeeper/application: + attributes: + redirect_uri: + fragment_present: ne peut contenir un fragment. + invalid_uri: doit être une URL valide. + unspecified_scheme: doit spécifier un schéma. + relative_uri: doit être une URL absolue. + secured_uri: doit être une URL HTTP/SSL. + forbidden_uri: est interdit par le serveur. + scopes: + not_match_configured: doesn't match configured on the server. + attributes: + doorkeeper/application: + name: Nom + redirect_uri: L'URL de redirection datetime: distance_in_words: half_a_minute: une demi-minute @@ -242,7 +258,8 @@ fr-CA: not_found_in_database: "%{authentication_keys} ou mot de passe incorrect." timeout: Votre session est expirée. Veuillez vous reconnecter pour continuer. unauthenticated: Vous devez vous connecter ou vous inscrire pour continuer. - unconfirmed: Vous devez confirmer votre adresse courriel pour continuer. + unconfirmed: Vous devez confirmer votre compte avant de continuer. (cliquez pour demander un nouveau courriel de confirmation) invited: Vous avez une invitation en attente. Acceptez-la pour terminer la création de votre compte. mailer: @@ -363,3 +380,148 @@ fr-CA: previous: "‹ précédent(e)" next: "› suivant(e)" truncate: "…" + doorkeeper: + applications: + confirmations: + destroy: Êtes-vous certain? + buttons: + edit: Modifier + destroy: Supprimer + submit: Envoyer + cancel: Annuler + authorize: Autoriser + form: + error: Oups! Vérifier votre formulaire pour des erreurs possibles + help: + confidential: | + L'application sera utilisée quand la confidentialité du secret pourra + être maintenue. Les application mobile native, et les Applications + mono-page ne sont pas considérées comme sûr. + redirect_uri: Utiliser une ligne par URL + blank_redirect_uri: Leave it blank if you configured your provider to use + Client Credentials, Resource Owner Password Credentials or any other grant + type that doesn't require redirect URI. + scopes: Utilisez un espace entre chaque portée. Laissez vide pour utiliser + la portée par defaut + edit: + title: Modifier l'application + index: + title: Vos applications + new: Nouvelle application + name: Nom + callback_url: URL de retour d'appel + confidential: Confidential? + actions: Actions + confidentiality: + 'yes': Oui + 'no': Non + new: + title: Nouvelle application + show: + title: 'Application : %{name}' + application_id: ID de l'application + secret: Secret + secret_hashed: + scopes: Portées + confidential: Confidential + callback_urls: URL du retour d'appel + actions: Actions + not_defined: + authorizations: + buttons: + authorize: Autoriser + deny: Refuser + error: + title: Une erreur est survenue + new: + title: Autorisation requise + prompt: Autorisez %{client_name} à utiliser votre compte? + able_to: Cette application pourra + show: + title: Code d'autorisation + form_post: + title: + authorized_applications: + confirmations: + revoke: Êtes-vous certain? + buttons: + revoke: Annuler + index: + title: Vos applications autorisées + application: Application + created_at: Créé le + date_format: "%Y-%m-%d %H:%M:%S" + pre_authorization: + status: Pre-authorization + errors: + messages: + invalid_request: + unknown: La demande manque un paramètre requis, inclut une valeur de paramètre + non prise en charge, ou est autrement mal formée. + missing_param: 'Missing required parameter: %{value}.' + request_not_authorized: Request need to be authorized. Required parameter + for authorizing request is missing or invalid. + invalid_code_challenge: + invalid_redirect_uri: L'URL de redirection n'est pas valide. + unauthorized_client: Le client n'est pas autorisé à effectuer cette demande + à l'aide de cette méthode. + access_denied: Le propriétaire de la ressource ou le serveur d'autorisation + a refusé la demande. + invalid_scope: Le scope demandé n'est pas valide, est inconnu, ou est mal + formé. + invalid_code_challenge_method: + zero: + one: + other: + server_error: Le serveur d'autorisation a rencontré une condition inattendue + qui l'a empêché de remplir la demande. + temporarily_unavailable: Le serveur d'autorisation est actuellement incapable + de traiter la demande à cause d'une surcharge ou d'un entretien temporaire + du serveur. + credential_flow_not_configured: Le flux des identifiants du mot de passe du + propriétaire de la ressource a échoué en raison de Doorkeeper.configure.resource_owner_from_credentials + n'est pas configuré. + resource_owner_authenticator_not_configured: La recherche du propriétaire + de la ressource a échoué en raison de Doorkeeper.configure.resource_owner_authenticator + n'est pas configuré. + admin_authenticator_not_configured: Access to admin panel is forbidden due + to Doorkeeper.configure.admin_authenticator being unconfigured. + unsupported_response_type: Le serveur d'autorisation ne prend pas en charge + ce type de réponse. + unsupported_response_mode: + invalid_client: L'authentification du client a échoué à cause d'un client + inconnu, d'aucune authentification de client incluse, ou d'une méthode d'authentification + non prise en charge. + invalid_grant: Le consentement d'autorisation accordé n'est pas valide, a + expiré, est annulé, ne concorde pas avec l'URL de redirection utilisée dans + la demande d'autorisation, ou a été émis à un autre client. + unsupported_grant_type: Le type de consentement d'autorisation n'est pas pris + en charge par le serveur d'autorisation. + invalid_token: + revoked: Le jeton d'accès a été annulé + expired: Le jeton d'accès a expiré + unknown: Le jeton d'accès n'est pas valide + revoke: + unauthorized: Vous n'êtes pas autorisé à révoquer ce jeton + forbidden_token: + missing_scope: + flash: + applications: + create: + notice: Application créée. + destroy: + notice: Application supprimée. + update: + notice: Application mise à jour. + authorized_applications: + destroy: + notice: Application annulée. + layouts: + admin: + title: Doorkeeper + nav: + oauth2_provider: Fournisseur OAuth2 + applications: Applications + home: Home + application: + title: Autorisation OAuth requise diff --git a/config/locales/translation.fr-FR.yml b/config/locales/translation.fr-FR.yml index ea80971e67..d541b9a742 100644 --- a/config/locales/translation.fr-FR.yml +++ b/config/locales/translation.fr-FR.yml @@ -144,6 +144,22 @@ fr-FR: dépendant(e) existe has_many: Vous ne pouvez pas supprimer l'enregistrement parce que les %{record} dépendants existent + models: + doorkeeper/application: + attributes: + redirect_uri: + fragment_present: ne peut contenir un fragment. + invalid_uri: doit être une URL valide. + unspecified_scheme: doit spécifier un schéma. + relative_uri: doit être une URL absolue. + secured_uri: doit être une URL HTTP/SSL. + forbidden_uri: est interdit par le serveur. + scopes: + not_match_configured: doesn't match configured on the server. + attributes: + doorkeeper/application: + name: Nom + redirect_uri: L'URL de redirection datetime: distance_in_words: half_a_minute: une demi-minute @@ -360,3 +376,148 @@ fr-FR: verification_failed: La vérification reCAPTCHA a échoué, veuillez réessayer. recaptcha_unreachable: Oups, nous n'avons pas réussi à valider votre réponse reCAPTCHA. Veuillez réessayer. + doorkeeper: + applications: + confirmations: + destroy: Êtes-vous certain? + buttons: + edit: Modifier + destroy: Supprimer + submit: Envoyer + cancel: Annuler + authorize: Autoriser + form: + error: Oups! Vérifier votre formulaire pour des erreurs possibles + help: + confidential: | + L'application sera utilisée quand la confidentialité du secret pourra + être maintenue. Les application mobile native, et les Applications + mono-page ne sont pas considérées comme sûr. + redirect_uri: Utiliser une ligne par URL + blank_redirect_uri: Leave it blank if you configured your provider to use + Client Credentials, Resource Owner Password Credentials or any other grant + type that doesn't require redirect URI. + scopes: Utilisez un espace entre chaque portée. Laissez vide pour utiliser + la portée par defaut + edit: + title: Modifier l'application + index: + title: Vos applications + new: Nouvelle application + name: Nom + callback_url: URL de retour d'appel + confidential: Confidential? + actions: Actions + confidentiality: + 'yes': Oui + 'no': Non + new: + title: Nouvelle application + show: + title: 'Application : %{name}' + application_id: ID de l'application + secret: Secret + secret_hashed: + scopes: Portées + confidential: Confidential + callback_urls: URL du retour d'appel + actions: Actions + not_defined: + authorizations: + buttons: + authorize: Autoriser + deny: Refuser + error: + title: Une erreur est survenue + new: + title: Autorisation requise + prompt: Autorisez %{client_name} à utiliser votre compte? + able_to: Cette application pourra + show: + title: Code d'autorisation + form_post: + title: + authorized_applications: + confirmations: + revoke: Êtes-vous certain? + buttons: + revoke: Annuler + index: + title: Vos applications autorisées + application: Application + created_at: Créé le + date_format: "%Y-%m-%d %H:%M:%S" + pre_authorization: + status: Pre-authorization + errors: + messages: + invalid_request: + unknown: La demande manque un paramètre requis, inclut une valeur de paramètre + non prise en charge, ou est autrement mal formée. + missing_param: 'Missing required parameter: %{value}.' + request_not_authorized: Request need to be authorized. Required parameter + for authorizing request is missing or invalid. + invalid_code_challenge: + invalid_redirect_uri: L'URL de redirection n'est pas valide. + unauthorized_client: Le client n'est pas autorisé à effectuer cette demande + à l'aide de cette méthode. + access_denied: Le propriétaire de la ressource ou le serveur d'autorisation + a refusé la demande. + invalid_scope: Le scope demandé n'est pas valide, est inconnu, ou est mal + formé. + invalid_code_challenge_method: + zero: + one: + other: + server_error: Le serveur d'autorisation a rencontré une condition inattendue + qui l'a empêché de remplir la demande. + temporarily_unavailable: Le serveur d'autorisation est actuellement incapable + de traiter la demande à cause d'une surcharge ou d'un entretien temporaire + du serveur. + credential_flow_not_configured: Le flux des identifiants du mot de passe du + propriétaire de la ressource a échoué en raison de Doorkeeper.configure.resource_owner_from_credentials + n'est pas configuré. + resource_owner_authenticator_not_configured: La recherche du propriétaire + de la ressource a échoué en raison de Doorkeeper.configure.resource_owner_authenticator + n'est pas configuré. + admin_authenticator_not_configured: Access to admin panel is forbidden due + to Doorkeeper.configure.admin_authenticator being unconfigured. + unsupported_response_type: Le serveur d'autorisation ne prend pas en charge + ce type de réponse. + unsupported_response_mode: + invalid_client: L'authentification du client a échoué à cause d'un client + inconnu, d'aucune authentification de client incluse, ou d'une méthode d'authentification + non prise en charge. + invalid_grant: Le consentement d'autorisation accordé n'est pas valide, a + expiré, est annulé, ne concorde pas avec l'URL de redirection utilisée dans + la demande d'autorisation, ou a été émis à un autre client. + unsupported_grant_type: Le type de consentement d'autorisation n'est pas pris + en charge par le serveur d'autorisation. + invalid_token: + revoked: Le jeton d'accès a été annulé + expired: Le jeton d'accès a expiré + unknown: Le jeton d'accès n'est pas valide + revoke: + unauthorized: Vous n'êtes pas autorisé à révoquer ce jeton + forbidden_token: + missing_scope: + flash: + applications: + create: + notice: Application créée. + destroy: + notice: Application supprimée. + update: + notice: Application mise à jour. + authorized_applications: + destroy: + notice: Application annulée. + layouts: + admin: + title: Doorkeeper + nav: + oauth2_provider: Fournisseur OAuth2 + applications: Applications + home: Home + application: + title: Autorisation OAuth requise diff --git a/config/locales/translation.pt-BR.yml b/config/locales/translation.pt-BR.yml index 9f39d22fb1..dbe1229130 100644 --- a/config/locales/translation.pt-BR.yml +++ b/config/locales/translation.pt-BR.yml @@ -143,6 +143,22 @@ pt-BR: restrict_dependent_destroy: has_one: Não é possível excluir o registro pois existe um %{record} dependente has_many: Não é possível excluir o registro pois existem %{record} dependentes + models: + doorkeeper/application: + attributes: + redirect_uri: + fragment_present: Não pode conter um fragmento. + invalid_uri: deve ser uma URI válida. + unspecified_scheme: must specify a scheme. + relative_uri: dever ser uma URI absoluta. + secured_uri: deve ser uma URI HTTPS/SSL. + forbidden_uri: is forbidden by the server. + scopes: + not_match_configured: doesn't match configured on the server. + attributes: + doorkeeper/application: + name: Nome + redirect_uri: URI de redirecionamento datetime: distance_in_words: half_a_minute: meio minuto @@ -357,3 +373,143 @@ pt-BR: verification_failed: A verificação do reCAPTCHA falhou. Tente novamente. recaptcha_unreachable: Ops, não foi possível validar sua resposta do reCAPTCHA. Por favor, tente novamente. + doorkeeper: + applications: + confirmations: + destroy: Você tem certeza? + buttons: + edit: Editar + destroy: Deletar + submit: Submeter + cancel: Cancelar + authorize: Autorizar + form: + error: Whoops! Veja o form para possíveis erros + help: + confidential: Application will be used where the client secret can be kept + confidential. Native mobile apps and Single Page Apps are considered non-confidential. + redirect_uri: Use uma linha por URI + blank_redirect_uri: Leave it blank if you configured your provider to use + Client Credentials, Resource Owner Password Credentials or any other grant + type that doesn't require redirect URI. + scopes: + edit: + title: Editar aplicação + index: + title: Suas aplicações + new: Nova Aplicação + name: Nome + callback_url: URL de Callback + confidential: Confidential? + actions: Actions + confidentiality: + 'yes': Sim + 'no': Não + new: + title: Nova Aplicação + show: + title: 'Aplicação: %{name}' + application_id: Id da Aplicação (Application UID) + secret: Segredo (Secret) + secret_hashed: + scopes: + confidential: Confidential + callback_urls: urls de Callback + actions: Ações + not_defined: + authorizations: + buttons: + authorize: Autorizar + deny: Negar + error: + title: Ocorreu um erro + new: + title: Autorização necessária + prompt: Autorizar %{client_name} a usar sua conta? + able_to: Essa aplicação será capaz de + show: + title: Código de autorização + form_post: + title: + authorized_applications: + confirmations: + revoke: Você tem certeza? + buttons: + revoke: Revogar + index: + title: Suas aplicações autorizadas + application: Aplicação + created_at: Criado em + date_format: "%Y-%m-%d %H:%M:%S" + pre_authorization: + status: Pre-authorization + errors: + messages: + invalid_request: + unknown: A requisição não possui um parâmetro obrigatório, inclui um parâmetro + inválido ou está malformada. + missing_param: 'Missing required parameter: %{value}.' + request_not_authorized: Request need to be authorized. Required parameter + for authorizing request is missing or invalid. + invalid_code_challenge: + invalid_redirect_uri: A uri de redirecionamento incluída não é válida. + unauthorized_client: O cliente não está autorizado a realizar essa requisição + usando este método. + access_denied: O dono do recurso (resource owner) ou servidor de autorização + (authorization server) negou a requisição. + invalid_scope: O escopo requisitado é inválido, desconhecido ou malformado. + invalid_code_challenge_method: + zero: + one: + other: + server_error: O servidor de autorização (authorization server) encontrou uma + condição inesperada que o impediu de completar a requisição. + temporarily_unavailable: O servidor de autorização (authorization server) + não foi rapaz de processar a requisição devido a um problema tempoário de + sobrecarga ou manuntenção. + credential_flow_not_configured: Resource Owner Password Credentials flow falhou + porque o Doorkeeper.configure.resource_owner_from_credentials não foi configurado. + resource_owner_authenticator_not_configured: Resource Owner find falhou porque + o Doorkeeper.configure.resource_owner_authenticator não foi configurado. + admin_authenticator_not_configured: Access to admin panel is forbidden due + to Doorkeeper.configure.admin_authenticator being unconfigured. + unsupported_response_type: O servidor de autorização não suporta este tipo + de resposta. + unsupported_response_mode: + invalid_client: Autenticação do cliente falhou devido a um cliente desconhecido, + a falta de inclusão da autenticação do cliente, ou a um método não suportado + de autenticação. + invalid_grant: A permissão de autorização (authorization grant) provida é + inválida, expirada, revogada, não bate com a URI de redirecionamento usada + na requisição de autorização, ou foi dada a outro cliente. + unsupported_grant_type: O tipo de permissão de autorização (authorization + grant) não é suportado pelo servidor de autorização(authorization server) + The authorization grant type is not supported by the authorization server. + invalid_token: + revoked: O token de acesso (access token) foi revogado + expired: O token de acesso (access token) expirou + unknown: O token de acesso (access token) é inválido + revoke: + unauthorized: You are not authorized to revoke this token + forbidden_token: + missing_scope: + flash: + applications: + create: + notice: Aplicação criada. + destroy: + notice: Aplicação deletada. + update: + notice: Aplicação atualizada. + authorized_applications: + destroy: + notice: Aplicação revogada. + layouts: + admin: + title: Doorkeeper + nav: + oauth2_provider: Provedor OAuth2 (OAuth2 Provider) + applications: Aplicações + home: Home + application: + title: Autorização OAuth necessária diff --git a/config/locales/translation.sv-FI.yml b/config/locales/translation.sv-FI.yml index db0e54cc33..9a8a99b0b3 100644 --- a/config/locales/translation.sv-FI.yml +++ b/config/locales/translation.sv-FI.yml @@ -141,6 +141,22 @@ sv-FI: restrict_dependent_destroy: has_one: Kan inte ta bort post då beroende %{record} finns has_many: Kan inte ta bort poster då beroende %{record} finns + models: + doorkeeper/application: + attributes: + redirect_uri: + fragment_present: + invalid_uri: + unspecified_scheme: + relative_uri: + secured_uri: + forbidden_uri: + scopes: + not_match_configured: + attributes: + doorkeeper/application: + name: Namn + redirect_uri: datetime: distance_in_words: half_a_minute: en halv minut @@ -351,3 +367,123 @@ sv-FI: verification_failed: verifiering av reCAPTCHA misslyckades, försök igen. recaptcha_unreachable: Oj, vi kunde inte validera ditt reCAPTCHA-svar. Var god försök igen. + doorkeeper: + applications: + confirmations: + destroy: Är du säker? + buttons: + edit: Redigera + destroy: + submit: Skicka + cancel: Annullera + authorize: + form: + error: + help: + confidential: + redirect_uri: + blank_redirect_uri: + scopes: + edit: + title: + index: + title: + new: + name: Namn + callback_url: + confidential: + actions: Åtgärder + confidentiality: + 'yes': Ja + 'no': Nej + new: + title: + show: + title: + application_id: + secret: + secret_hashed: + scopes: + confidential: + callback_urls: + actions: Åtgärder + not_defined: + authorizations: + buttons: + authorize: + deny: + error: + title: + new: + title: + prompt: + able_to: + show: + title: + form_post: + title: + authorized_applications: + confirmations: + revoke: Är du säker? + buttons: + revoke: + index: + title: + application: + created_at: + date_format: + pre_authorization: + status: + errors: + messages: + invalid_request: + unknown: + missing_param: + request_not_authorized: + invalid_code_challenge: + invalid_redirect_uri: + unauthorized_client: + access_denied: + invalid_scope: + invalid_code_challenge_method: + zero: + one: + other: + server_error: + temporarily_unavailable: + credential_flow_not_configured: + resource_owner_authenticator_not_configured: + admin_authenticator_not_configured: + unsupported_response_type: + unsupported_response_mode: + invalid_client: + invalid_grant: + unsupported_grant_type: + invalid_token: + revoked: + expired: + unknown: + revoke: + unauthorized: + forbidden_token: + missing_scope: + flash: + applications: + create: + notice: + destroy: + notice: + update: + notice: + authorized_applications: + destroy: + notice: + layouts: + admin: + title: + nav: + oauth2_provider: + applications: + home: Hem + application: + title: diff --git a/config/locales/translation.tr-TR.yml b/config/locales/translation.tr-TR.yml index ce56653e18..379e8db76e 100644 --- a/config/locales/translation.tr-TR.yml +++ b/config/locales/translation.tr-TR.yml @@ -146,6 +146,22 @@ tr-TR: restrict_dependent_destroy: has_one: Bağlı bir %{record} bulunduğu için kayıt silinemiyor has_many: Bağlı %{record} bulunduğu için kayıt silinemiyor + models: + doorkeeper/application: + attributes: + redirect_uri: + fragment_present: + invalid_uri: + unspecified_scheme: + relative_uri: + secured_uri: + forbidden_uri: + scopes: + not_match_configured: + attributes: + doorkeeper/application: + name: isim + redirect_uri: datetime: distance_in_words: half_a_minute: yarım dakika @@ -351,3 +367,123 @@ tr-TR: notices: error: Her iki alanı da doldurmalısınız. success: İletişim e-postası başarıyla gönderildi. + doorkeeper: + applications: + confirmations: + destroy: Emin misiniz? + buttons: + edit: Düzenle + destroy: + submit: Gönder + cancel: İptal + authorize: + form: + error: + help: + confidential: + redirect_uri: + blank_redirect_uri: + scopes: + edit: + title: + index: + title: + new: + name: isim + callback_url: + confidential: + actions: Eylemler + confidentiality: + 'yes': Evet + 'no': Yok + new: + title: + show: + title: + application_id: + secret: + secret_hashed: + scopes: + confidential: + callback_urls: + actions: Eylemler + not_defined: + authorizations: + buttons: + authorize: + deny: + error: + title: + new: + title: + prompt: + able_to: + show: + title: + form_post: + title: + authorized_applications: + confirmations: + revoke: Emin misiniz? + buttons: + revoke: + index: + title: + application: + created_at: + date_format: + pre_authorization: + status: + errors: + messages: + invalid_request: + unknown: + missing_param: + request_not_authorized: + invalid_code_challenge: + invalid_redirect_uri: + unauthorized_client: + access_denied: + invalid_scope: + invalid_code_challenge_method: + zero: + one: + other: + server_error: + temporarily_unavailable: + credential_flow_not_configured: + resource_owner_authenticator_not_configured: + admin_authenticator_not_configured: + unsupported_response_type: + unsupported_response_mode: + invalid_client: + invalid_grant: + unsupported_grant_type: + invalid_token: + revoked: + expired: + unknown: + revoke: + unauthorized: + forbidden_token: + missing_scope: + flash: + applications: + create: + notice: + destroy: + notice: + update: + notice: + authorized_applications: + destroy: + notice: + layouts: + admin: + title: + nav: + oauth2_provider: + applications: + home: Ana sayfa + application: + title: